/* Domain-first Consultant Studio — shared presentation contract.
   Product identity and accent are supplied by studio-product.css. */

/* Base tokens; alternate palettes live in studio-themes.css */
@font-face { font-family: "Roobert"; src: url("../assets/fonts/roobert/Roobert-Regular.woff2") format("woff2"); font-display: swap; font-weight: 400; }
@font-face { font-family: "Roobert"; src: url("../assets/fonts/roobert/Roobert-SemiBold.woff2") format("woff2"); font-display: swap; font-weight: 600; }
@font-face { font-family: "Roobert"; src: url("../assets/fonts/roobert/Roobert-Bold.woff2") format("woff2"); font-display: swap; font-weight: 700 900; }
/* Display serif for the public face. One variable roman covers 200-800 and
   carries its own optical sizing, so a 15px card title and a 60px headline are
   drawn as different designs rather than one design scaled. SIL Open Font
   Licence; OFL.txt travels with it. No italic: the public pages set none. */
@font-face {
  font-family: "Newsreader";
  src: url("../assets/fonts/newsreader/Newsreader-Variable.woff2") format("woff2-variations");
  font-display: swap; font-weight: 200 800; font-style: normal;
}

:root {
  color-scheme: light;
  --ink: #182a38; --navy: #173d68; --blue: #3e6f96; --muted: #5e6c77;
  --line: #d9e0e5; --paper: #fff; --soft: #f4f7f9;
  --clay: #a9694f; --clay-soft: #f6eee9; --clay-ink: #8a4a30;
  --gold: #b99042; --gold-soft: #faf4e4; --gold-ink: #8a5a10;  /* gold at 2.94:1 failed AA; -ink is 5.91:1 */
  --green: #2f6b4f; --green-soft: #eef4f0;
  --studio-brand: #2f6b4f; --studio-brand-soft: #eef4f0;
  --red: #ad504c;
  --page: #fbfcfd;              /* app background */
  --control: #fff;              /* inputs, buttons, chips, score cells */
  --control-line: #cbd5dc;      /* control borders, slightly darker than --line */
  --on-accent: #fff;            /* text on a navy fill */
  --on-accent-dim: #c6d5e7;
  --on-accent-weak: #f0c9b8;
  --navy-soft: #eef3f8; --navy-ink: #2b4562;
  --gold-text: #4a3608;
  --red-soft: #f9ecec; --red-ink: #7c3532;
  --green-ink: #2f4a3b;
  /* Over-photo pair: a hero photograph does not flip with the palette, so
     neither may the veil that darkens it nor the text that sits on it. */
  --photo-ground: #0d1a2a;
  --photo-veil: rgba(13, 26, 42, 0.72);
  --photo-veil-soft: rgba(13, 26, 42, 0.45);
  --on-photo: #f4f8fc;
  --on-photo-dim: #c9d7e6;
  --font: "Roobert", ui-sans-serif, system-ui, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
/* ── PUBLIC FACE ──────────────────────────────────────────────────────────
   The blueprint palette, scoped to the four public pages by an attribute on
   <html> so the workbench keeps the palette a consultant chose. Warm paper,
   navy ink, drafting-line rules -- a printed working document rather than a
   dashboard.

   Deliberately not theme-switchable. The look is a paper analogue and it does
   not have a dark counterpart that means the same thing; a prospect opening
   the site gets the document, in the one register it was designed in. The
   workbench, where a consultant spends hours, keeps its full palette set. */
[data-public-face="blueprint"] {
  color-scheme: light;
  --ink: #14385f; --navy: #10365f; --blue: #1f5f9f; --muted: #526b83;
  /* Hairline adopted from Cairn as a translucent navy rather than a fixed
     grey: it then composites proportionally over --page, --paper and --soft
     instead of reading heavy on the lightest surface. NOTE: the AA gate's
     token parser matches hex only, so this token is invisible to it. */
  --line: rgba(20, 56, 95, .14); --rule: #a9b7c4;
  --paper: #fefdfa; --page: #f9f7f2; --soft: #fcfaf6;
  --green: #5a6d42; --green-soft: #eef0e6; --green-ink: #4e5f3a;
  --gold: #9a7b3c; --gold-soft: #f5eeda; --gold-ink: #6f5620;
  --clay: #9a5f45; --clay-soft: #f3e8e2; --clay-ink: #7a4530;
  --control: #fefdfa; --control-line: #c3cedb;
  --navy-soft: #e8eef5; --navy-ink: #10365f;
  --on-accent: #eef3f8; --on-accent-dim: #b9cbdf;
  --shadow-card: 0 16px 40px rgba(18, 40, 71, .08);
  --display: "Newsreader", "Iowan Old Style", Georgia, serif;
}

* { box-sizing: border-box; }
body { margin: 0; background: var(--page); color: var(--ink); font: 400 15px/1.55 var(--font); }
code { font-family: var(--mono); font-size: .86em; }
button { font-family: var(--font); }

.skipLink { position: fixed; z-index: 100; top: 8px; left: 8px; padding: 10px 14px; background: var(--control); border: 1px solid var(--line); border-radius: 8px; transform: translateY(-150%); }
.skipLink:focus { transform: none; }

/* ---------- shell ---------- */
.studioShell { display: grid; grid-template-columns: 252px 1fr; min-height: 100vh; }

/* ---------- domain rail ---------- */
.rail { border-right: 1px solid var(--line); background: var(--paper); padding: 18px 0 30px; position: sticky; top: 0; height: 100vh; overflow-y: auto; }
.railBrand { display: block; padding: 0 18px 16px; border-bottom: 1px solid var(--line); }
/* CW, two-tone (Charlie, 2026-08-12: "one blue, one green"), echoing the
   public wordmark where "cloud" is ink and "waypoint" is green.

   Sized down from the single glyph it replaced rather than up. Two letters in
   a 34px box need less per letter than one did, and at 12px with negative
   tracking the W crowded its own box badly enough to read as a V. 10.5px with
   neutral tracking gives both letters their full width.

   The two spans are styled identically on purpose. The first version used a
   <b> for the green letter, which is a semantic element carrying the user
   agent's own bold — beside an explicit 800 on the sibling that renders as a
   visible weight mismatch, which is the unevenness. Same element, same
   declarations, colour as the only difference. */
/* The rail lockup is the public header's, not a boxed monogram (Charlie,
   2026-08-12: "drop the box and go with the front web page style").

   That ends a chase rather than winning it. A two-letter monogram in a fixed
   box needs the pair to kern AND the glyph mass — not the em box, which
   reserves descender space all-caps never uses — to sit dead centre. Those two
   wants pull against each other in CSS, and each fix I made exposed the other.
   The wordmark has neither problem: it is a word, set as a word.

   Mark size is set here and the SVG fills it, so the drawing never sets its
   own scale. */
/* The mark's footprint is declared once so the client line below can indent by
   exactly it. Hard-coding 35px would work today and silently misalign the
   moment the mark is resized — which has already happened twice this session. */
/* Sized to fill the rail rather than sit in the corner of it (Charlie,
   2026-08-12: "they look a little diminutive... should almost expand to
   seventy five percent"). The rail is 252px with 18px padding either side, so
   216px of usable width; mark + gap + wordmark comes to roughly 170px, about
   80% of that and 70% of the rail itself. Deliberately short of the padding —
   a lockup that touches its own margins reads as cramped rather than
   confident, and the wordmark is nowrap, so overrunning would push the rail
   sideways rather than wrap politely. */
.railBrand { --railMark: 32px; --railGap: 9px; }
.railBrandLock { display: flex; align-items: center; gap: var(--railGap); text-decoration: none; }
.railMark { display: block; width: var(--railMark); height: var(--railMark); flex: none; color: var(--blue); }
.railMark svg { width: 100%; height: 100%; display: block; }
/* nowrap because the rail is narrow and the product wordmark breaking across two
   lines turns a wordmark into a sentence. The b stays inline for the same
   reason — it was being blockified by a leftover .railBrand b rule written for
   the "Consultant Studio" label this lockup replaced. Equal specificity, later
   in the file, so it won: the wordmark wrapped AND lost its green. Both rules
   are deleted now; these declarations are explicit so a future sibling rule
   cannot quietly take the argument again. */
.railWord { font-family: var(--font); font-size: 19px; font-weight: 700; letter-spacing: -.02em; line-height: 1; color: var(--ink); white-space: nowrap; }
.railWord b { display: inline; font-size: inherit; color: var(--studio-brand); font-weight: 800; }
.railBrandLock:hover .railWord, .railBrandLock:focus-visible .railWord { color: var(--navy); }
/* Indented past the mark so the client name starts on the same vertical as the
   "c" of cloud, rather than under the drawing (Charlie, 2026-08-12). Derived
   from the lockup's own measurements, never a magic number. */
.railClient { display: block; margin-top: 7px; margin-left: calc(var(--railMark) + var(--railGap)); color: var(--muted); font-size: 12px; letter-spacing: .04em; text-transform: uppercase; }

.railGroup { padding: 14px 10px 4px; }
.railGroup > small { display: block; padding: 0 8px 6px; color: var(--muted); font-size: 10px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; }
.rail a { display: grid; grid-template-columns: 20px 1fr auto; gap: 8px; align-items: center; padding: 7px 8px; border-radius: 7px; color: var(--ink); font-size: 13px; text-decoration: none; }
.rail a:hover { background: var(--soft); }
.rail a:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }
.rail a.active { background: var(--navy); color: var(--on-accent); }
.rail a.active small, .rail a.active i { color: var(--on-accent-dim); }
.rail a i { font-style: normal; color: var(--muted); font-size: 11px; font-weight: 600; text-align: center; }
.rail a b { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rail a small { font-family: var(--mono); font-size: 11px; color: var(--muted); }
.rail a small.weak { color: var(--clay); font-weight: 700; }
.rail a.active small.weak { color: var(--on-accent-weak); }
.rail a small.review { color: var(--gold); font-weight: 700; }
.railFoot { margin: 16px 18px 0; padding-top: 12px; border-top: 1px solid var(--line); color: var(--muted); font-size: 11px; }
.railFoot a { display: inline; padding: 0; color: var(--blue); }
.mobileNavToggle, .mobileNavClose, .studioNavScrim { display: none; }

/* ---------- main ---------- */
.studioMain { padding: 0 0 90px; min-width: 0; }
.topbar { display: flex; justify-content: space-between; align-items: center; gap: 16px; padding: 12px 28px; border-bottom: 1px solid var(--line); background: var(--paper); position: sticky; top: 0; z-index: 5; }
.topbarLead { display: flex; align-items: center; gap: 10px; min-width: 0; }
.topbar .crumb { font-size: 12px; color: var(--muted); }
.topbar .crumb b { color: var(--navy); }
.topbar .who { display: flex; align-items: center; gap: 14px; font-size: 12px; color: var(--muted); }
.topbar .who b { color: var(--ink); font-weight: 600; }
.topbar .who button { border: 1px solid var(--control-line); border-radius: 7px; background: var(--control); color: var(--navy); font-weight: 700; font-size: 12px; padding: 5px 12px; cursor: pointer; }
.topbar .who button:hover { border-color: var(--navy); }

.studioWrap { max-width: 1180px; padding: 26px 28px 0; }

.studioToast { position: fixed; right: 20px; bottom: 20px; z-index: 50; border: 1px solid var(--green); border-radius: 9px; background: var(--green-soft); color: var(--green-ink); font-size: 13px; font-weight: 600; padding: 10px 16px; opacity: 0; transform: translateY(8px); transition: opacity .2s, transform .2s; pointer-events: none; }
.studioToast.show { opacity: 1; transform: none; }

/* ---------- empty / landing state ---------- */
.studioEmpty { max-width: 620px; margin: 90px auto; text-align: center; }
.studioEmpty h1 { color: var(--navy); font-size: 30px; margin: 0 0 8px; }
.studioEmpty p { color: var(--muted); }
.studioEmpty button { border: 1px solid var(--navy); border-radius: 8px; background: var(--navy); color: var(--on-accent); font-weight: 750; font-size: 14px; padding: 11px 18px; cursor: pointer; }

/* ---------- domain header ---------- */
/* Green, matching the public face's kicker and the "waypoint" in the wordmark
   (Charlie, 2026-08-12: "I would have thought it would have picked up some of
   the green title"). Carrying the ground and the ink across without the accent
   left the studio reading all-blue beside a front door with a green voice.

   Applied in every palette rather than dark alone — the mismatch was never a
   dark-mode problem, it was two products using different accents, and a
   palette-conditional accent is its own kind of wrong.

   Safe against the state colours because disposition state in this sheet is
   SHAPE-encoded, deliberately, so it reads without relying on hue. Green on a
   label therefore steals no meaning from green on a state. */
.eyebrow { color: var(--studio-brand); font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; }
.domainHead { border-bottom: 4px solid var(--navy); padding-bottom: 18px; margin-bottom: 8px; }
.domainHead h1 { margin: 4px 0 2px; color: var(--navy); font-size: 33px; line-height: 1.08; letter-spacing: -.01em; }
.domainHead .sub { color: var(--muted); font-size: 14px; max-width: 760px; }
.domainStats { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: 10px; margin-top: 16px; }
.domainStats article { border: 1px solid var(--line); border-radius: 10px; background: var(--paper); padding: 10px 14px; }
.domainStats span { display: block; color: var(--muted); font-size: 10px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; }
.domainStats b { display: block; font-size: 21px; color: var(--navy); }
.domainStats small { color: var(--muted); font-size: 11.5px; }

.bandTitle { display: flex; align-items: baseline; gap: 10px; margin: 26px 0 8px; }
.bandTitle h2 { margin: 0; color: var(--navy); font-size: 19px; }
.bandTitle small { color: var(--muted); font-size: 12px; }

/* ---------- inference ledger ---------- */
.infTable { border: 1px solid var(--line); border-radius: 12px; background: var(--paper); overflow: hidden; }
.infRow { display: grid; grid-template-columns: 150px minmax(0,1.5fr) minmax(0,1fr); border-top: 1px solid var(--line); }
.infRow:first-child { border-top: 0; }
.infRow > .k { padding: 12px 14px; background: var(--soft); border-right: 1px solid var(--line); }
.infRow > .k b { display: block; font-size: 12.5px; color: var(--navy); font-weight: 700; }
.infRow > .k small { display: block; color: var(--muted); font-size: 10.5px; margin-top: 2px; }
.infRow > .k code { display: inline-block; margin-top: 6px; color: var(--blue); font-size: 10.5px; }
.infRow > .v { padding: 12px 16px; font-size: 13.5px; border-right: 1px solid var(--line); overflow-wrap: break-word; }
.infRow > .v .cite { display: inline-block; margin-left: 6px; color: var(--blue); font-family: var(--mono); font-size: 10.5px; white-space: nowrap; }
.infRow > .d { padding: 10px 14px; }

/* disposition cell */
.disp { display: flex; flex-direction: column; gap: 6px; }
.dispState { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 700; letter-spacing: .04em; }
/* State is encoded by SHAPE first and colour second. Measured: the four state
   hues sat within 0.011 luminance of each other, and accepted/pending converge
   under deuteranopia. Shape survives both. */
.dispState::before { content: ""; width: 9px; height: 9px; flex: none; }
.dispState.accepted { color: var(--green); }
.dispState.accepted::before { background: var(--green); border-radius: 50%; }            /* filled disc */
.dispState.validated { color: var(--navy); }
.dispState.validated::before { background: var(--navy); border-radius: 50%; box-shadow: 0 0 0 2px var(--paper), 0 0 0 3.5px var(--navy); } /* ringed disc */
.dispState.edited { color: var(--gold-ink); }
.dispState.edited::before { background: var(--gold-ink); border-radius: 2px; transform: rotate(45deg); } /* diamond */
.dispState.pending { color: var(--muted); }
.dispState.pending::before { background: transparent; border: 2px solid var(--muted); border-radius: 50%; } /* hollow */
/* D-35 C1: the tinted pill Charlie picked. It WRAPS .dispState rather than
   replacing it, so the shape glyph above still carries the state and colour
   is never the only signal. A pill that dropped the glyph would encode
   evidence state in hue alone -- the exact defect the shapes exist to avoid. */
.dispState.chip { padding: 4px 11px 4px 9px; border-radius: 999px;
  background: color-mix(in srgb, currentColor 12%, transparent); }
.dispWho { color: var(--muted); font-size: 11px; }
.dispNote { border-left: 3px solid var(--gold-ink); background: var(--gold-soft); padding: 7px 10px; border-radius: 0 7px 7px 0; font-size: 12.5px; color: var(--gold-text); }
.dispNote b { color: var(--gold-ink); }
.dispNote.navy { border-left-color: var(--navy); background: var(--navy-soft); color: var(--navy-ink); }
.dispNote.navy b { color: var(--navy); }
.dispDrift { border-left: 3px solid var(--red); background: var(--red-soft); padding: 6px 10px; border-radius: 0 7px 7px 0; font-size: 12px; color: var(--red-ink); }
.dispActions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 2px; }
.dispActions button { border: 1px solid var(--control-line); border-radius: 6px; background: var(--control); color: var(--navy); font-weight: 700; font-size: 11.5px; padding: 4px 10px; cursor: pointer; }
.dispActions button:hover { border-color: var(--navy); }
.dispActions button.primary { background: var(--navy); border-color: var(--navy); color: var(--on-accent); }
.dispActions button.quiet { border-color: transparent; color: var(--muted); }
.editedPair { font-size: 12.5px; }
.editedPair .was { color: var(--muted); text-decoration: line-through; text-decoration-color: var(--gold-ink); }
.editedPair .now { color: var(--ink); font-weight: 700; }

/* inline disposition form */
.dispForm { display: flex; flex-direction: column; gap: 6px; border: 1px solid var(--line); border-radius: 8px; background: var(--soft); padding: 8px; }
.dispForm label { color: var(--muted); font-size: 10.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; }
.dispForm textarea, .dispForm select, .dispForm input[type="text"] { width: 100%; border: 1px solid var(--line); border-radius: 6px; background: var(--control); color: var(--ink); font: 400 12.5px/1.45 var(--font); padding: 6px 8px; resize: vertical; }
.dispForm textarea:focus, .dispForm select:focus, .dispForm input:focus { outline: 2px solid var(--blue); outline-offset: 0; }
.dispForm .row { display: flex; gap: 6px; justify-content: flex-end; }

/* ---------- artifact section ---------- */
.artifact { margin-top: 34px; border: 1px solid var(--line); border-radius: 14px; background: var(--paper); overflow: hidden; }
.artifact > header { display: flex; justify-content: space-between; gap: 16px; align-items: flex-start; padding: 16px 20px 14px; border-bottom: 1px solid var(--line);
  background: linear-gradient(125deg, rgba(244,247,249,.9), rgba(255,255,255,.96) 55%); }
.artifact > header .id { font-family: var(--mono); color: var(--blue); font-size: 12px; font-weight: 600; }
.artifact > header h3 { margin: 2px 0 4px; color: var(--navy); font-size: 21px; line-height: 1.15; }
.artifact > header .meta { display: flex; flex-wrap: wrap; gap: 6px; }
.chip { display: inline-block; border: 1px solid var(--line); border-radius: 999px; background: var(--control); padding: 2px 9px; font-size: 11px; color: var(--muted); }
.chip.dim { border-color: var(--control-line); color: var(--navy); font-weight: 600; }
.chip.floor { border-color: var(--clay); background: var(--clay-soft); color: var(--clay-ink); font-weight: 700; }
.chip.elevated { border-color: var(--gold-ink); background: var(--gold-soft); color: var(--gold-ink); font-weight: 700; }
.scoreBadge { text-align: center; min-width: 86px; }
.scoreBadge b { display: block; font-size: 30px; color: var(--navy); line-height: 1; }
.scoreBadge span { display: block; font-size: 10.5px; color: var(--muted); font-weight: 700; letter-spacing: .06em; text-transform: uppercase; margin-top: 3px; }

.artBody { display: grid; grid-template-columns: minmax(0,1.06fr) minmax(0,1fr); }
.artCol { padding: 16px 20px 20px; min-width: 0; }
.artCol + .artCol { border-left: 1px solid var(--line); }
.artCol > h4 { margin: 0 0 10px; color: var(--navy); font-size: 12px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; }
.artCol > h4 small { display: block; margin-top: 2px; color: var(--muted); font-weight: 500; font-size: 11px; letter-spacing: 0; text-transform: none; }

/* score editor */
.scoreEditor { border: 1px solid var(--line); border-radius: 10px; background: var(--soft); padding: 10px 12px; margin-bottom: 12px; }
.scoreEditorHead { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 7px; }
.scoreEditorHead > span:first-child { color: var(--muted); font-size: 10.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
.scoreScale { display: grid; grid-template-columns: repeat(5, 1fr); gap: 5px; }
.scoreOption { display: block; border: 1px solid var(--line); border-radius: 8px; background: var(--control); padding: 6px 4px; cursor: pointer; text-align: center; }
.scoreOption b { display: block; color: var(--navy); font-size: 16px; line-height: 1.1; }
.scoreOption small { display: block; color: var(--muted); font-size: 9.5px; margin-top: 1px; }
.scoreOption:hover { border-color: var(--blue); }
.scoreOption:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }
.scoreOption.on { border-color: var(--navy); background: var(--navy); }
.scoreOption.on::after { content: ""; }
.scoreOption.on b, .scoreOption.on small { color: var(--on-accent); }
.confirmRow { display: flex; gap: 7px; align-items: flex-start; margin-top: 8px; font-size: 12.5px; color: var(--ink); cursor: pointer; }
.confirmRow input { margin-top: 2px; accent-color: var(--navy); }

/* editable pills */
.pill.pillEdit { display: block; cursor: pointer; }
.pill.pillEdit select, .pill.pillEdit input[type="text"] {
  width: 100%; margin-top: 2px; border: 1px solid var(--line); border-radius: 5px; background: var(--control);
  color: var(--ink); font: 600 12.5px var(--font); padding: 3px 5px;
}
.pill.pillEdit select:focus, .pill.pillEdit input:focus { outline: 2px solid var(--blue); outline-offset: 0; }

/* consultant-entered fields */
.field { margin-bottom: 12px; }
.field > label { display: flex; justify-content: space-between; align-items: baseline; color: var(--muted); font-size: 10.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; margin-bottom: 3px; }
.field .val { border: 1px solid var(--line); border-radius: 8px; background: var(--control); padding: 8px 11px; font-size: 13.5px; white-space: pre-wrap; }
.field .val:empty::before { content: "—"; color: var(--muted); }
.field .val.editable { cursor: text; }
.field .val.editable:hover { border-color: var(--blue); }
.field .val.editable:focus { outline: 2px solid var(--blue); outline-offset: 0; }
.field .savedTick { color: var(--green); font-size: 10.5px; font-weight: 700; letter-spacing: 0; text-transform: none; opacity: 0; transition: opacity .18s; }
.field .savedTick.show { opacity: 1; }
.fieldGrid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; margin-bottom: 12px; }
.pill { display: block; border: 1px solid var(--line); border-radius: 8px; padding: 6px 10px; background: var(--soft); }
.pill span { display: block; color: var(--muted); font-size: 9.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
.pill b { font-size: 12.5px; color: var(--ink); font-weight: 600; overflow-wrap: break-word; }

/* shared studio form controls */
.studioPanel { border: 1px solid var(--line); border-radius: 12px; background: var(--paper); padding: 16px 18px; }
.studioInput { width: 100%; border: 1px solid var(--line); border-radius: 7px; background: var(--control); color: var(--ink); font: 400 13.5px/1.45 var(--font); padding: 7px 10px; }
.studioInput:focus { outline: 2px solid var(--blue); outline-offset: 0; }
textarea.studioInput { resize: vertical; }
.fieldHint { display: block; margin-top: 3px; color: var(--muted); font-size: 11.5px; }
.fieldGrid.two { grid-template-columns: 1fr 1fr; }
.fieldGrid.three { grid-template-columns: 1fr 1fr 1fr; }
.fieldGrid .field { margin-bottom: 0; }
.quietDanger { border: 1px solid var(--line); border-radius: 6px; background: var(--control); color: var(--clay); font-weight: 700; font-size: 11.5px; padding: 4px 10px; cursor: pointer; flex: none; }
.quietDanger:hover { border-color: var(--clay); }
.infRow .d .studioInput { margin-top: 4px; }

@media (max-width: 860px) { .fieldGrid.two, .fieldGrid.three { grid-template-columns: 1fr; } }

/* report tiles */
.reportGrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 10px; }
.reportTile { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; border: 1px solid var(--line); border-radius: 12px; background: var(--paper); padding: 14px 16px; }
.reportTile.canonical { border-color: var(--navy); background: linear-gradient(150deg, var(--soft), var(--paper) 65%); }
.reportTile b { display: block; color: var(--navy); font-size: 15px; margin-top: 4px; }
.reportTile small { display: block; color: var(--muted); font-size: 12px; margin-top: 3px; }
.reportTile button { border: 1px solid var(--navy); border-radius: 7px; background: var(--control); color: var(--navy); font-weight: 750; font-size: 12.5px; padding: 6px 12px; cursor: pointer; flex: none; }
.reportTile button:hover { background: var(--navy); color: var(--on-accent); }

/* trace strip */
.trace { border-top: 1px solid var(--line); background: var(--soft); padding: 12px 20px; }
.trace h5 { margin: 0 0 6px; color: var(--navy); font-size: 11px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; }
.trace ul { margin: 0; padding: 0; list-style: none; display: flex; flex-wrap: wrap; gap: 6px 18px; }
.trace li { font-size: 12px; color: var(--muted); }
.trace li b { color: var(--ink); font-weight: 600; }
.trace li code { color: var(--blue); }

.studioBoundary { margin-top: 30px; border: 1px solid var(--line); border-radius: 10px; background: var(--paper); padding: 12px 16px; color: var(--muted); font-size: 12.5px; }
.studioBoundary b { color: var(--navy); }

@media (max-width: 940px) {
  .studioShell { grid-template-columns: 1fr; }
  .studioMain { order: 1; }
  .rail { display: none; }
  .mobileNavToggle { display: inline-flex; align-items: center; justify-content: center; min-height: 44px; border: 1px solid var(--control-line); border-radius: 7px; background: var(--control); color: var(--navy); font-size: 12px; font-weight: 750; padding: 8px 12px; cursor: pointer; }
  .mobileNavToggle:hover { border-color: var(--studio-brand); }
  .mobileNavToggle:focus-visible, .mobileNavClose:focus-visible { outline: 2px solid var(--studio-brand); outline-offset: 2px; }
  body.studioNavOpen { overflow: hidden; }
  body.studioNavOpen .rail { display: block; position: fixed; inset: 0 auto 0 0; width: min(86vw, 340px); height: 100dvh; z-index: 50; border-right: 1px solid var(--line); border-bottom: 0; background: var(--paper); overflow-y: auto; box-shadow: 18px 0 44px rgba(3, 11, 23, .25); }
  .mobileNavClose { align-items: center; justify-content: center; width: calc(100% - 36px); min-height: 44px; margin: 0 18px 12px; border: 1px solid var(--control-line); border-radius: 7px; background: var(--control); color: var(--navy); font-size: 12px; font-weight: 750; cursor: pointer; }
  body.studioNavOpen .mobileNavClose { display: flex; }
  body.studioNavOpen .studioNavScrim { display: block; position: fixed; inset: 0; z-index: 49; width: 100%; height: 100%; border: 0; background: rgba(3, 11, 23, .58); cursor: pointer; }
  .artBody { grid-template-columns: 1fr; }
  .artCol + .artCol { border-left: 0; border-top: 1px solid var(--line); }
  .infRow { grid-template-columns: 1fr; }
  .infRow > .k, .infRow > .v { border-right: 0; border-bottom: 1px solid var(--line); }
  .domainStats { grid-template-columns: 1fr 1fr; }
}

@media print {
  .rail, .topbar, .mobileNavToggle, .mobileNavClose, .studioNavScrim, .dispActions, .studioToast { display: none !important; }
  .studioShell { grid-template-columns: 1fr; }
  .artifact { break-inside: avoid; }
  body { background: #fff; }
}

/* Identity & correlation console (D-16). Reuses the guidepost disclosure and
   panel primitives; only the two grids are new. */
.consoleActionGrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:12px;margin-top:10px}
.consoleActionGrid form{display:grid;gap:8px;padding:12px;border:1px solid var(--line);border-radius:10px;background:var(--paper)}
.consoleActionGrid label,.consoleRunForm label{display:grid;gap:4px;color:var(--muted);font-size:11.5px;font-weight:700}
.consoleActionGrid input,.consoleActionGrid select,.consoleActionGrid textarea,.consoleRunForm input,.consoleRunForm select,.consoleRunForm textarea{border:1px solid var(--control-line);border-radius:8px;background:var(--control);color:var(--ink);padding:7px 9px;font:inherit;font-size:12.5px}
.consoleRunForm{display:grid;gap:10px}
.consoleRunGrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:10px}

/* ── Interactive schedule (D-17) ─────────────────────────────────────────
   The Executive Transformation MAP as a studio page. Geometry mirrors the
   governed horizon scale; every colour is a token so all four palettes and
   print carry it without a special case. */
.schedToolbar { display: flex; justify-content: space-between; align-items: center; gap: 14px; flex-wrap: wrap; margin: 14px 0 10px; }
.schedToolbar button { border: 1px solid var(--control-line); border-radius: 7px; background: var(--control); color: var(--navy); font: 700 12px var(--font); padding: 7px 12px; cursor: pointer; }
.schedToolbar button:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }
.schedLegend { display: flex; align-items: center; gap: 7px; color: var(--muted); font-size: 11.5px; flex-wrap: wrap; }
/* In a legend an <i> is a COLOUR SWATCH, not emphasis: this sizes it to a
   18x7 pill. Prose belongs in a <span> -- an <i> of text gets squashed into
   the pill and paints straight over the schedule below it. */
.schedLegend i { display: inline-block; width: 18px; height: 7px; border-radius: 4px; }
.schedLegend .lgGate { background: var(--navy); }
.schedLegend .lgSupp { background: var(--blue); opacity: .55; }
.schedLegend .lgPos { width: 10px; height: 10px; border-radius: 50%; background: var(--green); }
.schedCapacity { margin: 10px 0 0; padding: 10px 14px; border-left: 4px solid var(--clay); background: var(--clay-soft); color: var(--clay-ink); border-radius: 0 9px 9px 0; font-size: 13px; max-width: 860px; }

.schedAxis { display: grid; grid-template-columns: 240px 1fr; gap: 10px; margin-top: 6px; }
.schedAxisTrack { position: relative; height: 34px; }
.schedAxisTrack b { position: absolute; top: 0; bottom: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; background: var(--soft); border: 1px solid var(--line); border-radius: 6px; color: var(--navy); font-size: 11px; line-height: 1.1; }
.schedAxisTrack b small { color: var(--muted); font-weight: 600; font-size: 9.5px; }
.schedAoLine { display: grid; grid-template-columns: 240px 1fr; margin: 2px 0 6px; }
.schedAoLine b { grid-column: 2; position: relative; display: block; height: 14px; font: 600 9.5px var(--font); color: var(--gold-ink); }
.schedAoLine b::before { content: ""; position: absolute; left: 37.5%; top: 0; bottom: 0; border-left: 2px dashed var(--gold); }
.schedAoLine b { padding-left: calc(37.5% + 8px); }

.schedLane { border: 1px solid var(--line); border-radius: 10px; background: var(--paper); margin-bottom: 10px; overflow: hidden; }
.schedLane > summary { display: flex; align-items: baseline; gap: 10px; padding: 10px 14px; cursor: pointer; list-style: none; }
.schedLane > summary::-webkit-details-marker { display: none; }
.schedLane > summary b { color: var(--navy); font-size: 13.5px; }
.schedLane > summary small { color: var(--muted); font-size: 11px; margin-left: auto; }
.schedLane[open] > summary { border-bottom: 1px solid var(--line); background: var(--soft); }
.schedLaneToggle { color: var(--muted); transition: transform .12s; }
.schedLane[open] .schedLaneToggle { transform: rotate(90deg); }
.schedRole { border-radius: 999px; padding: 1px 9px; font-size: 10px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase; }
.schedRole.constraint { background: var(--clay-soft); color: var(--clay-ink); border: 1px solid var(--clay); }
.schedRole.lever { background: var(--green-soft); color: var(--green-ink); border: 1px solid var(--green); }

.schedRows { padding: 8px 14px 12px; }
.schedStream { margin-bottom: 6px; }
.schedRow { display: grid; grid-template-columns: 226px 1fr; gap: 10px; align-items: center; }
.schedName { display: flex; gap: 7px; align-items: baseline; text-align: left; border: 0; background: none; color: var(--ink); font: 500 12.5px var(--font); padding: 3px 4px; border-radius: 6px; cursor: pointer; }
.schedName:hover, .schedName:focus-visible { background: var(--soft); outline: none; }
.schedName:focus-visible { outline: 2px solid var(--blue); }
.schedId { color: var(--blue); font: 700 11px var(--mono); }
.schedLabel { line-height: 1.25; }
.schedGateChip { margin-left: 6px; border-radius: 999px; background: var(--navy-soft); color: var(--navy-ink); font-size: 9.5px; font-weight: 800; padding: 1px 7px; }
.schedTrack { position: relative; height: 16px; background: var(--soft); border-radius: 8px; }
.schedTrack i { position: absolute; top: 3px; height: 10px; border-radius: 5px; }
.schedTrack i.gate { background: var(--navy); }
.schedTrack i.supp { background: var(--blue); opacity: .55; }
.schedTrack i.pos { width: 12px; height: 12px; top: 2px; border-radius: 50%; background: var(--green); box-shadow: 0 0 0 2px var(--paper); }
.schedTrack em { position: absolute; right: 8px; top: 0; line-height: 16px; color: var(--muted); font-size: 9.5px; font-style: normal; }
.schedPosition .schedPositionLabel { color: var(--green-ink); font-weight: 700; font-size: 11px; cursor: default; }
.schedPosition .schedTrack { background: var(--green-soft); }

.schedArRow { display: flex; flex-wrap: wrap; gap: 5px; margin: 3px 0 2px 236px; }
.schedArRow.schedLoose { margin-left: 0; padding-top: 6px; border-top: 1px dashed var(--line); }
.schedArLabel { color: var(--muted); font-size: 10.5px; font-weight: 700; align-self: center; }
.schedAr, .schedArDemo { display: inline-flex; align-items: baseline; gap: 4px; border: 1px solid var(--control-line); border-radius: 999px; background: var(--control); color: var(--navy); font: 700 10.5px var(--mono); padding: 2px 9px; text-decoration: none; }
.schedAr:hover, .schedAr:focus-visible { border-color: var(--blue); outline: none; }
.schedAr small, .schedArDemo small { color: var(--gold-ink); font-size: 9px; }
.schedDep { margin: 2px 0 4px 236px; color: var(--muted); font-size: 10.5px; }

.schedPreview { position: sticky; bottom: 12px; margin-top: 14px; border: 1px solid var(--line); border-left: 4px solid var(--blue); border-radius: 0 10px 10px 0; background: var(--paper); padding: 10px 14px; box-shadow: 0 6px 18px rgba(0,0,0,.06); }
.schedPreview > span { color: var(--muted); font-size: 10px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; }
.schedPreview h4 { margin: 2px 0 4px; color: var(--navy); font-size: 13px; }
.schedPreview p { margin: 0; color: var(--ink); font-size: 12px; }
.schedPreview .schedAttribution { margin-top: 4px; color: var(--muted); font-size: 11px; }

.schedDrawer { position: fixed; top: 0; right: 0; bottom: 0; width: min(480px, 92vw); background: var(--paper); border-left: 1px solid var(--line); box-shadow: -12px 0 32px rgba(0,0,0,.14); z-index: 40; display: flex; flex-direction: column; }
.schedDrawer > header { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; padding: 16px 18px 12px; border-bottom: 1px solid var(--line); background: var(--soft); }
.schedDrawer h2 { margin: 2px 0 4px; color: var(--navy); font-size: 17px; line-height: 1.2; }
.schedDrawerMeta { margin: 0; color: var(--muted); font-size: 11.5px; }
.schedDrawer > header button { border: 1px solid var(--control-line); border-radius: 7px; background: var(--control); color: var(--navy); font-size: 13px; padding: 5px 10px; cursor: pointer; }
.schedDrawer > header button:focus-visible { outline: 2px solid var(--blue); }
.schedDrawerBody { padding: 14px 18px 20px; overflow-y: auto; }
.schedOutcome { color: var(--ink); font-size: 13px; }
.schedGateNote { padding: 8px 12px; background: var(--navy-soft); color: var(--navy-ink); border-radius: 8px; font-size: 12px; }
.schedDrawerCols { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin: 10px 0; }
.schedDrawerCols span { display: block; color: var(--muted); font-size: 10px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; }
.schedDrawerCols p { margin: 3px 0 0; color: var(--ink); font-size: 12px; }
.schedSectionLabel { display: block; margin: 12px 0 4px; color: var(--muted); font-size: 10.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; }
.schedRelated { list-style: none; margin: 0; padding: 0; }
.schedRelated li { display: flex; justify-content: space-between; gap: 10px; padding: 5px 0; border-bottom: 1px dashed var(--line); }
.schedRelated a { color: var(--navy); text-decoration: none; font-size: 12.5px; }
.schedRelated a:hover { color: var(--blue); }
.schedRelated small { color: var(--muted); font-size: 11px; white-space: nowrap; }
.schedTeam { margin: 0; color: var(--ink); font-size: 12px; }
/* Exit conditions: the basis chip carries the whole point — a reader must be
   able to tell a published measure from the practice's judgement without
   reading the prose, so the two chips never share a colour. */
.schedExitConditions { margin: 0; padding-left: 18px; display: grid; gap: 10px; }
.schedExitConditions li p { margin: 0 0 4px; color: var(--ink); font-size: 12.5px; }
.schedExitConditions li small { display: block; margin-top: 3px; color: var(--muted); font-size: 11px; line-height: 1.45; }
.schedExitConditions li small b { color: var(--ink); }
.schedExitConditions li small a { color: var(--accent-ink); }
.schedBasis { display: inline-block; padding: 1px 7px; border-radius: 999px; font-size: 10px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase; }
.schedBasisSourced { background: color-mix(in srgb, var(--ok) 16%, transparent); color: var(--ok); }
.schedBasisCommentary { background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent-ink); }
.schedDrawerBody ol, .schedDrawerBody ul { margin: 0; padding-left: 18px; color: var(--ink); font-size: 12.5px; }

@media (max-width: 900px) {
  .schedRow { grid-template-columns: 1fr; gap: 2px; }
  .schedArRow, .schedDep { margin-left: 0; }
  .schedAxis, .schedAoLine { grid-template-columns: 0 1fr; }
  .schedDrawerCols { grid-template-columns: 1fr; }
}
@media print { .schedDrawer, .schedPreview, .schedToolbar button { display: none; } .schedLane { break-inside: avoid; } }

/* ── People swim lane (D-18): contracted scopes on the same horizon axis ── */
.schedPeople { margin-top: 22px; border: 1px solid var(--line); border-radius: 12px; background: var(--paper); padding: 16px 18px; }
.schedPplHead h2 { margin: 0 0 6px; color: var(--navy); font-size: 17px; }
.schedPplHead p { margin: 0 0 14px; color: var(--ink); font-size: 13px; max-width: 900px; }
.schedPplLane { display: grid; grid-template-columns: 240px 1fr; gap: 10px; align-items: center; margin-bottom: 10px; }
.schedPplName b { display: block; color: var(--navy); font-size: 12.5px; line-height: 1.25; }
.schedPplName small { display: block; color: var(--muted); font-size: 10.5px; line-height: 1.35; margin-top: 2px; }
.schedPplTrack { height: 26px; }
.schedPplTrack i { position: absolute; top: 3px; height: 20px; border-radius: 6px; display: flex; align-items: center; overflow: hidden; }
.schedPplTrack i b { color: var(--on-accent); font-size: 9.5px; font-weight: 700; padding: 0 8px; white-space: nowrap; }
.schedPplTrack .ppl-steady { background: var(--navy); }
.schedPplTrack .ppl-surge { background: var(--clay); }
.schedPplTrack .ppl-handoff { background: var(--clay-soft); border: 1px dashed var(--clay); }
.schedPplTrack .ppl-handoff b { color: var(--clay-ink); }
.schedPplTrack .ppl-build { background: var(--green-soft); border: 1px solid var(--green); }
.schedPplTrack .ppl-build b { color: var(--green-ink); }
.schedPplTrack .ppl-run { background: var(--green); }
.schedPplTrack .ppl-legacy { background: var(--soft); border: 1px solid var(--control-line); }
.schedPplTrack .ppl-legacy b { color: var(--muted); }
.schedPplTrack .ppl-winddown { background: transparent; border: 1px dashed var(--control-line); }
.schedPplTrack .ppl-winddown b { color: var(--muted); }
.schedPplBoundary { margin: 12px 0 0; padding-top: 10px; border-top: 1px dashed var(--line); color: var(--muted); font-size: 11.5px; }
.schedPplBoundary b { color: var(--navy-ink); }
.schedPplAttribution { margin: 8px 0 0; padding: 9px 12px; background: var(--navy-soft); border-radius: 8px; color: var(--navy-ink); font-size: 11.5px; line-height: 1.5; }
.schedPplAttribution i { font-style: italic; }
@media (max-width: 900px) { .schedPplLane { grid-template-columns: 1fr; gap: 3px; } }
@media print { .schedPeople { break-inside: avoid; } }

/* ── Acquisition overlay (D-19): the join decision on the lanes ────────── */
.schedAcq { border-radius: 999px; padding: 1px 9px; font-size: 9.5px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase; white-space: nowrap; }
.schedAcq.inherit { background: var(--green-soft); color: var(--green-ink); border: 1px solid var(--green); }
.schedAcq.accelerate { background: var(--gold-soft); color: var(--gold-ink); border: 1px solid var(--gold); }
.schedAcq.yours { background: var(--soft); color: var(--muted); border: 1px solid var(--control-line); }
.schedAcqLegend { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin: 2px 0 8px; }
.schedAcqSrc { color: var(--muted); font-size: 10.5px; font-style: normal; }
.schedAcqRow { margin: 2px 0 10px; padding: 8px 12px; border-radius: 8px; border-left: 4px solid var(--control-line); background: var(--soft); }
.schedAcqRow.inherit { border-left-color: var(--green); background: var(--green-soft); }
.schedAcqRow.accelerate { border-left-color: var(--gold); background: var(--gold-soft); }
.schedAcqKind { display: block; font-size: 10px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--navy-ink); }
.schedAcqRow.inherit .schedAcqKind { color: var(--green-ink); }
.schedAcqRow.accelerate .schedAcqKind { color: var(--gold-ink); }
.schedAcqRow p { margin: 3px 0 0; font-size: 12px; line-height: 1.5; color: var(--ink); }
@media print { .schedAcqRow { break-inside: avoid; } }

/* ── PUBLIC FACE LAYOUT ───────────────────────────────────────────────────
   Shared by the four public pages so the composition lives in one place and
   a page ships as content. Every class is pf-prefixed: the pages load this
   same sheet as the workbench, and an unprefixed .card or .row would inherit
   workbench rules that were never meant for them.

   Tints are color-mix off the tokens rather than literal rgba, so the whole
   surface follows the palette from one block. */

/* The dark values, defined ONCE. Two surfaces use them — the public face
   under prefers-color-scheme, and the studio's "Dark" palette choice — and
   studio-themes.css opens by recording what happened the last time dark was
   written out twice: the copies drifted and "follow system" left half the
   studio in the wrong palette. Referencing beats repeating. */
:root {
  --dk-ink: #dfeaf6; --dk-navy: #bcd6ef; --dk-blue: #7fb3ee; --dk-muted: #a3b6c9;
  --dk-line: rgba(186, 212, 238, .16); --dk-rule: #3d5169;
  --dk-paper: #141f2b; --dk-page: #0d1620; --dk-soft: #18242f;
  --dk-green: #7fc09a; --dk-green-soft: #16281f; --dk-green-ink: #a5dcbd;
  --dk-gold: #d9b164; --dk-gold-soft: #2c2515; --dk-gold-ink: #e6c483; --dk-gold-text: #eed6a8;
  --dk-clay: #d4956f; --dk-clay-soft: #2f2219; --dk-clay-ink: #e3aa8b;
  --dk-control: #18242f; --dk-control-line: #35485c;
  --dk-navy-soft: #1b2f45; --dk-navy-ink: #cfe0f2;
  --dk-on-accent: #0d1620; --dk-on-accent-dim: #6f8ba6; --dk-on-accent-weak: #8a6a58;
  --dk-red: #e69a94; --dk-red-soft: #2e1c1b; --dk-red-ink: #f0b3ad;
}

/* ── BLUEPRINT AFTER DARK ──────────────────────────────────────────────────
   The public face follows the visitor's system from 2026-08-12 (Charlie).
   It could not simply borrow the studio's dark palette: that one is a neutral
   blue-grey built for long working sessions, and next to blueprint's navy the
   site would have read as two different products depending on time of day.
   So this is blueprint at night — the same drafting-navy identity, inverted
   deliberately rather than mechanically.

   Delivered as a media query rather than a JS-resolved attribute: the public
   pages ship under a CSP that forbids inline script, and a resolver in an
   external file would paint light first and flash. CSS has neither problem.
   It sits after the light blueprint block so it wins on order at equal
   specificity.

   Every pair below is gated by the AA contrast test alongside the other
   palettes; it is not exempt for being new. */
@media (prefers-color-scheme: dark) {
[data-public-face="blueprint"] {
  color-scheme: dark;
  --ink: var(--dk-ink); --navy: var(--dk-navy); --blue: var(--dk-blue); --muted: var(--dk-muted);
  /* Translucent like its light twin, so the hairline composites over page,
     paper and soft in proportion instead of reading heavy on the darkest. */
  --line: var(--dk-line); --rule: var(--dk-rule);
  --paper: var(--dk-paper); --page: var(--dk-page); --soft: var(--dk-soft);
  --green: var(--dk-green); --green-soft: var(--dk-green-soft); --green-ink: var(--dk-green-ink);
  --gold: var(--dk-gold); --gold-soft: var(--dk-gold-soft); --gold-ink: var(--dk-gold-ink); --gold-text: var(--dk-gold-text);
  --clay: var(--dk-clay); --clay-soft: var(--dk-clay-soft); --clay-ink: var(--dk-clay-ink);
  --control: var(--dk-control); --control-line: var(--dk-control-line);
  --navy-soft: var(--dk-navy-soft); --navy-ink: var(--dk-navy-ink);
  --on-accent: var(--dk-on-accent); --on-accent-dim: var(--dk-on-accent-dim); --on-accent-weak: var(--dk-on-accent-weak);
  --red: var(--dk-red); --red-soft: var(--dk-red-soft); --red-ink: var(--dk-red-ink);
}
}

[data-public-face="blueprint"] body {
  margin: 0; color: var(--ink); font: 400 15px/1.6 var(--font);
  background:
    linear-gradient(color-mix(in srgb, var(--ink) 5%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, var(--ink) 5%, transparent) 1px, transparent 1px),
    var(--page);
  background-size: 34px 34px;
}
[data-public-face="blueprint"] h1,
[data-public-face="blueprint"] h2,
[data-public-face="blueprint"] h3,
[data-public-face="blueprint"] .pfSerif { font-family: var(--display); font-weight: 500; }
[data-public-face="blueprint"] a { color: inherit; text-decoration: none; }

/* ── THE PUBLIC-FACE MEASURE ──────────────────────────────────────────────
   Two rules govern this surface, and both were arrived at by measuring the
   page rather than by taste.

   ONE ELEVATION. The card fill (--paper #fefdfa) sits ~2% from the page
   ground (--page #f9f7f2), so a card was never separated by its fill; it was
   separated by a 40px-blur drop shadow, twenty-two times over. That soft
   float is the strongest "product page" signal in the vocabulary, and it is
   the exact register the .pfIco note below already disavows. So the shadow
   is spent in ONE place -- .pfBox, the drafted figure -- where elevation
   means "this is a plate", and everywhere else grouping is done by a rule
   and a gutter. Structure squares off; only controls keep a radius.

   THREE LEVELS OF PAUSE. Eleven sections all set 72px and all sat on the
   same ground, so a page with a clear argument read as twelve equal beats
   and gave a scanning reader nothing to navigate by. --sect is now one
   fluid step, and sections declare their role: .lead opens an act, .tight
   continues the thought above it, .ground gives an evidence-heavy act its
   own tone. The old 72px never responded to viewport either -- at 391px it
   was still 72px on a 13,733px page. */
[data-public-face="blueprint"] {
  --sect: clamp(40px, 5vw, 76px);
  --pf-ground: color-mix(in srgb, var(--ink) 4.5%, var(--page));
  /* Three body steps. The page was running 18/15/13/12.5/12/11.5/11 -- the
     near-collisions read as drift, not as a system. Labels share the fine
     size and separate themselves by tracking and case instead. */
  --pf-lead: 17px;
  --pf-body: 14px;
  --pf-fine: 12px;
}

/* The skip link. Off-canvas rather than display:none or visibility:hidden,
   because both of those remove it from the focus order and a bypass control
   nobody can focus is not a bypass control. It reappears on :focus-visible as
   a real, high-contrast target — and it must outrank the sticky masthead's
   z-index of 50 or it lands underneath the thing it exists to skip. */
/* Scoped to the public-face attribute deliberately, and not written as a bare
   `.pfSkip`. Four lines above, `[data-public-face="blueprint"] a` sets
   `color: inherit` at specificity (0,1,1); a bare class is (0,1,0) and loses,
   so the background applied and the colour did not. In dark mode that produced
   a light-on-light skip link at 1.23:1 — invisible, on the one control that
   exists for people who cannot use a mouse.

   axe cannot catch this: the link is off-canvas until focused, so a colour
   check treats it as hidden and skips it. It was found by looking at the page
   and measuring the focused state, which is why the browser audit now asserts
   the focused contrast explicitly. */
[data-public-face="blueprint"] a.pfSkip {
  position: absolute; left: 12px; top: -60px; z-index: 100;
  padding: 11px 16px; border-radius: 7px;
  background: var(--navy); color: var(--on-accent);
  font: 600 var(--pf-body)/1 var(--font);
  transition: top .12s ease;
}
[data-public-face="blueprint"] a.pfSkip:focus-visible { top: 12px; outline: 2px solid var(--ink); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) { .pfSkip { transition: none; } }
/* The landing target takes focus programmatically via tabindex="-1"; it must
   never draw a focus ring for a mouse user who happened to click in it. */
.pfWrap[tabindex="-1"]:focus { outline: none; }

.pfWrap { max-width: 1240px; margin: 0 auto; padding: 0 28px; }

.pfHeader { position: sticky; top: 0; z-index: 50; background: color-mix(in srgb, var(--page) 88%, transparent); backdrop-filter: blur(14px); border-bottom: 1px solid color-mix(in srgb, var(--ink) 12%, transparent); }
.pfNav { display: flex; align-items: center; justify-content: space-between; gap: 22px; padding: 17px 0; }
.pfBrand { display: flex; align-items: center; gap: 12px; }
/* The brand mark. D-35 A3 "Bearing" put a CSS clip-path needle inside a
   bordered circle, on the reasoning that one element beat an SVG across four
   pages of markup. That reasoning expired when the pages became generated:
   the masthead is authored once in build-public-pages.mjs, so an SVG costs
   the same one edit and buys weighted arms a clip-path cannot draw.
   Charlie chose the rose on 2026-08-11. The mark itself lives in the
   generator; this only sizes it and hands it a colour to inherit. */
.pfMark { width: 42px; height: 42px; display: grid; place-items: center; flex: none; color: var(--blue); }
.pfMark svg { width: 100%; height: 100%; display: block; }
.pfBrand > span:last-child { display: block; }
.pfType { display: block; font-family: var(--font); font-size: 26px; font-weight: 700; line-height: .95; letter-spacing: -.02em; }
.pfType b { color: var(--green); font-weight: 700; }
.pfSub { display: block; font-size: 9px; letter-spacing: .18em; font-weight: 700; color: var(--muted); line-height: 1.3; text-transform: uppercase; }
.pfLinks { display: flex; gap: 22px; align-items: center; font-size: var(--pf-body); color: var(--muted); }
.pfLinks a:hover, .pfLinks a.on { color: var(--ink); }

/* Controls keep their radius. With structure squared off, the 7px corner is
   now the signal that something is pressable rather than page furniture. */
.pfBtn { display: inline-flex; align-items: center; justify-content: center; gap: 9px; padding: 12px 17px; border-radius: 7px; border: 1px solid currentColor; font-weight: 600; font-size: var(--pf-body); }
.pfBtn.solid { background: var(--navy); color: var(--on-accent); border-color: var(--navy); }
.pfBtn.go { background: var(--green); color: var(--on-accent); border-color: var(--green); }

.pfEyebrow { font-size: 12px; letter-spacing: .18em; font-weight: 700; color: var(--green); margin-bottom: 13px; text-transform: uppercase; font-family: var(--font); }
.pfKicker { font-size: var(--pf-body); font-weight: 600; letter-spacing: .04em; color: var(--blue); font-family: var(--font); }
.pfBadge { display: inline-block; padding: 7px 10px; border: 1px solid color-mix(in srgb, var(--ink) 16%, transparent); border-radius: 999px; font-size: var(--pf-fine); letter-spacing: .11em; font-weight: 700; color: var(--green); font-family: var(--font); text-transform: uppercase; }

.pfHero { display: grid; grid-template-columns: 1.02fr .98fr; gap: 52px; align-items: center; padding: 58px 0 52px; }
.pfHero h1 { font-size: clamp(46px, 5.6vw, 78px); line-height: .98; letter-spacing: -.035em; margin: 0 0 19px; }
/* The measure travels with the element, not with its position in the tree:
   a lead inside a split column escaped the section-level cap and ran to 80
   characters. 66ch is USWDS's stated target for long text. */
.pfLead { font-size: var(--pf-lead); line-height: 1.68; color: var(--muted); margin: 0; max-width: 66ch; }
.pfCtas { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 27px; align-items: center; }

.pfBox { position: relative; border: 1px solid color-mix(in srgb, var(--blue) 20%, transparent); padding: 22px;
  background:
    linear-gradient(color-mix(in srgb, var(--blue) 5%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, var(--blue) 5%, transparent) 1px, transparent 1px),
    var(--paper);
  background-size: 26px 26px, 26px 26px, auto; box-shadow: var(--shadow-card); overflow: hidden; }
.pfBox svg { display: block; width: 100%; height: auto; }

/* D-35 D2 "Ticked": the section rule carries measuring ticks below it, so the
   page rhythm reads as a drafted instrument rather than a plain divider. The
   ticks are decorative only -- they sit in a pseudo-element and carry no
   meaning, so no contrast minimum applies. */
.pfSection { padding: var(--sect) 0; border-top: 1px solid color-mix(in srgb, var(--ink) 12%, transparent); position: relative; }
.pfSection::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 6px;
  background-image: linear-gradient(90deg, var(--rule) 1px, transparent 1px);
  background-size: 18px 6px; background-repeat: repeat-x; opacity: .5; pointer-events: none; }

/* The three roles. A section that opens an act gets half again the step; one
   that continues the thought above it gets a little under two-thirds and
   drops the ticks, so the rule carries two weights instead of one. */
.pfSection.lead { padding-block: calc(var(--sect) * 1.5); }
/* A page-opening section has nothing above it to be ruled off from. This was
   an inline border-top:0, which suppressed the rule but left the tick strip
   painting a row of stray dots under the masthead. */
.pfSection.bare { border-top: 0; }
.pfSection.bare::before { display: none; }
.pfSection.tight { padding-block: calc(var(--sect) * .62); }
.pfSection.tight::before { display: none; }

/* A tonal landing for the evidence-heavy acts. The band has to reach the
   viewport edge while the section itself stays inside the 1240px wrap, so it
   is painted by a zero-blur spread and clipped back vertically -- a layout
   device, not elevation, and it renders as a flat field. */
.pfSection.ground { background: var(--pf-ground); box-shadow: 0 0 0 100vmax var(--pf-ground); clip-path: inset(0 -100vmax); --pf-dot: var(--pf-ground); }

.pfSection h2 { font-size: clamp(32px, 3.4vw, 46px); line-height: 1.05; letter-spacing: -.025em; margin: 0 0 15px; max-width: 22ch; }
.pfSection h2.wide { max-width: 34ch; }
/* 74ch rendered one paragraph at 810px -- about 90 characters. */
.pfSection > p { max-width: 66ch; }

/* The gutter is what the card padding used to be. Losing 23px of inner
   padding on each side means the columns need it back between them, or the
   blocks read as one run-on field. */
.pfGrid2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 34px; margin-top: 28px; }
.pfGrid3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 34px; margin-top: 28px; }
.pfGrid4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 30px; margin-top: 28px; }
/* Anchored to a rule, not floated on a shadow: the top edge does the
   grouping a border-radius and a 40px blur used to do. */
.pfCard { border-top: 2px solid var(--ink); padding: 17px 0 0; }
.pfCard h3 { font-size: 24px; margin: 9px 0 9px; line-height: 1.15; }
.pfCard p { margin: 0; color: var(--muted); line-height: 1.58; font-size: var(--pf-body); }
.pfCard em { display: block; font-style: normal; font-family: var(--font); font-size: var(--pf-fine); letter-spacing: .12em; text-transform: uppercase; font-weight: 700; color: var(--green); }
.pfNum { font-family: var(--display); font-size: 42px; line-height: 1; color: var(--green); }

/* Glyphs, untiled. The tinted rounded tile is what reads as a product page;
   a bare line glyph in ink reads as a printed document, which is the register
   this surface wants. */
.pfIco { width: 22px; height: 22px; display: block; color: var(--blue); margin-bottom: 12px; }

.pfSplit { display: grid; grid-template-columns: .78fr 1.22fr; gap: 42px; align-items: center; }
.pfStacked { display: grid; gap: 12px; }
.pfLayer { padding: 18px 22px; border: 1px solid currentColor; background: color-mix(in srgb, var(--paper) 62%, transparent); transform: skewX(-4deg); font-family: var(--font); font-size: var(--pf-body); }

/* The rail keeps its hairlines top and bottom -- a measured band across the
   page -- but loses the fill, the radius and the float. It is a timeline, and
   a timeline is a rule with marks on it. */
.pfRail { display: grid; grid-template-columns: repeat(6, 1fr); margin-top: 30px; border-top: 1px solid color-mix(in srgb, var(--ink) 12%, transparent); border-bottom: 1px solid color-mix(in srgb, var(--ink) 12%, transparent); padding: 25px 0 15px; }
.pfStep { text-align: center; position: relative; padding: 34px 10px 10px; }
/* The node knocks out the dashed line behind it, so it has to be filled with
   whatever ground the section is actually sitting on. */
.pfStep::before { content: ""; position: absolute; top: 10px; left: 50%; width: 14px; height: 14px; margin-left: -7px; border: 2px solid var(--blue); border-radius: 50%; background: var(--pf-dot, var(--page)); }
.pfStep:not(:last-child)::after { content: ""; position: absolute; left: 50%; right: -50%; top: 17px; border-top: 2px dashed color-mix(in srgb, var(--blue) 40%, transparent); }
.pfStep small { display: block; color: var(--green); font-weight: 700; letter-spacing: .08em; font-family: var(--font); font-size: 12px; }
.pfStep b { display: block; margin: 5px 0; font-family: var(--display); font-size: 17px; font-weight: 600; }
.pfStep p { font-size: var(--pf-fine); line-height: 1.45; color: var(--muted); margin: 0; }

/* A list of rows is a table, so it is ruled like one: no gap, no tile, one
   hairline between each pair and none after the last. */
.pfTable { display: grid; gap: 0; margin-top: 26px; border-top: 1px solid color-mix(in srgb, var(--ink) 12%, transparent); }
.pfRow { display: grid; grid-template-columns: 180px 1fr; gap: 18px; border-bottom: 1px solid color-mix(in srgb, var(--ink) 10%, transparent); padding: 17px 0; align-items: baseline; }
.pfRow b { color: var(--blue); font-family: var(--font); font-size: var(--pf-fine); letter-spacing: .1em; text-transform: uppercase; }
.pfRow span { color: var(--muted); line-height: 1.55; }
.pfRow .pfRowTitle { display: block; color: var(--ink); font-family: var(--display); font-size: 17px; font-weight: 600; letter-spacing: 0; text-transform: none; margin-bottom: 3px; }

.pfCallout { background: linear-gradient(145deg, var(--navy), color-mix(in srgb, var(--navy) 78%, black)); color: var(--on-accent); padding: 34px; display: grid; grid-template-columns: 1.1fr .9fr; gap: 24px; align-items: center; }
.pfCallout h2 { margin: 0 0 10px; color: var(--on-accent); }
.pfCallout p { color: var(--on-accent-dim); line-height: 1.65; margin: 0; }
.pfCallout .pfEyebrow { color: var(--on-accent-dim); }

.pfFilm { width: 100%; height: auto; display: block; border: 1px solid color-mix(in srgb, var(--ink) 12%, transparent); background: var(--navy); }
.pfNote { font-size: var(--pf-fine); color: var(--muted); margin-top: 12px; max-width: 74ch; }

/* The industry snapshot, laid out as a split (Charlie, 2026-08-12: "redesign
   the first section to be more like the second"). It reuses .pfSplit and
   .pfRow from the deliverables section rather than carrying its own card
   styles — same job, same pattern, one less thing to keep in step.

   Two adjustments the borrowed pattern needs for eight rows instead of three:
   the columns align to the top, because centring a short narrative against a
   tall list strands it in the middle of nowhere; and the label column is
   narrower, since a lens name plus its count needs less room than a
   deliverable title. */
.pfSplitTop { align-items: start; }
.pfSplitTop > div:first-child { position: sticky; top: 92px; }
.pfStdRow { grid-template-columns: 200px 1fr; }
.pfStdRow b { color: var(--muted); font-size: var(--pf-fine); }
.pfStdRow .pfRowTitle { font-size: 15px; line-height: 1.25; }
.pfStdRow span { font-size: var(--pf-fine); }
@media (max-width: 900px) {
  .pfSplitTop > div:first-child { position: static; }
  .pfStdRow { grid-template-columns: 1fr; }
}

.oppCapture { max-width: 760px; }
.framingBar { margin-bottom: 20px; }
.framingBar .oppBoxHead { margin-bottom: 0; align-items: center; }
.framingTitle { margin: 0; font-size: 17px; letter-spacing: -0.01em; color: var(--ink); }
.framingMeta { margin: 4px 0 0; font-size: 12px; color: var(--muted); }
.framingMeta b { color: var(--clay-ink); }
.framingDemoTag { font-size: 10px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--clay-ink); background: var(--clay-soft); border-radius: 5px; padding: 2px 7px; vertical-align: middle; }
.oppBox { border: 1px solid var(--control-line); border-radius: 14px; padding: 22px 24px; background: var(--paper); box-shadow: var(--shadow-card); }
.oppBoxHead { display: flex; align-items: flex-start; justify-content: space-between; gap: 26px; margin-bottom: 18px; }
.oppBoxHead h1 { margin: 0 0 8px; }
/* The demo switch lives in the corner of the framing box, not under it: it is
   the alternative to framing, not a step within it. Disabled once anything is
   typed — loading it replaces the record outright. */
.oppDemo { flex: 0 1 260px; min-width: 0; max-width: 100%; text-align: right; }
.oppDemo button { max-width: 100%; white-space: normal; }
.oppDemo button:disabled { opacity: .45; cursor: not-allowed; }
.oppDemo small { display: block; margin-top: 6px; font-size: 11px; line-height: 1.5; color: var(--muted); }
@media (max-width: 700px) { .oppBoxHead { flex-direction: column; gap: 14px; } .oppDemo { text-align: left; max-width: none; } }
.oppLead { color: var(--muted); font-size: 13.5px; line-height: 1.65; margin: 0 0 22px; }
.oppForm { display: grid; gap: 14px; text-align: left; }
.oppRow { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.oppRow > * { min-width: 0; }
.oppForm label { display: grid; gap: 5px; font-size: 12px; font-weight: 600; color: var(--ink); letter-spacing: .01em; }
.oppForm input, .oppForm select { width: 100%; min-width: 0; font: inherit; font-size: 13.5px; font-weight: 400; padding: 9px 11px; border: 1px solid var(--control-line); border-radius: 8px; background: var(--control); color: var(--ink); }
.oppForm select { cursor: pointer; }
.oppLockedValue { display: block; width: 100%; padding: 9px 11px; border: 1px solid var(--control-line); border-radius: 8px; background: var(--soft); color: var(--ink); font-size: 13.5px; font-weight: 600; }
.oppLens { border: 1px solid var(--green); background: var(--green-soft); border-radius: 10px; padding: 13px 15px; }
.oppLensSummary { margin: 0; font-size: 12.5px; line-height: 1.6; color: var(--ink); }
.oppLensStandards { margin: 7px 0 0; font-size: 11.5px; line-height: 1.6; color: var(--muted); }
.oppLensStandards b { color: var(--green-ink); }
.oppHint { margin: 0; font-size: 12px; color: var(--muted); font-style: italic; }
.oppActions { margin-top: 4px; }
.oppAlt { margin-top: 26px; padding-top: 18px; border-top: 1px solid var(--control-line); }
.oppAlt p { margin: 0 0 9px; font-size: 12.5px; color: var(--muted); }
@media (max-width: 620px) { .oppRow { grid-template-columns: 1fr; } }

/* Worked-example labels. The figures and the briefing are DoD, and stay DoD:
   Charlie's call, and the right one — a commercial buyer seeing that the
   rigours of Department of Defense cloud are handled reads it as reassurance,
   not exclusion. The label exists so nobody mistakes the example for the
   scope. */
.pfExample { margin: 12px 0 0; font-size: 12px; line-height: 1.6; color: var(--muted); border-top: 1px solid color-mix(in srgb, var(--ink) 10%, transparent); padding-top: 10px; }
.pfExample b { color: var(--ink); font-weight: 650; }

.pfStdGrid { display: grid; gap: 0; margin-top: 20px; border-top: 1px solid color-mix(in srgb, var(--ink) 12%, transparent); }
.pfStdRow { border-bottom: 1px solid color-mix(in srgb, var(--ink) 12%, transparent); padding: 15px 0; }
.pfStdHead { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.pfStdHead h3 { margin: 0; font-size: 15px; letter-spacing: -0.01em; }
.pfStdHead span { font-size: 19px; font-weight: 700; color: var(--accent-ink, var(--ink)); font-variant-numeric: tabular-nums; }
.pfStdRow p { margin: 6px 0 0; font-size: var(--pf-fine); line-height: 1.65; color: var(--muted); }
@media (max-width: 640px) { .pfStdHead { flex-direction: column; gap: 2px; } }

.pfFooter { padding: 30px 0 50px; color: var(--muted); font-size: var(--pf-fine); border-top: 1px solid color-mix(in srgb, var(--ink) 12%, transparent); display: flex; justify-content: space-between; gap: 18px; flex-wrap: wrap; }

@media (max-width: 900px) {
  .pfHero, .pfSplit, .pfCallout { grid-template-columns: 1fr; }
  .pfGrid2, .pfGrid3, .pfGrid4 { grid-template-columns: 1fr; }
  .pfRail { grid-template-columns: repeat(2, 1fr); }
  .pfStep:not(:last-child)::after { display: none; }
  .pfLinks a:not(.pfBtn) { display: none; }
  .pfRow { grid-template-columns: 1fr; }
}

@media (max-width: 480px) {
  .pfWrap { padding-inline: 16px; }
  .pfNav { gap: 12px; }
  .pfMark { width: 36px; height: 36px; }
  .pfType { font-size: 24px; }
  .pfBtn { padding: 10px 12px; }
}

/* ── THE OVERLAY FIGURE ───────────────────────────────────────────────────
   The annotated version of the stack: each plane names itself in the drawing,
   the way a real blueprint annotates, and hovering a plane brings up the one
   line that says what it is for. The names are always visible -- hover adds
   detail, it is never the only way to read the figure. */
.geometry.annotated .geoPlane { transition: opacity .18s ease; }
.geometry.annotated:hover .geoPlane { opacity: .55; }
.geometry.annotated .geoPlane:hover { opacity: 1; }
.geometry.annotated .geoFill { transition: fill-opacity .18s ease; }
.geometry.annotated .geoPlane:hover .geoFill { fill-opacity: .32; }
.geometry.annotated .geoLead { stroke-width: 1.2; stroke-dasharray: 3 3; }
.geometry.annotated .geoName { font: 600 13px var(--font); letter-spacing: .01em; }
.geometry.annotated .geoDetail { font: 400 12px var(--font); fill: var(--muted); opacity: 0; transition: opacity .18s ease; }
.geometry.annotated .geoPlane:hover .geoDetail { opacity: 1; }

/* Touch and reduced-motion: there is no hover, so the detail simply shows. */
@media (hover: none) {
  .geometry.annotated:hover .geoPlane { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .geometry.annotated .geoPlane, .geometry.annotated .geoFill, .geometry.annotated .geoDetail { transition: none; }
}

/* Product identity, said quietly. The runway was already a dashed route with
   nodes on it; the last node becomes the target waypoint you are navigating
   to, so the metaphor in the domain name shows up in the drawing rather than
   only in the copy. Same device as the route across Overlay 1. */
.pfStep:last-child::before { border-color: var(--green); box-shadow: 0 0 0 3px var(--paper), 0 0 0 4.5px color-mix(in srgb, var(--green) 55%, transparent); }
.pfStep:last-child small { color: var(--green); }

/* ── THE RESEARCH FIGURE ──────────────────────────────────────────────────
   The hero used to carry the same overlay stack that the map section explains,
   which meant one figure making one argument twice. This one makes the earlier
   argument instead: standards, requirements, provider practice and the peer
   programs converge into the single researched road, which runs to a waypoint.
   Plan view rather than isometric, so the two figures never read as duplicates. */
.researchFig { display: block; width: 100%; height: auto; }
.researchFig .rfName { font: 600 14px var(--font); fill: var(--ink); }
.researchFig .rfDetail { font: 400 11.5px var(--font); fill: var(--muted); }
.researchFig .rfRoad { font: 600 12px var(--font); fill: var(--navy); letter-spacing: .1em; text-transform: uppercase; }


/* The figure walks itself. Charlie: highlight one plane at a time, two seconds
   each, with its subtitle -- so a reader who never hovers still sees all four
   arguments. Four planes x 2s is an 8s loop; each plane runs the same keyframes
   offset by a negative delay, which is why there is one animation here and not
   four. Hovering cancels the cycle outright rather than pausing it, so the
   pointer always wins and never lands mid-fade. */
@keyframes geoCyclePlane { 0%, 22% { opacity: 1; } 28%, 100% { opacity: .45; } }
@keyframes geoCycleFill  { 0%, 22% { fill-opacity: .32; } 28%, 100% { fill-opacity: .14; } }
@keyframes geoCycleText  { 0%, 22% { opacity: 1; } 28%, 100% { opacity: 0; } }

.geometry.annotated .geoPlane { animation: geoCyclePlane 8s linear infinite; }
.geometry.annotated .geoFill { animation: geoCycleFill 8s linear infinite; }
.geometry.annotated .geoDetail { animation: geoCycleText 8s linear infinite; }

/* Base first, then overlays 1, 2, 3 -- bottom of the stack upward. */
.geometry.annotated .geoPlane:nth-of-type(1),
.geometry.annotated .geoPlane:nth-of-type(1) .geoFill,
.geometry.annotated .geoPlane:nth-of-type(1) .geoDetail { animation-delay: 0s; }
.geometry.annotated .geoPlane:nth-of-type(2),
.geometry.annotated .geoPlane:nth-of-type(2) .geoFill,
.geometry.annotated .geoPlane:nth-of-type(2) .geoDetail { animation-delay: -6s; }
.geometry.annotated .geoPlane:nth-of-type(3),
.geometry.annotated .geoPlane:nth-of-type(3) .geoFill,
.geometry.annotated .geoPlane:nth-of-type(3) .geoDetail { animation-delay: -4s; }
.geometry.annotated .geoPlane:nth-of-type(4),
.geometry.annotated .geoPlane:nth-of-type(4) .geoFill,
.geometry.annotated .geoPlane:nth-of-type(4) .geoDetail { animation-delay: -2s; }

.geometry.annotated:hover .geoPlane,
.geometry.annotated:hover .geoFill,
.geometry.annotated:hover .geoDetail { animation: none; }

/* No motion: no cycle, and every subtitle simply stays up. */
@media (prefers-reduced-motion: reduce) {
  .geometry.annotated .geoPlane,
  .geometry.annotated .geoFill,
  .geometry.annotated .geoDetail { animation: none; }
  .geometry.annotated .geoDetail { opacity: 1; }
}

/* A section's own layer, lifted out of the stack at the top of the page.
   Same coordinates, cropped by viewBox rather than redrawn, so the slice and
   the stack cannot drift apart. The badge is the tie-in: it is the one the
   reader already met on the full figure. */
.pfSliceFig { margin: 26px 0 0; padding: 0; max-width: 720px; }
.pfSliceFig .pfSlice { display: block; width: 100%; height: auto; }
.pfSliceFig figcaption { margin-top: 8px; font-size: 12.5px; color: var(--muted); }

/* WO20 §2.2: Import SOW — the row on Engage and the review modal. The modal
   reuses the studio's paper/line tokens; the native <dialog> centres itself
   and paints its own backdrop. */
.sowImportRow { align-items: center; gap: 10px; margin-bottom: 12px; }
.importPreviewDialog { border: 1px solid var(--line); border-radius: 12px; padding: 0; max-width: 560px; width: calc(100vw - 32px); background: var(--paper); color: var(--ink); box-shadow: 0 24px 64px rgba(0,0,0,.28); }
.importPreviewDialog::backdrop { background: rgba(10,20,35,.44); }
.importPreviewPanel { display: flex; flex-direction: column; gap: 12px; padding: 18px 20px 20px; margin: 0; }
.importPreviewHead { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }
.importPreviewHead h2 { margin: 2px 0 0; color: var(--navy); font-size: 18px; }
.importPreviewHead .eyebrow { margin: 0; color: var(--muted); font-size: 10px; font-weight: 800; letter-spacing: .07em; text-transform: uppercase; }
.importPreviewSummary { margin: 0; color: var(--ink); font-size: 13px; }
.importPreviewSection { margin: 0; }
.importPreviewSection h3 { margin: 0 0 5px; color: var(--navy); font-size: 12px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; }
.importPreviewSection ul { margin: 0; padding-left: 18px; color: var(--ink); font-size: 12.5px; }
.importPreviewSection li { margin: 2px 0; }
.importPreviewSection.caution ul { color: var(--muted); }
.importPreviewActions { display: flex; justify-content: flex-end; gap: 8px; }
.importPreviewPanel button { border: 1px solid var(--control-line); border-radius: 7px; background: var(--control); color: var(--navy); font-weight: 700; font-size: 12.5px; padding: 6px 12px; cursor: pointer; }
.importPreviewPanel button:hover { border-color: var(--navy); }
.importPreviewPanel button.primary { background: var(--navy); border-color: var(--navy); color: var(--on-accent); }
.importPreviewPanel button[disabled] { opacity: .5; cursor: not-allowed; }

/* WO20 §2.3: Synthesize's three blocks — KB Health, Migration Foundation
   Readiness (6R), and Native Capability Coverage. Studio-native presentation
   over the same engines; tokens only, legible in all four palettes. */
.synthBlock { margin: 18px 0 0; padding: 16px 18px; border: 1px solid var(--line); border-radius: 12px; background: var(--paper); }
.synthBlockHead { display: flex; justify-content: space-between; align-items: flex-start; gap: 14px; margin-bottom: 12px; }
.synthBlockHead h2 { margin: 0 0 3px; color: var(--navy); font-size: 17px; }
.synthBlockHead p { margin: 0; color: var(--muted); font-size: 12.5px; max-width: 760px; line-height: 1.5; }

/* KB Health */
.kbSummaryBadge { flex-shrink: 0; align-self: center; background: var(--clay); color: var(--clay-ink); border: 1px solid var(--clay-ink); border-radius: 999px; padding: 4px 11px; font-size: 11px; font-weight: 800; }
.kbGrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 10px; }
.kbRow { border: 1px solid var(--control-line); border-radius: 9px; background: var(--control); overflow: hidden; }
.kbRow.kbRowAtRisk { border-color: var(--clay-ink); }
.kbRow > summary { display: flex; justify-content: space-between; align-items: center; gap: 8px; padding: 9px 12px; cursor: pointer; list-style: none; }
.kbRow > summary::-webkit-details-marker { display: none; }
.kbRow h4 { margin: 0; color: var(--ink); font-size: 13px; }
.kbRiskBadge { background: var(--clay); color: var(--clay-ink); border-radius: 5px; padding: 2px 7px; font-size: 10px; font-weight: 800; }
.kbInputs { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 10px; padding: 4px 12px 12px; }
.kbInputs label { display: flex; flex-direction: column; gap: 3px; font-size: 11px; font-weight: 700; color: var(--muted); }
.kbInputs label.kbWide { grid-column: 1 / -1; }
.kbInputs select, .kbInputs input { border: 1px solid var(--control-line); border-radius: 6px; background: var(--paper); color: var(--ink); font-size: 12px; padding: 5px 7px; }
.kbContext { margin-top: 12px; padding-top: 10px; border-top: 1px dashed var(--line); }
.kbContext p { margin: 4px 0; color: var(--muted); font-size: 11.5px; line-height: 1.45; }
.kbContext a { color: var(--blue); }

/* Migration Foundation Readiness (6R) */
.sixRGrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 10px; }
.sixRCard { border: 1px solid var(--control-line); border-radius: 9px; background: var(--control); padding: 12px 13px; }
.sixRCard header { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; }
.sixRCard h3 { margin: 0; color: var(--navy); font-size: 14px; }
.sixRCard header p { margin: 2px 0 0; color: var(--muted); font-size: 11px; }
.sixRCard header > span { flex-shrink: 0; font-weight: 800; color: var(--navy); font-size: 15px; }
.sixRThreshold { margin: 8px 0; color: var(--ink); font-size: 11.5px; line-height: 1.4; }
.sixRArtifacts { display: flex; flex-wrap: wrap; gap: 5px; }
.sixRArtifact { border: 1px solid var(--control-line); border-radius: 5px; padding: 2px 7px; font-size: 11px; font-weight: 700; color: var(--navy); cursor: default; }
.sixRArtifact.isBlocker { border-color: var(--red-ink); color: var(--red-ink); }
.sixRArtifact:focus-visible { outline: 2px solid var(--blue); }

/* Native Capability Coverage — the shared 40-cell grid */
.cspCoverageGrid { display: grid; grid-template-columns: 130px repeat(4, 1fr); gap: 4px 10px; align-items: center; }
.cspCoverageHeadRow, .cspCoverageRow { display: contents; }
.cspCoverageHeadCell { font-size: 11px; font-weight: 800; letter-spacing: .03em; }
.cspCoverageRowLabel { font-size: 12px; font-weight: 700; color: var(--ink); }
.cspCoverageBarTrack { display: block; height: 12px; border-radius: 6px; background: var(--soft); overflow: hidden; }
.cspCoverageBarTrack i { display: block; height: 100%; border-radius: 6px; }
a.cspCoverageBarTrack:focus-visible { outline: 2px solid var(--blue); }
.cspCoverageCaveat { margin: 12px 0 0; color: var(--muted); font-size: 11px; line-height: 1.45; }

/* WO20 §2.4: the custody cluster — one table, three services, four operations.
   Clear is visually separated and tinted with the danger token because it is
   the only control here that destroys retained work. */
.custodyTable { display: flex; flex-direction: column; gap: 10px; }
.custodyRow { display: grid; grid-template-columns: minmax(200px, 1fr) auto; grid-template-areas: "what ops" "keeps keeps"; gap: 6px 14px; align-items: center; padding: 11px 13px; border: 1px solid var(--control-line); border-radius: 9px; background: var(--control); }
.custodyWhat { grid-area: what; }
.custodyWhat b { display: block; color: var(--navy); font-size: 13.5px; }
.custodyWhat small { display: block; margin-top: 2px; color: var(--muted); font-size: 11.5px; }
.custodyOps { grid-area: ops; display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; }
.custodyOps button { border: 1px solid var(--control-line); border-radius: 6px; background: var(--paper); color: var(--navy); font-weight: 700; font-size: 11.5px; padding: 5px 10px; cursor: pointer; }
.custodyOps button:hover:not([disabled]) { border-color: var(--navy); }
.custodyOps button[disabled] { opacity: .45; cursor: not-allowed; }
.custodyOps button:focus-visible { outline: 2px solid var(--blue); }
.custodyOps button.custodyClear { margin-left: 10px; border-color: var(--red); color: var(--red-ink); }
.custodyOps button.custodyClear:hover:not([disabled]) { background: var(--red-soft); border-color: var(--red-ink); }
.custodyKeeps { grid-area: keeps; color: var(--muted); font-size: 11px; line-height: 1.4; }
@media (max-width: 760px) {
  .custodyRow { grid-template-columns: 1fr; grid-template-areas: "what" "ops" "keeps"; }
  .custodyOps { justify-content: flex-start; }
  .custodyOps button.custodyClear { margin-left: 0; }
}

/* WO21: distributed collection — the issue documents and the return review. */
.collectionDocs { flex-wrap: wrap; gap: 6px; }
.collectionDocs button small { margin-left: 5px; opacity: .65; font-size: 9.5px; font-weight: 700; letter-spacing: .04em; }
.collectionLegend { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 6px 14px; margin-top: 12px; padding-top: 10px; border-top: 1px dashed var(--line); }
.collectionLegend div { font-size: 11.5px; line-height: 1.4; }
.collectionLegend b { color: var(--ink); }
.collectionLegend span { display: block; color: var(--muted); }
.collectionReviewRow[data-tone="warn"] .k b { color: var(--clay-ink); }
.collectionReviewRow[data-tone="blocked"] .k b, .collectionReviewRow[data-tone="repair"] .k b { color: var(--red-ink); }
.collectionAcceptance { margin-top: 12px; padding: 10px 12px; border: 1px solid var(--control-line); border-radius: 8px; background: var(--soft); }
.collectionAcceptance b { display: block; color: var(--navy); font-size: 12.5px; }
.collectionAcceptance span { display: block; margin-top: 2px; color: var(--ink); font-size: 12px; }
.collectionAcceptance small { display: block; margin-top: 4px; color: var(--muted); font-size: 11px; line-height: 1.4; }

/* WO22: the controlled-release lifecycle strip and its review grid. The strip
   is not decoration — five gates, each bound to the same hash, and a
   consultant needs to see which ones the current candidate has passed. */
.releaseSteps { display: grid; grid-template-columns: repeat(5, 1fr); gap: 6px; margin: 0 0 12px; }
.releaseStep { display: flex; flex-direction: column; gap: 1px; padding: 8px 10px; border: 1px solid var(--control-line); border-radius: 8px; background: var(--control); }
.releaseStep[data-done="yes"] { border-color: var(--green); background: var(--green-soft); }
.releaseStep b { color: var(--muted); font-size: 10px; font-weight: 800; }
.releaseStep[data-done="yes"] b { color: var(--green-ink); }
.releaseStep span { color: var(--navy); font-size: 12.5px; font-weight: 700; }
.releaseStep small { color: var(--muted); font-size: 10.5px; }
.releaseDimensions { display: grid; gap: 5px; margin-top: 10px; }
.releaseDimension { display: grid; grid-template-columns: 230px 150px 1fr; gap: 8px; align-items: center; }
.releaseDimension span { color: var(--ink); font-size: 12px; font-weight: 600; }
.releaseDimension select, .releaseDimension input { border: 1px solid var(--control-line); border-radius: 6px; background: var(--paper); color: var(--ink); font-size: 12px; padding: 4px 7px; }
.releaseStale { margin: 6px 0 0; color: var(--red-ink); font-size: 12px; }
.releaseOk { margin: 6px 0 0; color: var(--green-ink); font-size: 12px; }
@media (max-width: 900px) {
  .releaseSteps { grid-template-columns: repeat(2, 1fr); }
  .releaseDimension { grid-template-columns: 1fr; }
}

/* WO24: durable autosave. The banner is standing and not dismissible — an
   engagement with no copy outside browser storage is one wipe from gone. */
.autosaveBanner { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 10px 16px; border-bottom: 1px solid var(--clay-ink); background: var(--clay-soft); }
.autosaveBanner[data-tone="error"] { border-bottom-color: var(--red-ink); background: var(--red-soft); }
.autosaveBanner strong { display: block; color: var(--navy); font-size: 13px; }
.autosaveBanner span { display: block; margin-top: 2px; color: var(--ink); font-size: 12px; line-height: 1.45; max-width: 900px; }
.autosaveBanner button { flex-shrink: 0; border: 1px solid var(--navy); border-radius: 7px; background: var(--navy); color: var(--on-accent); font-weight: 700; font-size: 12.5px; padding: 7px 13px; cursor: pointer; }
.autosaveBanner button:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.autosaveStamp { font-size: 11.5px; color: var(--muted); }
.autosaveStamp[data-ok="no"] { color: var(--red-ink); font-weight: 700; }

/* WO25 link 1: cohort checkpoint capture. The source list answers one
   question — can a checkpoint be taken now, and if not, which workspace is
   missing — so readiness is a filled dot and absence states its reason. */
/* Transformation planning (WO25 link 3). Candidates read as cards because
   each one is a separate judgment with its own trace back to an observation —
   a table would flatten the provenance line that is the point of the record. */
.tpLead { display: grid; grid-template-columns: 1fr auto; gap: 14px; align-items: center; }
.tpLead span { display: block; color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: .04em; }
.tpLead strong { display: block; margin-top: 2px; color: var(--ink); font-size: 13.5px; }
.tpLead small { display: block; margin-top: 3px; color: var(--muted); font-size: 11px; line-height: 1.45; }
.tpCards { display: grid; gap: 10px; }
.tpCard { border: 1px solid var(--control-line); border-radius: 10px; padding: 12px 14px; background: var(--control); }
.tpCard[data-status="analyst-supported"] { border-color: var(--green); background: var(--green-soft); }
.tpCard[data-status="rejected"], .tpCard[data-status="deferred"] { opacity: .78; }
.tpCard header { display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline; }
.tpCard header span { font-family: var(--mono, ui-monospace, monospace); font-size: 11px; color: var(--muted); }
.tpCard header b { font-size: 11px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; color: var(--clay-ink); background: var(--clay-soft); border-radius: 5px; padding: 2px 7px; }
.tpCard header small { color: var(--muted); font-size: 11px; }
.tpCard h4 { margin: 7px 0 0; font-size: 13.5px; color: var(--ink); }
.tpCard p { margin: 5px 0 0; font-size: 12.5px; color: var(--ink); line-height: 1.5; }
.tpCard .tpTrace { color: var(--muted); font-size: 11.5px; }
.tpCard form { display: grid; gap: 8px; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--control-line); }

/* Enterprise advisory (WO25 link 2). The stage ladder reads as a progression
   rather than a checklist, so reached stages carry the ink and unreached ones
   stay quiet — the point is where you ARE, not how many boxes are ticked. */
.advStages { list-style: none; margin: 0 0 14px; padding: 0; display: grid; gap: 4px; }
.advStage { display: grid; grid-template-columns: 18px 1fr; gap: 10px; align-items: start; padding: 7px 11px; border: 1px solid transparent; border-radius: 8px; }
.advStage[data-reached="yes"] { background: var(--control); border-color: var(--control-line); }
.advStage[data-current="yes"] { border-color: var(--green); background: var(--green-soft); }
.advTick { font-size: 13px; color: var(--muted); line-height: 1.5; }
.advStage[data-reached="yes"] .advTick { color: var(--green-ink); }
.advStage b { display: block; color: var(--ink); font-size: 12.5px; text-transform: capitalize; }
.advStage small { display: block; margin-top: 1px; color: var(--muted); font-size: 11px; line-height: 1.45; }
.advAdvance { display: grid; gap: 8px; padding-top: 12px; border-top: 1px solid var(--control-line); }
.advUpstreams { display: grid; gap: 5px; }
.advUpstream { display: grid; grid-template-columns: 16px 1fr auto; gap: 9px; align-items: center; padding: 7px 10px; border: 1px solid var(--control-line); border-radius: 7px; background: var(--control); font-size: 12.5px; }
.advUpstream[data-present="yes"] { border-color: var(--green); background: var(--green-soft); }
.advUpstream span { color: var(--muted); font-size: 12px; line-height: 1; }
.advUpstream[data-present="yes"] span { color: var(--green-ink); }
.advUpstream b { color: var(--ink); font-weight: 600; }
.advUpstream small { color: var(--muted); font-size: 11px; }
.advDims { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 4px 14px; margin-bottom: 10px; }
.advDim { display: flex; align-items: center; gap: 7px; font-size: 12px; color: var(--ink); text-transform: capitalize; }
.advDim input { margin: 0; }
form[data-adv-form] { display: grid; gap: 8px; }
form[data-adv-form][data-locked="yes"] { opacity: .55; }

.cohortSources { display: grid; gap: 6px; }
.cohortSource { display: grid; grid-template-columns: 18px 1fr auto; gap: 10px; align-items: center; padding: 8px 11px; border: 1px solid var(--control-line); border-radius: 8px; background: var(--control); }
.cohortSource[data-ready="yes"] { border-color: var(--green); background: var(--green-soft); }
.cohortTick { font-size: 13px; color: var(--muted); line-height: 1; }
.cohortSource[data-ready="yes"] .cohortTick { color: var(--green-ink); }
.cohortSource b { display: block; color: var(--ink); font-size: 12.5px; }
.cohortSource small { display: block; margin-top: 1px; color: var(--muted); font-size: 11px; line-height: 1.4; }
.cohortSource em { font-style: normal; font-size: 10px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; color: var(--clay-ink); background: var(--clay-soft); border-radius: 5px; padding: 2px 6px; }
