/* ============================================================
   Paper & Volt — production stylesheet for the Chart My Path funnel.
   Design system lifted verbatim from design/paper-volt/reference.html
   (the authoritative component CSS), plus funnel-screen layout.
   THE ONE RULE: volt (#D4F84C) is a highlight fill, never a text colour.
   ============================================================ */
:root {
  --paper: #F3F0E6; --paper-soft: #E9E5D8; --surface: #FFFFFF;
  --ink: #141310; --ink-soft: #5A574E; --volt: #D4F84C; --shadow: #141310;
  --edge-purple: #7C5CFF; --edge-gold: #E0A32E; --edge-green: #2E9E5B; --edge-red: #E5484D;
  /* Status TEXT colours. --edge-green/--edge-red are fill colours: as text on
     --paper they measure 2.99:1 and 3.43:1, both below WCAG AA. These are the
     hardened text-only variants (4.69:1 and 5.53:1 on light paper, 7.8:1 and
     6.7:1 on dark), ported from app/hub/css/hub.css so the two Paper & Volt
     surfaces agree. Never point .save-status back at --edge-*. */
  --status-ok: #147A4A; --status-err: #B3301C;
  --on-volt: #141310; --on-dark: #F3F0E6;
  --font-display: "Archivo", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", "Inter", Roboto, Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --bw: 2px;
  --sh-card: 6px 6px 0 var(--shadow); --sh-card-hover: 4px 4px 0 var(--shadow);
  --sh-btn: 5px 5px 0 var(--shadow); --sh-btn-hover: 3px 3px 0 var(--shadow); --sh-btn-active: 0 0 0 var(--shadow);
  --sh-chip: 3px 3px 0 var(--shadow);
}
/* Dark --paper-soft is #26251E, matching hub.css. It was #1E1E1A until
   2026-07-27: only 2 units per channel off --surface (#1C1C19), which made
   .suggest li separators and their hover fill effectively invisible in dark
   theme on the role-search dropdown — this door's primary interaction.
   --paper-soft's whole job is to be a visible step off the base surface, so
   both P&V files now carry the value that actually reads. */
@media (prefers-color-scheme: dark) {
  :root {
    --paper: #141412; --paper-soft: #26251E; --surface: #1C1C19;
    --ink: #F3F0E6; --ink-soft: #B4AEA0; --volt: #D4F84C; --shadow: #000000;
    --edge-purple: #9B84FF; --edge-gold: #F0B93E; --edge-green: #3FBE73; --edge-red: #FF6B70; --on-dark: #141310;
    --status-ok: #3FBE73; --status-err: #FF6B70;
  }
}
:root[data-theme="dark"] {
  --paper: #141412; --paper-soft: #26251E; --surface: #1C1C19;
  --ink: #F3F0E6; --ink-soft: #B4AEA0; --volt: #D4F84C; --shadow: #000000;
  --edge-purple: #9B84FF; --edge-gold: #F0B93E; --edge-green: #3FBE73; --edge-red: #FF6B70; --on-dark: #141310;
  --status-ok: #3FBE73; --status-err: #FF6B70;
}
:root[data-theme="light"] {
  --paper: #F3F0E6; --paper-soft: #E9E5D8; --surface: #FFFFFF;
  --ink: #141310; --ink-soft: #5A574E; --volt: #D4F84C; --shadow: #141310;
  --edge-purple: #7C5CFF; --edge-gold: #E0A32E; --edge-green: #2E9E5B; --edge-red: #E5484D; --on-dark: #F3F0E6;
  --status-ok: #147A4A; --status-err: #B3301C;
}

* { box-sizing: border-box; border-radius: 0; }
[hidden] { display: none !important; } /* author display rules (e.g. .badge) must never defeat the hidden attribute */
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; background: var(--paper); color: var(--ink);
  font-family: var(--font-body); font-size: 16px; line-height: 1.55;
  overflow-x: hidden; transition: background-color .15s ease, color .15s ease;
}
img, svg { display: block; max-width: 100%; }
a { color: var(--ink); text-decoration-thickness: 2px; text-underline-offset: 3px; }
::selection { background: var(--volt); color: var(--on-volt); }
:focus-visible { outline: 3px solid var(--ink); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
}
h1, h2, h3, h4 { font-family: var(--font-display); font-weight: 800; margin: 0; color: var(--ink); }
.wrap { max-width: 1120px; margin: 0 auto; padding: 0 24px 96px; }
.mono { font-family: var(--font-mono); }
.tnum { font-variant-numeric: tabular-nums; }
.visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }

/* ---- NAV (slim) ---- */
.nav { position: sticky; top: 0; z-index: 50; background: var(--surface); border-bottom: var(--bw) solid var(--ink); }
.nav-inner { max-width: 1120px; margin: 0 auto; display: flex; align-items: center; gap: 22px; padding: 9px 20px; flex-wrap: wrap; }
.nav-links { display: flex; align-items: center; gap: 26px; list-style: none; margin: 0; padding: 0; flex-wrap: wrap; }
.nav-link { font-family: var(--font-body); font-weight: 600; font-size: 14.5px; color: var(--ink); text-decoration: none; padding-bottom: 6px; border-bottom: 3px solid transparent; white-space: nowrap; }
.nav-link:hover { border-bottom-color: var(--ink-soft); }
.nav-link.active { border-bottom-color: var(--ink); font-weight: 700; }
.nav-actions { display: flex; align-items: center; gap: 18px; margin-left: auto; flex-wrap: wrap; }
.nav-login { font-family: var(--font-body); font-weight: 600; font-size: 14px; color: var(--ink); text-decoration: none; white-space: nowrap; }
.nav-login:hover { text-decoration: underline; }
.theme-toggle { display: inline-flex; border: var(--bw) solid var(--ink); background: var(--surface); }
/* 44px minimum touch target, both dimensions — matching app/hub/css/hub.css's
   fix for the same control. min-height/min-width are a floor: the mobile
   breakpoint below only tightens padding/font-size, never these minimums. */
.theme-toggle button { font-family: var(--font-mono); font-size: 10px; text-transform: uppercase; letter-spacing: .04em; border: none; border-right: 1px solid var(--ink); background: transparent; color: var(--ink); padding: 6px 9px; cursor: pointer; min-height: 44px; min-width: 44px; }
.theme-toggle button:last-child { border-right: none; }
.theme-toggle button[aria-pressed="true"] { background: var(--ink); color: var(--on-dark); }
.theme-toggle button:hover:not([aria-pressed="true"]) { background: var(--paper-soft); }

/* ---- WORDMARK ---- */
.wordmark { display: inline-flex; align-items: center; gap: 10px; font-family: var(--font-display); font-weight: 800; font-size: 17px; color: var(--ink); text-decoration: none; }
.wordmark-mark { width: 30px; height: 30px; background: var(--ink); position: relative; flex: none; }
.wordmark-mark::after { content: ""; position: absolute; left: 8px; top: 4px; width: 6px; height: 22px; background: var(--volt); transform: skewX(-12deg); }
.wordmark-logo { width: 30px; height: 30px; flex: none; }

/* ---- PRIMITIVES ---- */
.card { background: var(--surface); border: var(--bw) solid var(--ink); box-shadow: var(--sh-card); }
.edge-volt { border-left: 6px solid var(--volt); } .edge-gold { border-left: 6px solid var(--edge-gold); }
.edge-red { border-left: 6px solid var(--edge-red); } .edge-purple { border-left: 6px solid var(--edge-purple); }
.section { margin-top: 64px; }
.section-title { display: inline-block; font-family: var(--font-display); font-weight: 800; font-size: 22px; color: var(--ink); padding-bottom: 8px; border-bottom: 4px solid var(--volt); margin: 0 0 28px; }
.section-kicker { font-family: var(--font-mono); font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-soft); margin: 0 0 8px; }
.badge { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-mono); font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; padding: 7px 12px; border: var(--bw) solid var(--ink); box-shadow: var(--sh-chip); background: var(--volt); color: var(--on-volt); }
.chip { display: inline-flex; align-items: center; font-family: var(--font-mono); font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; padding: 7px 13px; border: var(--bw) solid var(--ink); box-shadow: var(--sh-chip); white-space: nowrap; }
.chip-durable { background: var(--volt); color: var(--on-volt); } .chip-augmented { background: var(--edge-gold); color: var(--on-volt); } .chip-exposed { background: var(--edge-red); color: #141310; } /* black on red ≈5.9:1 (cream on red fails AA) */
.source-tag { display: inline-flex; align-items: center; font-family: var(--font-mono); font-size: 11px; color: var(--ink-soft); border: var(--bw) dashed var(--ink-soft); padding: 4px 8px; white-space: nowrap; }
.btn { font-family: var(--font-display); font-weight: 800; font-size: 15px; text-transform: uppercase; letter-spacing: .04em; border: var(--bw) solid var(--ink); padding: 15px 26px; cursor: pointer; box-shadow: var(--sh-btn); transition: transform .08s ease, box-shadow .08s ease; display: inline-flex; align-items: center; justify-content: center; gap: 8px; text-decoration: none; }
.btn:hover, .btn:focus-visible { transform: translate(2px, 2px); box-shadow: var(--sh-btn-hover); }
.btn:active { transform: translate(5px, 5px); box-shadow: var(--sh-btn-active); }
.btn-primary { background: var(--volt); color: var(--on-volt); }
.btn-secondary { background: var(--ink); color: var(--on-dark); }
.btn-sm { padding: 8px 14px; font-size: 11.5px; box-shadow: 3px 3px 0 var(--shadow); }
.btn-sm:hover, .btn-sm:focus-visible { box-shadow: 2px 2px 0 var(--shadow); }
.input { font-family: var(--font-body); font-size: 16px; color: var(--ink); background: var(--surface); border: var(--bw) solid var(--ink); padding: 13px 16px; }
.input::placeholder { color: var(--ink-soft); }

/* ---- LANDING (S-00) ---- */
.pv-landing-main { max-width: 900px; margin: 0 auto; padding: 0 24px 40px; }
.pv-hero { margin-top: 48px; text-align: center; display: flex; flex-direction: column; align-items: center; }
.pv-hero .badge { margin-bottom: 28px; }
.pv-fig { width: 150px; height: 150px; margin-bottom: 8px; }
.pv-fig img { width: 100%; height: 100%; object-fit: contain; }
.pv-fig-cap { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); margin-bottom: 24px; }
.pv-hero h1 { font-weight: 900; text-transform: uppercase; letter-spacing: -.01em; font-size: clamp(40px, 8vw, 76px); line-height: 1.0; margin-bottom: 26px; }
.pv-hero h1 .swipe { position: relative; white-space: nowrap; }
.pv-hero h1 .swipe::after { content: ""; position: absolute; left: -2%; right: -2%; bottom: 0.06em; height: 0.38em; background: var(--volt); z-index: -1; }
/* Dark-mode swipe fix: the thin light-mode highlight bar becomes a
   full-height volt block behind the word in dark mode, so the word itself
   must switch to the on-volt ink color instead of the (now light) --ink —
   otherwise light-on-light text would vanish into the volt fill. */
@media (prefers-color-scheme: dark) {
  .pv-hero h1 .swipe { color: var(--on-volt); }
  .pv-hero h1 .swipe::after { bottom: -0.04em; height: 1.12em; }
}
:root[data-theme="dark"] .pv-hero h1 .swipe { color: var(--on-volt); }
:root[data-theme="dark"] .pv-hero h1 .swipe::after { bottom: -0.04em; height: 1.12em; }
/* An explicit light choice must win even when the OS itself prefers dark. */
:root[data-theme="light"] .pv-hero h1 .swipe { color: inherit; }
:root[data-theme="light"] .pv-hero h1 .swipe::after { bottom: 0.06em; height: 0.38em; }
.pv-hero .lede { max-width: 46ch; font-size: 18px; color: var(--ink-soft); margin: 0 auto 30px; }
.pv-hero-form { display: flex; gap: 12px; flex-wrap: wrap; justify-content: center; align-items: stretch; width: 100%; max-width: 620px; margin: 0 auto 16px; }
.pv-hero-form .input { flex: 1 1 300px; min-width: 0; padding-top: 15px; padding-bottom: 15px; }
.pv-hero-form .btn { flex: 0 0 auto; }
.pv-reassure { font-family: var(--font-mono); font-size: 12.5px; color: var(--ink-soft); letter-spacing: .02em; }

/* value strip */
.pv-values { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 64px; }
.pv-value { padding: 22px; } .pv-value h3 { font-size: 15px; margin-bottom: 8px; } .pv-value p { margin: 0 0 12px; font-size: 14px; color: var(--ink-soft); }
.pv-honesty-strip { margin-top: 40px; display: flex; align-items: flex-start; gap: 12px; padding: 18px 22px; border-left: 4px solid var(--ink); background: var(--paper-soft); font-size: 14px; color: var(--ink-soft); }
.pv-honesty-strip strong { color: var(--ink); }
.pv-browse { margin-top: 28px; text-align: center; }
.pv-browse a { font-family: var(--font-body); font-weight: 600; font-size: 15px; color: var(--ink); }

footer.pv-footer { margin-top: 72px; padding: 24px; border-top: var(--bw) solid var(--ink); font-family: var(--font-mono); font-size: 11.5px; color: var(--ink-soft); text-align: center; }
footer.pv-footer .footer-cross { font-weight: 700; text-decoration: underline; text-underline-offset: 3px; }
footer.pv-footer .footer-cross:hover, footer.pv-footer .footer-cross:focus-visible { color: var(--ink-soft); }

@media (max-width: 720px) {
  .pv-values { grid-template-columns: 1fr; }
}
/* Mobile nav: ONE row — a wrapped two-row sticky nav taxes every viewport.
   The nav CTA hides on phones: the hero form directly below IS the CTA. */
@media (max-width: 460px) {
  .nav-inner { gap: 10px; padding: 8px 12px; flex-wrap: nowrap; }
  .nav-actions { gap: 8px; flex-wrap: nowrap; }
  .nav-actions .btn-sm { display: none; }
  .wordmark { font-size: 14.5px; gap: 7px; }
  .wordmark-logo { width: 24px; height: 24px; }
  .theme-toggle button { padding: 4px 5px; font-size: 8.5px; }
  .nav-login { font-size: 12px; white-space: nowrap; }
}
@media (max-width: 420px) {
  .pv-hero-form { flex-direction: column; } .pv-hero-form .btn { width: 100%; }
}

/* ============================================================
   FLOW SCREENS (S-01 Role · S-02 Guess · Gathering · S-03 Results)
   ONE container width for the whole funnel. This was 760px while
   #screen-results sat in a separate 1120px subtree with its own sticky
   nav, so crossing from the guess step to the chart visibly re-laid the
   page out — the audit's "genuine layout jump". The nav is now page-level
   and permanent (chart.html), and both .flow-main and .results-main run at
   1120px; the intake stays narrow because .cv-anchor is narrow INSIDE this
   container, not because the container itself changes.
   ============================================================ */
.flow-main { max-width: 1120px; margin: 0 auto; padding: 32px 24px 80px; }
.flow-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 28px; gap: 16px; }
.flow-back { font-family: var(--font-mono); font-size: 12px; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-soft); background: none; border: none; cursor: pointer; padding: 6px 0; }
.flow-back:hover { color: var(--ink); }
.flow-kicker { font-family: var(--font-mono); font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-soft); margin: 0 0 10px; }
.flow-h { font-family: var(--font-display); font-weight: 800; font-size: clamp(24px, 4vw, 34px); line-height: 1.1; margin: 0 0 14px; }
.flow-sub { font-size: 15.5px; color: var(--ink-soft); margin: 0 0 28px; max-width: 54ch; }

/* Decision 2A quiet line (job-door results header): typical entry education */
.edu-line { font-size: 12px; color: var(--ink-soft); margin: 10px 0 0; }
.edu-line .source-tag { font-size: 10px; }

/* Fig presence (wrapper screens) — art only, never narrated */
.fig-bar { display: flex; align-items: center; gap: 14px; padding: 12px 0 26px; }
.fig-bar .fig-img { width: 56px; height: 56px; flex: none; }
.fig-bar .fig-img img { width: 100%; height: 100%; object-fit: contain; }
.fig-bar .fig-say { font-size: 14px; color: var(--ink-soft); }
.fig-solo { width: 64px; height: 64px; margin-bottom: 18px; }
.fig-solo img { width: 100%; height: 100%; object-fit: contain; }
/* Fig moments on results — silent art beats between sections */
.fig-moment { display: flex; justify-content: center; margin: 34px 0 -26px; }
.fig-moment img { width: 88px; height: 88px; }

/* Role pills (S-01 zero-typing path) */
.rolepill { font-family: var(--font-body); font-weight: 600; font-size: 14px; color: var(--ink); background: var(--surface); border: var(--bw) solid var(--ink); box-shadow: var(--sh-chip); padding: 10px 16px; cursor: pointer; transition: transform 80ms ease, box-shadow 80ms ease; }
.rolepill:hover, .rolepill:focus-visible { transform: translate(1px, 1px); box-shadow: 2px 2px 0 var(--shadow); }
.rolepill[aria-pressed="true"] { background: var(--ink); color: var(--on-dark); }

/* Role search + suggestions (S-01) */
.role-search { position: relative; }
.role-search .input { width: 100%; }
.suggest { list-style: none; margin: 8px 0 0; padding: 0; border: var(--bw) solid var(--ink); background: var(--surface); }
.suggest:empty { display: none; }
.suggest li { padding: 12px 16px; border-bottom: 1px solid var(--paper-soft); cursor: pointer; font-size: 15px; }
.suggest li:last-child { border-bottom: none; }
.suggest li:hover, .suggest li[aria-selected="true"] { background: var(--paper-soft); }
.role-hint { margin-top: 12px; font-family: var(--font-mono); font-size: 12px; color: var(--ink-soft); }
.flow-actions { display: flex; gap: 12px; align-items: center; margin-top: 30px; flex-wrap: wrap; }
.linklike { background: none; border: none; font-family: var(--font-body); font-weight: 600; font-size: 14.5px; color: var(--ink); cursor: pointer; text-decoration: underline; text-underline-offset: 3px; padding: 0; }
.flow-error { color: var(--edge-red); font-size: 14px; margin-top: 14px; font-weight: 600; }
.flow-error[hidden] { display: none; }

/* Guess slider (S-02) */
.guess-wrap { margin: 20px 0 8px; }
.guess-slider { -webkit-appearance: none; appearance: none; width: 100%; height: 14px; background: var(--paper-soft); border: var(--bw) solid var(--ink); cursor: pointer; }
.guess-slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 26px; height: 26px; background: var(--ink); border: var(--bw) solid var(--ink); cursor: grab; box-shadow: var(--sh-chip); }
.guess-slider.moved::-webkit-slider-thumb { background: var(--volt); }
.guess-slider::-moz-range-thumb { width: 26px; height: 26px; background: var(--ink); border: var(--bw) solid var(--ink); cursor: grab; }
.guess-slider.moved::-moz-range-thumb { background: var(--volt); }
.guess-readout { font-family: var(--font-display); font-weight: 800; font-size: 40px; margin-top: 18px; }
.guess-readout .pct { color: var(--ink); }
.guess-scale { display: flex; justify-content: space-between; font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-soft); margin-top: 6px; }

/* Gathering interstitial — one small, quiet composition */
.gathering { text-align: center; padding: 64px 0; display: flex; flex-direction: column; align-items: center; }
.gathering .g-fig { width: 64px; height: 64px; margin-bottom: 14px; }
.gathering .g-fig img { width: 100%; height: 100%; object-fit: contain; }
.gathering .dots { display: inline-flex; gap: 7px; margin-bottom: 22px; }
.gathering .dots i { width: 10px; height: 10px; background: var(--ink); display: block; animation: g-pulse 1s infinite ease-in-out; }
.gathering .dots i:nth-child(2) { animation-delay: .15s; } .gathering .dots i:nth-child(3) { animation-delay: .3s; }
@keyframes g-pulse { 0%,100% { opacity: .25; } 50% { opacity: 1; background: var(--volt); } }
.gathering h1 { font-size: 21px; margin: 0 0 8px; }
.gathering .g-sub { font-size: 14px; color: var(--ink-soft); max-width: 44ch; margin: 0 0 18px; }

/* ============================================================
   THE CONVERSATION SHELL (J1, approved 2026-07-27)

   The degree door's anchored conversation-card pattern translated into
   Paper & Volt. Same contract as app/degree-cooked/css/flow.css: two
   elements are FIXED for the whole intake and only their contents change,
   so nothing the user is looking at moves between steps. Deliberately NOT
   a receipt-skin port — no printer, no slip, no stamp red, no fixed dark.

   Divergence from the degree door, on purpose: its card height transitions
   (a printer visibly growing its slip is that door's metaphor). This door
   has no printer, so height here is auto and untransitioned — the anchor is
   the card's top edge and width, which never move. Contents cross-fade.
   ============================================================ */

/* Shared transition grammar, same values as flow.css so both doors move
   alike (DESIGN.md §5). t1 is the one custom curve in the system. */
:root {
  --cv-t1-dur: 220ms; --cv-t1-ease: cubic-bezier(.23, 1, .32, 1);
  --cv-t2-dur: 220ms; --cv-t2-ease: ease-out;
}

/* Outcome screens (uncharted) borrow the anchor's measure so the page keeps
   one rhythm, but NOT the class: .cv-anchor means "the conversation anchor",
   and only the shell has one. */
.cv-outcome { width: min(560px, 100%); margin: 0 auto; }

/* Two rules, one row:
   1. min-height — the back link and step counter both disappear during the
      wait, which collapsed this row to zero and lifted Fig and the card 30px,
      the exact drift the anchor exists to prevent. It now holds its height
      whether or not it has anything in it.
   2. the same measure as .cv-anchor — the container is 1120px wide but the
      conversation is 560px, so an un-narrowed row flung "Step 2 of 2" ~200px
      clear of the card's right edge and read as page furniture rather than
      part of the exchange. */
#flow-shell .flow-top, #screen-uncharted .flow-top { min-height: 32px; width: min(560px, 100%); margin-left: auto; margin-right: auto; }

.cv-anchor {
  /* 96px top margin reserves clearance for Fig (top:-46px, 66px tall) and
     a bubble that has grown upward to three lines — both float above this
     box's own top edge and are positioned relative to IT, not the page. */
  width: min(560px, 100%); margin: 96px auto 0; position: relative;
}

/* ---- ANCHOR 1 — Fig. Fixed size + position, never itself animated or
   reflowed by a step change. Only the images inside cross-fade. Kept fully
   transparent, matching flow.css: an opaque backing here would paint a
   rectangle over the card wherever the two overlap. ---- */
.cv-fig { position: absolute; top: -46px; left: 18px; width: 66px; height: 66px; z-index: 3; pointer-events: none; }
.cv-fig-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; opacity: 0; transition: opacity var(--cv-t1-dur) var(--cv-t1-ease); }
.cv-fig-img.is-on { opacity: 1; }

/* ---- ANCHOR 1b — the speech bubble. Anchored by its BOTTOM edge, not its
   top: this door's questions run long ("how much of a typical week in X do
   you think is already durable?"), so the bubble has to grow upward or it
   would push into the card. Bottom edge and tail therefore never move.
   The 2px border is VOLT — this door's own accent, so the pattern reads as
   house style rather than borrowed from /AICookedMyDegree. ---- */
.cv-bubble {
  position: absolute; left: 92px; right: 6px; bottom: 100%; margin-bottom: 10px; z-index: 3;
  background: var(--surface); color: var(--ink); border: var(--bw) solid var(--volt);
  box-shadow: var(--sh-btn); padding: 11px 14px;
  opacity: 0; pointer-events: none; transition: opacity var(--cv-t1-dur) var(--cv-t1-ease);
}
.cv-bubble.is-on { opacity: 1; }
.cv-q { font-family: var(--font-display); font-weight: 800; font-size: clamp(16px, 2.4vw, 20px); line-height: 1.25; margin: 0; outline-offset: 4px; }
/* tail: two stacked triangles sharing one pivot so they stay concentric
   under rotation — a continuous 2px volt outline wrapping bubble->tail with
   no seam (back layer larger all round, offset by the border width). Method
   lifted verbatim from flow.css:84-98 so the two doors draw it identically. */
.cv-bubble::after {
  content: ""; position: absolute; top: 100%; left: -6px; margin-top: -2px;
  width: 0; height: 0; border-left: 9px solid transparent; border-right: 9px solid transparent;
  border-top: 31px solid var(--volt); transform: rotate(55deg); transform-origin: top center; z-index: 1;
}
.cv-bubble::before {
  content: ""; position: absolute; top: 100%; left: -4px; margin-top: -2px;
  width: 0; height: 0; border-left: 7px solid transparent; border-right: 7px solid transparent;
  border-top: 26px solid var(--surface); transform: rotate(55deg); transform-origin: top center; z-index: 2;
}

/* ---- ANCHOR 2 — the card frame. Fixed top edge + fixed width, defined
   once, never animated. Every intake step renders inside it. ---- */
.cv-card { background: var(--surface); border: var(--bw) solid var(--ink); box-shadow: var(--sh-card); padding: 26px 24px 0; }
/* the role-specific question, when it is too long to live in the bubble */
.cv-question { font-family: var(--font-display); font-weight: 800; font-size: clamp(19px, 2.6vw, 24px); line-height: 1.2; color: var(--ink); margin: 0 0 12px; }
.cv-slot[hidden] { display: none !important; }
.cv-slot { animation: cv-slot-in var(--cv-t2-dur) var(--cv-t2-ease); }
@keyframes cv-slot-in { from { opacity: 0; } to { opacity: 1; } }

/* the escape hatch, pushed to a dashed bottom bar inside the card */
.cv-actionbar { display: block; width: calc(100% + 48px); margin: 22px -24px 0; padding: 15px 24px; min-height: 44px; background: none; border: none; border-top: 2px dashed var(--ink-soft); font-family: var(--font-body); font-weight: 600; font-size: 14.5px; color: var(--ink); text-align: center; cursor: pointer; }
.cv-actionbar:hover { background: var(--paper-soft); }
.cv-pad { padding-bottom: 26px; }

/* progress dots — decorative and aria-hidden; #cv-step carries the real
   "Step N of 2" as visible text, so it is read as words rather than shapes.
   Both sit under the card, out of the upward-growing bubble's path. */
.cv-foot { display: flex; align-items: center; justify-content: center; gap: 12px; margin-top: 18px; min-height: 20px; }
.cv-step { margin: 0 !important; }
.cv-dots { display: flex; gap: 8px; justify-content: center; }
.cv-dots span { width: 9px; height: 9px; border: var(--bw) solid var(--ink); background: none; }
.cv-dots span.on { background: var(--volt); }

/* the gathering beat, rendered inside the anchored card rather than as its
   own full screen: a named, honest, skippable wait. GATHER_BEAT_MS in
   flow.js is the floor; this bar is the visible read of it. scaleX, not
   width — the no-layout-animation rule (DESIGN.md §5). */
.cv-beat { padding: 6px 0 4px; }
.cv-beat-track { height: 14px; border: var(--bw) solid var(--ink); background: var(--paper-soft); overflow: hidden; }
.cv-beat-fill { height: 100%; background: var(--volt); transform-origin: left center; transform: scaleX(0); }
.cv-beat-fill.run { transition: transform var(--cv-beat-dur, 1200ms) linear; transform: scaleX(1); }
/* Indeterminate variant, for waits whose length we genuinely don't know (the
   projected-mode ledger fetch, and a picked=1 arrival waiting on the dataset).
   It shows activity and claims no percentage — a determinate bar there would
   be inventing progress it can't know. */
.cv-beat-fill.loop { width: 38%; transform: none; animation: cv-beat-loop 1.1s ease-in-out infinite; }
@keyframes cv-beat-loop { from { transform: translateX(-105%); } to { transform: translateX(275%); } }

@media (max-width: 460px) {
  .cv-anchor { margin-top: 88px; }
  .cv-fig { left: 6px; }
  .cv-bubble { left: 76px; right: 0; }
  .cv-card { padding: 22px 18px 0; }
  .cv-actionbar { width: calc(100% + 36px); margin-left: -18px; margin-right: -18px; padding-left: 18px; padding-right: 18px; }
}

@media (prefers-reduced-motion: reduce) {
  .cv-fig-img, .cv-bubble { transition: none; }
  .cv-slot { animation: none; }
  .cv-beat-fill.run { transition: none; transform: scaleX(1); }
  /* A looping bar is exactly what reduced-motion is asking us not to do, so
     it becomes a static filled track: still reads as "working", holds the
     same space, and never moves. */
  .cv-beat-fill.loop { animation: none; width: 100%; transform: none; }
}

/* ============================================================
   THE ROLE DIRECTORY (job-door landing)

   Parity with /AICookedMyDegree's compact wall (receipt.css "the verdict
   wall (landing): compact directory"), translated into Paper & Volt. Same
   structure — filter chips + live search + dense one-line rows — because
   200 roles cannot be a card grid and were previously not browsable at all:
   the landing offered only a typeahead, so you could reach a role only by
   already knowing its name.

   DELIBERATELY VERDICT-FREE. The degree door's chips filter by SUBJECT, and
   these filter by job FAMILY for the same reason: this door's mechanic is
   guess-first-then-evidence, so showing a role's exposure tier here would
   both spoil the guess and front-load the anxiety Law 5 rules out. The only
   metric printed is the sourced charted-task count.
   ============================================================ */
.pv-directory { margin-top: 56px; }
/* align-items:flex-start, not center: ten family chips wrap to three rows at
   this container width, and a vertically centred search box floated against
   that block reads as unaligned. Top-aligned, it sits level with the first
   chip row. */
.dir-toolbar { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; margin-bottom: 16px; flex-wrap: wrap; }
@media (min-width: 860px) { .dir-toolbar { flex-wrap: nowrap; } }
.chip-row { display: flex; gap: 8px; flex-wrap: wrap; }
.dir-chip {
  font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
  padding: 10px 14px; min-height: 40px; cursor: pointer;
  border: var(--bw) solid var(--ink-soft); color: var(--ink-soft); background: none;
  transition: background 80ms ease, color 80ms ease, border-color 80ms ease;
}
.dir-chip:hover { border-color: var(--ink); color: var(--ink); }
.dir-chip.is-active { background: var(--ink); color: var(--on-dark); border-color: var(--ink); }
.dir-chip-count { opacity: .75; }
.dir-chip.is-active .dir-chip-count { opacity: 1; }

.dir-search { flex: 0 0 auto; }
.dir-search .input { width: 200px; }
@media (max-width: 520px) { .dir-toolbar { align-items: stretch; } .dir-search, .dir-search .input { width: 100%; } }

.dir-count-line { font-family: var(--font-mono); font-size: 11.5px; color: var(--ink-soft); margin: 0 0 10px; }

/* Family tiles — the DEFAULT view (approved 2026-07-27).
   "All" used to render all 200 rows on load: 13,871px on a 390px screen, or
   16.4 full screens of list before anything else on the page. It now renders
   the nine families instead, so the default is 9 tiles rather than 200 rows
   and the worst case after one tap is 50. Nothing is hidden — the count on
   each tile is the real filtered count, search still reaches every role
   without touching the tiles, and "show all 200" below is one click.
   Chosen over a capped preview because we hold no popularity data, and
   showing "the first 12" would imply a ranking we cannot source (Rule 3). */
.dir-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 12px; margin-bottom: 16px; }
.dir-tile {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  min-height: 64px; padding: 16px 18px; cursor: pointer; text-align: left;
  background: var(--surface); border: var(--bw) solid var(--ink); box-shadow: var(--sh-chip);
  font-family: var(--font-body); color: var(--ink);
  transition: transform 80ms ease, box-shadow 80ms ease;
}
.dir-tile:hover, .dir-tile:focus-visible { transform: translate(1px, 1px); box-shadow: 2px 2px 0 var(--shadow); }
.dir-tile-name { font-weight: 700; font-size: 15px; }
.dir-tile-count { font-family: var(--font-mono); font-size: 11.5px; color: var(--ink-soft); white-space: nowrap; }
.dir-showall { margin-bottom: 4px; }
.dir-empty { border: var(--bw) dashed var(--ink-soft); color: var(--ink-soft); font-size: 14px; padding: 16px; line-height: 1.6; }

.dir-cols { margin-bottom: 4px; }
@media (min-width: 640px) { .dir-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 0 40px; } }
.dir-list { list-style: none; margin: 0; padding: 0; }
.dir-row {
  display: flex; justify-content: space-between; align-items: center; gap: 14px;
  padding: 11px 4px; min-height: 44px; border-bottom: 1px solid var(--paper-soft);
  text-decoration: none; color: var(--ink); transition: background 80ms ease;
}
.dir-row:hover, .dir-row:focus-visible { background: var(--paper-soft); }
.dir-name { font-weight: 600; font-size: 14.5px; min-width: 0; }
.dir-count { font-family: var(--font-mono); font-size: 11.5px; color: var(--ink-soft); white-space: nowrap; flex: 0 0 auto; }

/* ---- MOTION SYSTEM (ui-ux rules: 140–320ms, ease-out, reduced-motion safe) ---- */
.screen { animation: screen-in 220ms ease-out; }
@keyframes screen-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.reveal { opacity: 0; transform: translateY(16px); transition: opacity 260ms ease-out, transform 260ms ease-out; }
.reveal.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .screen { animation: none; }
  .reveal { opacity: 1; transform: none; transition: none; }
}
@media print {
  .reveal { opacity: 1 !important; transform: none !important; }
}

/* ---- PROPBAR (the shape of your week) + guess marker ---- */
.propbar-wrap { position: relative; padding-top: 24px; margin-bottom: 30px; }
.propbar { display: flex; height: 36px; border: var(--bw) solid var(--ink); background: var(--paper-soft); box-shadow: var(--sh-chip); }
.propbar span { display: block; height: 100%; transition: width 600ms ease-out; min-width: 0; overflow: hidden; white-space: nowrap; }
.p-dur { background: var(--volt); } .p-aug { background: var(--edge-gold); } .p-exp { background: var(--edge-red); }
.propbar-cap { display: flex; justify-content: space-between; gap: 10px; font-family: var(--font-mono); font-size: 11.5px; color: var(--ink-soft); margin-top: 8px; flex-wrap: wrap; }
.guess-marker { position: absolute; top: 14px; height: 46px; width: 3px; background: var(--ink); z-index: 2; }
.guess-label { position: absolute; top: 0; transform: translateX(-50%); font-family: var(--font-mono); font-size: 10px; letter-spacing: .05em; text-transform: uppercase; color: var(--ink); white-space: nowrap; }

/* ---- EXPANDABLE RECEIPT ROWS ---- */
.ledger details { background: var(--surface); border: var(--bw) solid var(--ink); box-shadow: var(--sh-card); }
.ledger details > summary { list-style: none; cursor: pointer; display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 16px 20px; flex-wrap: wrap; }
.ledger details > summary::-webkit-details-marker { display: none; }
.ledger .src-caret { font-family: var(--font-mono); font-size: 12px; color: var(--ink-soft); transition: transform 180ms ease-out; flex: none; }
.ledger details[open] .src-caret { transform: rotate(180deg); }
.ledger .src-body { padding: 0 20px 16px; font-size: 13.5px; color: var(--ink-soft); border-top: 1px dashed var(--ink-soft); margin: 0 20px 0; padding-left: 0; padding-right: 0; padding-top: 12px; }
.ledger .src-body .conflict-note { margin-top: 8px; padding: 10px 12px; background: var(--paper-soft); border-left: 4px solid var(--edge-gold); }
.ledger .src-body a { font-weight: 600; }

/* ---- HARBOR OVERLAP BARS ---- */
.overlap-bar { height: 10px; border: var(--bw) solid var(--ink); background: var(--paper-soft); margin-top: 10px; }
.overlap-bar > span { display: block; height: 100%; background: var(--volt); transition: width 500ms ease-out; }

/* ---- RESULTS HERO (short, visual, Fig-featured) ---- */
.verdict-hero { display: flex; gap: 24px; align-items: flex-start; padding: 26px 28px; margin-bottom: 26px; }
.verdict-hero .vh-main { flex: 1 1 auto; min-width: 0; }
.verdict-hero .vh-fig { flex: none; width: 116px; }
.verdict-hero .vh-fig img { width: 100%; }
/* Mobile: content BEFORE character (reading order = DOM order = SR order). */
@media (max-width: 640px) { .verdict-hero { flex-direction: column; } .verdict-hero .vh-fig { width: 72px; align-self: center; } }

/* ---- RESULTS (S-03) — lifted from reference.html ---- */
.results-main { max-width: 1120px; margin: 0 auto; padding: 24px; }
.compare-line { padding: 14px 18px; border-left: 4px solid var(--ink); background: var(--paper-soft); font-size: 14.5px; color: var(--ink-soft); margin-bottom: 28px; }
.compare-line strong { color: var(--ink); }
.stat-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-bottom: 32px; }
.stat-tile { padding: 22px; }
.stat-tile.highlight { background: var(--volt); color: var(--on-volt); }
.stat-tile.highlight .stat-label, .stat-tile.highlight .stat-desc { color: var(--on-volt); opacity: .82; }
.stat-number { font-family: var(--font-display); font-weight: 800; font-size: 40px; line-height: 1; color: var(--ink); margin-bottom: 8px; }
.stat-tile.highlight .stat-number { color: var(--on-volt); }
.stat-label { font-family: var(--font-mono); font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink); margin-bottom: 6px; }
.stat-desc { font-size: 13.5px; color: var(--ink-soft); }
.ledger { display: flex; flex-direction: column; gap: 14px; margin-bottom: 24px; }
.ledger-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 18px 22px; flex-wrap: wrap; }
.ledger-main { min-width: 0; }
.ledger-task { font-family: var(--font-display); font-weight: 700; font-size: 16px; color: var(--ink); margin-bottom: 4px; }
.ledger-source { font-size: 13px; color: var(--ink-soft); }
.ledger-side { display: flex; align-items: center; gap: 10px; flex: none; }
.honesty-note { background: var(--surface); border: var(--bw) dashed var(--ink-soft); padding: 18px 22px; display: flex; align-items: flex-start; gap: 12px; }
.honesty-note .mark { font-family: var(--font-mono); font-weight: 700; font-size: 13px; color: var(--ink); border: var(--bw) solid var(--ink); width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center; flex: none; }
.honesty-note p { margin: 0; font-size: 13.5px; color: var(--ink-soft); } .honesty-note strong { color: var(--ink); }

/* Save / the pinch (terminal) */
.save-block { margin-top: 48px; padding: 30px; }
.save-block h2 { font-size: 22px; padding-bottom: 8px; border-bottom: 4px solid var(--volt); display: inline-block; margin-bottom: 18px; }
.save-form { display: flex; gap: 12px; flex-wrap: wrap; margin: 18px 0 12px; }
.save-form .input { flex: 1 1 300px; }
.save-consent { display: flex; gap: 10px; align-items: flex-start; font-size: 13.5px; color: var(--ink-soft); margin-bottom: 12px; }
.save-fine { font-family: var(--font-mono); font-size: 11.5px; color: var(--ink-soft); }
.save-status { font-size: 14px; margin-top: 10px; font-weight: 600; }
.save-status[hidden] { display: none; }
.save-status.ok { color: var(--status-ok); } .save-status.error { color: var(--status-err); } .save-status.info { color: var(--ink-soft); }

@media (max-width: 720px) {
  .stat-row { grid-template-columns: 1fr; }
  .ledger-row { flex-direction: column; align-items: flex-start; }
  .ledger-side { width: 100%; justify-content: space-between; }
}
