/* 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;
  /* 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: #A8721A;
  /* 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. */
  --bar: #F5F8F6; --bar-2: #EDF2EF; --bar-line: #D7DFDA; --on-bar: #16211C; --on-bar-dim: #5F6F67;
  --splash: #14201B; --splash-2: #1D2E26;
  --lift: 0 1px 2px rgba(22,33,28,.05);
  --tone: var(--green); --tone-tint: var(--green-tint); --tone-line: var(--green-line);
  --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;
}

.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: #1A3258; }
.tone-purple { --tone: var(--purple); --tone-tint: var(--purple-tint); --tone-line: var(--purple-line); --tone-deep: #443A6E; }

* { 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, #8E9A93 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 10px/1.4 var(--mono); letter-spacing: .14em; color: var(--faint); }

/* ── buttons & inputs ─────────────────────────────────────────────────── */
.btn-ghost { padding: 5px 10px; border: 1px solid var(--border); border-radius: 3px; background: var(--surface); font: 500 9px/1.5 var(--mono); letter-spacing: .08em; 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 11px/1.4 var(--sans); color: #fff; 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 10px/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 11px/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 9px/1.5 var(--mono); letter-spacing: .08em; color: #fff; cursor: pointer; white-space: nowrap; }
.btn-link { border: none; background: transparent; padding: 0; font: 400 10.5px/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 10.5px/1.4 var(--sans); color: #fff; 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 10px/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 8.5px/1.4 var(--mono); letter-spacing: .13em; 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 12px/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 11px/1.4 var(--sans); color: var(--ink); cursor: pointer; text-overflow: ellipsis; }
.select-wide select { padding: 9px 30px 9px 11px; font-size: 12px; }
.select::after { content: "▾"; position: absolute; right: 11px; top: 50%; transform: translateY(-50%); color: var(--faint); pointer-events: none; font-size: 11px; }
.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 11px/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 9px/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 12.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 8.5px/1.4 var(--mono); letter-spacing: .12em; 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 9.5px/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: #9A6A64; }
.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 11.5px/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: #6E1F19; }
.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 #A9B3AC; background-image: repeating-linear-gradient(45deg, #8E9A93 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: #fff; font: 600 8px/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 #D3DAD5; color: var(--muted); }
.chip { display: inline-block; padding: 2px 8px; border: 1px solid var(--border); border-radius: 999px; background: var(--sunk); font: 500 9px/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 #2E6B4C; border-radius: 3px; background: linear-gradient(180deg, #279159 0%, #1C7A4A 100%); display: flex; align-items: center; justify-content: center; flex: none; font: 700 13px/1 var(--sans); color: #fff; }
.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 7px/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 11.5px/1.3 var(--sans); }
.modetab i { display: block; font: 400 9px/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 9.5px/1.5 var(--mono); letter-spacing: .06em; color: #1F7A4A; 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 9px/1.5 var(--mono); letter-spacing: .08em; 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: #fff; }
.login-brand .brand-mark { border-color: rgba(255,255,255,.4); background: rgba(255,255,255,.1); color: #fff; }
.login-brand .brand-word { color: #fff; } .login-brand .brand-tag { color: #6FC495; } .login-brand .brand-word sup { color: rgba(255,255,255,.6); } .login-brand .brand-tag { color: rgba(255,255,255,.7); }
.login-brand h1 { margin: 26px 0 12px; font: 400 25px/1.25 var(--serif); color: #fff; }
.login-brand p { margin: 0 0 22px; font: 400 12px/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 10.5px/1.5 var(--sans); color: rgba(255,255,255,.86); }
.login-points .dot { background: #7FD4A4; }
.login-build { margin-top: 26px; padding-top: 16px; border-top: 1px solid rgba(255,255,255,.16); font: 400 9px/1.6 var(--mono); letter-spacing: .08em; color: rgba(255,255,255,.5); text-transform: uppercase; }
.login-form { padding: 34px 32px; }
.login-form .kicker { font: 500 9px/1.4 var(--mono); letter-spacing: .15em; 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 10.5px/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 11px/1.5 var(--sans); color: #6E1F19; }

/* ── 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 9px/1.5 var(--mono); letter-spacing: .14em; 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 13.5px/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 8.5px/1.4 var(--mono); letter-spacing: .15em; 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 11.5px/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 9px/1.4 var(--mono); letter-spacing: .15em; 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 8.5px/1.4 var(--mono); letter-spacing: .15em; 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 12px/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 12px/1.4 var(--sans); color: #fff; 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 8.5px/1.5 var(--mono); letter-spacing: .1em; color: var(--green-deep); }
.pill-green .dot { width: 5px; height: 5px; border-radius: 50%; background: var(--green); }
.drop-or { font: 400 11px/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 8.5px/1.5 var(--mono); letter-spacing: .06em; color: var(--muted); }
.drop-status { font: 500 10px/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 11.5px/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 9px/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 11px/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 10.5px/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 11px/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 11px/1.4 var(--sans); color: var(--ink); margin-bottom: 3px; }
.check span { display: block; font: 400 10.5px/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 10.5px/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 11px/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: #fff; color: var(--muted); }
.step-n { width: 18px; height: 18px; border-radius: 50%; flex: none; text-align: center; font: 600 9px/18px var(--mono); background: var(--border); color: var(--faint); }
.step.on .step-n, .step.done .step-n { background: var(--green); color: #fff; }
.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 9px/1.4 var(--mono); letter-spacing: .13em; color: var(--faint); text-transform: uppercase; }
.dropzone .body { font: 400 12px/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 11.5px/1.45 var(--sans); color: var(--ink); overflow-wrap: anywhere; }
.receipt.ok .receipt-name { color: var(--green-deep); }
.receipt-meta { font: 400 9.5px/1.5 var(--mono); color: var(--faint); margin-top: 3px; text-transform: uppercase; }
.receipt.ok .receipt-meta { color: var(--green-text); }
.receipt-state { font: 500 9px/1.4 var(--mono); letter-spacing: .1em; 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 9.5px/1.4 var(--mono); letter-spacing: .08em; 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: 1640px; margin: 0 auto; padding: 20px 20px 0; display: flex; gap: 16px; align-items: flex-start; }
.sidebar { flex: none; width: 208px; position: sticky; top: 72px; }
.side { background: var(--surface); border: 1px solid var(--border); border-radius: 4px; padding: 13px 0 11px; box-shadow: var(--lift); }
.side-title { font: 500 8.5px/1.4 var(--mono); letter-spacing: .14em; color: var(--faint); padding: 0 13px 9px; }
.side-group { display: flex; align-items: center; gap: 7px; padding: 13px 13px 6px; font: 600 8px/1.4 var(--mono); letter-spacing: .14em; 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 11px/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: #fff; border-left-color: var(--tone-deep, var(--tone)); }
.side-item span { font: 500 8.5px/1.4 var(--mono); letter-spacing: .06em; flex: none; color: var(--ghost); }
.side-item.on span { color: rgba(255,255,255,.72); }
.side-item em { margin-left: auto; font: 400 9px/1 var(--mono); font-style: normal; color: var(--ghost); }
.side-item.on em { color: rgba(255,255,255,.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 12.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 8px/1.4 var(--mono); letter-spacing: .12em; color: var(--amber-deep); margin-top: 6px; }
.score-sub { font: 400 9px/1.4 var(--sans); color: #A08347; 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: #9A6A64; }
.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 10px/1.5 var(--sans); background: var(--surface); color: var(--muted); }
.subtab.on { background: var(--tone); border-color: var(--tone); color: #fff; }
.tbl-right { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.rows-label { font: 500 8.5px/1.5 var(--mono); letter-spacing: .12em; color: var(--faint); white-space: nowrap; }
.pagesize { padding: 5px 9px; border: 1px solid var(--border); border-radius: 3px; cursor: pointer; font: 500 9px/1.5 var(--mono); background: var(--surface); color: var(--muted); }
.pagesize.on { background: var(--tone); border-color: var(--tone); color: #fff; }
.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 8.5px/1.5 var(--mono); letter-spacing: .12em; 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: #fff; }
.tr:nth-child(odd) { background: var(--sunk); }
.tr:first-of-type { border-top: none; }
.td-text { font: 400 11px/1.55 var(--sans); color: var(--ink); text-wrap: pretty; overflow-wrap: anywhere; }
.td-mono { font: 400 9.5px/1.55 var(--mono); color: var(--muted); overflow-wrap: anywhere; }
.td-num { font: 500 11px/1.5 var(--mono); color: var(--ink); }
.bar { height: 6px; border-radius: 3px; background: #EDF0EE; overflow: hidden; }
.bar i { display: block; height: 6px; border-radius: 3px; background: var(--green); }
.tbl-empty { padding: 26px 14px; text-align: center; font: 400 11.5px/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 9.5px/1.6 var(--mono); letter-spacing: .06em; color: var(--faint); text-transform: uppercase; }
.pager { display: flex; align-items: center; gap: 8px; }
.pager span { font: 500 9px/1.5 var(--mono); letter-spacing: .1em; 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: 11px; }

/* ── 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(--ink); border-radius: 3px; padding: 16px 18px; overflow: auto; max-height: 62vh; }
.code pre { margin: 0; font: 400 11.5px/1.75 var(--mono); color: #CFE3D6; white-space: pre; tab-size: 4; }
.code-foot { margin-top: 12px; font: 400 9.5px/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 12px/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 9px/1.4 var(--mono); letter-spacing: .08em; 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 9px/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 #DCE1DD; font: 400 10.5px/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 9px/1.5 var(--mono); letter-spacing: .08em; background: #fff; color: var(--faint); }
.seg button.on { background: var(--ink); color: #fff; }
.zoom { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-width: 0; }
.zoom-label { font: 500 9px/1 var(--mono); letter-spacing: .12em; color: var(--faint); }
.zoom-btn { width: 26px; height: 26px; border: 1px solid var(--border); border-radius: 3px; background: #fff; font: 400 14px/1 var(--sans); color: var(--ink); cursor: pointer; }
.zoom-val { min-width: 44px; text-align: center; font: 400 11px/1 var(--mono); }
.btn-fit { height: 26px; padding: 0 11px; border-radius: 3px; font: 600 9px/24px var(--mono); letter-spacing: .08em; cursor: pointer; white-space: nowrap; border: 1px solid var(--border); background: #fff; color: var(--muted); }
.btn-fit.on { border-color: var(--green); background: var(--green); color: #fff; }
.meta-mono { font: 400 10px/1.5 var(--mono); color: var(--faint); white-space: nowrap; }
.hint-mono { font: 400 9px/1.5 var(--mono); letter-spacing: .06em; color: var(--ghost); 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: #fff; 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 12px/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 9.5px/1.6 var(--mono); 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: #C2CCC6; }

.card { flex: none; position: relative; z-index: 2; width: 168px; background: #fff; 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-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 #E6EAE7; 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 #E6EAE7; }
.card-state-t { font: 500 8.5px/1.4 var(--mono); letter-spacing: .08em; 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: #16211C; --fam-rgb: 22,33,28; }
.fam-note { --fam: #1C7A4A; --fam-rgb: 28,122,74; border-top-style: solid; border-right-style: dashed; border-bottom-style: dashed; border-left-style: dashed; border-right-color: #A9CFB8; border-bottom-color: #A9CFB8; border-left-color: #A9CFB8; }
.fam-note .card-band { border-bottom-style: dashed; }
.fam-table { --fam: #2F6E8A; --fam-rgb: 47,110,138; }
.fam-util { --fam: #A8721A; --fam-rgb: 168,114,26; }
.fam-logic { --fam: #23685F; --fam-rgb: 35,104,95; }
.fam-write { --fam: #1C7A4A; --fam-rgb: 28,122,74; }
.fam-priv { --fam: #B3261E; --fam-rgb: 179,38,30; }
.fam-api { --fam: #22406F; --fam-rgb: 34,64,111; }
.fam-call { --fam: #5B4B8A; --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: #FBF0D8; }

.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 9px/1.4 var(--sans); letter-spacing: .1em; text-transform: uppercase; color: #fff; }
.fail-band span:last-child { font: 600 13px/1 var(--mono); color: #fff; }
.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: #fff; border-radius: 1px; flex: none; }
.confirm span { font: 600 8.5px/1.4 var(--mono); letter-spacing: .07em; color: #fff; }
.err-text { margin-top: 9px; padding: 7px 8px; background: var(--red-tint); border-radius: 2px; font: 400 9.5px/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 8.5px/1.4 var(--mono); letter-spacing: .08em; color: var(--red); margin-bottom: 5px; }
.priv-skip span { font: 400 10.5px/1.5 var(--sans); color: #4A2A26; }
.btn-payload { margin-top: 8px; padding: 4px 9px; border: 1px solid var(--border); border-radius: 3px; background: #fff; font: 500 8.5px/1.6 var(--mono); letter-spacing: .06em; 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 9px/1.4 var(--mono); letter-spacing: .1em; }
.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 9px/1.4 var(--mono); letter-spacing: .09em; 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 10px/1.5 var(--sans); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fact-pill b { font: 600 8px/1.4 var(--mono); letter-spacing: .12em; 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 8.5px/1.4 var(--mono); letter-spacing: .12em; 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 8.5px/1.4 var(--mono); letter-spacing: .14em; 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 10.5px/1.55 var(--sans); }
.insp-row span { color: var(--muted); flex: none; }
.insp-row b { font: 400 10.5px/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 11px/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 11.5px/1.4 var(--sans); color: var(--ink); }
.insp-find p { margin: 0 0 7px; font: 400 11px/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: 11px; }
@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 10px/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 8.5px/1.4 var(--mono); letter-spacing: .14em; color: var(--faint); text-transform: uppercase; margin-bottom: 6px; }
.fx-block p { margin: 0; font: 400 11.5px/1.6 var(--sans); color: var(--muted); text-wrap: pretty; }
.fx-impact { color: var(--amber-deep) !important; }
.fx-where { font: 400 11px/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 12.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 8.5px/1.4 var(--mono); letter-spacing: .12em; color: var(--faint); }
.fx-steps { margin: 0 0 9px; padding-left: 17px; }
.fx-steps li { font: 400 11.5px/1.65 var(--sans); color: var(--ink); margin-bottom: 5px; text-wrap: pretty; }
.fx-ref { font: 500 10.5px/1.4 var(--sans); color: var(--green); }
.fx-places { display: flex; flex-direction: column; gap: 5px; }
.fx-place { font: 400 10px/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 12px/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 9px/1.4 var(--mono); letter-spacing: .09em; 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: #F1F4F2; }
.box-closed > div { padding: 11px 14px; }
.box-closed > div + div { border-left: 1px dotted #D3DAD5; }
.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 9px/1.6 var(--mono); 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 8.5px/1.3 var(--mono); letter-spacing: .07em; 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 9px/1.4 var(--mono); letter-spacing: .1em; 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: #fff; white-space: nowrap; }
.box-head span:last-child { display: flex; align-items: center; gap: 14px; font: 400 9px/1.4 var(--mono); color: #DBE2DD; white-space: nowrap; }
.box-head b { font-weight: 500; color: #fff; }
.box-body { display: flex; align-items: center; padding: 18px 18px 6px; }
.box-foot { padding: 0 18px 12px; font: 400 9px/1.6 var(--mono); letter-spacing: .05em; color: var(--faint); text-transform: uppercase; }
.box.handler { border-color: var(--amber); background: #FEFCF6; }
.box.handler .box-head { background: var(--amber); }
.box.handler .box-head span:last-child { color: #FBF2DC; }
.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: #F8F0DA; }
.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: #46524B; }
/* 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: #FBFAFE; }
.box.box-call > .box-head { background: var(--purple); }
.box.box-call > .box-head span:last-child { color: #E5E0F2; }
.box.box-call > .box-foot { color: var(--purple); }
.box.box-call.depth2 > .box-head { background: #6E5FA0; }
.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: #fff; padding: 0 8px; }
.dim-label b { font: 600 9px/1.4 var(--mono); letter-spacing: .1em; color: var(--amber-deep); }
.dim-label span { font: 400 9px/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 11px/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 12.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: #fff; font: 500 10px/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 9px/1.4 var(--mono); letter-spacing: .13em; 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 11px/1.4 var(--sans); }
.model-row span:last-child { font: 400 10px/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: #fff; font: 400 10px/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: #fff; 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 11px/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 #fff; background: #fff; 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 9px/1.5 var(--mono); letter-spacing: .1em; color: var(--amber-deep); padding-top: 1px; flex: none; }
.boundary span { font: 400 11.5px/1.6 var(--sans); color: var(--muted); max-width: 1000px; text-wrap: pretty; }
.ranking { margin-top: 14px; background: #fff; 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 12.5px/1.4 var(--sans); color: var(--ink); overflow-wrap: anywhere; }
.rank-meta { font: 400 9.5px/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 9.5px/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 10.5px/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: #fff; font: 500 11px/1.4 var(--sans); }
.lm-card i { display: block; font: 400 9px/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 8.5px/1.4 var(--mono); color: var(--red); letter-spacing: .06em; }
.empty { padding: 26px 14px; text-align: center; font: 400 12px/1.6 var(--sans); color: var(--faint); }
.empty small { display: block; margin-top: 4px; font-size: 11px; }

.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: #fff; 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: #fff; 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 11.5px/1.4 var(--sans); color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.exec-row2 { font: 400 11px/1.5 var(--sans); color: var(--muted); margin-top: 3px; }
.exec-row3 { font: 400 9.5px/1.5 var(--mono); color: var(--faint); margin-top: 2px; }
.exec-err { font: 400 9.5px/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 11.5px/1.4 var(--sans); color: var(--ink); }
.trace-meta { font: 400 9.5px/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 8.5px/1.6 var(--mono); letter-spacing: .1em; color: var(--faint); text-transform: uppercase; }
.kv dd { margin: 0; font: 400 10px/1.5 var(--mono); color: var(--ink); overflow-wrap: anywhere; }
.payload { margin-top: 8px; max-height: 260px; overflow: auto; background: var(--ink); color: #CFE3D6; border-radius: 3px; padding: 10px 12px; font: 400 10px/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 10px/20px var(--mono); background: var(--border); color: var(--faint); }
.ob-step.done .ob-n { background: var(--green); color: #fff; }
.ob-t b { display: block; font: 600 11.5px/1.4 var(--sans); color: var(--ink); }
.ob-t i { display: block; font: 400 10.5px/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 10.5px/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: #fff; min-width: 0; }
.fact .stat-label { margin-bottom: 5px; }
.fact strong { display: block; font: 500 13px/1.4 var(--sans); overflow-wrap: anywhere; }
.fact code { display: block; font: 400 10px/1.5 var(--mono); color: var(--muted); overflow-wrap: anywhere; }
.fact p { margin: 5px 0 0; font: 400 10px/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: rgba(12,26,19,.42); display: flex; align-items: center; justify-content: center; padding: 20px; }
.modal { width: 100%; max-width: 520px; max-height: calc(100vh - 40px); overflow: auto; background: #fff; 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 12px/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: #fff; font: 400 11.5px/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 12px/1.55 var(--sans); color: #6E1F19; }

@media (max-width: 860px) {
  .report { 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, .sidebar, .toolbar, .tbl-tools, .tbl-foot, .rt-controls, .rt-tabs { display: none !important; }
  .report { display: block; }
  .tbl-scroll, .canvas, .code { max-height: none; overflow: visible; }
}

/* ── the assessment header, pinned ────────────────────────────────────
   The same block heads every section, so when it scrolls away the reader is
   left reading a table with no score, no counts and no scope beside it. This
   strip carries those, fixed under the top bar, and appears only once the full
   header has actually left the screen (a sentinel measures that). */
.head-sentinel { height: 1px; margin-top: -1px; }
.headbar { display: none; }
body.head-stuck .headbar {
  display: flex; position: fixed; top: var(--topbar-h, 52px); left: 0; right: 0; z-index: 44;
  align-items: center; gap: 18px; flex-wrap: wrap;
  padding: 7px 22px; background: var(--surface); border-bottom: 1px solid var(--border);
  box-shadow: 0 6px 18px -14px rgba(16, 24, 32, .5);
}
.headbar-score { font: 600 18px/1 var(--serif); color: var(--ink); }
.headbar-score.good { color: var(--green); }
.headbar-score.poor { color: var(--red); }
.headbar-band { font: 500 9px/1.4 var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--muted); }
.headbar-stats { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; min-width: 0; }
.headbar-stat { font: 500 9px/1.4 var(--mono); letter-spacing: .1em; color: var(--faint); text-transform: uppercase; white-space: nowrap; }
.headbar-stat b { font: 600 12px/1 var(--sans); letter-spacing: 0; color: var(--ink); margin-right: 5px; }
.headbar-scope { margin-left: auto; font: 400 10px/1.5 var(--mono); color: var(--faint); text-transform: uppercase; }

/* ── 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 9px/1.4 var(--mono); letter-spacing: .14em; 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 11.5px/1.6 var(--sans); color: var(--muted); }
.col-legend-k { font: 500 9px/1.7 var(--mono); letter-spacing: .09em; 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 11.5px/1.7 var(--sans); }
.miss-list li { margin: 3px 0; }
.miss-list .btn-linkish { font-size: 11.5px; }
.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 10px/1.6 var(--mono); 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 11.5px/1.6 var(--sans); }
.probe b { font: 600 9px/1.6 var(--mono); letter-spacing: .12em; }
.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 9px/1.5 var(--mono); letter-spacing: .13em; color: var(--ink); }
.matchbox-head span { font: 400 11.5px/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 9.5px/1.7 var(--mono); letter-spacing: .08em; text-transform: uppercase; color: var(--ink); }
.matchrow .mr-v { font: 400 11.5px/1.6 var(--sans); color: var(--muted); }
.matchbox p { margin: 10px 0 0; font: 400 11.5px/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 8.5px/1.5 var(--mono); letter-spacing: .11em; text-transform: uppercase; color: var(--faint); }
.runfacts b { font: 500 11.5px/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 9px/1.5 var(--mono); letter-spacing: .14em; 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 9px/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 12px/1.45 var(--sans); color: var(--ink); }
.howstep em { font: 400 10.5px/1.5 var(--mono); font-style: normal; color: var(--faint); text-transform: uppercase; letter-spacing: .04em; }

/* 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 7.5px/1.5 var(--mono); letter-spacing: .12em; 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 9px/1.5 var(--mono); letter-spacing: .15em; 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 11.5px/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 11px/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 12.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 12.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: 11.5px !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: #fff; }
.tick-fail { background: var(--red); color: #fff; }
.tick-notObserved { background: var(--amber-tint, #FAF0DC); 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 7.5px/1.6 var(--mono); letter-spacing: .1em; 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 13px/1.4 var(--sans); color: var(--ink); }
.keep-sub { display: block; margin-top: 4px; font: 400 11.5px/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 11px/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: #fff; font: 500 9.5px/1.5 var(--mono); letter-spacing: .04em; }
.grade-chip b { font: 600 10px/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 11px/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 9.5px/1.5 var(--mono); letter-spacing: .04em; text-transform: uppercase; }
.sev-pill b { font: 600 11px/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 11px/1.4 var(--sans); color: inherit; letter-spacing: 0; }
.hist-gone { display: block; font: 400 9px/1.4 var(--mono); font-style: normal; color: var(--ghost); }
.side-item.on .hist-gone { color: rgba(255,255,255,.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 11px/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 9.5px/1.4 var(--mono); color: var(--faint); }
.tl-runs { margin-top: 5px; font: 400 10px/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 11.5px/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 9.5px/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 11.5px/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 11px/1.7 var(--sans); color: var(--muted); }
.diff-field { font: 500 9.5px/1.4 var(--mono); text-transform: uppercase; letter-spacing: .04em; 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 11px/1.7 var(--sans); color: var(--muted); }
.delta-good { font: 600 11px/1.4 var(--sans); color: var(--green-deep); }
.delta-bad { font: 600 11px/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 11px/1.5 var(--sans); color: var(--ink); }
.run-version b { font: 500 9.5px/1.4 var(--mono); letter-spacing: .04em; 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: 11px; }
  .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: #fff; }
.arch-col { font: 600 9px/1 var(--mono); letter-spacing: .12em; fill: var(--faint); }
.arch-name { font: 600 12px/1 var(--sans); fill: var(--ink); }
.arch-sub { font: 400 9.5px/1 var(--mono); fill: var(--faint); }
.arch-grade { font: 600 11px/1 var(--mono); }
/* A folder heading inside a column, when the diagram is grouped by folder. */
.arch-band-t { font: 600 9px/1 var(--mono); letter-spacing: .1em; }
.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 11.5px/1.5 var(--sans); }
.coup-side { font: 400 11px/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 11.5px/1.5 var(--sans); }
.step-row .step-n { font: 500 9.5px/1.5 var(--mono); color: var(--ghost); text-align: right; }
.step-row b { font: 600 9.5px/1.5 var(--mono); letter-spacing: .05em; text-transform: uppercase; color: var(--faint); }
.step-row span:last-of-type { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.step-card { font: 400 9.5px/1.5 var(--mono); font-style: normal; color: var(--ghost); 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 12px/1.7 var(--sans); color: var(--muted); }
.trust-list { display: flex; flex-direction: column; gap: 7px; margin-top: 16px; font: 400 11px/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 10.5px/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: #fff; }
.gk-head b { display: block; font: 600 9.5px/1 var(--mono); letter-spacing: .13em; color: var(--faint); }
.gk-head span { display: block; margin-top: 7px; font: 400 11.5px/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 11px/1 var(--mono); color: var(--ink); white-space: nowrap; }
.gk-band { font: 500 10px/1.4 var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.gk-rule { font: 400 11.5px/1.55 var(--sans); color: var(--muted); }
.gk-you { font: 600 8.5px/1 var(--mono); letter-spacing: .12em; 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: #fff;
  font: 400 11px/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 10.5px/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 11.5px/1.5 var(--sans); color: var(--ink); }
.store-row span { font: 400 11.5px/1.6 var(--sans); color: var(--muted); }
.store-row em { font: 600 8.5px/1 var(--mono); letter-spacing: .1em; 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, #8a5a00); border-color: var(--amber-line, #e2c489); background: var(--amber-wash, #fdf6e8); }
.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: #fff; }
/* 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 8.5px/1 var(--mono);
  letter-spacing: .1em; 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 12px/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 12.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 8px/1.7 var(--mono); }
.legend-more { border: 1px dashed var(--strong); border-radius: 999px; background: none; padding: 3px 9px; font: 600 8.5px/1.6 var(--mono); letter-spacing: .08em; 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, #22406F); }

/* ── Dark diagrams ────────────────────────────────────────────────────
   Scoped to the diagram, not the workspace: the report around it is a
   document and stays a document. Done by redefining the tokens inside the
   canvas rather than by restyling forty card classes, so anything added to a
   card later inherits the dark theme without a second rule. */
.canvas.dark {
  --surface: #17201D; --sunk: #141C1A; --page: #101715;
  --border: #2C3833; --soft: #26312D; --strong: #46554E;
  --ink: #E6EDE9; --muted: #A8B5AE; --faint: #8FA098; --ghost: #6E7D76;
  /* 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;
  background: #101715;
}
/* The canvas re-states `color` rather than relying on the token alone: `body`
   already computed its colour from the light `--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.dark .card { background: #17201D; }
/* The entry/return family is the ink colour by design — invisible against a
   dark ground, so it takes the light end of the same scale. */
.canvas.dark .fam-flow { --fam: #C6CFC9; --fam-rgb: 198,207,201; }
/* A payload block is dark-on-light by design; on a dark canvas `var(--ink)`
   would make it light-on-light. */
.canvas.dark .payload, .canvas.dark .code pre { background: #0A100E; }
.canvas.dark .box { background: #141C1A; }
.canvas.dark.is-runtime .wire, .canvas.dark .is-runtime .wire { stroke: #46554E; }
.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: #101715; }
/* 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: #101715; border-color: #24312C; }
.archsvg.dark .arch-name { fill: #E6EDE9; }
.archsvg.dark .arch-sub, .archsvg.dark .arch-col { fill: #8FA098; }
.archsvg.dark .arch-node:hover rect:first-of-type { fill: #1F2C27; }
.archsvg.dark .arch-node.on rect:first-of-type { fill: #202E3F; }

/* ── 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 9px/1.6 var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--faint); }
.file-chip { padding: 3px 9px; border: 1px solid var(--border); border-radius: 999px; background: var(--sunk); font: 400 10px/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 12px/1.4 var(--sans); color: var(--ink); }
.check-row i { display: block; margin-top: 4px; font: 400 10.5px/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 11.5px/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: 10px; color: var(--green); }
.sso-or { display: flex; align-items: center; gap: 10px; margin: 0 0 14px; font: 600 8.5px/1.6 var(--mono); letter-spacing: .12em; 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 8.5px/1 var(--mono); color: #8FD4AE; flex: none; }
.whoami-n { font: 500 10.5px/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 10.5px/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 10.5px/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 10px/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 9px/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 10px/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: #fff; }
.folder-tab.on .legend-n { background: rgba(255,255,255,.18); color: #fff; }
/* 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 10px/1.5 var(--mono); color: var(--muted); }
.folder-all { letter-spacing: .1em; font-weight: 600; font-size: 8.5px; }
.folder-note { font: 400 10px/1.6 var(--sans); color: var(--faint); text-wrap: pretty; }
.folder-note-x { color: var(--amber); }

/* 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 8px/1 var(--mono); fill: #fff; pointer-events: none; }
.archsvg.dark .arch-dot-n { fill: #0F1613; }
/* 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 9px/1 var(--sans); fill: var(--ink2); pointer-events: none;
  paint-order: stroke; stroke: #fff; stroke-width: 3px; stroke-linejoin: round;
}
.arch-dot-l.back { fill: var(--ink3); }
.archsvg.dark .arch-dot-l { fill: #CFDAD4; stroke: #1A2422; }
.archsvg.dark .arch-dot-l.back { fill: #8B978F; }

/* ── 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 11.5px/1.55 var(--sans); color: var(--ink2);
}
.arch-trace-note b { font: 600 11.5px/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 11px/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 9.5px/1 var(--mono);
  letter-spacing: .15em; color: var(--muted);
}
.help-is { margin: 0 0 4px; color: var(--ink2); }
.help-h {
  margin: 18px 0 8px; font: 600 11px/1 var(--mono);
  letter-spacing: .1em; text-transform: uppercase; color: var(--muted);
}
.help-list { margin: 0; padding-left: 18px; }
.help-list li { margin: 0 0 7px; font-size: 13.5px; 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: 13.5px; 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 9px/1 var(--mono); letter-spacing: .12em; color: var(--muted);
}
.arch-pace-v {
  font: 500 10px/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; }
.archsvg.dark ~ .arch-pace-r, .arch-scroll.dark .arch-pace-r { background: #2A3A34; }
@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: #fff; font-family: var(--mono); font-weight: 600; pointer-events: none; }
.arch-chip-more { fill: var(--muted); font-family: var(--mono); font-weight: 600; }
.archsvg.dark .arch-chip { fill: #E6EDE9; stroke: #101715; }
.archsvg.dark .arch-chip-n { fill: #0F1613; }
.archsvg.dark .arch-chip-more { fill: #8FA098; }
@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: #fff; font-family: var(--mono); font-weight: 700; pointer-events: none; }
.arch-failm { cursor: help; }
.arch-failb-t { font: 600 8.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 #B4402F; border-radius: 6px;
  background: var(--surface);
}
.arch-failchip {
  font: 500 11.5px/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: #B4402F; border-color: #B4402F55; background: #B4402F12; }
.arch-failchip.swallowed { color: #8A5F10; border-color: #B07A1655; background: #B07A1614; }
.arch-failchip.routed    { color: #5B489A; border-color: #6E59A555; background: #6E59A512; }
.arch-failchip.unstartable { color: #B4402F; border-color: #B4402F55; background: #B4402F12; }
/* 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 11px/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 12px/1.4 var(--mono); }
.fail-arrow { color: var(--muted); }
.fail-target { font: 400 12px/1.4 var(--mono); color: var(--muted); }
.fail-why { flex: 1 0 100%; font: 400 12px/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 12.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: #fff; 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: #fff; font-family: var(--mono); font-weight: 700; pointer-events: none; }
.canvas.dark .walk-dot, .canvas.dark .walk-chip rect { fill: #E6EDE9; }
.canvas.dark .walk-chip rect { stroke: #101715; }
.canvas.dark .walk-dot-n, .canvas.dark .walk-chip-n { fill: #0F1613; }
@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; }
}
/* 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: #C6CFCA; stroke-opacity: .55; stroke-width: 1; }
.archsvg.dark .arch-wire.off { stroke: #39473F; stroke-opacity: .9; }
.arch-wire.base { stroke: #C6CFCA; stroke-opacity: .55; }
.archsvg.dark .arch-wire.base { stroke: #39473F; 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: #9AA8A1; }
.archsvg.dark .arch-dot.courier { fill: #6E7F77; }
.arch-dot-n.courier { fill: #fff; }
.archsvg.dark .arch-dot-n.courier { fill: #101715; }

/* ── 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 11.5px/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: 13px; }
.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 12.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 12px/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 10.5px/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(--surface); 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: 11px; 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 12px/1 var(--mono);
                      letter-spacing: .1em; text-transform: uppercase; color: var(--green); }
.explore-promise ul { margin: 0; padding-left: 18px; }
.explore-promise li { margin: 0 0 8px; font: 400 13.5px/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 12.5px/1.6 var(--mono); color: var(--ink2); }
.explore-confirm { display: flex; align-items: flex-start; gap: 9px;
                   font: 400 13px/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 9.5px/1.4 var(--mono);
                 letter-spacing: .14em; color: var(--muted); }
.explore-bar-v { display: block; font: 500 13px/1.5 var(--sans); color: var(--ink); }
.explore-bar-r { display: flex; align-items: center; gap: 12px; }
