/* Assay workspace — styles.
   Tokens follow the design package: borders rather than shadows, 3px radius on
   controls, 4px on panels. Spectral for headings, Public Sans for interface,
   IBM Plex Mono for anything a machine produced. All fonts are served from
   /assets/fonts — the page makes no request to any other origin. */

@font-face { font-family: "Spectral"; font-weight: 400; font-style: normal; font-display: swap; src: url(fonts/Spectral-Regular.woff) format("woff"); }
@font-face { font-family: "Spectral"; font-weight: 500; font-style: normal; font-display: swap; src: url(fonts/Spectral-Medium.woff) format("woff"); }
@font-face { font-family: "Spectral"; font-weight: 600; font-style: normal; font-display: swap; src: url(fonts/Spectral-SemiBold.woff) format("woff"); }
@font-face { font-family: "Spectral"; font-weight: 400; font-style: italic; font-display: swap; src: url(fonts/Spectral-Italic.woff) format("woff"); }
@font-face { font-family: "Public Sans"; font-weight: 100 900; font-style: normal; font-display: swap; src: url(fonts/PublicSans-Variable.woff) format("woff"); }
@font-face { font-family: "IBM Plex Mono"; font-weight: 400; font-display: swap; src: url(fonts/IBMPlexMono-Regular.woff) format("woff"); }
@font-face { font-family: "IBM Plex Mono"; font-weight: 500; font-display: swap; src: url(fonts/IBMPlexMono-Medium.woff) format("woff"); }
@font-face { font-family: "IBM Plex Mono"; font-weight: 600; font-display: swap; src: url(fonts/IBMPlexMono-SemiBold.woff) format("woff"); }

:root {
  --page: #F4F6F4; --surface: #FFFFFF; --sunk: #FAFBFA;
  --border: #E2E6E2; --soft: #E9EDEA; --strong: #C6CFC9;
  --ink: #16211C; --muted: #5C6B63; --faint: #8B978F; --ghost: #A9B3AC; --ink-rgb: 22,33,28;
  /* ALIASES, AND WHY THEY EXIST.
     These names were used in rules across the stylesheet and defined nowhere.
     A custom property that does not resolve raises nothing: the declaration is
     dropped at computed-value time and the property falls back to its
     inherited or initial value — so the rule renders almost right, which is
     how twelve of them survived. `var(--card)` was the one that finally showed
     it, leaving the help drawer with no background at phone width.
     They are defined here, as what each was plainly reaching for, rather than
     rewritten at every use — and `test_stylesheet.py` now fails on the next
     one invented. */
  --ink2: #33413A; --ink3: var(--muted);
  --paper: var(--surface); --line: var(--border);
  --rule: var(--border); --rule-soft: var(--soft);
  --verd: var(--green); --och: var(--amber); --indigo: var(--navy);
  --amber-ink: var(--amber-deep); --amber-wash: var(--amber-tint);
  --green: #1C7A4A; --green-deep: #14563A; --green-tint: #F2F9F4; --green-line: #CFE3D6; --green-wash: #F6FBF7; --green-text: #4E7A62;
  --amber: #C9901B; --amber-deep: #8A6410; --amber-tint: #FDF7E6; --amber-line: #EBDCB0; --amber-text: #4A3E20;
  --red: #B3261E; --red-tint: #FDF1EF; --red-line: #EBD2CE; --red-wash: #FDF6F4; --red-text: #9A2A22;
  --navy: #22406F; --navy-tint: #F1F4F9; --navy-line: #D2DBE8;
  --purple: #5B4B8A; --purple-tint: #F5F3FB; --purple-line: #DCD6EE;
  --teal: #23685F; --slate: #2F6E8A; --util: #8C5F12;
  /* THE APP BAR IS LIGHT. The chrome below it is light, the report is light,
     and a dark strip across the top of a light page reads as a different
     product wearing a hat. The sign-in splash stays dark — it is a cover, not
     chrome — so the two are separate tokens rather than one set doing both. */
  /* 5.15: dark again — see the note at the end of this file. */
  --bar: #14221B; --bar-2: #182A21; --bar-line: #2A3D33; --on-bar: #F1F5F2; --on-bar-dim: #9FB2A7;
  --splash: #14201B; --splash-2: #1D2E26; --splash-3: #132A20;
  --lift: 0 1px 2px rgba(22,33,28,.05);
  --tone: var(--green); --tone-tint: var(--green-tint); --tone-line: var(--green-line);
  /* 5.29: SEMANTIC TOKENS THE DARK THEME NEEDS.
     `#fff` on a green button and `#fff` on the app bar were the same literal
     for different reasons. In dark mode the button fill goes light and the bar
     stays dark, so the two have to be told apart: --on-tone is the text on a
     filled tone or ink surface (flips with the theme), --on-bar is the text on
     the bar and the sign-in cover (which are dark in both themes). */
  --on-tone: #FFFFFF; --scrim: rgba(12,26,19,.42);
  --navy-deep: #1A3258; --purple-deep: #443A6E;
  --red-deep: #6E1F19; --red-dim: #9A6A64; --amber-dim: #A08347;
  --orange: #B4530A; --orange-deep: #8A3F06;
  --purple-2: #6E5FA0; --util-tint: #FBF0D8;
  --hatch: #8E9A93;
  /* A code block is dark-on-light by design and stays so: the dark theme only
     deepens it, rather than inverting it into a light block on a dark page. */
  --code-bg: #16211C; --code-fg: #CFE3D6;
  /* The bar's own greens and the demo amber. The bar is dark in both themes,
     so these do not change with it. */
  --bar-green: #2E9A62; --bar-green-hover: #33A86B; --bar-accent: #4CC38A; --bar-accent-soft: #8FD4AE;
  --bar-amber: #E9C46A; --bar-amber-text: #F1D48A;
  --serif: "Spectral", Georgia, "Times New Roman", serif;
  --sans: "Public Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  color-scheme: light;
}

/* ── 5.29 · dark theme ─────────────────────────────────────────────────
   The same tokens, re-stated for a dark page. Two selectors on purpose: the
   first follows the operating system unless the reader has chosen Light in
   the top bar; the second is the reader choosing Dark. core.js sets
   data-theme on <html> before the first paint, so nothing flashes. Text
   colours are picked for 4.5:1 or better against --surface; the greens,
   ambers and reds are lightened so they still read as text on a dark ground
   and darkened where they are fills, which is what --on-tone is for. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --page: #0F1512; --surface: #171E1A; --sunk: #131A16;
    --border: #2A352F; --soft: #232C27; --strong: #44524A;
    --ink: #E8EDEA; --muted: #A3AFA8; --faint: #8A978F; --ghost: #66736C; --ink-rgb: 232,237,234;
    --ink2: #CBD4CE;
    --green: #4DB57E; --green-deep: #7CCFA0; --green-tint: #16281F; --green-line: #24503A; --green-wash: #141F19; --green-text: #8CC9A6;
    --amber: #D9A441; --amber-deep: #E6BE6A; --amber-tint: #2A2214; --amber-line: #4E3F1C; --amber-text: #E3CF9A;
    --red: #E0665C; --red-tint: #2C1A18; --red-line: #5A2B27; --red-wash: #221614; --red-text: #EF8F86;
    --navy: #8FB0E0; --navy-tint: #161E2B; --navy-line: #2B3D58;
    --purple: #B1A3E0; --purple-tint: #1C192A; --purple-line: #3C3560;
    --teal: #4FA89A; --slate: #6FA3BE; --util: #D59A3E;
    --bar: #0B140F; --bar-2: #0E1913; --bar-line: #22332A; --on-bar: #F2F6F3; --on-bar-dim: #A3B5AA;
    --splash: #0B140F; --splash-2: #142219; --splash-3: #10201A;
    --lift: 0 1px 2px rgba(0,0,0,.35);
    --on-tone: #0D1410; --scrim: rgba(0,0,0,.64);
    --navy-deep: #B9CCEC; --purple-deep: #CBC2EC;
    --red-deep: #F3A79F; --red-dim: #C9918A; --amber-dim: #C9AB6E;
    --orange: #E08A3C; --orange-deep: #F0B37A;
    --purple-2: #8B7CC0; --util-tint: #3A2E14;
    --hatch: #66736C;
    --code-bg: #0A100E; --code-fg: #CFE3D6;
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --page: #0F1512; --surface: #171E1A; --sunk: #131A16;
  --border: #2A352F; --soft: #232C27; --strong: #44524A;
  --ink: #E8EDEA; --muted: #A3AFA8; --faint: #8A978F; --ghost: #66736C; --ink-rgb: 232,237,234;
  --ink2: #CBD4CE;
  --green: #4DB57E; --green-deep: #7CCFA0; --green-tint: #16281F; --green-line: #24503A; --green-wash: #141F19; --green-text: #8CC9A6;
  --amber: #D9A441; --amber-deep: #E6BE6A; --amber-tint: #2A2214; --amber-line: #4E3F1C; --amber-text: #E3CF9A;
  --red: #E0665C; --red-tint: #2C1A18; --red-line: #5A2B27; --red-wash: #221614; --red-text: #EF8F86;
  --navy: #8FB0E0; --navy-tint: #161E2B; --navy-line: #2B3D58;
  --purple: #B1A3E0; --purple-tint: #1C192A; --purple-line: #3C3560;
  --teal: #4FA89A; --slate: #6FA3BE; --util: #D59A3E;
  --bar: #0B140F; --bar-2: #0E1913; --bar-line: #22332A; --on-bar: #F2F6F3; --on-bar-dim: #A3B5AA;
  --splash: #0B140F; --splash-2: #142219; --splash-3: #10201A;
  --lift: 0 1px 2px rgba(0,0,0,.35);
  --on-tone: #0D1410; --scrim: rgba(0,0,0,.64);
  --navy-deep: #B9CCEC; --purple-deep: #CBC2EC;
  --red-deep: #F3A79F; --red-dim: #C9918A; --amber-dim: #C9AB6E;
  --orange: #E08A3C; --orange-deep: #F0B37A;
  --purple-2: #8B7CC0; --util-tint: #3A2E14;
  --hatch: #66736C;
  --code-bg: #0A100E; --code-fg: #CFE3D6;
  color-scheme: dark;
}

.tone-green { --tone: var(--green); --tone-tint: var(--green-tint); --tone-line: var(--green-line); --tone-deep: var(--green-deep); }
.tone-navy { --tone: var(--navy); --tone-tint: var(--navy-tint); --tone-line: var(--navy-line); --tone-deep: var(--navy-deep); }
.tone-purple { --tone: var(--purple); --tone-tint: var(--purple-tint); --tone-line: var(--purple-line); --tone-deep: var(--purple-deep); }

* { box-sizing: border-box; }
html, body { margin: 0; }
body { background: var(--page); color: var(--ink); font-family: var(--sans); -webkit-font-smoothing: antialiased; }
button, input, select, textarea { font-family: inherit; }
button { color: inherit; }
button:disabled { cursor: not-allowed !important; opacity: .6; }
a { color: var(--green); text-decoration: underline; text-underline-offset: 2px; }
a:hover { color: var(--green-deep); }
:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }
[hidden] { display: none !important; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.hatch { background-image: repeating-linear-gradient(45deg, var(--hatch) 0 1.5px, transparent 1.5px 4px); }
.hatchband { background-image: repeating-linear-gradient(45deg, rgba(92,107,99,.10) 0 6px, transparent 6px 14px); }
.mono { font-family: var(--mono); }
.muted { color: var(--muted); }
.faint { color: var(--faint); }

#app { min-height: 100vh; padding-bottom: 56px; }
.boot { min-height: 100vh; display: flex; align-items: center; justify-content: center; font: 500 13px/1.4 var(--sans); letter-spacing: .03em; color: var(--faint); }

/* ── buttons & inputs ─────────────────────────────────────────────────── */
.btn-ghost { padding: 5px 10px; border: 1px solid var(--border); border-radius: 3px; background: var(--surface); font: 500 12px/1.5 var(--sans); letter-spacing: .03em; color: var(--muted); cursor: pointer; white-space: nowrap; text-transform: uppercase; }
.btn-ghost:hover { background: var(--page); }
.btn-green { padding: 8px 14px; border: 1px solid var(--green); border-radius: 3px; background: var(--green); font: 600 12.5px/1.4 var(--sans); color: var(--on-tone); cursor: pointer; white-space: nowrap; }
.btn-green:hover { background: var(--green-deep); border-color: var(--green-deep); }
.btn-amber { padding: 6px 11px; border: 1px solid var(--amber); border-radius: 3px; background: var(--surface); font: 600 11.5px/1.4 var(--sans); color: var(--amber-deep); cursor: pointer; white-space: nowrap; }
.btn-danger { padding: 8px 14px; border: 1px solid var(--red); border-radius: 3px; background: var(--surface); font: 600 12.5px/1.4 var(--sans); color: var(--red); cursor: pointer; white-space: nowrap; }
.btn-danger:hover { background: var(--red-tint); }
.btn-dark { padding: 5px 10px; border: 1px solid var(--ink); border-radius: 3px; background: var(--ink); font: 600 12px/1.5 var(--sans); letter-spacing: .03em; color: var(--on-tone); cursor: pointer; white-space: nowrap; }
.btn-link { border: none; background: transparent; padding: 0; font: 400 12px/1 var(--sans); color: var(--muted); cursor: pointer; white-space: nowrap; }
.btn-link:hover { color: var(--ink); }
.btn-wide-green { display: block; width: 100%; padding: 8px 10px; border: 1px solid var(--green); border-radius: 3px; background: var(--green); font: 600 12px/1.4 var(--sans); color: var(--on-tone); cursor: pointer; }
.btn-wide-green:hover { background: var(--green-deep); }
.btn-wide-ghost { display: block; width: 100%; padding: 7px 10px; border: 1px solid var(--border); border-radius: 3px; background: var(--surface); font: 500 11.5px/1.4 var(--sans); color: var(--muted); cursor: pointer; text-align: left; }
.btn-wide-ghost:hover { background: var(--page); color: var(--ink); }

.field-label { display: block; font: 500 11.5px/1.4 var(--sans); letter-spacing: .03em; color: var(--faint); margin-bottom: 6px; text-transform: uppercase; }
.field { display: block; width: 100%; padding: 9px 11px; border: 1px solid var(--border); border-radius: 3px; background: var(--surface); font: 400 13px/1.4 var(--sans); color: var(--ink); }
.field:focus { outline: none; border-color: var(--green); box-shadow: 0 0 0 3px rgba(28,122,74,.12); }
.field[readonly] { background: var(--sunk); color: var(--muted); }
.field-static { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.select { position: relative; display: inline-flex; min-width: 200px; max-width: 100%; }
.select-wide { display: flex; width: 100%; }
.select select { appearance: none; -webkit-appearance: none; width: 100%; padding: 7px 30px 7px 11px; border: 1px solid var(--border); border-radius: 3px; background: var(--surface); font: 400 12.5px/1.4 var(--sans); color: var(--ink); cursor: pointer; text-overflow: ellipsis; }
.select-wide select { padding: 9px 30px 9px 11px; font-size: 13px; }
.select::after { content: "▾"; position: absolute; right: 11px; top: 50%; transform: translateY(-50%); color: var(--faint); pointer-events: none; font-size: 12.5px; }
.select select:disabled { background: var(--sunk); color: var(--ghost); }
.search { width: 230px; max-width: 100%; padding: 6px 10px; border: 1px solid var(--border); border-radius: 3px; background: var(--surface); font: 400 12.5px/1.5 var(--sans); color: var(--ink); }
.search:focus { outline: none; border-color: var(--green); }

/* ── shared blocks ────────────────────────────────────────────────────── */
.eyebrow { display: flex; align-items: center; gap: 8px; margin-bottom: 11px; font: 500 10.5px/1.4 var(--mono); letter-spacing: .15em; color: var(--tone); text-transform: uppercase; }
.eyebrow-rule { width: 14px; height: 1px; background: var(--tone); flex: none; }
.panel { background: var(--surface); border: 1px solid var(--border); border-radius: 4px; padding: 22px; box-shadow: var(--lift); }
.h-serif { margin: 0 0 8px; font: 400 27px/1.15 var(--serif); letter-spacing: -.01em; }
.h-serif-sm { margin: 0 0 7px; font: 400 24px/1.2 var(--serif); }
.lede { margin: 0 0 18px; font: 400 13.5px/1.6 var(--sans); color: var(--muted); max-width: 760px; text-wrap: pretty; }
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
.stat { border: 1px solid var(--border); border-radius: 4px; padding: 11px 13px; background: var(--surface); min-width: 0; }
.stat-label { font: 500 11.5px/1.4 var(--sans); letter-spacing: .03em; color: var(--faint); margin-bottom: 7px; text-transform: uppercase; }
.stat-value { font: 400 24px/1 var(--serif); color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stat-sub { font: 400 11px/1.45 var(--sans); color: var(--faint); margin-top: 5px; }
.stat-red { border-color: var(--red-line); background: var(--red-wash); }
.stat-red .stat-label { color: var(--red-text); } .stat-red .stat-value { color: var(--red); } .stat-red .stat-sub { color: var(--red-dim); }
.stat-green { border-color: var(--green-line); background: var(--green-wash); }
.stat-green .stat-label, .stat-green .stat-value { color: var(--green-deep); } .stat-green .stat-sub { color: var(--green-text); }
.stat-amber { border-color: var(--amber-line); background: var(--amber-tint); }
.stat-amber .stat-label, .stat-amber .stat-value { color: var(--amber-deep); }
.stat-navy { border-color: var(--navy-line); background: var(--navy-tint); }
.stat-navy .stat-label, .stat-navy .stat-value { color: var(--navy); }
.stat-purple { border-color: var(--purple-line); background: var(--purple-tint); }
.stat-purple .stat-label, .stat-purple .stat-value { color: var(--purple); }
.stat { box-shadow: var(--lift); }
.stat-value { font-variant-numeric: tabular-nums; letter-spacing: -.01em; }

.notice { padding: 12px 15px; border-radius: 4px; border: 1px solid; font: 400 13px/1.6 var(--sans); text-wrap: pretty; }
.notice strong { font-weight: 600; }
.notice-text { max-width: 1000px; }
.notice-amber { background: var(--amber-tint); border-color: var(--amber-line); color: var(--amber-text); }
.notice-red { background: var(--red-tint); border-color: var(--red-line); color: var(--red-deep); }
.notice-green { background: var(--green-wash); border-color: var(--green-line); color: var(--green-deep); }
.notice-grey { background: var(--sunk); border-color: var(--border); color: var(--muted); }
.notice .btn-amber { margin-top: 10px; }

.marker { width: 9px; height: 9px; border-radius: 2px; flex: none; display: inline-block; }
.marker-observed { background: var(--green); }
.marker-notObserved { background: var(--amber); }
.marker-notEvidenced { border: 1px solid var(--ghost); background-image: repeating-linear-gradient(45deg, var(--hatch) 0 1.5px, transparent 1.5px 4px); }
.marker-confirmed { background: var(--ink); }
.marker-critical { background: var(--red); } .marker-high { background: var(--amber); } .marker-medium, .marker-low { background: var(--muted); }

.badge { display: inline-block; padding: 2px 7px; border-radius: 2px; background: var(--muted); color: var(--on-tone); font: 600 10.5px/1.6 var(--mono); letter-spacing: .09em; white-space: nowrap; text-transform: uppercase; }
.badge-red { background: var(--red); } .badge-amber { background: var(--amber); } .badge-green { background: var(--green); } .badge-ink { background: var(--ink); }
.badge-outline { background: var(--page); border: 1px solid var(--border); color: var(--muted); }
.chip { display: inline-block; padding: 2px 8px; border: 1px solid var(--border); border-radius: 999px; background: var(--sunk); font: 500 10.5px/1.6 var(--mono); color: var(--muted); white-space: nowrap; }

/* ── top chrome ───────────────────────────────────────────────────────── */
.topbar { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; column-gap: 24px; row-gap: 10px; padding: 9px 20px; background: linear-gradient(180deg, var(--bar) 0%, var(--bar-2) 100%); border-bottom: 1px solid var(--bar-line); position: sticky; top: 0; z-index: 50; }
.topbar-left { display: flex; align-items: center; flex-wrap: wrap; column-gap: 20px; row-gap: 10px; min-width: 0; }
.topbar-right { display: flex; align-items: center; flex-wrap: wrap; justify-content: flex-end; column-gap: 12px; row-gap: 8px; min-width: 0; flex: 1 1 auto; }
.brand { display: flex; align-items: center; gap: 8px; border: none; background: none; padding: 0; cursor: pointer; text-align: left; }
.brand-mark { width: 26px; height: 26px; border: 1px solid var(--bar-green); border-radius: 3px; background: linear-gradient(180deg, var(--bar-green) 0%, var(--green-deep) 100%); display: flex; align-items: center; justify-content: center; flex: none; font: 700 14px/1 var(--sans); color: var(--on-bar); }
.brand-word { display: block; font: 700 17px/1 var(--sans); letter-spacing: -.02em; color: var(--on-bar); }
.brand-word sup { font: 400 8px/1 var(--sans); color: var(--on-bar-dim); vertical-align: super; }
.brand-tag { display: block; font: 600 10.5px/1.4 var(--sans); letter-spacing: .08em; color: var(--green); white-space: nowrap; margin-top: 2px; text-transform: uppercase; }
.modetabs { display: flex; gap: 0; padding: 3px; background: rgba(22,33,28,.035); border: 1px solid var(--bar-line); border-radius: 5px; }
.modetab { padding: 5px 11px; border: none; border-radius: 3px; cursor: pointer; text-align: left; white-space: nowrap; background: transparent; color: var(--on-bar-dim); }
.modetab:hover { color: var(--ink); }
.modetab.on { background: var(--surface); border: 1px solid var(--border); box-shadow: 0 1px 2px rgba(22,33,28,.07); color: var(--ink); }
.modetab.on i { color: var(--muted); }
.modetab b { display: block; font: 600 13px/1.3 var(--sans); }
.modetab i { display: block; font: 400 10.5px/1.3 var(--sans); color: inherit; opacity: .78; font-style: normal; }
.trust-pill { display: inline-flex; align-items: center; gap: 6px; min-width: 0; padding: 4px 10px; border: 1px solid rgba(31,122,74,.28); border-radius: 999px; background: rgba(31,122,74,.07); font: 500 12.5px/1.5 var(--sans); letter-spacing: .03em; color: var(--green); overflow: hidden; }
.trust-pill span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dot { width: 6px; height: 6px; border-radius: 50%; background: var(--green); flex: none; display: inline-block; }
.buildsig { padding: 4px 8px; border: 1px solid var(--bar-line); border-radius: 3px; font: 400 12px/1.5 var(--sans); letter-spacing: .03em; color: var(--on-bar-dim); white-space: nowrap; }
.topbar .btn-link { color: var(--on-bar-dim); }
.topbar .btn-link:hover { color: var(--ink); }
.buildsig.mismatch { border-color: var(--red-line); color: var(--red); background: var(--red-tint); }

/* ── login ────────────────────────────────────────────────────────────── */
.login-wrap { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 40px 20px; }
.login { width: 100%; max-width: 940px; display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); border: 1px solid var(--border); border-radius: 4px; overflow: hidden; background: var(--surface); }
.login-brand { padding: 34px 32px; background: linear-gradient(180deg, var(--splash) 0%, var(--splash-2) 100%); color: var(--on-bar); }
.login-brand .brand-mark { border-color: rgba(255,255,255,.4); background: rgba(255,255,255,.1); color: var(--on-bar); }
.login-brand .brand-word { color: var(--on-bar); } .login-brand .brand-tag { color: rgba(255,255,255,.7); } .login-brand .brand-word sup { color: rgba(255,255,255,.6); }
.login-brand h1 { margin: 26px 0 12px; font: 400 25px/1.25 var(--serif); color: var(--on-bar); }
.login-brand p { margin: 0 0 22px; font: 400 13px/1.65 var(--sans); color: rgba(255,255,255,.76); text-wrap: pretty; }
.login-points { display: flex; flex-direction: column; gap: 8px; }
.login-points span { display: inline-flex; align-items: center; gap: 8px; font: 500 12px/1.5 var(--sans); color: rgba(255,255,255,.86); }
.login-points .dot { background: var(--bar-accent); }
.login-build { margin-top: 26px; padding-top: 16px; border-top: 1px solid rgba(255,255,255,.16); font: 400 12px/1.6 var(--sans); letter-spacing: .03em; color: rgba(255,255,255,.5); text-transform: uppercase; }
.login-form { padding: 34px 32px; }
.login-form .kicker { font: 500 12px/1.4 var(--sans); letter-spacing: .03em; color: var(--green); text-transform: uppercase; margin-bottom: 18px; }
.login-fields { display: flex; flex-direction: column; gap: 14px; }
.login-note { margin-top: 18px; padding: 11px 12px; border: 1px solid var(--border); border-radius: 3px; background: var(--sunk); font: 400 12px/1.55 var(--sans); color: var(--muted); text-wrap: pretty; }
.form-error { padding: 9px 11px; border: 1px solid var(--red-line); border-radius: 3px; background: var(--red-tint); font: 400 12.5px/1.5 var(--sans); color: var(--red-deep); }

/* ── upload landing ───────────────────────────────────────────────────── */
/* The landing is a screen of this application, not a brochure in front of it.
   Same ground, same panels, same type as the wizard and the report; the only
   dark surface in the product stays the application bar, which is on every
   screen and therefore reads as identity rather than as a change of place. */
.hero { background: var(--page); padding: 26px 20px 40px; }
.hero-grid { max-width: 1640px; margin: 0 auto; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(430px, 100%), 1fr)); gap: 24px; align-items: start; }
.hero-copy { min-width: 0; padding-top: 4px; }
.hero-pill { display: inline-flex; align-items: center; gap: 8px; padding: 5px 12px; border: 1px solid var(--green-line); border-radius: 999px; background: var(--green-tint); font: 500 12px/1.5 var(--sans); letter-spacing: .03em; text-transform: uppercase; color: var(--green-deep); margin-bottom: 18px; }
.hero h1 { margin: 0 0 14px; font: 400 clamp(30px, 3.2vw, 44px)/1.12 var(--serif); letter-spacing: -.015em; color: var(--ink); max-width: 640px; text-wrap: pretty; }
.hero h1 span { color: var(--green); }
.hero-lede { margin: 0 0 24px; font: 400 14px/1.7 var(--sans); color: var(--muted); max-width: 620px; text-wrap: pretty; }
.feat-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; max-width: 700px; }
@media (max-width: 560px) { .feat-grid { grid-template-columns: minmax(0, 1fr); } }
.feat { border: 1px solid var(--border); border-top: 3px solid; border-radius: 4px; background: var(--surface); padding: 14px 15px 15px; box-shadow: var(--lift); }
.feat-green { border-top-color: var(--green); } .feat-blue { border-top-color: var(--navy); }
.feat-amber { border-top-color: var(--amber); } .feat-red { border-top-color: var(--red); }
.feat-k { font: 500 11.5px/1.4 var(--sans); letter-spacing: .03em; text-transform: uppercase; color: var(--faint); margin-bottom: 8px; }
.feat-t { font: 500 15px/1.3 var(--sans); color: var(--ink); margin-bottom: 6px; }
.feat-b { font: 400 13px/1.55 var(--sans); color: var(--muted); text-wrap: pretty; }
.upcard { min-width: 0; background: var(--surface); border: 1px solid var(--border); border-top: 2px solid var(--green); border-radius: 4px; padding: 16px; box-shadow: var(--lift); }
.upcard-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 2px 2px 14px; }
.upcard-head span:first-child { font: 500 12px/1.4 var(--sans); letter-spacing: .03em; color: var(--tone, var(--green)); text-transform: uppercase; }
.dropzone-hero { border: 1.5px dashed var(--strong); border-radius: 4px; background: var(--sunk); padding: 32px 24px; text-align: center; transition: border-color .15s, background .15s; }
.dropzone-hero.drag, .dropzone.drag { border-color: var(--green); background: var(--green-tint); }
.drop-icon { width: 44px; height: 44px; margin: 0 auto 14px; border: 1px solid var(--green-line); border-radius: 50%; background: var(--green-tint); color: var(--green); font: 400 19px/42px var(--sans); }
.drop-over { font: 500 11.5px/1.4 var(--sans); letter-spacing: .03em; text-transform: uppercase; color: var(--faint); margin-bottom: 10px; }
.dropzone-hero h2 { margin: 0 0 10px; font: 400 22px/1.3 var(--serif); color: var(--ink); }
.dropzone-hero p { margin: 0 auto 18px; max-width: 420px; font: 400 13px/1.6 var(--sans); color: var(--muted); text-wrap: pretty; }
.drop-actions { display: flex; align-items: center; justify-content: center; gap: 12px; flex-wrap: wrap; margin-bottom: 16px; }
.btn-hero { padding: 9px 18px; border: 1px solid var(--green); border-radius: 3px; background: var(--green); font: 600 13px/1.4 var(--sans); color: var(--on-tone); cursor: pointer; white-space: nowrap; }
.btn-hero:hover { background: var(--green-deep); border-color: var(--green-deep); }
.pill-green { display: inline-flex; align-items: center; gap: 6px; padding: 3px 9px; border: 1px solid var(--green-line); border-radius: 999px; background: var(--green-tint); font: 500 11.5px/1.5 var(--sans); letter-spacing: .03em; color: var(--green-deep); }
.pill-green .dot { width: 5px; height: 5px; border-radius: 50%; background: var(--green); }
.drop-or { font: 400 12.5px/1.4 var(--sans); color: var(--faint); }
.drop-chips { display: flex; align-items: center; justify-content: center; gap: 7px; flex-wrap: wrap; margin-bottom: 12px; }
.drop-chip { padding: 3px 9px; border: 1px solid var(--border); border-radius: 999px; background: var(--surface); font: 400 11.5px/1.5 var(--sans); letter-spacing: .03em; color: var(--muted); }
.drop-status { font: 500 11.5px/1.4 var(--sans); color: var(--green-deep); }
.safe { margin-top: 12px; border: 1px solid var(--border); border-radius: 4px; background: var(--sunk); padding: 14px 16px; }
.safe-head { display: flex; align-items: center; gap: 9px; margin-bottom: 11px; font: 500 13px/1.4 var(--sans); color: var(--ink); }
.safe-tick { width: 16px; height: 16px; border-radius: 3px; background: var(--green-tint); border: 1px solid var(--green-line); color: var(--green-deep); font: 700 10.5px/15px var(--sans); text-align: center; flex: none; }
.safe-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 8px 18px; }
.safe-grid span { display: flex; align-items: center; gap: 9px; font: 400 12.5px/1.5 var(--sans); color: var(--muted); }
.safe-grid .dot { width: 5px; height: 5px; background: var(--green); }
.hero-foot { max-width: 1640px; margin: 30px auto 0; padding-top: 18px; border-top: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; gap: 20px; flex-wrap: wrap; }
.hero-foot span { font: 400 12px/1.6 var(--sans); color: var(--faint); max-width: 900px; text-wrap: pretty; }
.btn-hero-ghost { padding: 7px 13px; border: 1px solid var(--border); border-radius: 3px; background: var(--surface); font: 500 12.5px/1.4 var(--sans); color: var(--green-deep); cursor: pointer; white-space: nowrap; }
.btn-hero-ghost:hover { background: var(--green-tint); border-color: var(--green-line); }

/* ── wizard ───────────────────────────────────────────────────────────── */
.wizard { max-width: 1180px; margin: 0 auto; padding: 22px 20px 0; }
.wizard-grid { display: grid; grid-template-columns: minmax(0, 1fr) 268px; gap: 16px; align-items: start; }
.form-col { max-width: 560px; }
.wizard-aside { min-width: 0; }
.check-list { display: flex; flex-direction: column; }
.check { padding: 9px 13px; border-top: 1px solid var(--soft); }
.check:first-child { border-top: none; }
.check b { display: block; font: 500 12.5px/1.4 var(--sans); color: var(--ink); margin-bottom: 3px; }
.check span { display: block; font: 400 12px/1.5 var(--sans); color: var(--muted); text-wrap: pretty; }
.check-note { margin: 8px 11px 2px; padding: 10px 11px; border: 1px solid var(--green-line); border-radius: 3px; background: var(--green-wash); font: 400 12px/1.55 var(--sans); color: var(--green-text); text-wrap: pretty; }
@media (max-width: 900px) { .wizard-grid { grid-template-columns: minmax(0, 1fr); } }
.wizard h1 { margin: 0 0 8px; font: 400 28px/1.15 var(--serif); letter-spacing: -.01em; }
.wizard .lede { max-width: 620px; margin-bottom: 20px; }
.steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 8px; margin-bottom: 16px; }
.step { display: flex; align-items: center; gap: 8px; padding: 9px 12px; border-radius: 3px; font: 500 12.5px/1.4 var(--sans); border: 1px solid var(--border); background: var(--sunk); color: var(--ghost); }
.step.on { background: var(--green-tint); border-color: var(--green-line); color: var(--green-deep); }
.step.done { background: var(--surface); color: var(--muted); }
.step-n { width: 18px; height: 18px; border-radius: 50%; flex: none; text-align: center; font: 600 10.5px/18px var(--mono); background: var(--border); color: var(--faint); }
.step.on .step-n, .step.done .step-n { background: var(--green); color: var(--on-tone); }
.dropzone { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 9px; padding: 34px 22px; border: 1.5px dashed var(--strong); border-radius: 4px; background: var(--sunk); text-align: center; }
.dropzone .over { font: 500 12px/1.4 var(--sans); letter-spacing: .03em; color: var(--faint); text-transform: uppercase; }
.dropzone .body { font: 400 13px/1.55 var(--sans); color: var(--muted); max-width: 400px; }
.receipt { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin-top: 14px; padding: 11px 13px; border: 1px solid var(--border); border-radius: 3px; background: var(--sunk); }
.receipt.ok { border-color: var(--green-line); background: var(--green-wash); }
.receipt.bad { border-color: var(--red-line); background: var(--red-tint); }
.receipt-name { font: 500 13px/1.45 var(--sans); color: var(--ink); overflow-wrap: anywhere; }
.receipt.ok .receipt-name { color: var(--green-deep); }
.receipt-meta { font: 400 12.5px/1.5 var(--sans); color: var(--faint); margin-top: 3px; text-transform: uppercase; }
.receipt.ok .receipt-meta { color: var(--green-text); }
.receipt-state { font: 500 12px/1.4 var(--sans); letter-spacing: .03em; color: var(--green-deep); white-space: nowrap; flex: none; text-transform: uppercase; }
.receipt.bad .receipt-state { color: var(--red); }
.wizard-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--soft); }
.progress { display: flex; align-items: center; gap: 8px; margin-top: 12px; font: 500 12.5px/1.4 var(--sans); letter-spacing: .03em; color: var(--green-deep); text-transform: uppercase; }
.progress i { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--green); animation: pulse 1s ease-in-out infinite; }
@keyframes pulse { 0%, 100% { opacity: .25; } 50% { opacity: 1; } }
.form-col { display: flex; flex-direction: column; gap: 14px; max-width: 520px; }

/* ── report shell ─────────────────────────────────────────────────────── */
.report { max-width: none; margin: 0; padding: 0; }
.report-body { max-width: 1640px; margin: 0 auto; padding: 18px 20px 0; display: flex; gap: 16px; align-items: flex-start; }
.sidebar { flex: none; width: 200px; position: sticky; top: calc(var(--topbar-h, 52px) + 58px); }
.side { background: var(--surface); border: 1px solid var(--border); border-radius: 4px; padding: 13px 0 11px; box-shadow: var(--lift); }
.side-title { font: 500 11.5px/1.4 var(--sans); letter-spacing: .03em; color: var(--faint); padding: 0 13px 9px; }
.side-group { display: flex; align-items: center; gap: 7px; padding: 13px 13px 6px; font: 600 11px/1.4 var(--sans); letter-spacing: .03em; text-transform: uppercase; color: var(--tone); }
.side-group::before { content: ""; width: 6px; height: 6px; border-radius: 1px; background: var(--tone); flex: none; }
.side-group:first-of-type { padding-top: 2px; }
.side-item { display: flex; align-items: center; gap: 9px; width: 100%; padding: 6px 13px; border: none; text-align: left; cursor: pointer; font: 500 12.5px/1.4 var(--sans); background: transparent; color: var(--muted); }
.side-item:hover { background: var(--page); color: var(--ink); }
.side-item { border-left: 2px solid transparent; }
.side-item:hover { border-left-color: var(--tone-line); }
.side-item.on { background: var(--tone); color: var(--on-tone); border-left-color: var(--tone-deep, var(--tone)); }
.side-item span { font: 500 11.5px/1.4 var(--sans); letter-spacing: .03em; flex: none; color: var(--ghost); }
.side-item.on span { color: var(--on-tone); opacity: .72; }
.side-item em { margin-left: auto; font: 400 10.5px/1 var(--mono); font-style: normal; color: var(--ghost); }
.side-item.on em { color: var(--on-tone); opacity: .72; }
.side-actions { padding: 12px 11px 0; display: flex; flex-direction: column; gap: 6px; }
.main { flex: 1 1 auto; min-width: 0; }
.rhead-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 26px; flex-wrap: wrap; }
.rhead h1 { margin: 0 0 8px; font: 400 29px/1.15 var(--serif); letter-spacing: -.01em; }
.main .panel, .main .card-panel { border-top: 2px solid var(--tone-line); }
.main .panel.rhead { border-top: 2px solid var(--tone); }
.rhead p { margin: 0; font: 400 13.5px/1.6 var(--sans); color: var(--muted); text-wrap: pretty; max-width: 700px; }
.score { flex: none; border: 1px solid var(--amber-line); border-radius: 4px; background: var(--amber-tint); padding: 13px 16px; text-align: center; min-width: 132px; }
.score-n { font: 400 30px/1 var(--serif); color: var(--amber-deep); }
.score-band { font: 500 11px/1.4 var(--sans); letter-spacing: .03em; color: var(--amber-deep); margin-top: 6px; }
.score-sub { font: 400 10.5px/1.4 var(--sans); color: var(--amber-dim); margin-top: 6px; }
.score.good { border-color: var(--green-line); background: var(--green-wash); } .score.good .score-n, .score.good .score-band { color: var(--green-deep); } .score.good .score-sub { color: var(--green-text); }
.score.poor { border-color: var(--red-line); background: var(--red-wash); } .score.poor .score-n, .score.poor .score-band { color: var(--red); } .score.poor .score-sub { color: var(--red-dim); }
.scopebar { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--soft); }
.scopebar-fields { display: flex; gap: 14px; flex-wrap: wrap; min-width: 0; }
.rhead .stats { margin-top: 16px; }
.rhead .notice { margin-top: 14px; }
.section-gap { margin-top: 14px; }

/* ── tables ───────────────────────────────────────────────────────────── */
.tbl-tools { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; padding-bottom: 12px; border-bottom: 1px solid var(--soft); }
.subtabs { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.subtab { padding: 6px 12px; border: 1px solid var(--border); border-radius: 3px; cursor: pointer; white-space: nowrap; font: 600 11.5px/1.5 var(--sans); background: var(--surface); color: var(--muted); }
.subtab.on { background: var(--tone); border-color: var(--tone); color: var(--on-tone); }
.tbl-right { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.rows-label { font: 500 11.5px/1.5 var(--sans); letter-spacing: .03em; color: var(--faint); white-space: nowrap; }
.pagesize { padding: 5px 9px; border: 1px solid var(--border); border-radius: 3px; cursor: pointer; font: 500 10.5px/1.5 var(--mono); background: var(--surface); color: var(--muted); }
.pagesize.on { background: var(--tone); border-color: var(--tone); color: var(--on-tone); }
.tbl-scroll { overflow: auto; max-height: 56vh; border: 1px solid var(--border); border-radius: 3px; }
.tbl-head { display: grid; gap: 14px; padding: 10px 14px; background: var(--page); border-bottom: 1px solid var(--border); position: sticky; top: 0; z-index: 2; }
.th { display: flex; align-items: center; gap: 5px; background: transparent; border: none; padding: 0; cursor: pointer; text-align: left; font: 500 11.5px/1.5 var(--sans); letter-spacing: .03em; white-space: nowrap; color: var(--faint); }
.th.on { color: var(--green-deep); }
.th span { opacity: .5; }
.tr { display: grid; gap: 14px; align-items: baseline; padding: 10px 14px; border-top: 1px solid var(--soft); background: var(--surface); }
.tr:nth-child(odd) { background: var(--sunk); }
.tr:first-of-type { border-top: none; }
.td-text { font: 400 12.5px/1.55 var(--sans); color: var(--ink); text-wrap: pretty; overflow-wrap: anywhere; }
.td-mono { font: 400 11px/1.55 var(--mono); color: var(--muted); overflow-wrap: anywhere; }
.td-num { font: 500 12.5px/1.5 var(--mono); color: var(--ink); }
.bar { height: 6px; border-radius: 3px; background: var(--soft); overflow: hidden; }
.bar i { display: block; height: 6px; border-radius: 3px; background: var(--green); }
.tbl-empty { padding: 26px 14px; text-align: center; font: 400 13px/1.6 var(--sans); color: var(--faint); }
.tbl-foot { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; margin-top: 12px; }
.tbl-foot .count { font: 400 12.5px/1.6 var(--sans); letter-spacing: .03em; color: var(--faint); text-transform: uppercase; }
.pager { display: flex; align-items: center; gap: 8px; }
.pager span { font: 500 12px/1.5 var(--sans); letter-spacing: .03em; color: var(--muted); white-space: nowrap; }
.drift-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin: 0 0 12px; }
.drift-actions .field { width: 260px; padding: 6px 10px; font-size: 12.5px; }

/* ── as code ──────────────────────────────────────────────────────────── */
.code-tools { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.code-tools > div { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.code { background: var(--code-bg); border: 1px solid var(--soft); border-radius: 3px; padding: 16px 18px; overflow: auto; max-height: 62vh; }
.code pre { margin: 0; font: 400 13px/1.75 var(--mono); color: var(--code-fg); white-space: pre; tab-size: 4; }
.code-foot { margin-top: 12px; font: 400 11px/1.6 var(--mono); color: var(--faint); text-transform: uppercase; }

/* ── flow map ─────────────────────────────────────────────────────────── */
.map-head { background: var(--surface); border: 1px solid var(--border); border-radius: 4px 4px 0 0; border-bottom: none; padding: 20px 22px 16px; }
.map-head-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 24px; flex-wrap: wrap; }
.map-head-row > div:first-child { min-width: 0; max-width: 760px; }
.map-head p { margin: 0; font: 400 13px/1.6 var(--sans); color: var(--muted); text-wrap: pretty; }
.map-head-tools { display: flex; align-items: center; gap: 10px; flex: none; flex-wrap: wrap; }
.crumbs { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; font: 500 12px/1.4 var(--sans); letter-spacing: .03em; color: var(--faint); }
.crumbs button { border: none; background: none; padding: 0; font: inherit; color: var(--green); cursor: pointer; letter-spacing: inherit; text-decoration: underline; text-underline-offset: 2px; }
.toolbar { background: var(--surface); border: 1px solid var(--border); border-top: 1px solid var(--soft); }
.toolbar-row { display: flex; align-items: center; justify-content: space-between; gap: 20px; flex-wrap: wrap; padding: 11px 14px; }
.toolbar-row + .toolbar-row, .toolbar-band { border-top: 1px solid var(--border); }
.toolbar-band { background: var(--sunk); padding: 11px 14px; }
.legend { display: flex; align-items: center; gap: 15px; flex-wrap: wrap; font: 500 10.5px/1.6 var(--mono); letter-spacing: .05em; color: var(--muted); }
.legend > span { display: flex; align-items: center; gap: 6px; white-space: nowrap; }
.legend .legend-title { color: var(--faint); letter-spacing: .12em; }
.legend .legend-note { color: var(--faint); letter-spacing: 0; white-space: normal; }
.sw { width: 11px; height: 11px; border-radius: 2px; flex: none; }
.sw-api { background: rgba(34,64,111,.16); border: 1.5px solid var(--navy); }
.sw-priv { background: var(--red); } .sw-write { background: var(--green); }
.sw-table { background: rgba(47,110,138,.16); border: 1.5px solid var(--slate); }
.sw-logic { background: rgba(35,104,95,.16); border: 1.5px solid var(--teal); }
.sw-util { background: rgba(168,114,26,.16); border: 1.5px solid var(--util); }
.sw-call { background: rgba(91,75,138,.16); border: 1.5px solid var(--purple); }
.sw-note { border: 1.5px dashed var(--green); } .sw-flow { background: var(--ink); }
.sw-container { border: 1.5px solid var(--muted); border-top-width: 4px; }
.state-note { margin-top: 9px; padding-top: 9px; border-top: 1px dotted var(--border); font: 400 12px/1.6 var(--sans); color: var(--muted); max-width: 1020px; text-wrap: pretty; }
.state-note strong { font-weight: 600; color: var(--ink); }
.seg { display: flex; border: 1px solid var(--border); border-radius: 3px; overflow: hidden; }
.seg button { padding: 5px 10px; border: none; cursor: pointer; white-space: nowrap; font: 600 12px/1.5 var(--sans); letter-spacing: .03em; background: var(--surface); color: var(--faint); }
.seg button.on { background: var(--ink); color: var(--on-tone); }
.zoom { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-width: 0; }
.zoom-label { font: 500 12px/1 var(--sans); letter-spacing: .03em; color: var(--faint); }
.zoom-btn { width: 26px; height: 26px; border: 1px solid var(--border); border-radius: 3px; background: var(--surface); font: 400 14px/1 var(--sans); color: var(--ink); cursor: pointer; }
.zoom-val { min-width: 44px; text-align: center; font: 400 12.5px/1 var(--mono); }
.btn-fit { height: 26px; padding: 0 11px; border-radius: 3px; font: 600 12px/24px var(--sans); letter-spacing: .03em; cursor: pointer; white-space: nowrap; border: 1px solid var(--border); background: var(--surface); color: var(--muted); }
.btn-fit.on { border-color: var(--green); background: var(--green); color: var(--on-tone); }
.meta-mono { font: 400 11.5px/1.5 var(--mono); color: var(--faint); white-space: nowrap; }
.hint-mono { font: 400 12px/1.5 var(--sans); letter-spacing: .03em; color: var(--faint); white-space: nowrap; }
.btn-reset.moved { border-color: var(--amber); background: var(--amber-tint); color: var(--amber-deep); }

/* The map is the thing people came for, so it gets the room. 74vh sounded
   generous and was not: the toolbar, legend and band above it eat ~300px, so a
   flow of any size arrived pre-squashed and had to be scrolled to be read.
   Sized against the viewport minus the chrome, with a floor that still shows
   several rows of cards rather than a letterbox. */
.canvas { background: var(--surface); border: 1px solid var(--border); border-top: none; border-radius: 0 0 4px 4px; cursor: grab; overflow: auto; max-height: calc(100vh - 210px); min-height: 360px; }
body.map-full .canvas { height: calc(100vh - 150px); max-height: none; }
.canvas.panning { cursor: grabbing; }
.canvas-zoom { width: max-content; position: relative; }
.wire { fill: none; stroke: var(--strong); stroke-width: 1.1; stroke-linecap: round; stroke-linejoin: round; }
.wire.moved { stroke: var(--green); stroke-width: 1.4; }
.wire.fail { stroke: var(--red-line); }
.lane { display: flex; align-items: center; padding: 40px 32px; width: max-content; }
.seq { display: flex; align-items: center; }
.map-empty { padding: 40px 32px; font: 400 13px/1.6 var(--sans); color: var(--faint); }
.canvas-foot { display: flex; justify-content: space-between; gap: 24px; flex-wrap: wrap; margin-top: 11px; font: 400 11px/1.6 var(--sans); color: var(--faint); text-transform: uppercase; }

/* Spacers only: the SVG wire layer draws every connector, so a dragged card
   keeps its links. */
.edge { width: 24px; height: 1px; flex: none; position: relative; }
.edge.short { width: 16px; }
.is-runtime .wire { stroke: var(--strong); }

.card { flex: none; position: relative; z-index: 2; width: 168px; background: var(--surface); border-top: 3px solid var(--fam); border-right: 1px solid var(--border); border-bottom: 1px solid var(--border); border-left: 1px solid var(--border); border-radius: 3px; padding: 12px 13px; cursor: grab; user-select: none; touch-action: none; }
.card.dragging { z-index: 40; box-shadow: 0 8px 20px rgba(22,33,28,.16); cursor: grabbing; }
.card.inspected { outline: 2px solid var(--green); outline-offset: 2px; z-index: 13; }
.card.moved { z-index: 12; box-shadow: 0 2px 8px rgba(22,33,28,.10); }
.card.wide { width: 206px; }
.card-band { display: flex; align-items: center; gap: 7px; margin: -12px -13px 10px; padding: 6px 11px; border-radius: 2px 2px 0 0; background: rgba(var(--fam-rgb), .10); border-bottom: 1px solid rgba(var(--fam-rgb), .26); }
.card-band { background: color-mix(in srgb, var(--fam) 12%, transparent); border-bottom-color: color-mix(in srgb, var(--fam) 30%, transparent); }
.card-ico { width: 11px; height: 11px; border-radius: 2px; flex: none; border: 1.5px solid var(--fam); }
.card-kicker { font: 600 9px/1.4 var(--sans); letter-spacing: .09em; text-transform: uppercase; white-space: nowrap; color: var(--fam); overflow: hidden; text-overflow: ellipsis; }
.card-grip { margin-left: auto; font: 400 11px/1 var(--mono); color: var(--strong); flex: none; cursor: grab; padding: 2px 3px; border-radius: 3px; }
.card-grip:hover { color: var(--ink); background: var(--soft); }
.card { cursor: inherit; }
.canvas.panning, .canvas.panning * { cursor: grabbing !important; }
.card-title { font: 500 12.5px/1.4 var(--sans); color: var(--ink); overflow-wrap: anywhere; }
.card-sub { font: 400 10px/1.45 var(--sans); color: var(--muted); margin-top: 4px; overflow-wrap: anywhere; }
.card-id { font: 400 9.5px/1.4 var(--mono); color: var(--faint); margin-top: 5px; }
.card-id.warn { color: var(--red-text); }
.card-note { font: italic 400 11.5px/1.45 var(--serif); color: var(--muted); overflow-wrap: anywhere; }
.card-flags { display: flex; align-items: center; gap: 5px; margin-top: 9px; padding-top: 8px; border-top: 1px solid var(--soft); flex-wrap: wrap; }
.card-flag { font: 400 9px/1.45 var(--mono); color: var(--muted); }
.card-state { display: flex; align-items: center; gap: 6px; margin-top: 9px; padding-top: 8px; border-top: 1px solid var(--soft); }
.card-state-t { font: 500 10px/1.4 var(--sans); letter-spacing: .03em; white-space: nowrap; }
.t-observed { color: var(--green-deep); } .t-notObserved { color: var(--amber-deep); } .t-notEvidenced { color: var(--muted); } .t-confirmed { color: var(--ink); }
.compact .card-meta, .compact .card-state-t, .compact .card-flags .card-flag { display: none; }
.compact .card { width: 150px; }

.fam-flow { --fam: var(--ink); --fam-rgb: var(--ink-rgb); }
.fam-note { --fam: var(--green); --fam-rgb: 28,122,74; border-top-style: solid; border-right-style: dashed; border-bottom-style: dashed; border-left-style: dashed; border-right-color: var(--green-line); border-bottom-color: var(--green-line); border-left-color: var(--green-line); }
.fam-note .card-band { border-bottom-style: dashed; }
/* 5.29: the family colours are the theme's own tokens, so a card reads in
   dark mode too. --fam-rgb stays for a browser without color-mix(). */
.fam-table { --fam: var(--slate); --fam-rgb: 47,110,138; }
.fam-util { --fam: var(--util); --fam-rgb: 168,114,26; }
.fam-logic { --fam: var(--teal); --fam-rgb: 35,104,95; }
.fam-write { --fam: var(--green); --fam-rgb: 28,122,74; }
.fam-priv { --fam: var(--red); --fam-rgb: 179,38,30; }
.fam-api { --fam: var(--navy); --fam-rgb: 34,64,111; }
.fam-call { --fam: var(--purple); --fam-rgb: 91,75,138; }
.fam-flow .card-ico { border-radius: 50%; background: var(--fam); }
.fam-write .card-ico, .fam-priv .card-ico { background: var(--fam); }
.fam-api .card-ico { border-radius: 50%; }
.fam-logic .card-ico { border-radius: 50% 0 50% 0; }
.fam-call .card-ico { border-left: 3px double var(--fam); }
.fam-util .card-ico { background: var(--util-tint); }

.card.fail { border-top-color: var(--red); border-right-color: var(--red); border-bottom-color: var(--red); border-left-color: var(--red); box-shadow: 0 0 0 3px rgba(179,38,30,.08); width: 212px; }
.fail-band { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: -12px -13px 11px; padding: 7px 12px; background: var(--red); border-radius: 2px 2px 0 0; }
.fail-band span:first-child { font: 600 10.5px/1.4 var(--sans); letter-spacing: .1em; text-transform: uppercase; color: var(--on-tone); }
.fail-band span:last-child { font: 600 14px/1 var(--mono); color: var(--on-tone); }
.fail-band + .card-band { margin-top: 0; border-radius: 0; }
.fail-detail { margin-top: 11px; padding-top: 10px; border-top: 1px solid var(--red-line); }
.fail-detail .card-state-t { white-space: normal; }
.confirm { display: flex; align-items: center; gap: 7px; padding: 5px 8px; background: var(--ink); border-radius: 2px; margin-top: 9px; }
.confirm i { width: 8px; height: 8px; background: var(--on-tone); border-radius: 1px; flex: none; }
.confirm span { font: 600 11.5px/1.4 var(--sans); letter-spacing: .03em; color: var(--on-tone); }
.err-text { margin-top: 9px; padding: 7px 8px; background: var(--red-tint); border-radius: 2px; font: 400 11px/1.55 var(--mono); color: var(--red-text); word-break: break-all; max-height: 46px; overflow: hidden; }
.priv-skip { margin-top: 9px; padding: 8px 9px; background: var(--red-tint); border-left: 3px solid var(--red); border-radius: 0 2px 2px 0; }
.priv-skip b { display: block; font: 600 11.5px/1.4 var(--sans); letter-spacing: .03em; color: var(--red); margin-bottom: 5px; }
.priv-skip span { font: 400 12px/1.5 var(--sans); color: var(--red-text); }
.btn-payload { margin-top: 8px; padding: 4px 9px; border: 1px solid var(--border); border-radius: 3px; background: var(--surface); font: 500 11.5px/1.6 var(--sans); letter-spacing: .03em; color: var(--muted); cursor: pointer; white-space: nowrap; }

.branch-col { flex: none; display: flex; flex-direction: column; gap: 34px; padding: 12px 0 12px 20px; }
.branch-row { display: flex; align-items: center; }
.branch-lead { display: none; }
.branch-tag { flex: none; position: relative; z-index: 2; padding: 2px 7px; margin-right: 6px; border-radius: 2px; font: 500 10.5px/1.4 var(--sans); letter-spacing: .03em; }
.branch-tag.true { background: var(--green-tint); border: 1px solid var(--green-line); color: var(--green-deep); }
.branch-tag.false { background: var(--red-tint); border: 1px solid var(--red-line); color: var(--red); }
.live-pill { display: inline-flex; align-items: center; gap: 7px; padding: 6px 11px; border: 1px solid var(--border); border-radius: 999px; background: var(--surface); font: 500 12px/1.4 var(--sans); letter-spacing: .03em; color: var(--muted); white-space: nowrap; }
.live-pill .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--ghost); flex: none; }
.live-pill.live-live { border-color: var(--green-line); background: var(--green-tint); color: var(--green-deep); }
.live-pill.live-live .dot { background: var(--green); box-shadow: 0 0 0 0 rgba(28,122,74,.45); animation: live-beat 2s ease-out infinite; }
.live-pill.live-quiet { border-color: var(--strong); }
.live-pill.live-quiet .dot, .live-pill.live-waiting .dot { background: var(--slate); }
.live-pill.live-paused { border-color: var(--amber-line); background: var(--amber-tint); color: var(--amber-deep); }
.live-pill.live-paused .dot { background: var(--amber); }
.live-pill.live-file { border-style: dashed; }
@keyframes live-beat { 0% { box-shadow: 0 0 0 0 rgba(28,122,74,.45); } 70% { box-shadow: 0 0 0 7px rgba(28,122,74,0); } 100% { box-shadow: 0 0 0 0 rgba(28,122,74,0); } }
.btn-ghost.on { border-color: var(--green); color: var(--green-deep); background: var(--green-tint); }

/* Wires live inside the sequence they belong to; cards paint above them. */
.lane, .box-body { position: relative; }
.wires { position: absolute; left: 0; top: 0; overflow: visible; pointer-events: none; }

/* What a card runs on. */
.card-uses { display: flex; align-items: center; gap: 5px; margin-top: 4px; font: 400 8.5px/1.4 var(--mono); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.card-uses i { width: 5px; height: 5px; border-radius: 1px; flex: none; }
.card-uses.table i { background: var(--slate); }
.card-uses.conn i { background: var(--navy); }
.card-uses.sched { color: var(--green-deep); white-space: normal; }
.card-uses.sched i { background: var(--green); }

/* What starts a flow, where it lives, what it touches. */
.map-facts { display: flex; flex-wrap: wrap; gap: 7px; margin: 8px 0 10px; }
.fact-pill { display: inline-flex; align-items: center; gap: 7px; max-width: 100%; padding: 4px 10px; border: 1px solid var(--border); border-radius: 999px; background: var(--surface); font: 400 11.5px/1.5 var(--sans); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fact-pill b { font: 600 11px/1.4 var(--sans); letter-spacing: .03em; color: var(--faint); }
.fact-pill.on { border-color: var(--green-line); background: var(--green-tint); color: var(--green-deep); }
.fact-pill.on b { color: var(--green); }

/* The card inspector: what the console makes you open the card to see. */
.canvas-split { display: grid; grid-template-columns: minmax(0, 1fr) 340px; align-items: stretch; }
.canvas-split .canvas { border-right: none; border-bottom-right-radius: 0; }
.inspector { border: 1px solid var(--border); border-left: 2px solid var(--tone, var(--green)); border-top: none; background: var(--surface); display: flex; flex-direction: column; max-height: calc(100vh - 210px); min-height: 360px; min-width: 0; overflow: auto; }
.insp-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 12px 14px; border-bottom: 1px solid var(--border); background: var(--sunk); }
.insp-kicker { font: 600 11.5px/1.4 var(--sans); letter-spacing: .03em; text-transform: uppercase; color: var(--faint); margin-bottom: 5px; }
.insp-head h3 { margin: 0; font: 500 14px/1.3 var(--sans); color: var(--ink); overflow-wrap: anywhere; }
.insp-body { overflow: auto; padding: 4px 14px 16px; }
.insp-sec { padding: 12px 0; border-bottom: 1px solid var(--soft); }
.insp-sec:last-child { border-bottom: none; }
.insp-k { font: 600 11.5px/1.4 var(--sans); letter-spacing: .03em; text-transform: uppercase; color: var(--faint); margin-bottom: 8px; }
.insp-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 3px 0; font: 400 12px/1.55 var(--sans); }
.insp-row span { color: var(--muted); flex: none; }
.insp-row b { font: 400 12px/1.55 var(--mono); color: var(--ink); text-align: right; overflow-wrap: anywhere; }
.insp-chips { display: flex; flex-wrap: wrap; gap: 5px; }
.insp-none { margin: 0; font: 400 12.5px/1.6 var(--sans); color: var(--muted); text-wrap: pretty; }
.insp-find { border: 1px solid var(--border); border-radius: 3px; background: var(--sunk); padding: 10px 11px; margin-bottom: 10px; }
.insp-find-head { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; margin-bottom: 7px; }
.insp-find-head b { font: 500 13px/1.4 var(--sans); color: var(--ink); }
.insp-find p { margin: 0 0 7px; font: 400 12.5px/1.6 var(--sans); color: var(--muted); text-wrap: pretty; }
.insp-impact { color: var(--amber-deep) !important; }
.insp-fix { border-top: 1px dotted var(--strong); padding-top: 9px; }
.insp-fix .fx-steps li { font-size: 12.5px; }
@media (max-width: 1100px) { .canvas-split { grid-template-columns: minmax(0, 1fr); } .inspector { border-left-width: 1px; border-top: 2px solid var(--tone, var(--green)); max-height: none; } }

/* Full screen means the window, not a taller panel. The browser's own
   fullscreen is requested alongside this class, so the page chrome goes too;
   the app behind is covered rather than hidden, so nothing has to be put back
   on the way out. The map is laid out as a column — header, toolbar and foot
   take what they need, the canvas takes everything left. */
body.map-full { overflow: hidden; }
body.map-full .mapwrap { position: fixed; inset: 0; z-index: 90; margin: 0; padding: 0; border-radius: 0; background: var(--page); display: flex; flex-direction: column; }
body.map-full .map-head { flex: none; border: none; border-bottom: 1px solid var(--border); border-radius: 0; padding: 8px 18px; }
body.map-full .map-head .eyebrow, body.map-full .map-head p,
body.map-full .toolbar-band .state-note, body.map-full .legend .legend-note { display: none; }
/* The title and the facts about the flow share one line here: every row of
   prose is a row the map does not get. */
body.map-full .map-head-row { flex-wrap: nowrap; align-items: center; gap: 16px; }
body.map-full .map-head-row > div:first-child { display: flex; align-items: center; gap: 8px 16px; flex-wrap: wrap; max-width: none; }
body.map-full .map-head .h-serif-sm { font-size: 18px; }
body.map-full .map-facts { margin: 0; }
body.map-full .toolbar { flex: none; }
body.map-full .toolbar-row, body.map-full .toolbar-band { padding: 5px 16px; }
body.map-full .canvas-split, body.map-full .canvas { flex: 1 1 auto; min-height: 0; }
body.map-full .canvas { max-height: none; border-left: none; border-right: none; border-radius: 0; }
/* One row, the height of the space left: the inspector scrolls inside it
   rather than pushing the map off the bottom of the screen. */
body.map-full .canvas-split { grid-template-rows: minmax(0, 1fr); }
body.map-full .canvas-split .canvas, body.map-full .canvas-split .inspector { max-height: none; height: auto; min-height: 0; }
/* A flow one row deep used to sit at the top of a tall white field. Centre it
   in whatever space is going; `safe` keeps the top reachable when the flow is
   taller than the window. */
body.map-full .canvas { display: flex; flex-direction: column; justify-content: safe center; align-items: safe center; }
/* Rows. The width is set on the lane itself (in unzoomed pixels, by the fit),
   so flexbox breaks the flow where the window ends; the gutter between rows is
   where the wires travel back. */
.lane.wrapped { flex-wrap: wrap; align-content: flex-start; row-gap: 46px; }
/* A branch column is a single item on that line, so its own rows have to break
   too — otherwise one wide branch decides the scale for the whole flow. */
.lane.wrapped .branch-col { max-width: 100%; min-width: 0; }
.lane.wrapped .branch-row { flex-wrap: wrap; row-gap: 26px; min-width: 0; }

body.map-full .canvas-foot { flex: none; margin: 0; padding: 7px 18px; border-top: 1px solid var(--border); background: var(--surface); }

/* The card a finding sent the reader to. */
.card.revealed { outline: 2px solid var(--amber); outline-offset: 3px; animation: reveal-beat 1.1s ease-out 2; }
@keyframes reveal-beat { 0% { box-shadow: 0 0 0 0 rgba(201,144,27,.5); } 70% { box-shadow: 0 0 0 14px rgba(201,144,27,0); } 100% { box-shadow: 0 0 0 0 rgba(201,144,27,0); } }
.btn-linkish { border: none; background: none; padding: 0; font: 400 11.5px/1.5 var(--mono); color: var(--green); cursor: pointer; text-align: left; }
.btn-linkish:hover { text-decoration: underline; }
.fx-where .btn-payload { margin-top: 9px; }

/* A row that can be opened, and what opens under it. */
.tr-openable { cursor: pointer; }
.tr-openable:hover { background: var(--sunk); }
.tr.on { background: var(--tone-tint); }
.tr-detail { border-bottom: 1px solid var(--border); background: var(--sunk); padding: 14px 16px 16px; display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 14px 22px; }
.fx-block { min-width: 0; }
.fx-k { font: 600 11.5px/1.4 var(--sans); letter-spacing: .03em; color: var(--faint); text-transform: uppercase; margin-bottom: 6px; }
.fx-block p { margin: 0; font: 400 13px/1.6 var(--sans); color: var(--muted); text-wrap: pretty; }
.fx-impact { color: var(--amber-deep) !important; }
.fx-where { font: 400 12.5px/1.6 var(--mono); color: var(--ink); }
.fx-where b { display: block; font-weight: 500; }
.fx-where span { color: var(--faint); }
.fx-pattern { font: 500 13.5px/1.4 var(--sans); color: var(--ink); margin-bottom: 8px; }
.fx-cards { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-bottom: 9px; }
.fx-cards > span:first-child { font: 600 11.5px/1.4 var(--sans); letter-spacing: .03em; color: var(--faint); }
.fx-steps { margin: 0 0 9px; padding-left: 17px; }
.fx-steps li { font: 400 13px/1.65 var(--sans); color: var(--ink); margin-bottom: 5px; text-wrap: pretty; }
.fx-ref { font: 500 12px/1.4 var(--sans); color: var(--green); }
.fx-places { display: flex; flex-direction: column; gap: 5px; }
.fx-place { font: 400 11.5px/1.5 var(--mono); color: var(--muted); }
.fx-place b { display: block; font-weight: 500; color: var(--ink); }

.step-done { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; margin-top: 14px; padding: 12px 14px; border: 1px solid var(--green-line); background: var(--green-wash); border-radius: 4px; font: 400 13px/1.5 var(--sans); color: var(--green-text); }
.branch-tag.case { background: var(--surface); border: 1px solid var(--strong); color: var(--ink); max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; letter-spacing: .04em; }
.branch-end { display: flex; align-items: center; gap: 8px; margin-left: 12px; flex: none; font: 500 10.5px/1.4 var(--sans); letter-spacing: .03em; color: var(--faint); white-space: nowrap; }
.branch-end i { width: 16px; height: 1px; background: var(--strong); }
.rejoin { width: 14px; height: 1px; background: var(--strong); flex: none; }
.branch-col.rejoins { border-right: 1px solid var(--soft); }

.box { flex: none; position: relative; z-index: 2; border: 1px solid var(--muted); border-top-width: 4px; border-radius: 3px; background: var(--sunk); }
.box-closed { display: flex; align-items: stretch; padding: 0; cursor: pointer; text-align: left; }
.box-closed:hover { background: var(--page); }
.box-closed > div { padding: 11px 14px; }
.box-closed > div + div { border-left: 1px dotted var(--strong); }
.box-k { font: 600 9px/1.4 var(--sans); letter-spacing: .11em; text-transform: uppercase; color: var(--muted); margin-bottom: 7px; }
.box-t { font: 500 13px/1.4 var(--sans); color: var(--ink); max-width: 220px; overflow-wrap: anywhere; }
.box-m { font: 400 10.5px/1.6 var(--sans); color: var(--faint); margin-top: 5px; text-transform: uppercase; }
.box-sev { display: flex; flex-direction: column; justify-content: center; gap: 5px; }
.box-sev span { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; font: 600 10px/1.3 var(--sans); letter-spacing: .03em; text-transform: uppercase; }
.box-sev i { width: 7px; height: 7px; border-radius: 1px; flex: none; }
.sev-critical { color: var(--red); } .sev-critical i { background: var(--red); }
.sev-high { color: var(--amber-deep); } .sev-high i { background: var(--amber); }
.sev-medium, .sev-low, .sev-priv { color: var(--muted); } .sev-medium i, .sev-low i, .sev-priv i { background: var(--muted); }
.box-open-btn { display: flex; align-items: center; font: 600 10.5px/1.4 var(--sans); letter-spacing: .03em; color: var(--green); }
.box-head { display: flex; align-items: center; justify-content: space-between; gap: 20px; width: 100%; padding: 8px 12px; background: var(--muted); border: none; cursor: pointer; }
.box-head span:first-child { font: 600 9px/1.4 var(--sans); letter-spacing: .11em; text-transform: uppercase; color: var(--on-tone); white-space: nowrap; }
.box-head span:last-child { display: flex; align-items: center; gap: 14px; font: 400 9px/1.4 var(--mono); color: var(--on-tone); opacity: .85; white-space: nowrap; }
.box-head b { font-weight: 500; color: var(--on-tone); }
.box-body { display: flex; align-items: center; padding: 18px 18px 6px; }
.box-foot { padding: 0 18px 12px; font: 400 10.5px/1.6 var(--sans); letter-spacing: .03em; color: var(--faint); text-transform: uppercase; }
.box.handler { border-color: var(--amber); background: var(--amber-tint); }
.box.handler .box-head { background: var(--amber); }
.box.handler .box-head span:last-child { color: var(--on-tone); }
.box.handler .box-foot, .box.handler .box-k, .box.handler .box-m { color: var(--amber-deep); }
.box-closed.handler { background: var(--amber-tint); border-color: var(--amber); }
.box-closed.handler:hover { background: var(--amber-line); }
.box-closed.handler > div + div { border-left-color: var(--amber-line); }
.box-closed.handler .box-open-btn { color: var(--amber-deep); }
.box.depth2 .box-head { background: var(--ink2); }
/* A called flow drawn where it is called: same container language, its own
   colour, so "this is another flow" reads at a glance. */
.box.box-call { border-color: var(--purple); background: var(--purple-tint); }
.box.box-call > .box-head { background: var(--purple); }
.box.box-call > .box-head span:last-child { color: var(--on-tone); }
.box.box-call > .box-foot { color: var(--purple); }
.box.box-call.depth2 > .box-head { background: var(--purple-2); }
.btn-payload.on { border-color: var(--purple); color: var(--purple); }
.dim-group { flex: none; position: relative; padding: 18px 14px 14px; margin-left: 6px; border: 1px dashed var(--amber); border-radius: 3px; }
.dim-group > .hatchband { position: absolute; inset: 0; pointer-events: none; }
.dim-label { position: absolute; left: 12px; top: -10px; display: flex; align-items: center; gap: 8px; white-space: nowrap; background: var(--surface); padding: 0 8px; }
.dim-label b { font: 600 12px/1.4 var(--sans); letter-spacing: .03em; color: var(--amber-deep); }
.dim-label span { font: 400 10.5px/1.4 var(--mono); color: var(--faint); }
.findings-list { display: flex; flex-direction: column; margin-top: 8px; }
.findings-list div { display: grid; grid-template-columns: 84px 84px 1fr; gap: 12px; align-items: baseline; padding: 7px 0; border-top: 1px solid var(--soft); font: 400 12.5px/1.5 var(--sans); }

/* ── runtime ──────────────────────────────────────────────────────────── */
.rt { max-width: 1640px; margin: 0 auto; padding: 20px 20px 0; }
/* Left-aligned like every other screen: a centred column here made Runtime
   look like a different product from the report it sits beside. */
.rt-hero { display: flex; gap: 18px; flex-wrap: wrap; align-items: stretch; background: var(--surface); border: 1px solid var(--border); border-top: 2px solid var(--green); border-radius: 4px; padding: 22px 24px; box-shadow: var(--lift); }
.rt-hero-copy { flex: 1 1 420px; min-width: 0; display: flex; flex-direction: column; justify-content: center; padding: 2px 0; }
.rt-hero h1 { margin: 0 0 10px; font: 400 28px/1.15 var(--serif); letter-spacing: -.01em; max-width: 560px; }
.rt-hero p { margin: 0 0 14px; font: 400 13.5px/1.6 var(--sans); color: var(--muted); max-width: 620px; text-wrap: pretty; }
.pills { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; }
.pill { display: inline-flex; align-items: center; gap: 7px; padding: 5px 11px; border: 1px solid var(--border); border-radius: 999px; background: var(--surface); font: 500 11.5px/1.4 var(--sans); color: var(--muted); white-space: nowrap; }
.model { flex: 0 1 400px; min-width: 0; border: 1px solid var(--border); border-radius: 4px; padding: 15px 16px; background: var(--sunk); }
.model-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 13px; font: 500 12px/1.4 var(--sans); letter-spacing: .03em; color: var(--faint); }
.model-head span:last-child { color: var(--green); }
.model-row { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; padding: 7px 0; border-top: 1px solid var(--soft); }
.model-row span:first-child { display: flex; align-items: center; gap: 8px; font: 500 12.5px/1.4 var(--sans); }
.model-row span:last-child { font: 400 11.5px/1.4 var(--sans); color: var(--faint); text-align: right; }
.model-note { margin-top: 13px; padding: 10px 11px; border: 1px solid var(--border); border-radius: 3px; background: var(--surface); font: 400 11.5px/1.55 var(--sans); color: var(--muted); text-wrap: pretty; }
.rt-controls { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; flex-wrap: wrap; margin-top: 12px; background: var(--surface); border: 1px solid var(--border); border-radius: 4px; padding: 14px 16px; }
.rt-controls > div { display: flex; gap: 16px; flex-wrap: wrap; align-items: flex-end; }
.rt-tabs { display: flex; gap: 2px; flex-wrap: wrap; margin-top: 12px; border-bottom: 1px solid var(--border); }
.rt-tab { padding: 8px 13px; border: 1px solid transparent; border-bottom: none; border-radius: 3px 3px 0 0; margin-bottom: -1px; background: transparent; font: 400 12.5px/1.4 var(--sans); color: var(--faint); white-space: nowrap; cursor: pointer; }
.rt-tab:hover { color: var(--ink); }
.rt-tab.on { border-color: var(--border); border-bottom: 1px solid var(--surface); background: var(--surface); font-weight: 600; color: var(--ink); }
.rt .stats { margin-top: 14px; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.rt .notice { margin-top: 12px; }
.boundary { display: flex; gap: 14px; align-items: flex-start; margin-top: 10px; padding: 12px 15px; background: var(--sunk); border: 1px solid var(--border); border-radius: 4px; }
.boundary b { font: 500 12px/1.5 var(--sans); letter-spacing: .03em; color: var(--amber-deep); padding-top: 1px; flex: none; }
.boundary span { font: 400 13px/1.6 var(--sans); color: var(--muted); max-width: 1000px; text-wrap: pretty; }
.ranking { margin-top: 14px; background: var(--surface); border: 1px solid var(--border); border-radius: 4px; padding: 20px 22px 18px; }
.ranking-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.ranking-head .eyebrow { margin-bottom: 12px; }
.rank-row { border-top: 1px solid var(--soft); padding: 15px 0; }
.rank-row:last-child { padding-bottom: 0; }
.rank-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 18px; flex-wrap: wrap; }
.rank-top > div:first-child { min-width: 0; flex: 1 1 420px; }
.rank-name { font: 600 13.5px/1.4 var(--sans); color: var(--ink); overflow-wrap: anywhere; }
.rank-meta { font: 400 11px/1.5 var(--mono); color: var(--faint); margin-top: 4px; overflow-wrap: anywhere; }
.ev-chip { display: inline-block; margin: 9px 6px 0 0; padding: 5px 9px; border: 1px solid var(--border); border-radius: 3px; background: var(--sunk); font: 400 11px/1.5 var(--mono); color: var(--muted); overflow-wrap: anywhere; }
.ev-chip.red { display: block; border-color: var(--red-line); background: var(--red-wash); color: var(--red-text); word-break: break-all; }
.rank-right { display: flex; align-items: center; gap: 12px; flex: none; }
.rank-count { font: 600 14px/1 var(--mono); color: var(--red); }
.gapbox { margin-top: 11px; padding: 11px 12px; border: 1px solid var(--border); border-radius: 3px; background: var(--sunk); }
.gapbox .field-label { margin-bottom: 8px; }
.gap-notice { padding: 9px 11px; border: 1px solid var(--amber-line); border-radius: 3px; background: var(--amber-tint); font: 400 12px/1.55 var(--sans); color: var(--amber-text); }
.linear-map { display: flex; align-items: center; gap: 0; overflow-x: auto; padding: 6px 2px; }
.lm-card { flex: none; min-width: 120px; max-width: 180px; padding: 8px 10px; border: 1px solid var(--border); border-top: 3px solid var(--ink); border-radius: 3px; background: var(--surface); font: 500 12.5px/1.4 var(--sans); }
.lm-card i { display: block; font: 400 10.5px/1.4 var(--mono); color: var(--faint); font-style: normal; }
.lm-card.fail { border-color: var(--red); background: var(--red-wash); }
.lm-card b { display: block; margin-top: 4px; font: 600 11.5px/1.4 var(--sans); color: var(--red); letter-spacing: .03em; }
.empty { padding: 26px 14px; text-align: center; font: 400 13px/1.6 var(--sans); color: var(--faint); }
.empty small { display: block; margin-top: 4px; font-size: 12.5px; }

.split { display: grid; grid-template-columns: minmax(280px, 380px) 1fr; gap: 14px; margin-top: 14px; align-items: start; }
@media (max-width: 900px) { .split { grid-template-columns: 1fr; } }
.card-panel { background: var(--surface); border: 1px solid var(--border); border-radius: 4px; padding: 16px 18px; min-width: 0; }
.filters { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
.exec-list { display: flex; flex-direction: column; max-height: 64vh; overflow: auto; margin: 0 -18px; }
.exec { display: block; width: 100%; text-align: left; padding: 11px 18px; border: none; border-top: 1px solid var(--soft); background: var(--surface); cursor: pointer; }
.exec:hover { background: var(--sunk); }
.exec.on { background: var(--green-tint); box-shadow: inset 3px 0 0 var(--green); }
.exec-row1 { display: flex; align-items: center; gap: 8px; }
.exec-flow { font: 600 13px/1.4 var(--sans); color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.exec-row2 { font: 400 12.5px/1.5 var(--sans); color: var(--muted); margin-top: 3px; }
.exec-row3 { font: 400 11px/1.5 var(--mono); color: var(--faint); margin-top: 2px; }
.exec-err { font: 400 11px/1.5 var(--mono); color: var(--red-text); margin-top: 4px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.trace { margin-top: 12px; border-left: 1px solid var(--border); margin-left: 5px; }
.trace-ev { position: relative; padding: 0 0 14px 18px; }
.trace-ev::before { content: ""; position: absolute; left: -5px; top: 4px; width: 9px; height: 9px; border-radius: 2px; background: var(--green); }
.trace-ev.failed::before { background: var(--red); }
.trace-ev button { border: none; background: none; padding: 0; text-align: left; cursor: pointer; }
.trace-name { font: 500 13px/1.4 var(--sans); color: var(--ink); }
.trace-meta { font: 400 11px/1.5 var(--mono); color: var(--faint); }
.trace-meta u { color: var(--green); }
.kv { display: grid; grid-template-columns: 120px 1fr; gap: 6px 12px; margin-top: 8px; padding: 10px 12px; border: 1px solid var(--border); border-radius: 3px; background: var(--sunk); }
.kv dt { font: 500 11.5px/1.6 var(--sans); letter-spacing: .03em; color: var(--faint); text-transform: uppercase; }
.kv dd { margin: 0; font: 400 11.5px/1.5 var(--mono); color: var(--ink); overflow-wrap: anywhere; }
.payload { margin-top: 8px; max-height: 260px; overflow: auto; background: var(--code-bg); color: var(--code-fg); border-radius: 3px; padding: 10px 12px; font: 400 11.5px/1.6 var(--mono); white-space: pre-wrap; word-break: break-all; }

.onboard { display: flex; flex-direction: column; gap: 0; margin-top: 12px; }
.ob-step { display: flex; align-items: flex-start; gap: 11px; padding: 10px 0; border-top: 1px solid var(--soft); }
.ob-n { width: 20px; height: 20px; border-radius: 50%; flex: none; text-align: center; font: 600 11.5px/20px var(--mono); background: var(--border); color: var(--faint); }
.ob-step.done .ob-n { background: var(--green); color: var(--on-tone); }
.ob-t b { display: block; font: 600 13px/1.4 var(--sans); color: var(--ink); }
.ob-t i { display: block; font: 400 12px/1.5 var(--sans); color: var(--muted); font-style: normal; }
.copyrow { display: grid; grid-template-columns: 1fr auto; gap: 6px; }
/* The base-URL row carries a Clear button as well, so it sizes to its buttons. */
form.copyrow { grid-template-columns: 1fr auto auto; margin: 0; }
form.copyrow:has(button:only-of-type) { grid-template-columns: 1fr auto; }
.copyrow .field { font: 400 12px/1.4 var(--mono); }
.grid2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 14px; margin-top: 14px; align-items: start; }
.facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 10px; margin-top: 12px; }
.fact { border: 1px solid var(--border); border-radius: 4px; padding: 11px 13px; background: var(--surface); min-width: 0; }
.fact .stat-label { margin-bottom: 5px; }
.fact strong { display: block; font: 500 14px/1.4 var(--sans); overflow-wrap: anywhere; }
.fact code { display: block; font: 400 11.5px/1.5 var(--mono); color: var(--muted); overflow-wrap: anywhere; }
.fact p { margin: 5px 0 0; font: 400 11.5px/1.5 var(--sans); color: var(--faint); }
.inline-form { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-top: 10px; }
.inline-form .field { width: auto; flex: 1 1 200px; }

/* ── modal & toast ────────────────────────────────────────────────────── */
.backdrop { position: fixed; inset: 0; z-index: 100; background: var(--scrim); display: flex; align-items: center; justify-content: center; padding: 20px; }
.modal { width: 100%; max-width: 520px; max-height: calc(100vh - 40px); overflow: auto; background: var(--surface); border: 1px solid var(--border); border-radius: 4px; padding: 22px; box-shadow: 0 24px 60px rgba(4,20,13,.25); }
.modal h2 { margin: 0 0 8px; font: 400 22px/1.2 var(--serif); }
.modal p { margin: 0 0 12px; font: 400 13px/1.6 var(--sans); color: var(--muted); text-wrap: pretty; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; flex-wrap: wrap; margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--soft); }
.modal .form-col { max-width: none; }
.toast { position: fixed; right: 20px; bottom: 20px; z-index: 120; max-width: 420px; padding: 11px 14px; border-radius: 4px; background: var(--ink); color: var(--on-tone); font: 400 13px/1.5 var(--sans); box-shadow: 0 10px 30px rgba(0,0,0,.2); }
.toast.bad { background: var(--red); }
.banner { padding: 10px 20px; background: var(--red-tint); border-bottom: 2px solid var(--red); font: 400 13px/1.55 var(--sans); color: var(--red-deep); }

@media (max-width: 860px) {
  .report-body { flex-direction: column; align-items: stretch; }
  .sidebar { width: 100%; position: static; }
  .hero { padding: 32px 18px 40px; }
  .rt-hero-copy { align-items: flex-start; text-align: left; }
}
@media print {
  .topbar, .ctxbar, .sidebar, .toolbar, .tbl-tools, .tbl-foot, .rt-controls, .rt-tabs { display: none !important; }
  .report, .report-body { display: block; }
  .tbl-scroll, .canvas, .code { max-height: none; overflow: visible; }
}


/* ── how to read this table ───────────────────────────────────────────
   A column name is not always its own definition. Where a number is computed
   — change impact, an impact score, a criticality band — this says what it is
   made of, next to the table rather than in a document nobody opens. */
.col-legend { border: 1px solid var(--border); border-left: 2px solid var(--tone, var(--green)); background: var(--sunk); border-radius: 3px; padding: 11px 14px; margin: 0 0 16px; }
.col-legend-t { font: 500 12px/1.4 var(--sans); letter-spacing: .03em; text-transform: uppercase; color: var(--tone, var(--green)); margin-bottom: 7px; }
.col-legend-row { display: grid; grid-template-columns: 170px 1fr; gap: 14px; padding: 4px 0; font: 400 13px/1.6 var(--sans); color: var(--muted); }
.col-legend-k { font: 500 12px/1.7 var(--sans); letter-spacing: .03em; color: var(--ink); text-transform: uppercase; }
@media (max-width: 760px) { .col-legend-row { grid-template-columns: 1fr; gap: 2px; } }

/* Which flow calls the one that is missing from the export. */
.miss-list { margin: 9px 0 0; padding: 0 0 0 16px; font: 400 13px/1.7 var(--sans); }
.miss-list li { margin: 3px 0; }
.miss-list .btn-linkish { font-size: 13px; }
.miss-note { color: var(--faint); }

/* A finding on the map says which card, in which flow, and goes there. */
.findings-list .find-where { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-top: 4px; font: 400 13px/1.6 var(--sans); color: var(--faint); text-transform: uppercase; }
.findings-list .find-where b { color: var(--ink); }
.findings-list .find-where i { font-style: normal; }

/* The destination check: reached, or not, and which hop answered. */
.copyrow-3 { grid-template-columns: 1fr auto auto; }
.probe { display: grid; grid-template-columns: 74px minmax(0, 1fr); gap: 10px; align-items: baseline;
         margin-top: 9px; padding: 10px 12px; border-radius: 3px; border: 1px solid var(--border);
         font: 400 13px/1.6 var(--sans); }
.probe b { font: 600 12px/1.6 var(--sans); letter-spacing: .03em; }
.probe.ok { background: var(--green-tint); border-color: var(--green-line); }
.probe.ok b { color: var(--green); }
.probe.bad { background: var(--red-tint); border-color: var(--red-line); }
.probe.bad b { color: var(--red-text); }

/* ── how an event found its flow ──────────────────────────────────────
   Okta names a flow with one identifier system and a folder export with
   another. "Matched by version id" meant nothing on its own; this shows the
   count against each basis, strongest first, and what each one rests on. */
.matchbox { border: 1px solid var(--border); border-left: 2px solid var(--green); background: var(--surface); border-radius: 3px; padding: 13px 15px; margin-top: 14px; }
.matchbox.soft { border-left-color: var(--amber); }
.matchbox-head { display: flex; flex-direction: column; gap: 4px; margin-bottom: 10px; }
.matchbox-head b { font: 600 12px/1.5 var(--sans); letter-spacing: .03em; color: var(--ink); }
.matchbox-head span { font: 400 13px/1.6 var(--sans); color: var(--muted); }
.matchbox-rows { display: flex; flex-direction: column; }
.matchrow { display: grid; grid-template-columns: 56px 150px minmax(0, 1fr); gap: 12px; align-items: baseline; padding: 6px 0; border-top: 1px solid var(--soft); }
.matchrow b { font: 600 14px/1.3 var(--sans); font-variant-numeric: tabular-nums; }
.matchrow.strong b { color: var(--green); }
.matchrow.weak b { color: var(--amber-deep, var(--amber)); }
.matchrow .mr-k { font: 500 12.5px/1.7 var(--sans); letter-spacing: .03em; text-transform: uppercase; color: var(--ink); }
.matchrow .mr-v { font: 400 13px/1.6 var(--sans); color: var(--muted); }
.matchbox p { margin: 10px 0 0; font: 400 13px/1.6 var(--sans); color: var(--muted); }
@media (max-width: 700px) { .matchrow { grid-template-columns: 46px minmax(0, 1fr); } .matchrow .mr-v { grid-column: 1 / -1; } }

/* The numbers Okta puts beside a run, for the ones its stream actually sends. */
.runfacts { display: grid; grid-template-columns: repeat(auto-fit, minmax(118px, 1fr)); gap: 1px; background: var(--border);
            border: 1px solid var(--border); border-radius: 3px; margin: 12px 0 14px; overflow: hidden; }
.runfacts > div { background: var(--surface); padding: 8px 10px; display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.runfacts span { font: 500 11.5px/1.5 var(--sans); letter-spacing: .03em; text-transform: uppercase; color: var(--faint); }
.runfacts b { font: 500 13px/1.4 var(--mono); color: var(--ink); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }

/* What this view is doing, before the numbers it produces. */
.howbox { margin-top: 18px; border: 1px solid var(--border); background: var(--surface); border-radius: 4px; padding: 13px 16px 15px; }
.howbox > b { display: block; font: 600 12px/1.5 var(--sans); letter-spacing: .03em; color: var(--tone, var(--green)); margin-bottom: 11px; }
.howsteps { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 14px 22px; }
.howstep { display: grid; grid-template-columns: 20px minmax(0, 1fr); gap: 10px; align-items: start; }
.howstep i { font: 600 10.5px/18px var(--mono); font-style: normal; text-align: center; border-radius: 50%; background: var(--tone-tint, var(--green-tint)); color: var(--tone, var(--green)); }
.howstep span { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.howstep b { font: 500 13px/1.45 var(--sans); color: var(--ink); }
.howstep em { font: 400 13px/1.5 var(--sans); font-style: normal; color: var(--faint); text-transform: uppercase; letter-spacing: .03em; }

/* Card fields on the card's face — the Okta console's "Show mappings", drawn
   from the export. During a run the header says as configured, because the
   values Okta shows there are runtime ones and its stream does not send them. */
.card-maps { border-top: 1px dotted var(--soft); margin-top: 7px; padding-top: 6px; display: flex; flex-direction: column; gap: 2px; }
.cm-k { font: 500 9px/1.5 var(--sans); letter-spacing: .03em; color: var(--faint); margin-bottom: 2px; }
.cm-row { display: grid; grid-template-columns: minmax(0, max-content) minmax(0, 1fr); gap: 8px; align-items: baseline; font: 400 9px/1.45 var(--mono); }
.cm-row > span { color: var(--faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cm-row > b { color: var(--ink); font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cm-row > em { color: var(--faint); font-style: italic; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cm-more { font: 400 8px/1.5 var(--mono); color: var(--faint); margin-top: 2px; }
.canvas.compact .card-maps { display: none; }

/* The runtime header, as one strip. It was a hero with a panel of definitions
   beside it — a quarter of the screen spent re-stating a legend the map already
   carries, above the thing the reader came for. */
.rt-strip { display: flex; align-items: center; justify-content: space-between; gap: 18px; flex-wrap: wrap;
            background: var(--surface); border: 1px solid var(--border); border-top: 2px solid var(--green);
            border-radius: 4px; padding: 11px 18px; box-shadow: var(--lift); }
.rt-strip-l { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; min-width: 0; }
.rt-eyebrow { font: 500 12px/1.5 var(--sans); letter-spacing: .03em; color: var(--green); white-space: nowrap; }
.rt-strip h1 { margin: 0; font: 400 20px/1.2 var(--serif); letter-spacing: -.01em; white-space: nowrap; }
.rt-strip-sub { font: 400 13px/1.5 var(--sans); color: var(--muted); min-width: 0; }
.rt-strip-r { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
@media (max-width: 860px) { .rt-strip h1 { font-size: 18px; } .rt-strip-sub { display: none; } }

/* Stepping through the runs of one flow. */
.runstep { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.rs-n { font: 600 12.5px/1 var(--mono); color: var(--ink); font-variant-numeric: tabular-nums; min-width: 42px; text-align: center; }
.box-foot.loopnote { border-top: 1px dotted var(--soft); color: var(--amber-deep, var(--amber)); }

/* Runtime evidence, in the wizard. Almost nobody arrives with a log file; what
   they need is the ten-minute setup that makes every later run arrive by
   itself, with the file upload kept for those who do have one. */
.evsetup { border: 1px solid var(--border); border-left: 2px solid var(--green); background: var(--green-wash); border-radius: 4px; padding: 16px 18px; }
.evsetup-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 18px; flex-wrap: wrap; }
.evsetup h3 { margin: 4px 0 6px; font: 400 19px/1.25 var(--serif); }
.evsetup p { margin: 0; font: 400 13.5px/1.65 var(--sans); color: var(--muted); max-width: 66ch; text-wrap: pretty; }
.evsteps { margin: 14px 0 0; padding-left: 18px; display: flex; flex-direction: column; gap: 9px; }
.evsteps li { font: 400 13.5px/1.55 var(--sans); color: var(--muted); }
.evsteps b { display: block; font-weight: 600; color: var(--ink); }
.evsetup-note { margin-top: 13px !important; font-size: 13px !important; color: var(--faint) !important; }
.evfile { margin-top: 20px; }
.evfile .field-label { margin-bottom: 8px; display: block; }

/* The run tick, as the Okta console marks a card — but only where an event
   says so. A tick on a card the stream never mentioned would assert more than
   the evidence carries, so "nothing said" has its own, quiet mark. */
.card-tick { margin-left: auto; margin-right: 6px; width: 14px; height: 14px; border-radius: 50%; flex: none;
             display: inline-flex; align-items: center; justify-content: center;
             font: 600 9px/1 var(--sans); }
.tick-observed, .tick-confirmed { background: var(--green); color: var(--on-tone); }
.tick-fail { background: var(--red); color: var(--on-tone); }
.tick-notObserved { background: var(--amber-tint); color: var(--amber-deep, var(--amber)); border: 1px solid var(--amber); }
.tick-notEvidenced { background: transparent; color: var(--faint); border: 1px dotted var(--soft); }

/* Stepping the items a loop processed. Present only when per-iteration events
   exist — Okta's own stream does not send them. */
.card-iter { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; margin-top: 6px; padding-top: 6px; border-top: 1px dotted var(--soft); }
.card-iter .zoom-btn { padding: 0 6px; min-width: 18px; line-height: 16px; }
.ci-n { font: 600 9.5px/1 var(--mono); color: var(--ink); font-variant-numeric: tabular-nums; min-width: 40px; text-align: center; }
.ci-s { font: 600 9px/1.6 var(--sans); letter-spacing: .03em; padding: 0 4px; border-radius: 2px; }
.ci-observed { background: var(--green-tint); color: var(--green); }
.ci-completed { background: var(--green-tint); color: var(--green); }
.ci-failed { background: var(--red-tint); color: var(--red-text); }
.ci-item { font: 400 9px/1.4 var(--mono); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
.ci-err { width: 100%; font: 400 8.5px/1.4 var(--mono); color: var(--red-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.box-iter { padding: 6px 12px 0; }
.box-iter .card-iter { margin-top: 0; border-top: none; padding-top: 0; }

/* ── keep this assessment ─────────────────────────────────────────────
   The retention opt-in on the last wizard step. Quiet when off: it is a
   decision, not a call to action, and a green box shouting to be ticked
   would be a dark pattern on a question about storing customer data. */
.keeppanel { border: 1px solid var(--border); border-radius: 4px; background: var(--sunk); padding: 16px 18px; margin-bottom: 18px; }
.keeppanel.on { border-color: var(--green-line); background: var(--green-wash); }
.keep-row { display: flex; gap: 11px; align-items: flex-start; cursor: pointer; }
.keep-box { width: 16px; height: 16px; margin: 2px 0 0; flex: none; accent-color: var(--green); cursor: pointer; }
.keep-row b { display: block; font: 600 14px/1.4 var(--sans); color: var(--ink); }
.keep-sub { display: block; margin-top: 4px; font: 400 13px/1.6 var(--sans); color: var(--muted); max-width: 74ch; }
.keep-body { margin-left: 27px; }
.keep-fields { display: grid; grid-template-columns: minmax(0,1.3fr) minmax(0,1fr); gap: 14px; margin: 14px 0 10px; }
.keep-note { margin: 10px 0 0; font: 400 12.5px/1.6 var(--sans); color: var(--faint); max-width: 78ch; }

/* ── grade ────────────────────────────────────────────────────────────
   Grade and score together, never one without the other: the grade is the
   count rule, the score is where inside that grade the flow sits. */
.grade-chip { display: inline-flex; align-items: center; gap: 5px; padding: 1px 6px; border-radius: 3px; border: 1px solid var(--border); background: var(--surface); font: 500 11px/1.5 var(--mono); letter-spacing: .04em; }
.grade-chip b { font: 600 11.5px/1 var(--mono); }
.grade-a { border-color: var(--green-line); background: var(--green-tint); color: var(--green-deep); }
.grade-b { border-color: var(--green-line); background: var(--green-wash); color: var(--green-text); }
.grade-c { border-color: var(--amber-line); background: var(--amber-tint); color: var(--amber-deep); }
.grade-d { border-color: var(--red-line); background: var(--red-wash); color: var(--red-text); }
.grade-e { border-color: var(--red); background: var(--red-tint); color: var(--red); }
.score-grade { display: flex; align-items: center; justify-content: center; gap: 6px; margin-top: 6px; }
.grade-why { margin: 10px 0 0; font: 400 12.5px/1.6 var(--sans); color: var(--muted); max-width: 84ch; }

.sev-pill { display: inline-flex; align-items: center; gap: 5px; padding: 2px 7px; border-radius: 3px; border: 1px solid var(--border); font: 500 12.5px/1.5 var(--sans); letter-spacing: .03em; text-transform: uppercase; }
.sev-pill b { font: 600 12.5px/1 var(--mono); }
.sev-critical { border-color: var(--red); background: var(--red-tint); color: var(--red); }
.sev-high { border-color: var(--red-line); background: var(--red-wash); color: var(--red-text); }
.sev-medium { border-color: var(--amber-line); background: var(--amber-tint); color: var(--amber-deep); }
.sev-low { border-color: var(--navy-line); background: var(--navy-tint); color: var(--navy); }
.sev-none { border-color: var(--green-line); background: var(--green-tint); color: var(--green-deep); }

/* ── version history ──────────────────────────────────────────────────── */
.hist { display: block; }
.hist-grid { display: grid; grid-template-columns: 250px minmax(0, 1fr); min-width: 0; gap: 18px; align-items: start; margin-top: 16px; }
.hist-side { position: sticky; top: calc(var(--topbar-h, 52px) + 12px); }
.hist-side .side { max-height: calc(100vh - var(--topbar-h, 52px) - 40px); overflow: auto; }
.hist-main { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.hist-vn { min-width: 16px; text-align: right; }
.hist-fname { display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: 500 12.5px/1.4 var(--sans); color: inherit; letter-spacing: 0; }
.hist-gone { display: block; font: 400 10.5px/1.4 var(--mono); font-style: normal; color: var(--ghost); }
.side-item.on .hist-gone { color: var(--on-tone); opacity: .7; }

/* The timeline reads left to right, oldest first, so "what changed and when"
   is a scan rather than a sort. Each entry carries its grade at the time —
   a grade that moved between versions is the thing worth seeing. */
.hist-tl .tl { display: flex; gap: 10px; list-style: none; margin: 10px 0 0; padding: 0 0 6px; overflow-x: auto; }
.tl-item { flex: 0 0 auto; }
.tl-btn { display: block; min-width: 190px; text-align: left; cursor: pointer; padding: 10px 12px; border: 1px solid var(--border); border-radius: 4px; background: var(--surface); }
.tl-btn:hover { border-color: var(--strong); }
.tl-item.on .tl-btn { border-color: var(--navy); background: var(--navy-tint); }
.tl-item.tl-current .tl-btn { border-left: 3px solid var(--green); }
.tl-when { font: 600 12.5px/1.4 var(--sans); color: var(--ink); }
.tl-when span { font-weight: 400; color: var(--muted); }
.tl-meta { display: flex; align-items: center; gap: 7px; margin-top: 6px; font: 400 11px/1.4 var(--mono); color: var(--faint); }
.tl-runs { margin-top: 5px; font: 400 11.5px/1.4 var(--sans); color: var(--muted); }
.tl-runs i { color: var(--ghost); }

.hist-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 18px; flex-wrap: wrap; }
.hist-counts { display: flex; gap: 6px; flex-wrap: wrap; }
.hist-compare { display: flex; align-items: center; gap: 10px; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--soft); }
.hist-compare .field-label { flex: none; margin: 0; }
.hist-note { font: 400 13px/1.6 var(--sans); color: var(--muted); }
.hist-datebar { display: flex; align-items: flex-end; gap: 10px; margin-top: 14px; }
.hist-datebar .field { max-width: 190px; }
.hist-row { display: flex; align-items: center; gap: 12px; }
.hist-inferred { font: 400 11px/1.4 var(--mono); color: var(--amber-deep); }

.diff-list { list-style: none; margin: 12px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.diff-list > li { padding: 8px 11px; border: 1px solid var(--border); border-radius: 3px; background: var(--sunk); font: 400 13px/1.6 var(--sans); }
.diff-list ul { list-style: none; margin: 5px 0 0; padding: 0 0 0 12px; border-left: 2px solid var(--soft); }
.diff-list ul li { font: 400 12.5px/1.7 var(--sans); color: var(--muted); }
.diff-field { font: 500 12.5px/1.4 var(--sans); text-transform: uppercase; letter-spacing: .03em; color: var(--faint); }
.diff-changed { border-left: 3px solid var(--amber); }
.diff-added { border-left: 3px solid var(--green); }
.diff-removed { border-left: 3px solid var(--red); }
.diff-was { color: var(--faint); font-style: italic; }
.diff-list s { color: var(--faint); }
.hist-delta { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px; margin-top: 14px; }
.hist-delta ul { list-style: none; margin: 6px 0 0; padding: 0; }
.hist-delta li { font: 400 12.5px/1.7 var(--sans); color: var(--muted); }
.delta-good { font: 600 12.5px/1.4 var(--sans); color: var(--green-deep); }
.delta-bad { font: 600 12.5px/1.4 var(--sans); color: var(--red); }

/* The version a run executed against, on the execution detail. */
.run-version { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; margin-top: 9px; padding: 7px 11px; border: 1px solid var(--navy-line); border-radius: 3px; background: var(--navy-tint); font: 400 12.5px/1.5 var(--sans); color: var(--ink); }
.run-version b { font: 500 12.5px/1.4 var(--sans); letter-spacing: .03em; text-transform: uppercase; color: var(--navy); }
.run-version .warn { color: var(--amber-deep); }

@media (max-width: 1080px) {
  /* minmax(0, 1fr), not 1fr: a bare `1fr` column will not shrink below its
     content's min-content width, so at 360px both columns sized themselves to
     391px and the page scrolled sideways. The inner scrollers handle what does
     not fit. */
  .hist-grid { grid-template-columns: minmax(0, 1fr); }
  .hist-side { position: static; }
  .keep-fields { grid-template-columns: 1fr; }
}

/* ── the mode switch at narrow widths ─────────────────────────────────
   Two tabs fitted a phone; a third does not, and the overflow pushed the
   whole page sideways on every screen, not just the new one. The subtitle
   is the first thing to go — it is orientation, and the label alone still
   says where you are. */
@media (max-width: 640px) {
  .modetabs { min-width: 0; flex: 1 1 auto; }
  .modetab { padding: 5px 8px; min-width: 0; }
  .modetab i { display: none; }
  .modetab b { font-size: 12.5px; }
  .topbar .trust-pill { display: none; }
}
@media (max-width: 420px) {
  .topbar { column-gap: 12px; padding: 9px 12px; }
  .brand-tag { display: none; }
}

/* The flow map inside History is a flex child, and a flex child's default
   min-width is `auto` — so the 2158px-wide lane pushed the whole document
   sideways at phone width instead of scrolling inside its own canvas, which
   is what `.canvas { overflow: auto }` was there to do. */
.hist-main > *, .hist-main .mapwrap, .hist-main .panel { min-width: 0; }
.hist-main .canvas, .hist-main .canvas-split { max-width: 100%; }
.hist-main .tbl-scroll { overflow-x: auto; }

/* Where a card's value came from, and where it goes. The pins graph made
   readable: a bound input names its producer instead of shrugging. */
.cm-src { font-style: normal; font: 400 8.5px/1.4 var(--mono); color: var(--navy); letter-spacing: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 62%; }
.canvas:not(.compact) .card { min-width: 178px; }
.cm-k.cm-out { margin-top: 7px; padding-top: 6px; border-top: 1px dotted var(--soft); }
.cm-gives .cm-row span { color: var(--green-text); }

.save-as { display: inline-flex; align-items: center; gap: 5px; margin-left: 6px; padding-left: 10px; border-left: 1px solid var(--soft); }
.save-as .hint-mono { margin-right: 2px; }

/* ── architecture (section 10) ────────────────────────────────────────
   Drawn as SVG, so it serialises straight to an image with no second
   painter. Columns read left to right: what starts a flow, the entry
   flows, what they call, what they reach, what they store. */
.arch-scroll { overflow: auto; max-height: 76vh; border: 1px solid var(--border); border-radius: 4px; background: var(--sunk); }
.archsvg { display: block; min-width: 100%; background: var(--surface); }
.arch-col { font: 600 12px/1 var(--sans); letter-spacing: .03em; fill: var(--faint); }
.arch-name { font: 600 13px/1 var(--sans); fill: var(--ink); }
.arch-sub { font: 400 11px/1 var(--mono); fill: var(--faint); }
.arch-grade { font: 600 12.5px/1 var(--mono); }
/* A folder heading inside a column, when the diagram is grouped by folder. */
.arch-band-t { font: 600 12px/1 var(--sans); letter-spacing: .03em; }
.arch-band { pointer-events: none; }
.arch-node { cursor: pointer; }
.arch-node:hover rect:first-of-type { fill: var(--green-wash); }
.arch-node.on rect:first-of-type { fill: var(--navy-tint); }
.arch-tools { flex-wrap: wrap; gap: 12px; }
.arch-key { display: inline-block; width: 9px; height: 2px; border-radius: 1px; }

.coupling { display: grid; grid-template-columns: minmax(180px, 1.2fr) minmax(0, 1fr) 24px minmax(0, 1fr); gap: 14px; align-items: start; padding: 12px 0; }
.coup-t { display: flex; flex-direction: column; gap: 5px; }
.coup-t b { font: 600 13px/1.5 var(--sans); }
.coup-side { font: 400 12.5px/1.7 var(--sans); color: var(--muted); min-width: 0; }
.coup-side .field-label { margin-bottom: 3px; }
.coup-arrow { font: 400 15px/1.4 var(--sans); color: var(--ghost); text-align: center; }

.steps-run { margin-top: 14px; display: flex; flex-direction: column; gap: 5px; }
.step-row { display: grid; grid-template-columns: 26px 92px minmax(0, 1fr) auto; gap: 10px; align-items: baseline; padding: 7px 11px; border: 1px solid var(--border); border-left-width: 3px; border-radius: 3px; background: var(--surface); font: 400 13px/1.5 var(--sans); }
.step-row .step-n { font: 500 11px/1.5 var(--mono); color: var(--ghost); text-align: right; }
.step-row b { font: 600 12.5px/1.5 var(--sans); letter-spacing: .03em; text-transform: uppercase; color: var(--faint); }
.step-row span:last-of-type { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.step-card { font: 400 11px/1.5 var(--mono); font-style: normal; color: var(--faint); white-space: nowrap; }
.step-start { border-left-color: var(--ghost); background: var(--sunk); }
.step-calls { border-left-color: var(--navy); }
.step-uses, .step-calls_out { border-left-color: var(--util); }
.step-reads { border-left-color: var(--purple); }
.step-writes { border-left-color: var(--red); }
@media (max-width: 900px) {
  .coupling { grid-template-columns: 1fr; }
  .coup-arrow { text-align: left; }
  .step-row { grid-template-columns: 22px minmax(0, 1fr); }
  .step-row .step-card { display: none; }
}

/* The author's own comment. Serif and full width because it is prose someone
   wrote, not a field value — and because it is often the only explanation of
   why a flow does what it does. */
.card-note { white-space: pre-wrap; max-height: 9.5em; overflow: hidden; }
.card-note-empty { color: var(--ghost); font-style: italic; }
.card-note-inline { margin-top: 6px; padding-top: 6px; border-top: 1px dotted var(--soft); font-size: 10.5px; }

/* Direction of travel along a link, the way a diagram tool shows it. The dash
   pattern is applied only while animating, so a still export is a solid line
   rather than a frozen dotted one that reads as a different kind of link. */
@keyframes arch-flow { to { stroke-dashoffset: -28; } }
.arch-wire.flowing { stroke-dasharray: 7 7; animation: arch-flow 1.1s linear infinite; }
@media (prefers-reduced-motion: reduce) {
  .arch-wire.flowing { stroke-dasharray: none; animation: none; }
}
/* Wraps: this row went from three buttons to six (step numbers, speed,
   full screen) and an inline-flex that cannot wrap pushed a phone's
   whole document 195px wide. */
.arch-switches { display: inline-flex; gap: 6px; align-items: center; flex-wrap: wrap; min-width: 0; }
.arch-chain { cursor: pointer; }
.arch-chain:hover { color: var(--ink); }
.arch-chain.on { color: var(--ink); font-weight: 600; }
.arch-legend-row { padding-bottom: 9px; }
.arch-legend-row .legend { flex: 1 1 100%; min-width: 0; }
.cm-filter { color: var(--navy) !important; }

/* A marker travelling the link. The dot is the reading aid; the dash is the
   route it follows. Both stop under reduced motion. */
/* The marker takes pointer events so the action text can be a tooltip — the
   number alone says WHEN a link is reached, never what it does there. */
.arch-dot { pointer-events: auto; cursor: help; }
/* A hop back is the flow receiving its answer, not reaching out: grey, so a
   glance separates the going from the coming back without reading a number. */
.arch-dot.back { fill-opacity: .6; }
@media (prefers-reduced-motion: reduce) {
  /* A sequence nobody asked to see should not move. The numbers are still on
     the links, and the reader can follow them by eye. */
  .arch-dot, .arch-dot-n, .arch-dot-l { display: none; }
}
.arch-zoom { margin-left: auto; }
.arch-tools .save-as { margin-left: 8px; }
.btn-gif.btn-ghost { border-color: var(--navy-line); color: var(--navy); }
.arch-scroll { overflow: auto; max-height: calc(100vh - 230px); min-height: 420px; resize: vertical; }
.arch-scroll { cursor: grab; }
.arch-scroll.panning, .arch-scroll.panning * { cursor: grabbing !important; }
.arch-scroll.panning .arch-node { pointer-events: none; }

/* ── demo workspace ───────────────────────────────────────────────────
   A demo visitor sees every screen and can change nothing. The chrome says
   so once, plainly, rather than letting them find out by pressing a button
   that fails. */
.demo-pill { border-color: var(--navy-line) !important; color: var(--navy) !important; background: var(--navy-tint) !important; }
.demo-pill .dot { background: var(--navy) !important; }
.demo-card { border-style: solid; border-color: var(--green-line); background: var(--green-wash); }
.demo-card p { margin: 0 0 16px; font: 400 13px/1.7 var(--sans); color: var(--muted); }
.trust-list { display: flex; flex-direction: column; gap: 7px; margin-top: 16px; font: 400 12.5px/1.5 var(--sans); color: var(--muted); }
.trust-list .dot { display: inline-block; width: 5px; height: 5px; border-radius: 50%; background: var(--green); margin-right: 7px; }
.side-demo { padding: 10px 12px; border: 1px dashed var(--border); border-radius: 3px; font: 400 12px/1.6 var(--sans); color: var(--faint); }

/* ── the grade legend ───────────────────────────────────────────────────
   The report graded an estate and never published the scale. This is that
   scale: one row per grade, with the score range it owns and the count rule
   that puts an estate in it, the reader's own grade marked. Laid out as a
   grid so the columns line up down the page; it collapses to stacked rows
   on a phone rather than scrolling sideways. */
.gradekey { margin: 14px 0 0; border: 1px solid var(--border); border-radius: 4px;
  background: var(--paper); overflow: hidden; }
.gk-head { padding: 12px 14px 11px; border-bottom: 1px solid var(--border); background: var(--surface); }
.gk-head b { display: block; font: 600 12.5px/1 var(--sans); letter-spacing: .03em; color: var(--faint); }
.gk-head span { display: block; margin-top: 7px; font: 400 13px/1.65 var(--sans); color: var(--muted); max-width: 88ch; }
.gk-rows { display: flex; flex-direction: column; }
.gk-row { display: grid; grid-template-columns: 150px 58px 116px 1fr auto; gap: 12px;
  align-items: center; padding: 9px 14px; border-top: 1px solid var(--rule-soft, var(--border)); }
.gk-row:first-child { border-top: none; }
.gk-row.on { background: var(--green-wash); }
.gk-range { font: 600 12.5px/1 var(--mono); color: var(--ink); white-space: nowrap; }
.gk-band { font: 500 13px/1.4 var(--sans); letter-spacing: .03em; text-transform: uppercase; color: var(--muted); }
.gk-rule { font: 400 13px/1.55 var(--sans); color: var(--muted); }
.gk-you { font: 600 11.5px/1 var(--sans); letter-spacing: .03em; color: var(--green);
  border: 1px solid var(--green-line); border-radius: 3px; padding: 4px 6px; white-space: nowrap; }
.gk-foot { margin: 0; padding: 11px 14px; border-top: 1px solid var(--border); background: var(--surface);
  font: 400 12.5px/1.6 var(--sans); color: var(--faint); }
@media (max-width: 760px) {
  .gk-row { grid-template-columns: 1fr auto; gap: 6px 10px; }
  .gk-band { grid-column: 1 / -1; }
  .gk-rule { grid-column: 1 / -1; }
  .gk-you { grid-column: 1 / -1; justify-self: start; }
}
.keep-aside { display: block; margin-top: 8px; padding-left: 10px; border-left: 2px solid var(--border);
  font: 400 12px/1.6 var(--sans); color: var(--faint); }

/* ── what this deployment holds ─────────────────────────────────────────
   One row per thing, with a plain STORED / NOT STORED so the list can be
   scanned rather than read. It spans both columns of the baseline grid. */
.span2 { grid-column: 1 / -1; }
.store-panel .store-rows { margin-top: 14px; border-top: 1px solid var(--border); }
.store-row { display: grid; grid-template-columns: 220px 1fr 92px; gap: 12px; align-items: baseline;
  padding: 9px 0; border-bottom: 1px solid var(--border); }
.store-row b { font: 600 13px/1.5 var(--sans); color: var(--ink); }
.store-row span { font: 400 13px/1.6 var(--sans); color: var(--muted); }
.store-row em { font: 600 11.5px/1 var(--sans); letter-spacing: .03em; font-style: normal;
  border: 1px solid var(--border); border-radius: 3px; padding: 4px 6px; text-align: center; }
.store-row em.yes { color: var(--amber-ink); border-color: var(--amber-line); background: var(--amber-wash); }
.store-row em.no { color: var(--green); border-color: var(--green-line); background: var(--green-wash); }
@media (max-width: 760px) {
  .store-row { grid-template-columns: 1fr auto; }
  .store-row span { grid-column: 1 / -1; }
}

/* ── the brand mark ─────────────────────────────────────────────────────
   The website's own logo file. Both places it appears here are dark, and the
   artwork is dark-on-transparent, so it is inverted to white — the same
   treatment the website's footer gives the same image. */
.brand { color: var(--on-bar); }
/* The artwork is dark on transparent. It is shown as drawn on the light app
   bar, and inverted only on the dark sign-in splash — which is why the invert
   moved off the base rule and onto the splash. */
.brand-img { display: block; width: auto; height: 30px; opacity: .92; }
.login-brand .brand-img { filter: brightness(0) invert(1); opacity: .95; }
.brand:hover .brand-img { opacity: 1; }
.login-brand .brand-img { height: 38px; }
@media (max-width: 640px) { .brand-img { height: 26px; } }

/* ── show / hide passphrase ─────────────────────────────────────────────
   A shared passphrase is long and typed from a password manager or a slide.
   The control sits inside the field so it cannot be mistaken for a button
   that submits. */
.pw-wrap { position: relative; display: block; }
.pw-wrap .field { width: 100%; padding-right: 58px; }
.pw-eye { position: absolute; top: 50%; right: 6px; transform: translateY(-50%);
  border: 1px solid var(--border); background: var(--paper); border-radius: 3px;
  padding: 5px 7px; cursor: pointer; font: 600 11.5px/1 var(--sans);
  letter-spacing: .03em; color: var(--muted); }
.pw-eye:hover { color: var(--ink); border-color: var(--faint); }
.pw-eye:focus-visible { outline: 2px solid var(--green); outline-offset: 1px; }

/* ── the section announcement ───────────────────────────────────────────
   Every report section sat under an identical header, so switching sections
   changed only what was below the fold and read as "nothing happened". Each
   section now says what it is, immediately above its own content, in the tone
   its group carries. */
.section-intro { display: flex; align-items: flex-start; gap: 14px; padding: 0 0 16px;
  margin: 0 0 18px; border-bottom: 1px solid var(--border); }
.section-intro .si-n { flex: none; min-width: 34px; height: 34px; display: flex;
  align-items: center; justify-content: center; border-radius: 3px;
  border: 1px solid var(--tone-line, var(--border)); background: var(--tone-tint, var(--paper));
  color: var(--tone-deep, var(--ink)); font: 600 13px/1 var(--mono); letter-spacing: .02em; }
.section-intro h2 { margin: 0; font: 400 22px/1.2 var(--serif); color: var(--ink); }
.section-intro p { margin: 5px 0 0; font: 400 13.5px/1.6 var(--sans); color: var(--muted);
  max-width: 88ch; text-wrap: pretty; }

/* The body is briefly marked as new, so a reader who was looking elsewhere on
   the page can see that something arrived. Once, never repeating, and skipped
   entirely for anyone who asked for less motion. */
@keyframes section-arrive {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
.section-gap.section-fresh { animation: section-arrive .26s ease-out both; }
@media (prefers-reduced-motion: reduce) {
  .section-gap.section-fresh { animation: none; }
}

@media (max-width: 640px) {
  .section-intro { gap: 10px; }
  .section-intro h2 { font-size: 19px; }
}

/* ── A tidy legend ────────────────────────────────────────────────────
   The architecture legend printed one chip per entry workflow, inline and
   unbounded: on a twelve-process estate that is three wrapped lines of names
   above the diagram, and the diagram itself pushed off the screen. The chips
   are now a bounded strip with the rest behind a count. */
.legend-tidy { align-items: flex-start; gap: 10px; }
.legend-chips { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; min-width: 0; }
.legend-chips .legend-item, .legend-chips .arch-chain {
  display: inline-flex; align-items: center; gap: 6px; padding: 3px 8px;
  border: 1px solid var(--border); border-radius: 999px; background: var(--surface);
  white-space: nowrap; max-width: 100%;
}
.legend-chips .arch-chain:hover { border-color: var(--strong); background: var(--sunk); }
.legend-chips .arch-chain.on { border-color: var(--ink); background: var(--sunk); }
.legend-n { margin-left: 2px; padding: 0 5px; border-radius: 999px; background: var(--soft); color: var(--muted); font: 600 10.5px/1.7 var(--mono); }
.legend-more { border: 1px dashed var(--strong); border-radius: 999px; background: none; padding: 3px 9px; font: 600 11.5px/1.6 var(--sans); letter-spacing: .03em; color: var(--muted); cursor: pointer; white-space: nowrap; }
.legend-more:hover { color: var(--ink); border-color: var(--ink); }

/* A call that leaves the folder. Named on the card face because it is the
   dependency most easily lost when one folder is moved or re-exported. */
.badge-folder { background: var(--indigo); }

/* ── Dark and light diagrams ───────────────────────────────────────────
   Scoped to the diagram, not the workspace: the report around it is a
   document and follows the page theme, while a diagram can be switched on
   its own because a saved image has to match the view. Done by redefining the
   tokens inside the canvas rather than by restyling forty card classes, so
   anything added to a card later inherits the theme without a second rule.
   5.29: `.light` is the other half — a diagram switched to light on a dark
   page — and the per-diagram toggle now defaults to the page theme. These two
   blocks are palette definitions, which is why they hold literal colours. */
.canvas.dark, .archsvg.dark, .arch-scroll.dark, .map-stagectl.dark, .arch-scroll.dark ~ .arch-stagectl {
  --surface: #17201D; --sunk: #141C1A; --page: #101715;
  --border: #2C3833; --soft: #26312D; --strong: #46554E;
  --ink: #E6EDE9; --muted: #A8B5AE; --faint: #8FA098; --ghost: #6E7D76;
  --ink-rgb: 230,237,233;
  /* The aliases above are written in terms of these, so they follow on their
     own. The two literals do not, and a dark-on-dark body text colour is the
     kind of thing nobody notices until a customer screenshots it. */
  --ink2: #C9D5CE; --ink3: #A8B5AE; --on-tone: #0F1613;
  --green: #4DB57E; --green-deep: #7CCFA0; --green-tint: #16281F; --green-line: #24503A; --green-wash: #141F19; --green-text: #8CC9A6;
  --amber: #D9A441; --amber-deep: #E6BE6A; --amber-tint: #2A2214; --amber-line: #4E3F1C; --amber-text: #E3CF9A;
  --red: #E0665C; --red-tint: #2C1A18; --red-line: #5A2B27; --red-wash: #221614; --red-text: #EF8F86;
  --navy: #8FB0E0; --navy-tint: #202E3F; --navy-line: #2B3D58;
  --purple: #B1A3E0; --purple-tint: #1C192A; --purple-line: #3C3560;
  --teal: #4FA89A; --slate: #6FA3BE; --util: #D59A3E; --util-tint: #3A2E14;
  --orange-deep: #F0B37A; --hatch: #66736C; --code-bg: #0A100E;
}
.canvas.light, .archsvg.light, .arch-scroll.light, .map-stagectl.light, .arch-scroll.light ~ .arch-stagectl {
  --surface: #FFFFFF; --sunk: #F6F8F6; --page: #EDF0ED;
  --border: #DCE2DD; --soft: #E8ECE9; --strong: #BAC5BE;
  --ink: #121B16; --muted: #53615A; --faint: #6D7A73; --ghost: #99A59F;
  --ink-rgb: 18,27,22;
  --ink2: #2C3932; --ink3: #53615A; --on-tone: #FFFFFF;
  --green: #1C7A4A; --green-deep: #14563A; --green-tint: #F2F9F4; --green-line: #CFE3D6; --green-wash: #F6FBF7; --green-text: #4E7A62;
  --amber: #C9901B; --amber-deep: #8A6410; --amber-tint: #FDF7E6; --amber-line: #EBDCB0; --amber-text: #4A3E20;
  --red: #B3261E; --red-tint: #FDF1EF; --red-line: #EBD2CE; --red-wash: #FDF6F4; --red-text: #9A2A22;
  --navy: #22406F; --navy-tint: #F1F4F9; --navy-line: #D2DBE8;
  --purple: #5B4B8A; --purple-tint: #F5F3FB; --purple-line: #DCD6EE;
  --teal: #23685F; --slate: #2F6E8A; --util: #A8721A; --util-tint: #FBF0D8;
  --orange-deep: #8A3F06; --hatch: #8E9A93; --code-bg: #16211C;
}
/* The canvas re-states `color` rather than relying on the token alone: `body`
   already computed its colour from the page's `--ink`, and an element with no
   colour of its own inherits that computed value, not the redefined token. Card
   field lists were black on black until this line existed. */
.canvas.dark { color: var(--ink); }
.canvas.light { color: var(--ink); }
.canvas.dark { background: var(--page); }
.canvas.light { background: var(--surface); }
.canvas.dark .card.dragging { box-shadow: 0 8px 20px rgba(0,0,0,.5); }
.canvas.dark .card.moved { box-shadow: 0 2px 8px rgba(0,0,0,.4); }

.archsvg.dark { background: var(--page); }
.archsvg.light { background: var(--surface); }
/* The surround, not just the picture. Zoomed out, the SVG is narrower than the
   box that holds it, and the box kept its light background — so zooming out in
   dark mode framed the diagram in white. */
.arch-scroll.dark { background: var(--page); border-color: var(--border); }
.arch-scroll.light { background: var(--surface); border-color: var(--border); }

/* ── Adding an export instead of replacing it ─────────────────────────── */
.file-list { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 11px; }
.file-list-t { font: 600 12px/1.6 var(--sans); letter-spacing: .03em; text-transform: uppercase; color: var(--faint); }
.file-chip { padding: 3px 9px; border: 1px solid var(--border); border-radius: 999px; background: var(--sunk); font: 400 11.5px/1.6 var(--mono); color: var(--muted); }

/* The append tick in the publish dialog. Same shape as the keep panel's own
   row, because it is the same kind of decision: what lands on disk. */
.check-row { display: flex; gap: 10px; align-items: flex-start; cursor: pointer; padding: 11px 12px; border: 1px solid var(--border); border-radius: 3px; background: var(--sunk); }
.check-row input { margin-top: 2px; flex: none; width: 15px; height: 15px; accent-color: var(--green); }
.check-row b { display: block; font: 600 13px/1.4 var(--sans); color: var(--ink); }
.check-row i { display: block; margin-top: 4px; font: 400 12px/1.55 var(--sans); font-style: normal; color: var(--muted); text-wrap: pretty; }

/* ── Sign in with the customer's own Okta ─────────────────────────────── */
/* The identity provider sits BELOW the passphrase form, so the divider leads
   the block rather than closing it. */
.sso-block { margin-top: 18px; }
.btn-wide-sso { display: flex; align-items: center; justify-content: center; gap: 9px; width: 100%; padding: 10px 12px; border: 1px solid var(--strong); border-radius: 3px; background: var(--surface); font: 600 13px/1.4 var(--sans); color: var(--ink); text-decoration: none; cursor: pointer; }
.btn-wide-sso:hover { border-color: var(--ink); background: var(--sunk); }
.btn-wide-sso:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }
.sso-key { font-size: 11.5px; color: var(--green); }
.sso-or { display: flex; align-items: center; gap: 10px; margin: 0 0 14px; font: 600 11.5px/1.6 var(--sans); letter-spacing: .03em; color: var(--faint); }
.sso-or i { flex: 1 1 auto; height: 1px; background: var(--border); }
.whoami { display: inline-flex; align-items: center; gap: 7px; min-width: 0; padding: 3px 10px 3px 3px; border: 1px solid rgba(255,255,255,.16); border-radius: 999px; }
.whoami-i { display: flex; align-items: center; justify-content: center; width: 20px; height: 20px; border-radius: 999px; background: rgba(111,196,149,.18); font: 600 10.5px/1 var(--mono); color: var(--bar-accent-soft); flex: none; }
.whoami-n { font: 500 12px/1.4 var(--sans); color: rgba(255,255,255,.82); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 150px; }

/* "I have lost the passphrase" has one honest answer in a self-hosted
   deployment, and it is not an email. */
.recovery { margin-top: 4px; }
.btn-link-sm { border: none; background: none; padding: 0; font: 500 12px/1.5 var(--sans); color: var(--muted); cursor: pointer; text-decoration: underline; text-underline-offset: 2px; }
.btn-link-sm:hover { color: var(--ink); }
.recovery-body { margin-top: 10px; padding: 12px 13px; border: 1px solid var(--border); border-radius: 3px; background: var(--sunk); }
.recovery-body p { margin: 0 0 9px; font: 400 12px/1.6 var(--sans); color: var(--muted); text-wrap: pretty; }
.recovery-body p:last-child { margin-bottom: 0; }
.recovery-body b { color: var(--ink); font-weight: 600; }
.recovery-body code { font: 500 11.5px/1.5 var(--mono); color: var(--ink); background: var(--soft); padding: 1px 4px; border-radius: 2px; }

/* ── One folder at a time ─────────────────────────────────────────────
   An estate assembled from several Okta folders is several estates; drawing
   all of them at once answers a question nobody asked. */
.folder-bar { flex-direction: column; align-items: stretch; gap: 8px; padding-bottom: 10px; }
.folder-pick { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font: 500 10.5px/1.6 var(--mono); letter-spacing: .05em; color: var(--muted); }
.folder-tab { display: inline-flex; align-items: center; gap: 7px; padding: 5px 11px; border: 1px solid var(--border); border-radius: 999px; background: var(--surface); font: 500 11.5px/1.5 var(--mono); color: var(--muted); cursor: pointer; white-space: nowrap; }
.folder-tab:hover { border-color: var(--strong); color: var(--ink); }
.folder-tab.on { border-color: var(--ink); background: var(--ink); color: var(--on-tone); }
.folder-tab.on .legend-n { background: rgba(127,127,127,.25); color: var(--on-tone); }
/* A single-folder estate. It names the folder but is not a control, so it does
   not take a pointer or a hover state that implies something happens. */
.folder-tab.folder-only { cursor: default; }
.folder-note { font: 400 11.5px/1.5 var(--mono); color: var(--muted); }
.folder-all { letter-spacing: .1em; font-weight: 600; font-size: 10.5px; }
.folder-note { font: 400 11.5px/1.6 var(--sans); color: var(--faint); text-wrap: pretty; }
.folder-note-x { color: var(--amber-deep); }

/* A subfolder's heading, set in from its parent's. */
.arch-band-t.sub { letter-spacing: .06em; opacity: .85; }

/* The numeral riding the travelling marker. */
.arch-dot-n { font: 600 10.5px/1 var(--mono); fill: var(--on-tone); pointer-events: none; }
/* Action text beside the marker. Paint-order puts a halo of the page colour
   under the glyphs so the words stay readable where they cross a link. */
.arch-dot-l {
  font: 500 10.5px/1 var(--sans); fill: var(--ink2); pointer-events: none;
  paint-order: stroke; stroke: var(--surface); stroke-width: 3px; stroke-linejoin: round;
}
.arch-dot-l.back { fill: var(--ink3); }

/* ── Architecture full screen ─────────────────────────────────────────
   The flow map has had this since it shipped; a diagram of the whole estate is
   the view that needs it more. */
body.arch-full { overflow: hidden; }
body.arch-full .arch-panel { position: fixed; inset: 0; z-index: 90; margin: 0; border-radius: 0; background: var(--page); display: flex; flex-direction: column; }
body.arch-full .arch-scroll { flex: 1 1 auto; max-height: none; height: auto; }
body.arch-full .arch-legend-row, body.arch-full .folder-bar, body.arch-full .arch-tools { flex: none; }
body.arch-full .hist-note { display: none; }

@media (max-width: 760px) {
  /* A folder name is long and a chip cannot be hyphenated, so on a narrow
     screen the strip scrolls sideways inside itself rather than pushing the
     page wider — a horizontal scrollbar on the document is how a phone layout
     stops being a layout. */
  .folder-pick { flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden; min-width: 0; -webkit-overflow-scrolling: touch; padding-bottom: 2px; }
  .folder-pick > .legend-title { position: sticky; left: 0; background: var(--surface); padding-right: 4px; z-index: 1; }
  .folder-tab { flex: none; }
  .folder-bar { min-width: 0; }
}

/* A <select> sizes itself to its widest OPTION, and the flow picker's options
   grew a folder path and a dependency class. `.select` was already capped at
   100% of its parent, but `.map-head-tools` is `flex: none`, so the parent
   itself grew to fit and took the document with it on a phone. */
.map-head-tools { min-width: 0; max-width: 100%; }
.map-head-tools .select { min-width: 0; }
.folder-bar > * { min-width: 0; max-width: 100%; }
@media (max-width: 760px) {
  .map-head-tools { flex: 1 1 100%; }
  .map-head-tools .select { width: 100%; }
}

/* Dragging a box on the architecture diagram. The links re-route as it moves,
   which is the point — so the whole picture is redrawn once per frame. */
.arch-scroll.dragging, .arch-scroll.dragging * { cursor: grabbing !important; }
.arch-scroll.dragging .arch-node { pointer-events: none; }
.arch-node.moved rect:first-of-type { filter: drop-shadow(0 2px 5px rgba(22,33,28,.22)); }
.archsvg.dark .arch-node.moved rect:first-of-type { filter: drop-shadow(0 2px 6px rgba(0,0,0,.6)); }

/* The one line that says what the numbers on the diagram are. It sits above
   the picture rather than under it because a reader who has not been told the
   sequence is DERIVED will have finished reading the numbers by then. */
.arch-trace-note {
  margin: 0; padding: 9px 12px 10px;
  border: 1px solid var(--border); border-bottom: 0;
  border-radius: 4px 4px 0 0; background: var(--sunk);
  font: 400 13px/1.55 var(--sans); color: var(--ink2);
}
.arch-trace-note b { font: 600 13px/1.55 var(--mono); color: var(--ink); }
.arch-trace-basis { color: var(--muted); }

/* ── per-section help ───────────────────────────────────────────────────────
   A section heading now carries a "?" that opens what the section is, how to
   read it, and what it cannot tell you. It sits ON the heading rather than in
   the toolbar because the question it answers — "what am I looking at" — is
   asked while looking at the heading. */
.si-help {
  display: inline-flex; align-items: center; justify-content: center;
  width: 19px; height: 19px; margin-left: 10px; padding: 0;
  vertical-align: 3px;
  border: 1px solid var(--border); border-radius: 50%;
  background: var(--surface); color: var(--muted);
  font: 600 12.5px/1 var(--mono); cursor: help;
  transition: border-color .15s, color .15s, background .15s;
}
.si-help:hover, .si-help:focus-visible {
  border-color: var(--verd, var(--strong)); color: var(--ink); background: var(--sunk);
}
.help-eyebrow {
  margin: 0 0 4px; font: 600 12.5px/1 var(--sans);
  letter-spacing: .03em; color: var(--muted);
}
.help-is { margin: 0 0 4px; color: var(--ink2); }
.help-h {
  margin: 18px 0 8px; font: 600 13px/1 var(--sans);
  letter-spacing: .03em; text-transform: uppercase; color: var(--muted);
}
.help-list { margin: 0; padding-left: 18px; }
.help-list li { margin: 0 0 7px; font-size: 14px; line-height: 1.55; color: var(--ink2); }
.help-cannot {
  margin: 0; padding: 10px 12px;
  border-left: 2px solid var(--och, var(--border)); background: var(--sunk);
  font-size: 14px; line-height: 1.55; color: var(--ink2);
}

/* ── the pace slider ────────────────────────────────────────────────────────
   A number you set, not a button you press until it says something you like.
   The value is printed beside it because "how fast" is a question with an
   answer, and the answer depends on the estate rather than on three presets
   someone chose once. */
.arch-pace {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 4px 10px 4px 11px;
  border: 1px solid var(--border); border-radius: 999px;
  background: var(--surface); white-space: nowrap;
}
.arch-pace-t {
  font: 500 12px/1 var(--sans); letter-spacing: .03em; color: var(--muted);
}
.arch-pace-v {
  font: 500 11.5px/1 var(--mono); color: var(--ink);
  min-width: 68px; text-align: right;
}
.arch-pace-r {
  -webkit-appearance: none; appearance: none;
  width: 104px; height: 3px; padding: 0; margin: 0;
  border-radius: 2px; background: var(--rule); cursor: pointer;
}
.arch-pace-r::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 13px; height: 13px; border-radius: 50%;
  background: var(--verd, var(--ink)); border: 0; cursor: grab;
}
.arch-pace-r::-moz-range-thumb {
  width: 13px; height: 13px; border-radius: 50%;
  background: var(--verd, var(--ink)); border: 0; cursor: grab;
}
.arch-pace-r:focus-visible { outline: 2px solid var(--verd, var(--ink)); outline-offset: 3px; }
@media (max-width: 720px) {
  /* The toolbar wraps on a phone; the slider is the widest thing in it. */
  .arch-pace-r { width: 76px; }
  .arch-pace-v { min-width: 60px; }
}

/* ── arrival chips ──────────────────────────────────────────────────────────
   A numbered chip docked on the box a step reached. The record of an arrival
   belongs on the thing that was reached, not on the line the step travelled:
   a marker left resting on a link reads as "it got this far and stopped". */
.arch-chip { fill: var(--ink); stroke: var(--surface); stroke-width: 1.5; pointer-events: auto; cursor: help; }
.arch-chip-n { fill: var(--on-tone); font-family: var(--mono); font-weight: 600; pointer-events: none; }
.arch-chip-more { fill: var(--muted); font-family: var(--mono); font-weight: 600; }
@media (prefers-reduced-motion: reduce) {
  /* No walk, so the chips have nothing to record. The numbers stay on the
     links, where a reader can follow them by eye. */
  .arch-chip, .arch-chip-n, .arch-chip-more { display: none; }
}

/* ── failure paths ──────────────────────────────────────────────────────────
   The diagram shows what the estate does when everything works. This is the
   other question — where it stops, what it swallows, where a failure goes —
   drawn on top of the same picture rather than in a view of its own, because
   "which link breaks" is only meaningful next to the links that do not. */
.arch-failm-t { fill: var(--on-tone); font-family: var(--mono); font-weight: 700; pointer-events: none; }
.arch-failm { cursor: help; }
.arch-failb-t { font: 600 10.5px/1 var(--mono); letter-spacing: .04em; pointer-events: none; }
.arch-failb { pointer-events: auto; cursor: help; }
.arch-wire.fail { stroke-linecap: round; }

.arch-failbar {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 14px;
  padding: 9px 12px; margin: 0 0 10px;
  border: 1px solid var(--line); border-left: 3px solid var(--red); border-radius: 6px;
  background: var(--surface);
}
.arch-failchip {
  font: 500 13px/1.3 var(--mono); letter-spacing: .02em;
  padding: 3px 9px; border-radius: 11px; border: 1px solid;
}
.arch-failchip b { font-weight: 700; }
.arch-failchip.unguarded { color: var(--red-text); border-color: var(--red-line); background: var(--red-tint); }
.arch-failchip.swallowed { color: var(--amber-deep); border-color: var(--amber-line); background: var(--amber-tint); }
.arch-failchip.routed    { color: var(--purple); border-color: var(--purple-line); background: var(--purple-tint); }
.arch-failchip.unstartable { color: var(--red-text); border-color: var(--red-line); background: var(--red-tint); }
/* A category with nothing in it keeps its row and loses its colour: the
   sentence "none" is a measurement, and an absent row reads as a broken
   feature. Two of the four are none on a typical Okta estate. */
.arch-failchip.none { color: var(--muted); border-color: var(--line); background: transparent; }
.arch-failbasis { font: 400 12.5px/1.5 var(--mono); color: var(--muted); flex: 1 1 260px; }

.fail-flow { display: grid; grid-template-columns: minmax(170px, 230px) 1fr; gap: 14px; }
.fail-who b { display: block; }
.fail-list { display: grid; gap: 9px; min-width: 0; }
.fail-pt { display: flex; flex-wrap: wrap; align-items: baseline; gap: 7px; min-width: 0; }
.fail-card { font: 600 13px/1.4 var(--mono); }
.fail-arrow { color: var(--muted); }
.fail-target { font: 400 13px/1.4 var(--mono); color: var(--muted); }
.fail-why { flex: 1 0 100%; font: 400 13px/1.6 var(--sans); color: var(--muted); }
.fail-orphans { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line); }
.fail-orphans > div { font: 500 13.5px/1.7 var(--mono); }

@media (max-width: 720px) { .fail-flow { grid-template-columns: 1fr; } }
.arch-failchip i { font-style: normal; opacity: .6; }

/* ── the card-level walk ────────────────────────────────────────────────────
   The architecture diagram's vocabulary, one level down: a numbered marker
   travels the link, a numbered chip stays on the card it reached. A reader
   who has learnt one should not have to learn the other. */
.walk-dot { fill: var(--ink); pointer-events: none; }
.walk-dot-n { fill: var(--on-tone); font-family: var(--mono); font-weight: 600; pointer-events: none; }
.walk-chip rect { fill: var(--ink); stroke: var(--surface); stroke-width: 1.5; }
.walk-chip-n { fill: var(--on-tone); font-family: var(--mono); font-weight: 700; pointer-events: none; }
@media (prefers-reduced-motion: reduce) {
  /* No walk, so the markers have nothing to say. The chips stay: they are the
     card numbers, and those are readable standing still. */
  .walk-dot, .walk-dot-n { display: none; }
  /* 5.26: a tile's landing flash is movement too. */
  .tile-landed { animation: none; }
}
/* Above the cards, not behind them: a chip in the wire layer was clipped by
   the very card it was numbering. Below `.dragging` (40), so a card being
   dragged still comes to the front. */
.wires.walks { z-index: 14; }

/* ── the walk's own emphasis ────────────────────────────────────────────────
   A link the walked process never touches is context, and looks like it. A
   link it HAS not reached yet starts on the grey base underneath and lights
   when its first step lands, so the picture fills in as the walk proceeds
   rather than presenting the whole route before any of it has happened. */
.arch-wire.off { stroke: var(--strong); stroke-opacity: .55; stroke-width: 1; }
.archsvg.dark .arch-wire.off { stroke-opacity: .9; }
.arch-wire.base { stroke: var(--strong); stroke-opacity: .55; }
.archsvg.dark .arch-wire.base { stroke-opacity: .9; }
/* A grey link is not a route anyone is travelling, so it does not march. */
.arch-wire.off, .arch-wire.base { stroke-dasharray: none; animation: none; }

/* The courier: the disc that completes the journey while the numbered marker
   stays behind as a label. Plain grey and a size smaller, because it is the
   same step arriving rather than another step happening. */
.arch-dot.courier { fill: var(--ghost); }
/* The dark palette's own ghost: stated so a reader of the dark rules finds it. */
.archsvg.dark .arch-dot.courier { fill: var(--ghost); }
.arch-dot-n.courier { fill: var(--on-tone); }

/* ── the help drawer ────────────────────────────────────────────────────────
   Docked right, in its own column. Help that opens over the thing it explains
   is help nobody reads: you close it, look, and open it again. This leaves the
   page alone, so you can read about the walk while the walk is running — which
   also means no backdrop, and Escape yields to a real dialog if one is up. */
.helpdrawer {
  position: fixed; top: var(--topbar-h, 52px); right: 0; bottom: 0;
  /* Above full screen (90), because a `?` pressed while the diagram owns the
     screen must still show you an answer — and below a real dialog, which is
     the thing a reader is actually stuck behind. */
  width: 380px; max-width: 100vw; z-index: 96;
  display: flex; flex-direction: column;
  background: var(--surface); border-left: 1px solid var(--border);
  box-shadow: -10px 0 30px rgba(22, 33, 28, .07);
}
.help-top {
  flex: none; display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 11px 14px 10px; border-bottom: 1px solid var(--border);
}
.help-back, .help-x {
  padding: 3px 8px; border: 1px solid transparent; border-radius: 4px;
  background: none; color: var(--muted); cursor: pointer;
  font: 500 13px/1.4 var(--mono);
}
.help-back:hover, .help-x:hover,
.help-back:focus-visible, .help-x:focus-visible {
  border-color: var(--border); color: var(--ink); background: var(--sunk);
}
.help-x { font-size: 14px; }
.help-body { flex: 1 1 auto; overflow: auto; padding: 16px 18px 28px; }
.help-body h2 { margin: 0 0 8px; font-size: 17px; line-height: 1.3; }
.help-see { margin-top: 20px; padding-top: 4px; border-top: 1px solid var(--border); }
.help-link {
  display: block; width: 100%; margin: 0 0 6px; padding: 7px 10px;
  border: 1px solid var(--border); border-radius: 4px;
  background: var(--surface); color: var(--ink2); text-align: left;
  font: 500 13.5px/1.4 var(--sans); cursor: pointer;
}
.help-link:hover, .help-link:focus-visible {
  border-color: var(--strong); color: var(--ink); background: var(--sunk);
}
/* Inside a sentence it is a link, not a button. */
.help-link.inline {
  display: inline; width: auto; margin: 0; padding: 0;
  border: 0; background: none; color: var(--green, var(--strong));
  text-decoration: underline; font-size: inherit; font-weight: 500;
}
.help-foot {
  margin: 22px 0 0; padding-top: 12px; border-top: 1px solid var(--border);
  font: 400 13px/1.6 var(--sans); color: var(--muted);
}

/* The page gives up the width rather than having the drawer sit on top of it:
   a reader comparing the words to the thing needs to see the thing. */
@media (min-width: 1180px) {
  #app-inner.help-open { padding-right: 380px; }
  #app-inner.help-open .topbar,
  #app-inner.help-open .pinned { right: 380px; }
  /* A full-screen diagram is positioned against the viewport rather than
     inside #app-inner, so the padding above does not reach it. Same width,
     same breakpoint — below it the drawer overlays and nothing moves. */
  body.map-full.help-shown .mapwrap,
  body.arch-full.help-shown .arch-panel { right: 380px; }
}
/* Too narrow to give up a column: the drawer takes the screen, and the page
   waits behind it. */
@media (max-width: 1179px) {
  .helpdrawer { width: min(420px, 100vw); }
}
@media (max-width: 560px) {
  .helpdrawer { top: auto; left: 0; height: 72vh; width: 100vw; border-left: 0;
                border-top: 1px solid var(--border); border-radius: 10px 10px 0 0; }
}

/* ── the ? itself ───────────────────────────────────────────────────────────
   Beside the thing it explains, everywhere there is something to explain.
   Help collected in a menu is help nobody finds. */
.helpmark {
  display: inline-flex; align-items: center; justify-content: center;
  flex: none; width: 17px; height: 17px; margin-left: 7px; padding: 0;
  vertical-align: 2px;
  border: 1px solid var(--border); border-radius: 50%;
  background: var(--surface); color: var(--muted);
  font: 600 12px/1 var(--mono); cursor: help;
  transition: border-color .15s, color .15s, background .15s;
}
.helpmark:hover, .helpmark:focus-visible {
  border-color: var(--strong); color: var(--ink); background: var(--sunk);
}
.helpmark.on { border-color: var(--ink); color: var(--on-tone); background: var(--ink); }
/* On a heading it can afford to be a touch larger. */
.section-intro h2 .helpmark { width: 19px; height: 19px; margin-left: 10px;
                              font-size: 12.5px; vertical-align: 3px; }
.stats-head {
  display: flex; align-items: center; gap: 2px;
  margin: 0 0 7px;
}

/* ── the public architecture preview ────────────────────────────────────────
   Its own small page, using the product's own renderer. The promise about the
   file sits next to the button in the same size as everything else: a
   reassurance in small grey type is a reassurance nobody reads, and this one
   has to be read before somebody uploads their workflow configuration. */
body.explore { background: var(--page); }
.explore-intro { max-width: 760px; margin: 0 auto; }
.explore-intro h1 { margin: 0 0 12px; }
.explore-promise {
  margin: 22px 0; padding: 16px 18px;
  border: 1px solid var(--green-line); border-radius: 4px; background: var(--green-wash);
}
.explore-promise h2 { margin: 0 0 10px; font: 600 13px/1 var(--sans);
                      letter-spacing: .03em; text-transform: uppercase; color: var(--green); }
.explore-promise ul { margin: 0; padding-left: 18px; }
.explore-promise li { margin: 0 0 8px; font: 400 14px/1.6 var(--sans); color: var(--ink2); }
.explore-promise li:last-child { margin-bottom: 0; }
.explore-pick { display: flex; flex-direction: column; gap: 12px; margin-top: 22px; }
.explore-files { display: flex; flex-direction: column; gap: 4px;
                 font: 500 13.5px/1.6 var(--mono); color: var(--ink2); }
.explore-confirm { display: flex; align-items: flex-start; gap: 9px;
                   font: 400 14px/1.5 var(--sans); color: var(--ink2); cursor: pointer; }
.explore-confirm input { margin-top: 2px; flex: none; }
.explore-cta { max-width: 760px; margin: 0 auto; }
.explore-cta h2 { margin: 0 0 12px; }
.explore-cta .btn-wide { margin-top: 8px; }
.is-explore .wrap { padding-top: 26px; }
.explore-bar {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 12px 18px;
  margin: 0 0 14px; padding: 11px 16px;
  border: 1px solid var(--border); border-radius: 4px; background: var(--surface);
}
.explore-bar-k { display: block; font: 600 12.5px/1.4 var(--sans);
                 letter-spacing: .03em; color: var(--muted); }
.explore-bar-v { display: block; font: 500 14px/1.5 var(--sans); color: var(--ink); }
.explore-bar-r { display: flex; align-items: center; gap: 12px; }


/* ══ 5.15 · workspace chrome ══════════════════════════════════════════════
   The bar is dark again. 5.14 made it light so the chrome would not read as
   a different product; it also left the workspace with no place of its own.
   The dark strip now holds only what belongs to the workspace — logo, the
   estate in view, the three modes, search, help and New assessment — and the
   light context bar under it holds what belongs to this assessment: grade,
   counts, scope and exports. Numbers are Public Sans; Spectral is for
   headings; mono is for identifiers only. */
.topbar { background: var(--bar); border-bottom: 1px solid var(--bar-line); padding: 8px 18px; }
.topbar .brand-img { filter: brightness(0) invert(1); height: 26px; }
.estate-id { display: flex; flex-direction: column; gap: 1px; padding-left: 14px; border-left: 1px solid var(--bar-line); min-width: 0; }
.estate-id b { font: 600 13px/1.3 var(--sans); color: var(--on-bar); white-space: nowrap; }
.estate-id span { font: 400 11.5px/1.3 var(--sans); color: var(--on-bar-dim); white-space: nowrap; }
.topbar .modetabs { background: rgba(255,255,255,.06); border-color: var(--bar-line); }
.topbar .modetab { color: var(--on-bar-dim); padding: 5px 13px; }
.topbar .modetab:hover { color: var(--on-bar); }
.topbar .modetab.on { background: var(--surface); color: var(--ink); border-color: transparent; }
.topbar .modetab b { font: 600 13px/1.3 var(--sans); }
.topbar .buildsig { border-color: var(--bar-line); color: var(--on-bar-dim); }
.topbar .btn-link { color: var(--on-bar-dim); }
.topbar .btn-link:hover { color: var(--on-bar); }
.topbar .trust-pill.demo-pill { border-color: rgba(233,196,106,.45); background: rgba(233,196,106,.12); color: var(--bar-amber-text); }
.topbar .trust-pill.demo-pill .dot { background: var(--bar-amber); }
.topbar .whoami-n { color: var(--on-bar); }
.bar-btn { padding: 6px 11px; border: 1px solid var(--bar-line); border-radius: 4px; background: rgba(255,255,255,.04); font: 600 13px/1.2 var(--sans); color: var(--on-bar); cursor: pointer; white-space: nowrap; }
.bar-btn:hover, .bar-btn.on { background: rgba(255,255,255,.12); }
.bar-btn.bar-primary { background: var(--bar-green); border-color: var(--bar-green); color: var(--on-bar); }
.bar-btn.bar-primary:hover { background: var(--bar-green-hover); }

.gsearch { position: relative; display: flex; align-items: center; min-width: 0; flex: 0 1 340px; }
.gsearch-in { width: 100%; padding: 7px 64px 7px 11px; border: 1px solid var(--bar-line); border-radius: 4px; background: rgba(255,255,255,.07); font: 400 13px/1.2 var(--sans); color: var(--on-bar); outline: none; }
.gsearch-in::placeholder { color: var(--on-bar-dim); }
.gsearch-in:focus { background: var(--surface); color: var(--ink); border-color: var(--surface); }
.gsearch kbd { position: absolute; right: 8px; padding: 1px 5px; border: 1px solid var(--bar-line); border-radius: 3px; font: 500 9px/1.5 var(--mono); color: var(--on-bar-dim); pointer-events: none; }
.gsearch-in:focus + kbd { display: none; }
.gsearch-pop { position: absolute; top: calc(100% + 6px); left: 0; right: 0; min-width: 360px; max-height: 420px; overflow: auto; background: var(--surface); border: 1px solid var(--border); border-radius: 6px; box-shadow: 0 12px 30px rgba(10,20,15,.22); padding: 6px; z-index: 80; }
.gs-row { display: grid; grid-template-columns: 62px 1fr; column-gap: 8px; width: 100%; padding: 7px 8px; border: none; border-radius: 4px; background: none; text-align: left; cursor: pointer; }
.gs-row:hover, .gs-row.on { background: var(--green-tint); }
.gs-row .gs-kind { grid-row: span 2; align-self: center; font: 600 10.5px/1.4 var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--faint); }
.gs-row b { font: 600 13px/1.35 var(--sans); color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gs-row .gs-sub { font: 400 12px/1.35 var(--sans); color: var(--muted); }
.gs-none { padding: 10px; font: 400 13px/1.4 var(--sans); color: var(--muted); }

.ctxbar { position: sticky; top: var(--topbar-h, 52px); z-index: 40; display: flex; align-items: center; flex-wrap: wrap; gap: 8px 18px; padding: 8px 20px; background: var(--surface); border-bottom: 1px solid var(--border); backdrop-filter: blur(6px); }
.ctx-grade { display: inline-flex; align-items: center; gap: 8px; padding: 0; border: none; background: none; cursor: pointer; }
.ctx-grade .grade-chip { padding: 2px 7px; }
.ctx-grade .grade-chip b { font: 700 14px/1 var(--sans); }
.ctx-score { font: 400 13px/1 var(--sans); color: var(--muted); }
.ctx-score b { font: 700 15px/1 var(--sans); color: var(--ink); }
.ctx-band { font: 500 13px/1 var(--sans); color: var(--muted); }
.ctx-stat { font: 400 13px/1.3 var(--sans); color: var(--muted); white-space: nowrap; }
.ctx-stat b { font: 700 13.5px/1 var(--sans); color: var(--ink); }
.ctx-stat b.t-red, .t-red { color: var(--red); }
.ctx-stat b.t-amber, .t-amber { color: var(--amber-deep); }
.ctx-spacer { flex: 1 1 auto; }
.ctx-scope { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.ctx-k { font: 600 12px/1 var(--sans); color: var(--faint); }
.ctx-scope select, .ctx-scope .select { max-width: 280px; }
.btn-sm { padding: 5px 11px !important; font-size: 12.5px !important; }

.menu { position: relative; }
.menu-btn { font: 600 12.5px/1.2 var(--sans); letter-spacing: 0; text-transform: none; color: var(--ink); padding: 6px 11px; }
.menu-pop { position: absolute; right: 0; top: calc(100% + 6px); width: 300px; background: var(--surface); border: 1px solid var(--border); border-radius: 6px; box-shadow: 0 12px 30px rgba(10,20,15,.16); padding: 6px; z-index: 70; }
.menu-item { display: block; width: 100%; padding: 8px 10px; border: none; border-radius: 4px; background: none; text-align: left; cursor: pointer; }
.menu-item:hover { background: var(--green-tint); }
.menu-item b { display: block; font: 600 13px/1.3 var(--sans); color: var(--ink); }
.menu-item span { display: block; font: 400 12px/1.35 var(--sans); color: var(--muted); }

.side { padding: 10px 0; }
.side-group { padding: 12px 13px 5px; }
.side-item { font: 500 13px/1.4 var(--sans); padding: 6px 13px; }
.side-item em { font: 500 11.5px/1 var(--sans); }

/* The Overview header no longer repeats; the section intro is a heading. */
.section-intro { padding-top: 2px; }

/* ── Flows list ────────────────────────────────────────────────────────── */
.fl-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 18px; flex-wrap: wrap; }
.fl-grades { display: flex; gap: 6px; flex-wrap: wrap; }
.fl-grades .grade-chip { cursor: pointer; padding: 4px 9px; font: 500 12.5px/1.2 var(--sans); }
.fl-grades .grade-chip b { font: 700 13px/1 var(--sans); }
.fl-grades .grade-chip.on { outline: 2px solid var(--ink); outline-offset: 1px; }
.fl-grid { display: grid; grid-template-columns: minmax(240px, 2.4fr) 90px 84px 70px 70px minmax(150px, 1.3fr); column-gap: 12px; align-items: center; }
.fl-row { width: 100%; border: none; border-bottom: 1px solid var(--soft); background: none; text-align: left; cursor: pointer; padding: 9px 12px; }
.fl-row:hover { background: var(--green-wash); }
.fl-row .td-text b { display: block; font: 600 13.5px/1.35 var(--sans); color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fl-row .td-text i { display: block; font: 400 12px/1.35 var(--sans); font-style: normal; color: var(--faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fl-row .td-num { font: 600 13.5px/1 var(--sans); }
.fl-row .grade-chip { font: 500 12.5px/1.3 var(--sans); }
.fl-row .grade-chip b { font: 700 13px/1 var(--sans); }
.fl-start { font: 400 13px/1.35 var(--sans); color: var(--muted); }
.fl-start.k-api, .fl-start.k-event, .fl-start.k-schedule { color: var(--green-deep); }
.fl-more { display: block; margin: 12px auto 0; }

/* ── one flow, as a page ──────────────────────────────────────────────── */
.fp-crumbs { margin: 0 0 8px; font: 400 13px/1.4 var(--sans); color: var(--faint); }
.fp-head { display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap; }
.fp-grade { flex: none; width: 46px; height: 46px; border-radius: 6px; border: 1px solid; display: flex; align-items: center; justify-content: center; font: 700 22px/1 var(--sans); }
.fp-title { flex: 1 1 420px; min-width: 0; }
.fp-title h1 { margin-bottom: 8px; }
.fp-title .map-facts { display: flex; flex-wrap: wrap; gap: 6px; }
.fp-pick { flex: 0 1 320px; min-width: 0; }
.fp-tabs { display: flex; gap: 2px; margin: 12px 0 12px; border-bottom: 1px solid var(--border); overflow-x: auto; }
.fp-tab { padding: 8px 14px; border: none; border-bottom: 2px solid transparent; background: none; cursor: pointer; font: 600 13px/1.2 var(--sans); color: var(--muted); white-space: nowrap; }
.fp-tab:hover { color: var(--ink); }
.fp-tab.on { color: var(--green-deep); border-bottom-color: var(--green); }
.map-head-page { padding-bottom: 6px; }
.e2e-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 8px; }
.seg-e2e button { padding: 6px 12px; font: 600 11.5px/1.4 var(--mono); }
.seg-e2e button.on { background: var(--green); }
.cc-row { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; padding: 7px 0; border-bottom: 1px solid var(--soft); font: 400 13px/1.4 var(--sans); }
.cc-dir { flex: none; width: 96px; font: 600 12px/1.4 var(--sans); letter-spacing: .03em; color: var(--faint); }

/* ── architecture: finding a process ──────────────────────────────────── */
.arch-pick { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.arch-find .search { width: 260px; max-width: 100%; }

/* ── help index ───────────────────────────────────────────────────────── */
.help-search { width: 100%; margin: 4px 0 14px; padding: 8px 10px; border: 1px solid var(--border); border-radius: 4px; font: 400 13.5px/1.3 var(--sans); }
.help-group { margin-bottom: 10px; }
.help-row { display: block; width: 100%; text-align: left; padding: 7px 8px; border-radius: 4px; }
.help-row b { display: block; font: 600 13px/1.35 var(--sans); color: var(--ink); }
.help-row span { display: block; font: 400 12.5px/1.45 var(--sans); color: var(--muted); }
.help-row:hover { background: var(--green-tint); }

@media (max-width: 1100px) {
  .gsearch { flex-basis: 220px; }
  .estate-id { display: none; }
}
@media (max-width: 760px) {
  .report-body { padding: 12px 12px 0; flex-direction: column; }
  .sidebar { position: static; width: 100%; }
  .ctxbar { position: static; padding: 8px 12px; }
  .gsearch { display: none; }
  .gsearch-pop { min-width: 0; }
}

.rhead-top h1 { margin: 0 0 8px; font: 400 29px/1.15 var(--serif); letter-spacing: -.01em; }
.main .panel.ov-table { margin-top: 16px; }
.grade-why .btn-linkish { margin-left: 4px; }
.stats-head { margin-top: 14px; }

/* ══ 5.15.1 · type and colour ═════════════════════════════════════════════
   Mono is for identifiers — rule ids, hashes, card numbers — and nothing else.
   Labels are Public Sans in sentence case at a size that can be read; numbers
   are Public Sans with tabular figures; Spectral is for headings only.
   Colour marks what needs action: the number and a thin top edge, not a
   filled tile, so one red number stands out instead of five amber panels. */
.stat-label, .field-label, .th, .legend-title, .zoom-label, .eyebrow, .score-band, .stats-head .field-label {
  font-family: var(--sans); font-size: 12.5px; font-weight: 600; letter-spacing: 0; text-transform: lowercase;
}
.stat-label::first-letter, .field-label::first-letter, .th::first-letter, .legend-title::first-letter,
.eyebrow::first-letter, .score-band::first-letter { text-transform: uppercase; }
.eyebrow { color: var(--tone); font-size: 13px; }
.stat-label { color: var(--muted); margin-bottom: 6px; }
.stat-value { font: 700 26px/1.05 var(--sans); letter-spacing: -.02em; }
.stat-sub { font-size: 12.5px; color: var(--faint); }
.stat { border-top: 3px solid var(--border); }
.stat-red, .stat-amber, .stat-navy, .stat-green, .stat-purple { background: var(--surface); border-color: var(--border); }
.stat-red { border-top-color: var(--red); } .stat-red .stat-label { color: var(--muted); } .stat-red .stat-sub { color: var(--faint); }
.stat-amber { border-top-color: var(--amber); } .stat-amber .stat-label { color: var(--muted); }
.stat-navy { border-top-color: var(--navy); } .stat-navy .stat-label { color: var(--muted); }
.stat-green { border-top-color: var(--green); } .stat-green .stat-label { color: var(--muted); } .stat-green .stat-value { color: var(--ink); }
.stat-purple { border-top-color: var(--purple); } .stat-purple .stat-label { color: var(--muted); }

.th { font-size: 12.5px; color: var(--muted); }
.td-num { font-family: var(--sans); font-variant-numeric: tabular-nums; }
.grade-chip, .grade-chip b { font-family: var(--sans); }

/* The score box: the grade, the score, one label. */
.score { background: var(--surface); border: 1px solid var(--border); border-top: 3px solid var(--amber); padding: 14px 18px; min-width: 150px; }
.score.good { background: var(--surface); border-top-color: var(--green); } .score.poor { background: var(--surface); border-top-color: var(--red); }
.score-n { font: 700 34px/1 var(--sans); color: var(--ink); letter-spacing: -.02em; }
.score-n::after { content: "/100"; font: 400 14px/1 var(--sans); color: var(--faint); margin-left: 2px; }
.score.good .score-n, .score.poor .score-n { color: var(--ink); }
.score-band { display: none; }
.score-grade .grade-chip { font: 600 13px/1.3 var(--sans); padding: 3px 9px; }
.score-grade .grade-chip b { font: 700 14px/1 var(--sans); }
.score-sub { font-size: 12px; color: var(--faint); }

/* The flow map toolbar: groups, readable buttons. */
.map-tools, .map-cards { justify-content: flex-start; gap: 10px 26px; }
.map-cards { justify-content: space-between; }
.tgroup { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.tgroup-t { font: 600 11px/1 var(--sans); color: var(--faint); margin-right: 2px; }
.tbtn { padding: 5px 10px; border: 1px solid var(--border); border-radius: 4px; background: var(--surface); font: 500 13px/1.3 var(--sans); color: var(--ink2); cursor: pointer; white-space: nowrap; }
.tbtn:hover { background: var(--page); }
.tbtn.on { background: var(--green-tint); border-color: var(--green-line); color: var(--green-deep); }
.map-tools .seg button, .seg-e2e button { font: 600 12.5px/1.4 var(--sans); letter-spacing: 0; padding: 5px 10px; }
.zoomctl { display: inline-flex; align-items: center; gap: 4px; }
.zoom-val { font: 600 13px/1 var(--sans); min-width: 38px; text-align: center; }
.meta-note { font: 400 12.5px/1.4 var(--sans); color: var(--faint); }
.key-row .legend span { font-family: var(--sans); font-size: 12.5px; letter-spacing: 0; }
.legend > span:not(.legend-title) { font-family: var(--sans); letter-spacing: .02em; }
.hint-mono { font-family: var(--sans); letter-spacing: 0; font-size: 12.5px; }
.btn-ghost { font: 600 12.5px/1.4 var(--sans); letter-spacing: 0; text-transform: none; }
/* ::first-letter needs a block or inline-block box; these were flex or inline. */
.th { display: inline-block; text-align: left; } .th span { margin-left: 4px; }
.legend-title { display: inline-block; }
.legend .legend-title { color: var(--faint); letter-spacing: 0; font: 600 12.5px/1.4 var(--sans); }
.eyebrow { text-transform: none; }
.eyebrow-t { display: inline-block; text-transform: lowercase; }
.eyebrow-t::first-letter { text-transform: uppercase; }
.btn-linkish { font: 500 13px/1.5 var(--sans); }
.chip { font: 500 12px/1.6 var(--sans); }
.hint-mono { display: inline-block; }
.legend-note { font-family: var(--sans); letter-spacing: 0; font-size: 12.5px; }
/* Buttons whose labels are written in capitals in the code read in sentence
   case. File formats stay as they are written. */
.btn-ghost, .btn-fit, .legend-more { text-transform: lowercase; }
.btn-ghost::first-letter, .btn-fit::first-letter, .legend-more::first-letter { text-transform: uppercase; }
.save-as .btn-ghost, .btn-gif, .save-as .tbtn { text-transform: none; }
.legend > .legend-title, .toolbar-band .legend-title { display: inline-block; text-transform: lowercase; }
.legend > .legend-title::first-letter, .toolbar-band .legend-title::first-letter { text-transform: uppercase; }
.side-group { font: 600 12px/1.4 var(--sans); letter-spacing: .06em; }
.legend-chips .legend-item, .arch-chain { font-family: var(--sans); letter-spacing: 0; font-size: 12.5px; }

/* 5.16 · Lens keys */
.lens-new { margin: 6px 0 14px; padding: 12px; background: var(--sunk); border: 1px solid var(--border); border-radius: 4px; }
.lens-new .field-static, .lens-create .field-static { gap: 8px; }
.lens-key { font: 500 13px/1.4 var(--mono, ui-monospace, monospace); }
.lens-create { margin: 4px 0 14px; }
.lens-keys { width: 100%; border-collapse: collapse; font: 400 13px/1.5 var(--sans); }
.lens-keys th { text-align: left; font: 500 11.5px/1.4 var(--sans); letter-spacing: .03em; text-transform: uppercase; color: var(--faint); padding: 6px 6px 6px 0; border-bottom: 1px solid var(--soft); }
.lens-keys td { padding: 7px 6px 7px 0; border-bottom: 1px solid var(--soft); vertical-align: middle; }
.lens-keys tr.is-revoked td { color: var(--faint); }
.lens-fp { margin-top: 12px; }
.lens-count { margin-right: auto; align-self: center; font: 400 13px/1.4 var(--sans); color: var(--muted); }
.modal:has(.lens-keys) { max-width: 640px; }
.lens-new-head { margin: 0 0 8px !important; color: var(--ink) !important; }
.lens-std { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--soft); }
.lens-std h3 { margin: 0 0 6px; font: 600 14px/1.3 var(--sans); color: var(--ink); }
.lens-std .select { margin: 4px 0 10px; }
.lens-std-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 10px; }
.lens-std-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 10px; }
.lens-std-msg { margin: 8px 0 0 !important; color: var(--green-deep) !important; }
.lens-std-msg.bad { color: var(--red) !important; }

/* 5.18 · clickable tiles, tile-name search, progress and accepted findings */
.visually-hidden { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.stat-link { all: unset; display: flex; flex-direction: column; cursor: pointer; border-radius: 4px; min-width: 0; }
.stat-link .stat { flex: 1; transition: border-color .12s, transform .12s; }
.stat-link:hover .stat, .stat-link:focus-visible .stat { border-color: var(--green); transform: translateY(-1px); }
.stat-link:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }
.stat-go { font: 600 12px/1.4 var(--sans); color: var(--green-deep); padding: 5px 2px 0; }
.click-hint { margin-left: auto; font: 400 12.5px/1.4 var(--sans); color: var(--muted); }
.click-hint::before { content: "↘ "; color: var(--green); }
.stats-head { display: flex; align-items: center; gap: 8px; }
.tbl-fam { padding: 10px 14px; font: 400 13px/1.5 var(--sans); color: var(--muted); background: var(--green-wash); border-top: 1px solid var(--green-line); }
.fx-accept { display: flex; align-items: center; gap: 10px; justify-content: flex-end; padding: 10px 0 2px; font: 400 13px/1.4 var(--sans); color: var(--muted); border-top: 1px dashed var(--soft); margin-top: 6px; }

.cmp-panel { margin-top: 18px; padding: 16px 18px; border: 1px dashed var(--border); border-radius: 4px; background: var(--surface); }
.cmp-head { display: flex; gap: 18px; justify-content: space-between; align-items: flex-start; flex-wrap: wrap; }
.cmp-head h3 { margin: 2px 0 4px; font: 400 18px/1.25 var(--serif); color: var(--ink); }
.cmp-head p { margin: 0; max-width: 620px; font: 400 13px/1.6 var(--sans); color: var(--muted); }
.cmp-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.cmp-pick { display: inline-block; cursor: pointer; }
.cmp-state { margin: 12px 0 0; font: 400 13px/1.5 var(--sans); color: var(--ink); }
.cmp-hint { margin: 10px 0 0; font: 400 12.5px/1.5 var(--sans); color: var(--faint); }
.keep-cmp { display: flex; gap: 8px; align-items: flex-start; margin: 12px 0 4px; font: 400 13px/1.5 var(--sans); color: var(--ink); cursor: pointer; }
.keep-cmp input { margin-top: 3px; }

.prog { margin-top: 16px; }
.prog-head { display: flex; justify-content: space-between; gap: 24px; align-items: flex-start; flex-wrap: wrap; }
.prog-head .lede { max-width: 640px; }
.prog-grade { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: flex-end; }
.prog-arrow { font: 400 20px/1 var(--serif); color: var(--muted); }
.prog-score { width: 100%; text-align: right; font: 400 13px/1.4 var(--sans); color: var(--muted); font-variant-numeric: tabular-nums; }
.prog-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin: 14px 0 10px; }
.prog-tab { border: 1px solid var(--border); background: var(--surface); border-radius: 999px; padding: 5px 12px; font: 500 13px/1.3 var(--sans); color: var(--muted); cursor: pointer; display: inline-flex; gap: 6px; align-items: baseline; }
.prog-tab b { font: 600 14px/1 var(--sans); color: var(--ink); }
.prog-tab.on { border-color: var(--ink); color: var(--ink); background: var(--page); }
.prog-fixed.on { border-color: var(--green); background: var(--green-tint); }
.prog-new.on { border-color: var(--red); background: var(--red-tint); }
.prog-ctl { display: flex; gap: 16px; flex-wrap: wrap; font: 400 13px/1.5 var(--sans); margin: 0 0 10px; }
.prog-ctl .good { color: var(--green-deep); } .prog-ctl .bad { color: var(--red); }
.prog-list { border: 1px solid var(--soft); border-radius: 4px; }
.prog-row { display: grid; grid-template-columns: 12px 76px 1fr minmax(160px, 34%); gap: 10px; align-items: center; padding: 8px 12px; border-top: 1px solid var(--soft); font: 400 13px/1.4 var(--sans); }
.prog-row:first-child { border-top: 0; }
.prog-rule { font: 500 12.5px/1.3 var(--mono, ui-monospace, monospace); color: var(--muted); }
.prog-wf { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.prog-empty, .prog-note { font: 400 13px/1.5 var(--sans); color: var(--muted); margin: 10px 0 0; }
.sev-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--faint); }
.sev-dot.sev-critical, .sev-dot.sev-high { background: var(--red); } .sev-dot.sev-medium { background: var(--amber); } .sev-dot.sev-low { background: var(--navy); }

.accp { margin-top: 16px; }
.accp-list { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.accp-row { display: flex; gap: 14px; justify-content: space-between; align-items: flex-start; padding: 10px 12px; border: 1px solid var(--soft); border-left: 3px solid var(--amber); border-radius: 4px; }
.accp-main { display: flex; flex-direction: column; gap: 3px; font: 400 13px/1.5 var(--sans); color: var(--ink); min-width: 0; }
.accp-main span, .accp-main small { color: var(--muted); }
.accp-main q { font-style: italic; color: var(--ink); }
.acc-flows { display: flex; flex-direction: column; gap: 6px; margin: 6px 0 14px; max-height: 180px; overflow: auto; }
.acc-flow { display: flex; gap: 8px; align-items: flex-start; font: 400 13px/1.4 var(--sans); cursor: pointer; }
.acc-flow small { color: var(--muted); }
.acc-reason { resize: vertical; min-height: 70px; }
.acc-row2 { display: flex; gap: 14px; align-items: flex-end; margin-top: 12px; flex-wrap: wrap; }
.acc-note { margin: 0 !important; }
@media (max-width: 720px) { .prog-row { grid-template-columns: 12px 64px 1fr; } .prog-wf { grid-column: 2 / -1; } }
.prog-why { width: 100%; max-width: 300px; text-align: right; font: 400 12.5px/1.45 var(--sans); color: var(--faint); }

/* 5.19 · progress by workflow and folder; what Assay remembers */
.prog-hint { margin: -4px 0 10px; font: 400 12.5px/1.4 var(--sans); color: var(--faint); }
.prog-x { font-weight: 600; color: var(--muted); }
.prog-folders { display: flex; gap: 8px; flex-wrap: wrap; margin: 14px 0 4px; }
.prog-folder { border: 1px solid var(--soft); border-radius: 4px; padding: 8px 12px; min-width: 190px; background: var(--page); }
.prog-folder-name { font: 600 13px/1.3 var(--sans); color: var(--ink); }
.prog-folder-n { font: 400 12.5px/1.4 var(--sans); color: var(--muted); margin: 2px 0 4px; }
.prog-folder-t { display: flex; gap: 8px; flex-wrap: wrap; font: 500 12.5px/1.4 var(--sans); color: var(--muted); }
.prog-folder-t .good, .t-better { color: var(--green-deep); } .prog-folder-t .bad, .t-worse { color: var(--red); }
.prog-folder-t .muted { color: var(--faint); }
.prog-wfs { margin-top: 12px; }
.prog-wfs .prog-list { margin-top: 8px; }
.prog-wfrow { display: grid; grid-template-columns: 84px 1fr 70px minmax(170px, 30%); gap: 10px; align-items: center; padding: 8px 12px; border-top: 1px solid var(--soft); font: 400 13px/1.4 var(--sans); }
.prog-wfrow:first-child { border-top: 0; }
.prog-wfrow small { color: var(--faint); }
.prog-trend { font: 600 12.5px/1.3 var(--sans); } .t-same { color: var(--muted); }
.prog-g { font: 600 13px/1.3 var(--sans); color: var(--ink); font-variant-numeric: tabular-nums; }
.prog-first { border-left: 3px solid var(--green); }
.remember { margin-top: 14px; padding: 12px 14px; border: 1px solid var(--green-line); border-radius: 4px; background: var(--green-wash); text-align: left; }
.remember p { margin: 4px 0 0; font: 400 13px/1.55 var(--sans); color: var(--muted); }
.remember-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.remember-hint { color: var(--green-deep) !important; }
.remember-list { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; }
.remember-row { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; font: 400 13px/1.45 var(--sans); color: var(--muted); }
.remember-row b { color: var(--ink); font-weight: 600; }
.remember-row .btn-ghost { margin-left: auto; }
.remember-manage { margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--green-line); display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.remember-manage p { width: 100%; margin: 0 0 4px; }
@media (max-width: 720px) { .prog-wfrow { grid-template-columns: 70px 1fr; } .prog-wfrow .prog-wf, .prog-wfrow .prog-g { grid-column: 2; } }

/* 5.19 · the whole top bar moves a card */
.card-band { cursor: grab; }
.card.dragging .card-band { cursor: grabbing; }
.move-hint { color: var(--green-deep); }

/* ── 5.20 workspace: reports, team, share ─────────────────────────────── */
.page-wrap { max-width: 1080px; margin: 0 auto; padding: 28px 28px 60px; }
.page-head { margin-bottom: 14px; }
.page-wrap .tbl-tools { margin-bottom: 14px; }
.page-wrap .panel { margin-bottom: 16px; }
.page-wrap .panel h3 { margin: 0 0 12px; font: 600 13px/1.4 var(--sans); letter-spacing: .03em; text-transform: uppercase; color: var(--muted); }
.rpt-list { display: flex; flex-direction: column; border: 1px solid var(--border); border-radius: 4px; background: var(--surface); }
.rpt-row { display: flex; align-items: center; gap: 14px; padding: 12px 14px; border-top: 1px solid var(--soft); }
.rpt-row:first-child { border-top: none; }
.rpt-row:hover { background: var(--green-wash); }
.rpt-row .grade-chip { min-width: 30px; justify-content: center; padding: 6px 8px; }
.rpt-row .grade-chip b { font-size: 14px; }
.rpt-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; padding: 0; border: none; background: transparent; text-align: left; cursor: pointer; color: var(--ink); }
.rpt-main b { font: 600 14px/1.4 var(--sans); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rpt-main span { font: 400 13px/1.5 var(--sans); color: var(--ink2); }
.rpt-main small { font: 400 12px/1.5 var(--sans); color: var(--faint); }
.rpt-main:hover b { color: var(--green-deep); text-decoration: underline; }
.rpt-actions { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
.role-chip { display: inline-flex; align-items: center; padding: 4px 9px; border: 1px solid var(--bar-line); border-radius: 999px; font: 500 12px/1.3 var(--sans); color: var(--on-bar); white-space: nowrap; max-width: 240px; overflow: hidden; text-overflow: ellipsis; }
.role-chip.role-owner { border-color: rgba(46,154,98,.7); }
.role-chip.role-viewer { opacity: .85; }
.team-form { display: grid; grid-template-columns: 1.4fr 1fr 1.3fr auto; gap: 12px; align-items: end; }
.team-form .field { width: 100%; }
.page-wrap .lens-keys .select, .page-wrap .lens-keys select { min-width: 110px; }
.page-wrap .lens-keys td .btn-ghost + .btn-ghost { margin-left: 6px; }
.share-h { margin: 22px 0 8px; font: 600 12.5px/1.4 var(--sans); letter-spacing: .03em; text-transform: uppercase; color: var(--muted); }
.grow { flex: 1; min-width: 200px; }
.grow .field { width: 100%; }
.modal:has(.share-h) { max-width: 680px; }
@media (max-width: 760px) {
  .page-wrap { padding: 18px 16px 48px; }
  .team-form { grid-template-columns: 1fr; }
  .rpt-row { flex-wrap: wrap; }
  .rpt-actions { width: 100%; justify-content: flex-start; }
  .page-wrap .lens-keys { display: block; overflow-x: auto; }
}
.page-wrap .panel p { font: 400 13px/1.6 var(--sans); }

/* ── 5.21 failure paths ──────────────────────────────────────────────── */
.fp-over { display: flex; gap: 18px; align-items: center; justify-content: space-between; flex-wrap: wrap; margin-top: 16px; border-left: 4px solid var(--green); }
.fp-over.is-high { border-left-color: var(--red); }
.fp-over-text { flex: 1 1 420px; min-width: 0; }
.fp-over-text p { margin: 6px 0 0; font: 400 13.5px/1.6 var(--sans); color: var(--muted); max-width: 760px; }
.fp-over-text .fp-over-lead { font: 600 15px/1.45 var(--sans); color: var(--ink); }
.fp { display: flex; flex-direction: column; gap: 14px; }
.fp-stats { margin: 0; }
.fp-legend { display: flex; flex-wrap: wrap; gap: 10px 22px; padding: 12px 14px; background: var(--surface); border: 1px solid var(--border); border-radius: 4px; }
.fp-legend > div { display: flex; gap: 8px; align-items: baseline; flex: 1 1 240px; font: 400 13px/1.5 var(--sans); color: var(--muted); }
.fp-mode { display: inline-block; padding: 3px 8px; border-radius: 999px; font: 600 11px/1.4 var(--sans); letter-spacing: .05em; text-transform: uppercase; white-space: nowrap; }
.fp-mode.m-stop { background: var(--red-tint); color: var(--red); }
.fp-mode.m-skip { background: var(--amber-tint); color: var(--amber-deep); }
.fp-mode.m-caught { background: var(--green-tint); color: var(--green-deep); }
.fp-mode.m-none { background: var(--soft); color: var(--muted); }
.fp-toggle { display: inline-flex; gap: 6px; align-items: center; font: 400 13px/1.4 var(--sans); color: var(--muted); cursor: pointer; }
.fp-list { display: flex; flex-direction: column; gap: 10px; }
.fp-flow { background: var(--surface); border: 1px solid var(--border); border-left: 4px solid var(--border); border-radius: 4px; }
.fp-flow.sev-high { border-left-color: var(--red); }
.fp-flow.sev-medium { border-left-color: var(--amber); }
.fp-flow-head { display: flex; gap: 12px; align-items: flex-start; width: 100%; padding: 12px 14px; border: none; background: transparent; text-align: left; cursor: pointer; color: var(--ink); flex-wrap: wrap; }
.fp-flow-head:hover .fp-flow-main b { color: var(--green-deep); }
.fp-flow-head:focus-visible { outline: 2px solid var(--green); outline-offset: -2px; }
.fp-caret { font: 400 12.5px/1.6 var(--mono); color: var(--muted); width: 12px; }
.fp-flow-main { flex: 1 1 360px; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.fp-flow-main b { font: 600 14px/1.4 var(--sans); color: var(--ink); overflow-wrap: anywhere; }
.fp-flow-sub { font: 400 12.5px/1.5 var(--sans); color: var(--muted); }
.fp-counts { display: flex; gap: 6px; flex-wrap: wrap; }
.fp-count { padding: 2px 8px; border-radius: 999px; font: 600 11.5px/1.5 var(--sans); white-space: nowrap; }
.fp-count.c-high { background: var(--red-tint); color: var(--red); }
.fp-count.c-silent { background: var(--amber-tint); color: var(--amber-deep); }
.fp-worst { margin: 0 14px 12px 38px; font: 400 13px/1.6 var(--sans); color: var(--ink2); max-width: 820px; }
.fp-worst b { color: var(--ink); font-weight: 600; }
.fp-body { padding: 4px 14px 14px 38px; border-top: 1px solid var(--soft); }
.fp-path-h { margin: 14px 0 8px; font: 600 11.5px/1.4 var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.fp-steps { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.fp-step { border: 1px solid var(--soft); border-left: 3px solid var(--soft); border-radius: 3px; padding: 9px 11px; background: var(--surface); }
.fp-step.sev-high { border-left-color: var(--red); }
.fp-step.sev-medium { border-left-color: var(--amber); }
.fp-step.sev-low { border-left-color: var(--strong); }
.fp-row { display: flex; gap: 10px; align-items: flex-start; flex-wrap: wrap; }
.fp-n { display: inline-block; min-width: 20px; font: 500 12px/1.7 var(--mono); color: var(--faint); font-variant-numeric: tabular-nums; }
.fp-what { flex: 1 1 300px; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.fp-what b { font: 600 13.5px/1.4 var(--sans); color: var(--ink); overflow-wrap: anywhere; }
.fp-meta { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.fp-sys { font: 500 11.5px/1.5 var(--mono); color: var(--ink2); background: var(--soft); border-radius: 2px; padding: 1px 6px; }
.fp-kind { font: 400 12.5px/1.4 var(--sans); color: var(--muted); }
.fp-kind.is-access { color: var(--ink2); font-weight: 500; }
.fp-tgt { font: 400 12px/1.4 var(--mono); color: var(--muted); overflow-wrap: anywhere; }
.fp-ctx { font: 400 12px/1.5 var(--sans); color: var(--faint); }
.fp-verdict { margin: 6px 0 0 30px; font: 400 13px/1.55 var(--sans); color: var(--ink2); max-width: 760px; }
.fp-sev { display: inline-block; margin-right: 7px; padding: 1px 5px; border-radius: 2px; font: 600 10.5px/1.5 var(--mono); letter-spacing: .06em; text-transform: uppercase; background: var(--soft); color: var(--muted); }
.sev-high > .fp-verdict .fp-sev { background: var(--red-tint); color: var(--red); }
.sev-medium > .fp-verdict .fp-sev { background: var(--amber-tint); color: var(--amber-deep); }
.fp-actions { display: flex; gap: 14px; flex-wrap: wrap; margin: 4px 0 0 30px; }
.fp-state { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin: 8px 0 0 30px; padding-top: 8px; border-top: 1px dashed var(--soft); }
.fp-state h5 { margin: 0 0 6px; font: 600 11px/1.4 var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.fp-grp { margin-bottom: 6px; }
.fp-grp ul, .fp-rerun ul { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.fp-grp li, .fp-rerun li { font: 400 13px/1.5 var(--sans); color: var(--ink2); }
.fp-none { margin: 0; font: 400 13px/1.5 var(--sans); color: var(--faint); }
.fp-rerun { grid-column: 1 / -1; }
.fp-foot { margin-top: 12px; }
.fp-limits { font: 400 13px/1.6 var(--sans); color: var(--muted); }
.fp-limits summary { cursor: pointer; color: var(--green-deep); font-weight: 500; }
.fp-limits ul { margin: 6px 0 0; padding-left: 18px; max-width: 780px; }
@media (max-width: 760px) {
  .fp-state { grid-template-columns: 1fr; margin-left: 0; }
  .fp-verdict, .fp-actions { margin-left: 0; }
  .fp-body { padding-left: 14px; }
  .fp-worst { margin-left: 14px; }
}

/* ── 5.22 Lens install ───────────────────────────────────────────────── */
.lens-install { margin: 12px 0 16px; padding: 12px 14px; border: 1px solid var(--green-line); border-radius: 4px; background: var(--green-wash); }
.lens-install-head { display: flex; gap: 12px; align-items: center; justify-content: space-between; flex-wrap: wrap; }
.lens-install-head h3 { margin: 0; font: 600 14px/1.4 var(--sans); color: var(--ink); }
.lens-install-none { font: 400 13px/1.5 var(--sans); color: var(--muted); }
.lens-steps { margin: 10px 0 0; padding-left: 20px; display: flex; flex-direction: column; gap: 5px; font: 400 13px/1.55 var(--sans); color: var(--ink2); }
.lens-steps code, .lens-install code { font: 400 12.5px/1.4 var(--mono); background: var(--surface); border: 1px solid var(--border); border-radius: 2px; padding: 0 4px; }
.lens-install-note { margin: 8px 0 0; font: 400 12.5px/1.5 var(--sans); color: var(--muted); }
.lens-dl { display: flex; gap: 8px; flex-wrap: wrap; }
.lens-local { display: flex; gap: 6px; align-items: flex-start; margin-top: 8px; font: 400 13px/1.5 var(--sans); color: var(--muted); }

/* ── 5.24 Assist ─────────────────────────────────────────────────────── */
.bar-count { display: inline-block; margin-left: 6px; min-width: 16px; padding: 0 5px; border-radius: 999px; background: var(--amber); color: var(--on-tone); font: 600 11px/16px var(--mono); text-align: center; }
.as-tabs { display: flex; flex-wrap: wrap; gap: 2px; border-bottom: 1px solid var(--border); margin: 0 0 16px; }
.as-tab { border: 0; border-bottom: 2px solid transparent; background: none; padding: 9px 14px; font: 500 13px/1.3 var(--sans); color: var(--muted); cursor: pointer; margin-bottom: -1px; }
.as-tab:hover { color: var(--ink); }
.as-tab.on { color: var(--ink); border-bottom-color: var(--green); font-weight: 600; }
.as-tab .bar-count { vertical-align: 1px; }
.as-ta { resize: vertical; min-height: 64px; font-size: 14px; line-height: 1.5; }
.as-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 12px; }
.as-row .field { flex: 1 1 320px; }
.as-pats { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 16px; }
.as-pats .field-label { width: 100%; margin: 0; }
.as-pat { border: 1px solid var(--border); background: var(--sunk); border-radius: 999px; padding: 5px 12px; font: 500 13px/1.3 var(--sans); color: var(--ink); cursor: pointer; }
.as-pat:hover { border-color: var(--green); color: var(--green-deep); background: var(--green-tint); }
.as-busy { display: flex; align-items: center; gap: 8px; color: var(--muted); font: 400 13px/1.4 var(--sans); }
.as-spin { width: 13px; height: 13px; border: 2px solid var(--border); border-top-color: var(--green); border-radius: 50%; animation: as-spin .8s linear infinite; }
@keyframes as-spin { to { transform: rotate(360deg); } }
.as-plan-head { display: grid; grid-template-columns: 1fr minmax(200px, 300px); gap: 20px; }
.as-plan-meta { font: 400 13px/1.7 var(--sans); color: var(--muted); border-left: 1px solid var(--border); padding-left: 16px; }
.as-plan-meta b { color: var(--ink); font-weight: 600; }
.as-flow-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.as-flow-head h3 { margin: 0 !important; text-transform: none !important; letter-spacing: 0 !important; font: 600 14px/1.35 var(--sans) !important; color: var(--ink) !important; }
.as-flow .lede { margin: 6px 0 10px; }
.as-steps { list-style: none; margin: 0; padding: 0; counter-reset: none; }
.as-steps > li { display: grid; grid-template-columns: 28px 1fr; gap: 10px; padding: 10px 0; border-top: 1px dashed var(--soft); }
.as-steps > li:first-child { border-top: 0; }
.as-n { width: 24px; height: 24px; border-radius: 50%; border: 1px solid var(--border); background: var(--sunk); display: grid; place-items: center; font: 600 12px/1 var(--mono); color: var(--muted); }
.as-start .as-n { background: var(--green-tint); border-color: var(--green-line); color: var(--green-deep); }
.as-step-top { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.as-card { display: inline-block; padding: 3px 9px; border-radius: 3px; border: 1px solid var(--navy-line); background: var(--navy-tint); color: var(--navy); font: 600 13px/1.35 var(--sans); }
.as-acc { font: 500 11px/1.5 var(--mono); text-transform: uppercase; letter-spacing: .04em; padding: 1px 6px; border-radius: 3px; border: 1px solid var(--border); color: var(--muted); }
.as-acc-grant { border-color: var(--amber-line); background: var(--amber-tint); color: var(--amber-deep); }
.as-acc-revoke { border-color: var(--red-line); background: var(--red-wash); color: var(--red-text); }
.as-what { margin-top: 5px; font: 400 13.5px/1.5 var(--sans); color: var(--ink); }
.as-cfg { margin: 5px 0 0; padding-left: 18px; font: 400 13px/1.55 var(--sans); color: var(--muted); }
.as-onerr { display: inline-block; margin-top: 6px; padding: 3px 8px; border-radius: 3px; background: var(--red-wash); border: 1px solid var(--red-line); color: var(--red-text); font: 400 13px/1.45 var(--sans); }
.as-note { margin-top: 4px; font: 400 13px/1.5 var(--sans); color: var(--faint); }
.as-two { display: grid; grid-template-columns: 1.4fr 1fr; gap: 16px; }
.as-two > .panel:only-child { grid-column: 1 / -1; }
.as-list { margin: 0; padding-left: 18px; font: 400 13.5px/1.6 var(--sans); color: var(--ink); }
.as-fine { margin: 4px 0 0; padding-left: 18px; font: 400 13px/1.6 var(--sans); color: var(--faint); }
.as-tailored { border-top: 2px solid var(--navy) !important; }
.as-unk { color: var(--amber-deep); }
.as-picks { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 14px; }
.as-pick { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 12px; border: 1px dashed var(--strong); border-radius: 4px; background: var(--sunk); }
.as-pick .field-label { width: 100%; margin: 0; }
.as-file { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.as-pickbtn { padding: 6px 11px; border: 1px solid var(--strong); border-radius: 3px; background: var(--surface); font: 600 12.5px/1.4 var(--sans); cursor: pointer; }
.as-files { font: 400 13px/1.4 var(--mono); color: var(--muted); overflow-wrap: anywhere; }
.as-vmeta { margin-top: 6px; font: 400 12.5px/1.4 var(--sans); opacity: .85; }
tr.as-add td:first-child { box-shadow: inset 3px 0 0 var(--green); }
tr.as-mod td:first-child { box-shadow: inset 3px 0 0 var(--amber); }
tr.as-rm td:first-child { box-shadow: inset 3px 0 0 var(--red); }
.as-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--muted); vertical-align: 0; }
.as-critical { background: var(--red); } .as-high { background: var(--red); opacity: .85; } .as-medium { background: var(--amber); } .as-low { background: var(--navy); }
.as-click { cursor: pointer; }
.as-click:hover td { background: var(--sunk); }
.as-v, .as-st { display: inline-block; padding: 1px 7px; border-radius: 3px; font: 500 11.5px/1.6 var(--mono); text-transform: uppercase; letter-spacing: .04em; border: 1px solid var(--border); color: var(--muted); }
.as-v-block, .as-st-rejected { border-color: var(--red-line); background: var(--red-wash); color: var(--red-text); }
.as-v-review, .as-st-pending { border-color: var(--amber-line); background: var(--amber-tint); color: var(--amber-deep); }
.as-v-clear, .as-st-approved { border-color: var(--green-line); background: var(--green-tint); color: var(--green-deep); }
.as-decide { border-top: 2px solid var(--amber) !important; }
.as-ack { display: flex; gap: 8px; align-items: baseline; margin: 6px 0; font: 400 13.5px/1.5 var(--sans); cursor: pointer; }
.as-grade { color: var(--on-tone); font: 700 14px/1 var(--sans); padding: 5px 9px; border-radius: 3px; background: var(--muted); }
.as-g-A { background: var(--green); } .as-g-B { background: var(--green-text); } .as-g-C { background: var(--amber); } .as-g-D { background: var(--red); } .as-g-E, .as-g-F { background: var(--red-text); }
.as-prose { white-space: pre-wrap; font: 400 14px/1.65 var(--sans); background: var(--sunk); border: 1px solid var(--border); border-radius: 4px; padding: 12px 14px; margin: 8px 0 12px; }
.as-kv { display: grid; grid-template-columns: 110px 1fr; gap: 6px 14px; margin: 12px 0; font: 400 13.5px/1.5 var(--sans); }
.as-kv dt { color: var(--faint); font-weight: 500; }
.as-kv dd { margin: 0; color: var(--ink); }
.as-det summary { cursor: pointer; color: var(--green-deep); font: 500 13px/1.4 var(--sans); margin-top: 10px; }
.as-narr { margin: 8px 0 0; padding-left: 22px; font: 400 13px/1.6 var(--sans); color: var(--muted); }
.as-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 16px; }
.as-cardx p { margin: 8px 0; font: 400 13.5px/1.55 var(--sans); }
.as-form { display: grid; grid-template-columns: 1fr 1fr; gap: 14px 16px; margin-top: 16px; max-width: 760px; }
.as-form .as-row, .as-form .as-ack { grid-column: 1 / -1; }
@media (max-width: 760px) {
  .as-plan-head, .as-two, .as-picks, .as-form { grid-template-columns: 1fr; }
  .as-plan-meta { border-left: 0; padding-left: 0; }
}
.lens-toggle { border: 1px solid var(--border); background: var(--sunk); border-radius: 999px; padding: 1px 10px; font: 500 12px/1.6 var(--mono); color: var(--muted); cursor: pointer; text-transform: uppercase; }
.lens-toggle.on { border-color: var(--green-line); background: var(--green-tint); color: var(--green-deep); }
/* 5.24.3 — examples from Okta's templates */
.ax-det { margin-top: 12px; border-top: 1px dashed var(--border); padding-top: 8px; }
.ax-det > summary { cursor: pointer; font: 600 13px/1.4 var(--sans); color: var(--amber-deep); }
.ax-tech { margin-top: 12px; }
.ax-t { font: 600 14px/1.4 var(--sans); color: var(--ink); }
.ax-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 340px), 1fr)); gap: 10px; margin-top: 8px; }
.ax-one { min-width: 0; overflow-wrap: anywhere; border: 1px solid var(--border); background: var(--sunk); border-radius: 4px; padding: 10px; }
.ax-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.ax-c { display: inline-block; padding: 2px 8px; border-radius: 3px; border: 1px solid var(--border); background: var(--surface); font: 600 12.5px/1.4 var(--sans); color: var(--ink); }
.ax-c.dim { color: var(--faint); font-weight: 500; }
.ax-c.acc { border-color: var(--red-line); background: var(--red-wash); color: var(--red-text); }
.ax-c.ext { border-color: var(--navy-line); background: var(--navy-tint); color: var(--navy); }
.ax-c.flow { border-style: dashed; }
.ax-c.hi { border-color: var(--amber); color: var(--amber-deep); }
.ax-arr { font: 400 12.5px/1 var(--sans); color: var(--faint); }
.ax-arr.err { color: var(--red); }
.ax-badge { font: 600 12px/1.5 var(--mono); color: var(--amber-deep); background: var(--amber-tint); border: 1px solid var(--amber-line); border-radius: 999px; padding: 1px 8px; }
.ax-box { min-width: 0; max-width: 100%; border: 1.5px solid var(--amber); border-radius: 4px; padding: 5px 7px; background: var(--surface); display: grid; gap: 4px; }
.ax-hd { font: 700 11px/1.3 var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--amber-deep); }
.ax-half { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; padding: 3px 5px; border-radius: 3px; background: var(--green-wash); }
.ax-half.err { background: var(--red-wash); }
.ax-lbl { font: 600 10.5px/1.3 var(--mono); text-transform: uppercase; color: var(--faint); margin-right: 2px; }
.ax-shows { margin-top: 7px; font: 400 13px/1.5 var(--sans); color: var(--muted); }
/* 5.24.5 — numbered starts, and the walk across every start */
.arch-start-n { font: 700 12px/1 var(--mono); fill: var(--on-tone); }
.arch-tour p { margin: 0 0 4px; }
.arch-tour-list { margin: 4px 0 6px; padding: 0; list-style: none; display: grid; gap: 3px; }
.arch-tour-list li { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
.arch-start-no { display: inline-grid; place-items: center; min-width: 18px; height: 18px; border-radius: 50%; background: var(--ink); color: var(--on-tone); font: 700 11.5px/1 var(--mono); }
/* 5.24.6 — the walk note is one line; its detail folds away */
details.arch-tour { padding: 6px 12px; }
details.arch-tour > summary { cursor: pointer; list-style: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
details.arch-tour > summary::-webkit-details-marker { display: none; }
details.arch-tour > summary b { font: 600 12.5px/1.5 var(--sans); }
.arch-tour-more { margin-left: 10px; color: var(--green-deep); text-decoration: underline; text-underline-offset: 2px; font-size: 12.5px; }
details.arch-tour[open] .arch-tour-more { display: none; }
details.arch-tour[open] > summary { white-space: normal; }
.arch-tour-list { max-height: 180px; overflow: auto; margin: 6px 0; }
.arch-tour-start { font: 600 12.5px/1.5 var(--sans); color: var(--ink); }
.arch-one { padding: 6px 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* a tighter toolbar, so the diagram starts higher on the screen */
.arch-tools { gap: 8px; padding-top: 7px; padding-bottom: 7px; }
.arch-tools .btn-ghost { padding: 4px 8px; font-size: 11.5px; }
.arch-legend-row { padding-top: 7px; padding-bottom: 7px; }
/* 5.24.6 — the walk bar: what is being walked, and every control for it, right above the diagram */
.arch-walkbar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 5px 10px; border: 1px solid var(--border); border-bottom: 0; border-radius: 4px 4px 0 0; background: var(--sunk); }
.arch-walk-note { flex: 1 1 380px; min-width: 0; }
.arch-walk-note .arch-trace-note { border: 0; padding: 0; background: none; }
.arch-walk-ctl { display: inline-flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-left: auto; }
.arch-walk-ctl .btn-ghost { padding: 4px 8px; font-size: 11.5px; }
.arch-walk-ctl .arch-pace-r { width: 90px; }
details.arch-tour[open] { flex-basis: 100%; }
/* 5.24.6 — zoom and full screen on the diagram, bottom right, faint until needed */
.arch-stage { position: relative; }
.arch-stagectl { position: absolute; right: 16px; bottom: 16px; z-index: 3; display: flex; align-items: center; gap: 2px;
  padding: 3px; border: 1px solid var(--border); border-radius: 6px; background: var(--surface);
  box-shadow: 0 2px 8px rgba(0,0,0,.12); opacity: .45; transition: opacity .15s; }
.arch-stage:hover .arch-stagectl, .arch-stagectl:focus-within { opacity: 1; }
.arch-stagectl .sc-btn, .arch-stagectl .sc-val { border: 0; background: none; cursor: pointer; border-radius: 4px;
  min-width: 28px; height: 28px; padding: 0 6px; font: 600 14px/28px var(--sans); color: var(--ink); }
.arch-stagectl .sc-val { font: 500 12.5px/28px var(--mono); color: var(--muted); min-width: 46px; }
.arch-stagectl .sc-fit { font: 600 11.5px/28px var(--sans); letter-spacing: .04em; color: var(--muted); }
.arch-stagectl .sc-full { font-size: 16px; }
.arch-stagectl button:hover { background: var(--sunk); }
.arch-stagectl .on { color: var(--green-deep); }
body.arch-full .arch-stage { flex: 1 1 auto; display: flex; min-height: 0; }
body.arch-full .arch-stage .arch-scroll { flex: 1 1 auto; }
/* 5.24.6 — the scroll box is the canvas: same white as the diagram, so the space below
   a short diagram (and in full screen) reads as more canvas, not a separate grey panel */
.arch-scroll { background: var(--surface); }
/* 5.24.7 — the flow page gives the map the screen */
.fp-head { padding: 14px 18px 0; gap: 12px; align-items: center; }
.fp-grade { width: 38px; height: 38px; font-size: 18px; }
.fp-title h1.h-serif { font-size: 22px; line-height: 1.2; margin: 0 0 6px; }
.fp-title .map-facts { gap: 5px; margin: 0 0 4px; }
.fp-title .fact-pill { padding: 2px 8px; font-size: 12.5px; }
.fp-head .fp-tabs { flex: 1 1 100%; margin: 6px -18px 0; padding: 0 12px; border-bottom: 0; border-top: 1px solid var(--border); }
.fp-head .fp-tab { padding: 9px 12px 8px; }
.flowpage > .panel.fp-head { margin-bottom: 10px; }
.map-one { gap: 8px 16px; padding: 7px 12px; }
.map-one .tbtn { padding: 4px 9px; font-size: 12.5px; }
.map-one .seg button { padding: 4px 10px; font-size: 12.5px; }
.map-one .tgroup-t { font-size: 10.5px; }
.fsum { display: inline-flex; gap: 8px; align-items: center; }
.fsum > span { display: inline-flex; align-items: center; gap: 4px; }
/* on-canvas zoom, fit, rows, dark and full screen — bottom right, faint until needed */
.canvas-stage { position: relative; }
.map-stagectl { position: absolute; right: 18px; bottom: 16px; z-index: 5; display: flex; align-items: center; gap: 2px;
  padding: 3px; border: 1px solid var(--border); border-radius: 6px; background: var(--surface);
  box-shadow: 0 2px 8px rgba(0,0,0,.12); opacity: .45; transition: opacity .15s; }
.canvas-stage:hover .map-stagectl, .map-stagectl:focus-within { opacity: 1; }
.map-stagectl button { border: 0; background: none; cursor: pointer; border-radius: 4px; height: 28px; padding: 0 7px; color: var(--ink); }
.map-stagectl .sc-btn { min-width: 28px; font: 600 14px/28px var(--sans); }
.map-stagectl .sc-val { min-width: 46px; font: 500 12.5px/28px var(--mono); color: var(--muted); }
.map-stagectl .sc-txt { font: 600 12px/28px var(--sans); color: var(--muted); }
.map-stagectl .sc-full { font-size: 16px; }
.map-stagectl button:hover { background: var(--sunk); }
.map-stagectl .on { color: var(--green-deep); }
body.map-full .canvas-stage { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; }
body.map-full .canvas-stage > .canvas, body.map-full .canvas-stage > .canvas-split { flex: 1 1 auto; min-height: 0; }
/* The panel sticks to the bottom of the window while the canvas runs past it,
   so zoom and full screen are in reach without scrolling to the canvas's end. */
.canvas-stage, .arch-stage { display: flex; flex-direction: column; }
/* 5.29: the overlap is made by the CANVAS's negative bottom margin, not the
   panel's negative top margin. A sticky element may be shifted up to, but not
   past, its containing block less its own margins — so a panel with
   margin-top: -50px was allowed 50px ABOVE the stage, which put it over the
   toolbar's last button ("Show failure paths") and over the runtime map's
   scope note. With the margin on the canvas instead, the stage ends where the
   panel does and the panel can rise no higher than the picture's top edge. */
.canvas-stage > .canvas, .canvas-stage > .canvas-split, .arch-stage > .arch-scroll { margin-bottom: -50px; }
.map-stagectl, .arch-stagectl { position: sticky; top: auto; bottom: 16px; right: auto; align-self: flex-end;
  margin: 0 18px 16px 0; opacity: .92; }
body.map-full .canvas-stage > .canvas, body.map-full .canvas-stage > .canvas-split, body.arch-full .arch-stage > .arch-scroll { margin-bottom: 0; }
body.map-full .map-stagectl, body.arch-full .arch-stagectl { position: absolute; right: 18px; bottom: 16px; margin: 0; }
/* 5.24.7 — intros use the width they have.
   Section intros put the heading and its sentence on one line; panel intros and
   leads run the full width of their panel. Long body text (fix steps, finding
   evidence, help) keeps its own measure, because that is read, not scanned. */
.section-intro { padding-bottom: 10px; margin-bottom: 14px; }
.section-intro > div { display: flex; align-items: baseline; gap: 4px 18px; flex-wrap: wrap; min-width: 0; flex: 1 1 auto; }
.section-intro h2 { flex: none; }
.section-intro p { margin: 0; flex: 1 1 360px; max-width: none; }
.main .lede, .rhead p, .map-head-row > div:first-child, .fp-over-text p, .state-note, .notice-text,
.cmp-head p, .prog-head .lede, .boundary span, .rt-hero p, .grade-why, .gk-head span { max-width: none; }
.rhead-top > div:first-child { flex: 1 1 480px; min-width: 0; }
.main .lede { margin-bottom: 14px; }
/* flow page: the picker sits in the tab row, so the facts get the header's whole width */
.fp-tabs .fp-pick { margin-left: auto; align-self: center; flex: 0 1 360px; padding: 4px 0; }
/* the report uses a wide screen: it was held to 1640px with empty margins either side */
.report-body { max-width: 1920px; }

/* ── 5.25 · the Lens page, key requests, support access, the plan ─────────── */
.lensdesk, .page-wrap.lensdesk { max-width: 1240px; }
.phead { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; flex-wrap: wrap; }
.phead > div:first-child { min-width: 280px; flex: 1 1 520px; }
.phead-act { display: flex; align-items: center; gap: 10px; padding-bottom: 6px; }
.pstats { margin-bottom: 16px; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }
.pcharts { display: grid; grid-template-columns: repeat(auto-fit, minmax(380px, 1fr)); gap: 16px; }
.pcols { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 16px; align-items: start; }
.pchart { position: relative; }
.pchart-read { display: flex; gap: 14px; align-items: center; min-height: 18px; margin: -4px 0 6px;
  font: 500 13px/1.4 var(--sans); color: var(--muted); font-variant-numeric: tabular-nums; }
.pchart-read b { color: var(--ink); font-weight: 600; }
.pchart-read span { display: inline-flex; align-items: center; gap: 5px; }
.pc-sw { width: 9px; height: 9px; flex: none; }
.pchart-svg { display: block; width: 100%; height: auto; overflow: visible; }
.pc-grid { stroke: var(--soft); stroke-width: 1; }
.pc-axis { stroke: var(--strong); stroke-width: 1; }
.pc-tick { font: 400 11px/1 var(--mono); fill: var(--faint); }
.pc-hit { fill: transparent; cursor: default; outline: none; }
.pc-hover { fill: var(--sunk); }
.ptable { width: 100%; }
.ptable th.num, .ptable td.num { text-align: right; font-variant-numeric: tabular-nums; }
.pnote { max-width: 96ch; line-height: 1.6; }
.pkept .lens-std-actions { justify-content: flex-start; align-items: center; }
.preq h3 .bar-count { margin-left: 8px; }
.preq-link { margin: 10px 0 14px; max-width: 640px; }
.preq-note { max-width: 260px; color: var(--muted); }
.preq-act { white-space: nowrap; text-align: right; }
.preq-act .btn-green { margin-right: 6px; }
.psupport-form { align-items: end; }
.psupport-on { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 12px 14px; margin: 4px 0 10px;
  border: 1px solid var(--amber-line); border-left: 3px solid var(--amber); background: var(--amber-tint); border-radius: 4px;
  font: 400 13.5px/1.5 var(--sans); color: var(--amber-text); }
.psupport-log > td { background: var(--sunk); padding: 6px 10px 10px; }
.psupport-log code { font-size: 12.5px; }
.banner.banner-support { display: flex; align-items: center; justify-content: space-between; gap: 16px;
  background: var(--amber-tint); border-bottom: 2px solid var(--amber); color: var(--amber-text); }
.banner-support .btn-link { font-size: 13px; font-weight: 600; color: var(--amber-deep); text-decoration: underline; text-underline-offset: 2px; }
.plan-chip { margin-left: 18px; padding: 4px 10px; border: 1px solid rgba(255,255,255,.22); border-radius: 999px;
  font: 600 12px/1.4 var(--sans); letter-spacing: .04em; text-transform: uppercase; color: rgba(255,255,255,.82); white-space: nowrap; }
@media (max-width: 720px) { .pcharts { grid-template-columns: 1fr; } .phead-act { padding-bottom: 0; } }
.ptable th.num, .ptable td.num { padding-right: 18px; }

/* ── 5.26 ─────────────────────────────────────────────────────────────────
   Tiles that go somewhere, the filter they leave on a table, the developer
   view, plain-English logic, and the marking for a flow that is called but is
   not in the export. */

/* a tile that is the current filter */
.stat-link.on .stat { border-color: var(--green); box-shadow: inset 0 0 0 1px var(--green); background: var(--green-wash); }
.stat-link.on .stat-go { color: var(--ink); }
.stats.dev-stats, .stats.fp-stats { align-items: stretch; }

/* "Showing only …" — what a tile left behind, and the way out of it */
.tbl-filt { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 8px; margin: 0 0 10px; padding: 8px 12px;
  border: 1px solid var(--green-line); border-left: 3px solid var(--green); border-radius: 3px; background: var(--green-wash);
  font: 400 13px/1.5 var(--sans); color: var(--muted); }
.tbl-filt b { color: var(--ink); font-weight: 600; }
.tbl-filt-k { font: 600 11.5px/1.5 var(--sans); letter-spacing: .05em; text-transform: uppercase; color: var(--green-deep); }
.tbl-filt .btn-linkish { margin-left: auto; font-size: 13px; }

/* the numbers in the context bar are tiles too */
.ctx-go { all: unset; cursor: pointer; font: inherit; color: inherit; border-radius: 2px; border-bottom: 1px dotted var(--strong); }
.ctx-go:hover { border-bottom-color: var(--green); color: var(--ink); }
.ctx-go:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }
button.ctx-stat.ctx-go { border-bottom: none; text-decoration: underline dotted var(--strong); text-underline-offset: 3px; }
button.ctx-stat.ctx-go:hover { text-decoration-color: var(--green); }

/* who is reading */
.seg-lang button { font: 600 12px/1.5 var(--sans); }
.side-note { margin-top: 12px; padding: 10px 12px; border: 1px dashed var(--border); border-radius: 3px; font: 400 12px/1.6 var(--sans); color: var(--faint); }

/* where a tile's answer is further down the same page */
@keyframes tile-landed { from { box-shadow: 0 0 0 3px var(--green-line); } to { box-shadow: 0 0 0 3px transparent; } }
.tile-landed { animation: tile-landed 1.4s ease-out 1; }
/* reduced motion: `.tile-landed` is switched off in the stylesheet's one reduced-motion block */

/* the fix, in the finding's own words */
.fx-fix { margin: 0 0 8px !important; color: var(--ink) !important; font-weight: 500 !important; }

/* ── plain English ── */
.prose { border: 1px solid var(--border); border-radius: 3px; background: var(--surface); padding: 6px 18px 16px; max-height: 62vh; overflow: auto; }
.prose-flow + .prose-flow { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--border); }
.prose-h { display: flex; align-items: center; gap: 10px; margin-top: 12px; }
.prose-h b { font: 600 15px/1.35 var(--serif, "Spectral", Georgia, serif); color: var(--ink); }
.prose-start { margin: 4px 0 10px; font: 400 13px/1.6 var(--sans); color: var(--muted); }
.prose-steps { list-style: none; margin: 0; padding: 0; }
.prose-line { display: grid; grid-template-columns: 58px minmax(0, 1fr); gap: 10px; padding-top: 5px; padding-bottom: 5px; border-top: 1px solid var(--soft); }
.prose-line:first-child { border-top: none; }
.prose-n { font: 500 12.5px/1.75 var(--mono); color: var(--faint); text-align: right; white-space: nowrap; }
.prose-t { font: 400 14px/1.6 var(--sans); color: var(--ink); text-wrap: pretty; max-width: 86ch; }
.prose-note .prose-t { font-style: italic; color: var(--muted); }
.prose-miss .prose-t { color: var(--amber-deep); font-weight: 500; }
.prose-empty { font: 400 13px/1.6 var(--sans); color: var(--faint); }
@media print { .prose { max-height: none; overflow: visible; } }

/* ── the developer's page ── */
.dev .dev-stats { margin: 16px 0 14px; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
.dev-tools { margin-top: 4px; }
.dev-list { margin-top: 6px; }
.dev-flow { border: 1px solid var(--border); border-radius: 4px; background: var(--surface); margin-top: 12px; overflow: hidden; }
.dev-flow-h { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; padding: 11px 14px; background: var(--sunk); border-bottom: 1px solid var(--border); }
.dev-flow-t { min-width: 0; }
.dev-flow-t h2 { margin: 0; font: 600 14px/1.35 var(--sans); color: var(--ink); overflow-wrap: anywhere; }
.dev-flow-sub { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin-top: 3px; font: 400 12.5px/1.5 var(--sans); color: var(--muted); }
.dev-sev { padding: 1px 7px; border-radius: 999px; border: 1px solid var(--border); font: 600 11.5px/1.6 var(--sans); background: var(--surface); color: var(--muted); }
.dev-sev.sev-critical, .dev-sev.sev-high { border-color: var(--red-line); background: var(--red-tint); color: var(--red-text); }
.dev-sev.sev-medium { border-color: var(--amber-line); background: var(--amber-tint); color: var(--amber-text); }
.dev-flow-go { display: flex; gap: 6px; flex: none; }
.dev-item { border-top: 1px solid var(--soft); }
.dev-flow .dev-item:first-of-type { border-top: none; }
.dev-list > .dev-item { border: 1px solid var(--border); border-radius: 4px; background: var(--surface); margin-top: 8px; overflow: hidden; }
.dev-row { display: flex; align-items: stretch; gap: 10px; padding: 0 14px 0 0; }
.dev-main { all: unset; box-sizing: border-box; flex: 1; min-width: 0; cursor: pointer; display: grid;
  grid-template-columns: 78px minmax(0, 1.05fr) minmax(0, 1.25fr) 14px; gap: 6px 14px; align-items: start; padding: 11px 0 11px 14px; }
.dev-main:hover { background: var(--green-wash); }
.dev-main:focus-visible { outline: 2px solid var(--green); outline-offset: -2px; }
.dev-main .badge { justify-self: start; margin-top: 2px; }
.dev-what { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.dev-what b { font: 600 13.5px/1.45 var(--sans); color: var(--ink); overflow-wrap: anywhere; }
.dev-what i { font: 400 12.5px/1.5 var(--sans); font-style: normal; color: var(--muted); overflow-wrap: anywhere; }
.dev-fix { font: 400 13px/1.55 var(--sans); color: var(--ink2); text-wrap: pretty; overflow-wrap: anywhere; }
.dev-caret { font: 400 12.5px/1.9 var(--sans); color: var(--faint); }
.dev-map { align-self: center; margin-top: 0; flex: none; }
.dev-item.on > .dev-row { background: var(--green-wash); }
.dev-item .tr-detail { border-top: 1px solid var(--border); border-bottom: none; }
@media (max-width: 860px) {
  .dev-main { grid-template-columns: 70px minmax(0, 1fr) 14px; }
  .dev-fix { grid-column: 2 / 3; }
  .dev-row { flex-direction: column; padding: 0; }
  .dev-map { align-self: flex-start; margin: 0 0 11px 98px; }
}

/* ── called, but not in this export ── */
.badge-missing { background: var(--orange); }
.fl-missing { margin-top: 16px; padding: 12px 14px; border: 1px dashed var(--amber-line); border-radius: 4px; background: var(--amber-tint); }
.fl-missing-h { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.fl-missing-h b { font: 600 13.5px/1.4 var(--sans); color: var(--ink); }
.fl-missing p { margin: 6px 0 0; font: 400 13px/1.6 var(--sans); color: var(--amber-text); }
.cc-row .badge-missing { margin-left: 8px; }
.arch-node.missing .arch-name { fill: var(--orange-deep); font-style: italic; }
.arch-node.missing .arch-sub { fill: var(--orange-deep); }
.arch-missing-q { font: 700 14px/1 var(--sans); }

/* what an architecture tile counted */
.arch-tile-panel { margin-top: 12px; border: 1px solid var(--green-line); border-left: 3px solid var(--green); border-radius: 3px; background: var(--green-wash); padding: 10px 14px 6px; }
.arch-tile-h { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 4px; }
.arch-tile-h b { font: 600 13.5px/1.5 var(--sans); color: var(--ink); }
.arch-tile-row { display: grid; grid-template-columns: minmax(140px, 260px) minmax(0, 1fr) auto; gap: 4px 14px; align-items: baseline; padding: 6px 0; border-top: 1px solid var(--green-line); }
.arch-tile-row b { font: 600 13px/1.5 var(--sans); color: var(--ink); overflow-wrap: anywhere; }
.arch-tile-row span { font: 400 13px/1.5 var(--sans); color: var(--muted); overflow-wrap: anywhere; }
.arch-tile-row .btn-linkish { font-size: 13px; white-space: nowrap; }
@media (max-width: 720px) { .arch-tile-row { grid-template-columns: 1fr; } }
button.ctx-stat.ctx-go { font: 400 13px/1.3 var(--sans); color: var(--muted); white-space: nowrap; }
button.ctx-stat.ctx-go b { font: 700 13.5px/1 var(--sans); color: var(--ink); }
.ctx-stat .ctx-go b.t-red { color: var(--red); } .ctx-stat .ctx-go b.t-amber { color: var(--amber-deep); }
.role-chip.role-developer { border-color: rgba(120,160,220,.7); }
.score-go { cursor: pointer; }
.score-go:hover { border-color: var(--green); }
.score-go:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }

/* ══ 5.29 · dark theme, phones, keyboards ═════════════════════════════════
   The tokens at the top of this file now have a dark set. What follows is the
   handful of places where a token was not enough: controls the chrome adds
   after a render (core.js), the sticky panels, the tables, and the things a
   keyboard or a thumb needs that a mouse never did. */

/* ── the theme control (System / Light / Dark), in the top bar ────────── */
.theme-ctl { display: inline-flex; align-items: center; gap: 0; min-width: 0; margin-left: 2px; }
/* The half-disc glyph is decoration and costs 20px the bar does not have
   when the help drawer takes its column; the select's own words say what it
   is, and the caret says it opens. */
.theme-ctl-k { display: none; }
.theme-ctl select { appearance: none; -webkit-appearance: none; padding: 7px 20px 7px 7px; border: 1px solid transparent; border-radius: 4px;
  background: transparent; font: 500 13px/1.2 var(--sans); color: var(--on-bar-dim); cursor: pointer; min-height: 32px; }
/* The native caret is drawn by the chrome, so a small one is painted here. */
.theme-ctl { position: relative; }
.theme-ctl::after { content: ""; position: absolute; right: 8px; top: 50%; width: 5px; height: 5px; margin-top: -4px;
  border-right: 1.5px solid var(--on-bar-dim); border-bottom: 1.5px solid var(--on-bar-dim); transform: rotate(45deg); pointer-events: none; }
.theme-ctl select:hover { background: rgba(255,255,255,.08); color: var(--on-bar); }
.theme-ctl select:focus-visible { outline: 2px solid var(--bar-accent); outline-offset: 1px; }
/* A native <select> opens its list in the browser's own colours; color-scheme
   on :root keeps that list legible in dark mode. The options themselves are
   painted by the browser on the page's surface colour. */
.theme-ctl select option { color: var(--ink); background: var(--surface); }

/* ── focus: the one ring, on a <select> as well as a button ──────────── */
.select select:focus-visible, select:focus-visible, html.ui27 .select select:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; box-shadow: none; }
/* With the help drawer open the bar is 380px narrower; the build stamp and
   some of the search box give way so it stays one row at 1440. */
@media (min-width: 1180px) {
  #app-inner.help-open .topbar .buildsig { display: none; }
  #app-inner.help-open .gsearch { flex-basis: 130px; }
  #app-inner.help-open .topbar-right { flex: 1 1 0; min-width: 0; }
}

/* ── destructive buttons ─────────────────────────────────────────────── */
/* .btn-danger has existed since 5.0; the dangerous buttons were not using it.
   The ones a screen renders as .btn-ghost with a destructive label are picked
   up by the renderer where that file is ours, and listed for the rest. */
.btn-danger { border-color: var(--red-line); color: var(--red-text); background: var(--surface); }
.btn-danger:hover { background: var(--red-tint); border-color: var(--red); color: var(--red); }
.btn-danger:focus-visible { outline-color: var(--red); }

/* ── the upload receipt, when the file could not be read ─────────────── */
/* It was a quiet grey box whose second line was set in capitals — so an
   error about "notes.txt" said NOTES.TXT, which is not the file's name. The
   bad receipt reads as an error: red tint, the message in sentence case. */
.receipt.bad { border-color: var(--red-line); background: var(--red-tint); border-left: 3px solid var(--red); }
.receipt.bad .receipt-name { color: var(--red-deep); }
.receipt.bad .receipt-meta { text-transform: none; letter-spacing: 0; color: var(--red-text); }

/* ── tables ──────────────────────────────────────────────────────────── */
/* Words wrap at spaces; a word longer than its column breaks only then.
   `overflow-wrap: anywhere` let the browser break after any letter, which is
   what made the first column collapse to twelve pixels and spell its names
   downward. The wrapper's min-width is set by core.js from the column list. */
.td-text { overflow-wrap: break-word; word-break: normal; min-width: 0; }
.td-mono { overflow-wrap: break-word; word-break: normal; }
/* The table scrolls sideways inside its box; a shadow at the right edge says
   there is more, where a scrollbar may be hidden until it is touched. */
.tbl-scroll { background:
  linear-gradient(to right, var(--surface) 30%, transparent) left / 24px 100% no-repeat local,
  linear-gradient(to left, var(--surface) 30%, transparent) right / 24px 100% no-repeat local,
  linear-gradient(to right, rgba(0,0,0,.18), transparent) left / 18px 100% no-repeat scroll,
  linear-gradient(to left, rgba(0,0,0,.18), transparent) right / 18px 100% no-repeat scroll;
  background-color: var(--surface); }
/* The rows are transparent so the edge shadow above can show through them;
   the box behind them is the same surface colour they were painted in. */
.ui27 .tr, .ui27 .tr:nth-child(odd) { background: transparent; }
.ui27 .tr-openable:hover { background: var(--sunk); }
.ui27 .tr.on { background: var(--tone-tint); }
/* A sortable heading is a button: 32px tall so a thumb can press it. */
.th { min-height: 32px; padding: 7px 0; line-height: 18px; }
.tbl-head { padding-top: 4px; padding-bottom: 4px; }

/* ── the ? mark: 24px to see, 36px to hit ─────────────────────────────── */
.helpmark, .section-intro h2 .helpmark { position: relative; width: 24px; height: 24px; font-size: 13px; margin-left: 8px; }
.helpmark::before { content: ""; position: absolute; inset: -6px; border-radius: 50%; }
.si-help { position: relative; width: 24px; height: 24px; }
.si-help::before { content: ""; position: absolute; inset: -6px; border-radius: 50%; }

/* ── the bar's own buttons are 32px tall ─────────────────────────────── */
.topbar .btn-link { min-height: 32px; padding: 6px 4px; }
.bar-btn { min-height: 32px; }

/* ── the flow map's call-card buttons wrap inside the card ───────────── */
.card-flags .btn-payload { white-space: normal; max-width: 100%; padding: 4px 7px; text-align: left; line-height: 1.4; }

/* ── the sticky stage panel is solid ──────────────────────────────────── */
.map-stagectl, .arch-stagectl { background: var(--surface); color: var(--ink); box-shadow: 0 2px 8px rgba(0,0,0,.18), 0 0 0 1px var(--border); }
.map-stagectl button, .arch-stagectl .sc-btn, .arch-stagectl .sc-val { color: var(--ink); }
.map-stagectl .sc-val, .map-stagectl .sc-txt, .arch-stagectl .sc-val, .arch-stagectl .sc-fit { color: var(--muted); }
.map-stagectl .on, .arch-stagectl .on { color: var(--green-deep); }
.map-stagectl button:hover, .arch-stagectl button:hover { background: var(--sunk); }

/* ── the phone ───────────────────────────────────────────────────────── */
/* One row: the brand, the three modes, and Menu. Everything else in the bar
   — search, help, the workspace buttons, who you are, sign out, the theme —
   is a sheet under the bar that Menu opens. Only the bar is sticky; the
   context bar scrolls with the page, because the two together were 43% of a
   phone's height before the report began. The rail is a row with a visible
   edge, so it reads as something that scrolls. */
.bar-menu { display: none; }
@media (max-width: 760px) {
  .topbar, html.ui27 .topbar { flex-wrap: nowrap; align-items: center; column-gap: 8px; row-gap: 0; padding: 0 10px; min-height: 48px; }
  .topbar-left, html.ui27 .topbar-left { flex: 1 1 auto; flex-wrap: nowrap; column-gap: 8px; min-width: 0; overflow: hidden; }
  .topbar .brand, html.ui27 .topbar .brand { flex: none; }
  .topbar .modetabs, html.ui27 .topbar .modetabs { flex: 1 1 auto; min-width: 0; overflow-x: auto; scrollbar-width: none; }
  .topbar .modetabs::-webkit-scrollbar { display: none; }
  html.ui27 .topbar .modetab, .topbar .modetab { flex: none; min-height: 48px; padding: 0 7px; }
  html.ui27 .topbar .modetab b { font-size: 12.5px; }
  html.ui27 .topbar .modetab.on::after { left: 7px; right: 7px; }
  .topbar .brand-img, html.ui27 .topbar .brand-img { height: 22px; }
  .topbar .estate-id, .topbar .plan-chip { display: none; }
  .bar-menu { display: inline-flex; align-items: center; gap: 7px; flex: none; min-height: 36px; padding: 6px 10px;
    border: 1px solid var(--bar-line); border-radius: 6px; background: rgba(255,255,255,.04);
    font: 600 13px/1 var(--sans); color: var(--on-bar); cursor: pointer; }
  .bar-menu-i { width: 14px; height: 2px; background: currentColor; border-radius: 1px; box-shadow: 0 -5px 0 currentColor, 0 5px 0 currentColor; }
  .topbar.menu-open .bar-menu { background: rgba(255,255,255,.14); }
  @media (max-width: 420px) { .bar-menu { padding: 6px 9px; } .bar-menu-t { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); } }
  .topbar-right, html.ui27 .topbar-right { display: none; position: absolute; left: 0; right: 0; top: 100%;
    flex-direction: column; align-items: stretch; gap: 2px; padding: 8px 10px 12px;
    background: var(--bar); border-bottom: 1px solid var(--bar-line); box-shadow: 0 16px 30px rgba(0,0,0,.35); }
  .topbar.menu-open .topbar-right { display: flex; }
  .topbar-right .bar-btn, .topbar-right .btn-link, html.ui27 .topbar-right .bar-btn, html.ui27 .topbar-right .btn-link { width: 100%; margin: 0; padding: 10px 12px; text-align: left; font-size: 14px; }
  .topbar-right .bar-btn.bar-primary, html.ui27 .topbar-right .bar-btn.bar-primary { margin: 6px 0; text-align: center; }
  .topbar-right .gsearch, html.ui27 .topbar-right .gsearch { display: flex; flex: none; max-width: none; margin: 0 0 6px; }
  .topbar-right .trust-pill, html.ui27 .topbar-right .trust-pill { display: inline-flex; align-self: flex-start; margin: 4px 0; }
  .topbar-right .whoami, .topbar-right .role-chip, .topbar-right .buildsig { align-self: flex-start; margin: 4px 0 0; }
  .theme-ctl { align-self: stretch; margin: 6px 0 0; padding-top: 8px; border-top: 1px solid var(--bar-line); }
  .theme-ctl select { flex: 1 1 auto; }
  .theme-ctl::after { top: auto; bottom: 12px; }

  .ctxbar, html.ui27 .ctxbar { position: static; gap: 6px 14px; padding: 8px 12px; min-height: 0; }
  .ctxbar .ctx-scope, html.ui27 .ctxbar .ctx-scope { display: flex; flex: 1 1 100%; min-width: 0; }
  .ctx-scope .select, html.ui27 .ctx-scope .select { max-width: none; flex: 1 1 0; min-width: 0; }
  .ctx-scope .select select, html.ui27 .ctx-scope .select select { min-width: 0; max-width: none; }
  .ctxbar .menu, html.ui27 .ctxbar .menu { margin-left: auto; }

  /* The rail as a strip: a fade and a chevron at the right edge, so the
     places past the fold are not a secret. */
  .sidebar, html.ui27 .sidebar { position: relative; top: auto; }
  .sidebar::after { content: ""; position: absolute; top: 1px; right: 1px; bottom: 1px; width: 56px; pointer-events: none;
    border-radius: 0 10px 10px 0;
    background: linear-gradient(to right, transparent, var(--surface) 70%); }
  .sidebar::before { content: ""; position: absolute; right: 12px; top: 50%; z-index: 1; width: 7px; height: 7px; margin-top: -5px; pointer-events: none;
    border-top: 2px solid var(--muted); border-right: 2px solid var(--muted); transform: rotate(45deg); }
  .sidebar.rail-end::after, .sidebar.rail-end::before { display: none; }
  html.ui27 .side { padding-right: 48px; align-items: center; }
  html.ui27 .side-item { padding: 9px 12px; min-height: 36px; }
  html.ui27 .side-actions, .side-actions { display: none; }
  html.ui27 .side-demo { display: none; }
  /* Tables scroll inside their box, never the page. */
  .tbl-scroll { max-height: 70vh; }
  .report-body, .rt, .hist, .page-wrap { overflow-x: clip; }
}
/* The cascade fix for the column legend: design.css set 190px 1fr on the
   html.ui27 layer, which outranked the plain 760px rule above. Stated here with
   the same weight, inside the same media query, so a phone stacks the rows. */
@media (max-width: 760px) {
  html.ui27 .col-legend-row, .col-legend-row { grid-template-columns: 1fr; gap: 2px; }
}

/* ── one voice for the newer screens ─────────────────────────────────── */
/* Report sections set their title in Spectral; History, Team, Lens and Build
   & Fix had drifted to bare h1/h2 in Public Sans at whatever size the browser
   chose. The same two heading classes everywhere, and one eyebrow colour. */
.hist h1, .rt-strip h1 { font: 400 20px/1.2 var(--serif); letter-spacing: -.01em; }
.page-wrap .panel > h2, .forge .panel > h2, .forge .fx-head h2, .forge .fx-result h2,
.page-wrap h2:not(.h-serif):not(.h-serif-sm), .modal h2 { font: 500 22px/1.25 var(--serif); letter-spacing: -.01em; color: var(--ink); }
.page-wrap .panel > h2 { margin: 0 0 10px; }
.forge h3, .page-wrap .panel h3, .lens-std h3, .lens-install-head h3 { font: 600 14px/1.4 var(--sans); letter-spacing: 0; text-transform: none; color: var(--ink); }
.rt-eyebrow, .eyebrow, .rt .eyebrow, .hist .eyebrow, .page-wrap .eyebrow { color: var(--green-deep); }
/* The uppercase labels in Runtime and in the wizard rail follow the report:
   sentence case, Public Sans, the muted colour. */
.model-head, .boundary b, .canvas-foot, .code-foot, .rt-eyebrow, .receipt-meta, .receipt-state, .progress, .tbl-foot .count,
.box-m, .box-foot, .file-list-t, .howstep em, .findings-list .find-where, .login-build, .drop-over, .dropzone .over, .kv dt, .runfacts span, .diff-field {
  text-transform: none; letter-spacing: 0; }
.boundary b { font: 600 12.5px/1.5 var(--sans); }
.matchrow .mr-k { text-transform: none; letter-spacing: 0; font-weight: 600; }
.page-wrap .lens-keys td .btn-ghost + .btn-danger, .lens-keys td .btn-ghost + .btn-danger { margin-left: 6px; }
.model-head { font: 600 12.5px/1.4 var(--sans); }
/* The Assist tabs match the sub-tabs over a table. */
.as-tabs { gap: 2px; padding: 3px; border: none; border-bottom: none; border-radius: 8px; background: var(--soft); margin: 0 0 16px; align-self: flex-start; display: inline-flex; }
.as-tab { padding: 6px 13px; border: none; border-radius: 6px; margin: 0; font: 600 13px/1.4 var(--sans); color: var(--muted); }
.as-tab.on { background: var(--surface); color: var(--ink); border-bottom: none; box-shadow: 0 1px 2px rgba(0,0,0,.12), 0 0 0 1px rgba(0,0,0,.04); }
/* The explore page takes the app's type and controls. */
body.explore { font-family: var(--sans); color: var(--ink); }
body.explore .wrap { max-width: 1180px; margin: 0 auto; padding: 26px 20px 60px; }
.explore-intro h1 { font: 500 clamp(26px, 3vw, 34px)/1.15 var(--serif); letter-spacing: -.015em; color: var(--ink); }
.explore-intro p, .explore-cta p { font: 400 14px/1.65 var(--sans); color: var(--muted); }
.explore-cta h2 { font: 500 22px/1.25 var(--serif); color: var(--ink); }
.explore-promise h2 { color: var(--green-deep); }
.explore-promise li, .explore-confirm, .explore-files { color: var(--ink2); }

/* ── reduced motion already covers the diagrams; the theme change itself is
   not animated, so nothing to add here. ── */
