*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--text);font-family:var(--font-body);line-height:1.55;
  background-image:radial-gradient(90% 60% at 85% -10%,rgba(244,101,43,.12),transparent 60%);min-height:100vh}
a{color:inherit;text-decoration:none}
h1{font-family:var(--font-display);font-weight:700;font-size:clamp(1.8rem,4vw,2.8rem);letter-spacing:-.02em;margin:.3rem 0 0}
h2{font-family:var(--font-display);font-weight:600;font-size:1.15rem;margin:0 0 .9rem}
/* The hidden attribute must win. A class with its own display rule (.dl, .badge-grab) otherwise
   beats the UA stylesheet's [hidden]{display:none}, which is how "Download the PDF" ended up
   showing on a scan that had not run yet. One rule closes the whole class of bug. */
[hidden]{display:none !important}
/* Before a scan has produced anything there are no counts to state and nothing to stream, so the
   pre-scan screen stays on the one thing the owner has to do. Zeroes here would read as "we
   scanned and found nothing", which is a claim we have not earned. */
#scanView.awaiting .counts,
#scanView.awaiting #checkingCard{display:none}
.eyebrow{font-family:var(--font-mono);font-size:.72rem;letter-spacing:.16em;text-transform:uppercase;color:var(--accent);margin:0}
.lede{color:var(--text-muted);max-width:60ch;margin:.8rem 0 1.6rem}
.top{display:flex;justify-content:space-between;align-items:center;padding:1rem clamp(1rem,4vw,2.5rem);border-bottom:1px solid var(--border);position:sticky;top:0;background:rgba(20,16,13,.85);backdrop-filter:blur(8px);z-index:5}
.brand{display:flex;align-items:center;gap:.55rem}
.brand svg{width:30px;height:30px;flex:none}
/* The same lockup fix as the marketing header, and for the same reason: both inherited a 1.6 body
   line-height and the two-line wordmark came out taller than its own mark. */
.brand span{display:flex;flex-direction:column;justify-content:center;line-height:1}
.brand b{font-family:var(--font-display);font-weight:700;font-size:1.05rem;line-height:1;display:block}
.brand em{font-family:var(--font-mono);font-style:normal;font-size:.55rem;letter-spacing:.26em;
  text-transform:uppercase;color:var(--text-muted);display:block;line-height:1;margin-top:.28rem}
.top .tag{font-family:var(--font-mono);font-size:.72rem;color:var(--ember-hi);border:1px solid var(--ember-line);padding:.25rem .6rem;border-radius:4px}
.wrap{max-width:1120px;margin:0 auto;padding:clamp(1.5rem,4vw,3rem) clamp(1rem,4vw,2.5rem)}
.card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);padding:clamp(1.1rem,3vw,1.6rem)}
.form{max-width:760px}
.row{display:grid;grid-template-columns:1fr 1fr;gap:1rem;margin-bottom:1rem}
@media(max-width:640px){.row{grid-template-columns:1fr}}
label{display:flex;flex-direction:column;gap:.35rem;font-size:.86rem;color:var(--text-muted)}
input,select{min-height:44px;padding:0 .8rem;border-radius:var(--radius);border:1px solid var(--border-strong);background:var(--bg-2);color:var(--text);font-family:var(--font-body);font-size:.95rem}
input:focus,select:focus{outline:2px solid var(--accent);outline-offset:1px;border-color:var(--accent)}
.btn{min-height:46px;padding:0 1.4rem;border:0;border-radius:var(--radius);background:var(--accent);color:var(--accent-ink);font-weight:700;font-size:.96rem;cursor:pointer;transition:transform var(--dur) var(--ease),box-shadow var(--dur) var(--ease)}
.btn:hover{transform:translateY(-1px);box-shadow:var(--shadow-glow)}
.btn:disabled{opacity:.55;cursor:not-allowed}
.err{color:var(--crit);font-family:var(--font-mono);font-size:.82rem;min-height:1.1em;margin:.6rem 0 0}
.scanhead{display:flex;justify-content:space-between;align-items:flex-end;gap:1.5rem;flex-wrap:wrap;margin-bottom:1.6rem}
.counts{display:flex;gap:1.4rem}
.counts .c{display:flex;flex-direction:column;align-items:flex-end}
.counts .n{font-family:var(--font-mono);font-weight:700;font-size:clamp(1.6rem,4vw,2.4rem);line-height:1}
.counts .k{font-size:.76rem;color:var(--text-muted)}
.counts .crit .n{color:var(--crit)}.counts .ok .n{color:var(--good)}
.grid{display:grid;grid-template-columns:1.15fr .85fr;gap:1.2rem;align-items:start}
@media(max-width:860px){.grid{grid-template-columns:1fr}}
.term{font-family:var(--font-mono);font-size:.8rem;line-height:1.9;color:var(--text-muted);max-height:420px;overflow:auto}
.term .ln{white-space:pre-wrap;word-break:break-word;padding:1px 0}
.term .k-error{color:var(--crit)}.term .k-confirm{color:var(--good)}.term .k-candidate,.term .k-probe{color:var(--ember-hi)}
.term .k-report,.term .k-ownership{color:var(--plasma)}
.term .t{color:var(--text-dim)}
.findings{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.6rem}
.findings .empty{color:var(--text-dim);font-family:var(--font-mono);font-size:.82rem}
.finding{display:grid;grid-template-columns:auto 1fr;gap:.7rem;align-items:start;padding:.7rem;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg-2)}
.sev{font-family:var(--font-mono);font-size:.66rem;padding:.16rem .45rem;border-radius:3px;text-transform:uppercase}
.sev.critical,.sev.high{background:rgba(229,72,77,.16);color:var(--crit)}
.sev.medium{background:rgba(242,169,59,.16);color:var(--warn)}
.sev.low,.sev.info{background:var(--surface-3);color:var(--text-muted)}
.finding .ftitle{font-size:.9rem}
.finding .fstatus{font-family:var(--font-mono);font-size:.72rem;color:var(--good)}
.finding .fstatus.potential{color:var(--text-dim)}
.finding .fstatus.exploited{color:var(--accent)}
.term .k-exploit{color:var(--accent)}
/* FCD-022 withheld ledger. The register is the report's own evidence language: mono rows, tabular
   counts, hairlines. Deliberately NOT ember: ember is alarm and brand, and a withheld medium
   finding is neither. No blur, no padlock, no fade, no urgency. */
.withheld{background:var(--surface);border:1px solid var(--border-strong);border-radius:var(--radius);
  padding:clamp(1.1rem,3vw,1.6rem);margin-top:1.2rem}
.withheld h2{font-size:1.02rem;font-weight:700;margin:0 0 .5rem}
.wh-floor{color:var(--text);margin:0 0 .6rem;line-height:1.55}
.wh-count-line{color:var(--text-muted);margin:0 0 .8rem;line-height:1.55}
.wh-rows{list-style:none;margin:0 0 .9rem;padding:0;border-top:1px solid var(--border)}
.wh-rows li{display:grid;grid-template-columns:1fr auto;gap:.8rem;padding:.5rem 0;border-bottom:1px solid var(--border)}
.wh-name{font-family:var(--font-mono);font-size:.82rem;color:var(--text)}
.wh-count{font-family:var(--font-mono);font-weight:500;color:var(--text);font-variant-numeric:tabular-nums;text-align:right}
.wh-buys{color:var(--text-muted);margin:0 0 .9rem;line-height:1.55}
.wh-actions{display:flex;gap:.9rem;align-items:center;flex-wrap:wrap}
.wh-reassure{color:var(--text-muted);font-size:.82rem;margin:.7rem 0 0}
.wh-unavailable{color:var(--text-muted);margin:0;line-height:1.55}
.paystate{font-size:.86rem;margin:.6rem 0 0;line-height:1.5;color:var(--text-muted)}
.paystate[data-state="settled"],.paystate[data-state="recovered"]{color:var(--good)}
.paystate[data-state="refused"],.paystate[data-state="expired"],.paystate[data-state="notpaid"]{color:var(--crit)}
@media (max-width:520px){.wh-actions .btn{width:100%}}

/* ownership proof (FCD-012): the conversion moment, so it reads as two obvious steps */
.ownership{background:var(--bg-2);border:1px solid var(--ember-line);border-radius:var(--radius);padding:1.1rem 1.2rem;margin-bottom:1rem;font-size:.86rem}
.ownership code{font-family:var(--font-mono);font-size:.78rem;color:var(--ember-hi);word-break:break-all}
.ownership .btn{min-height:38px;font-size:.84rem;margin-top:.7rem}
.own-h{font-size:1.02rem;font-weight:700;margin:0 0 .35rem}
.own-h.own-ok{color:var(--good);margin:0}
.own-why{color:var(--text-muted);margin:0 0 .95rem;line-height:1.55}
.own-steps{list-style:none;margin:0 0 .9rem;padding:0;display:flex;flex-direction:column;gap:.85rem}
.own-steps li{display:flex;gap:.7rem;align-items:flex-start}
.own-n{flex:0 0 auto;width:22px;height:22px;border-radius:50%;background:var(--ember-line);color:var(--accent-ink);
  font-family:var(--font-mono);font-size:.74rem;font-weight:700;display:flex;align-items:center;justify-content:center;margin-top:.1rem}
.own-body{flex:1 1 auto;min-width:0}
.own-body p{margin:0 0 .45rem;line-height:1.5}
.own-copy{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;background:var(--bg);border:1px solid var(--border);
  border-radius:var(--radius);padding:.5rem .6rem}
.own-copy code{flex:1 1 12rem;min-width:0}
.own-copy .btn-copy{flex:0 0 auto;min-height:30px;padding:0 .75rem;font-size:.76rem;background:transparent;
  border:1px solid var(--border-strong);border-radius:var(--radius);color:var(--text);cursor:pointer}
.own-copy .btn-copy:hover{border-color:var(--accent);color:var(--accent)}
.own-note{color:var(--text-muted);font-size:.8rem;margin:.45rem 0 0}
.own-plat{margin:0 0 .3rem;border-top:1px solid var(--border);padding-top:.7rem}
.own-plat summary{cursor:pointer;color:var(--text-muted);font-size:.82rem}
.own-plat summary:hover{color:var(--accent)}
.own-hint{display:flex;flex-direction:column;gap:.15rem;padding:.55rem 0;border-bottom:1px solid var(--border)}
.own-hint:last-child{border-bottom:0}
.own-hint b{font-size:.82rem}
.own-hint span{color:var(--text-muted);font-size:.8rem;line-height:1.5}
.own-fail{margin:.7rem 0 0;padding:.6rem .7rem;background:rgba(229,72,77,.12);border:1px solid rgba(229,72,77,.4);
  border-radius:0 var(--radius) var(--radius) 0;color:var(--text);font-size:.83rem;line-height:1.5}
@media (max-width:560px){.own-copy{align-items:stretch}.own-copy .btn-copy{width:100%}}

.muted{color:var(--text-muted);font-size:.86rem;margin-top:.9rem}
.muted a{color:var(--accent)}
.fix{margin-top:1.2rem}
.fix .term{max-height:220px;margin-top:.8rem}
.fixresult{margin-top:.8rem;font-size:.92rem;color:var(--good);font-family:var(--font-mono)}
.fixresult a{color:var(--accent);word-break:break-all}
.monitor{margin-top:1.2rem}
.monitors{margin-top:1rem;display:flex;flex-direction:column;gap:.6rem}
.mon{display:flex;flex-direction:column;gap:.7rem;padding:.7rem .9rem;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg-2)}
.mon-row{display:flex;justify-content:space-between;align-items:center;gap:.8rem;flex-wrap:wrap}
.mon .k{color:var(--text-muted);font-size:.8rem;font-family:var(--font-mono)}
/* FCD-019 Frontier-Defended badge grab */
.badge-grab{border-top:1px solid var(--border);padding-top:.7rem;display:flex;flex-direction:column;gap:.6rem}
.badge-grab .k{color:var(--text-muted);font-size:.82rem;line-height:1.45;font-family:var(--font-body)}
.badge-grab .btn-badge{align-self:flex-start;min-height:38px;font-size:.86rem}
.badge-preview{padding:.7rem;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);display:flex;justify-content:center}
.badge-preview img{display:block}
.badge-snippet{display:flex;flex-direction:column;gap:.35rem}
.badge-snippet textarea{width:100%;resize:vertical;background:var(--surface);color:var(--text);border:1px solid var(--border-strong);border-radius:var(--radius);padding:.6rem .7rem;font-family:var(--font-mono);font-size:.78rem;line-height:1.5}
.badge-snippet textarea:focus-visible{outline:2px solid var(--ember-line);outline-offset:2px}
.badge-actions{display:flex;align-items:center;gap:.9rem;flex-wrap:wrap}
.badge-actions .btn-copy{min-height:34px;padding:0 .9rem;font-size:.8rem;background:transparent;border:1px solid var(--border-strong);color:var(--text)}
.badge-actions .btn-copy:hover{border-color:var(--accent);color:var(--accent)}
.badge-actions .lnk{color:var(--text-muted);font-size:.8rem;font-family:var(--font-mono);text-decoration:underline;text-underline-offset:2px}
.badge-actions .lnk:hover{color:var(--accent)}
.shield{font-family:var(--font-mono);font-size:.74rem;padding:.28rem .6rem;border-radius:4px;white-space:nowrap}
.shield.ok{background:rgba(63,185,140,.16);color:var(--good)}
.shield.warn{background:rgba(229,72,77,.16);color:var(--crit)}
.shield.pending{background:var(--surface-3);color:var(--text-muted)}
.btn-stop{min-height:34px;padding:0 .8rem;font-size:.8rem;background:transparent;border:1px solid var(--border-strong);color:var(--text-muted)}
.btn-stop:hover{border-color:var(--crit);color:var(--crit)}
.mfa{margin-top:1.2rem}
.mfa #mfaSetup{margin:.9rem 0;padding:.9rem;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg-2)}
.mfa #mfaSecret{font-family:var(--font-mono);font-size:1rem;letter-spacing:.12em;color:var(--accent);word-break:break-all}
.mfa #mfaUri{font-family:var(--font-mono);font-size:.74rem;color:var(--text-muted);margin-top:.4rem}
.mfa form{margin-top:.7rem}

/* ============ in-dashboard report (FCD-009): the live console ============ */
.counts .exploited .n{color:var(--accent)}
.dl{display:inline-flex;align-items:center;gap:.5rem;min-height:40px;padding:0 var(--space-3);background:var(--accent);color:var(--accent-ink);font-weight:700;font-size:.9rem;border:0;border-radius:var(--radius);cursor:pointer;transition:transform var(--dur) var(--ease),box-shadow var(--dur) var(--ease)}
.dl:hover{transform:translateY(-1px);box-shadow:var(--shadow-glow)}
.dl:focus-visible{outline:2px solid var(--ember-hi);outline-offset:2px}
.dl svg{width:15px;height:15px}

/* verdict band */
.prelim-banner{margin:0 0 1.2rem;padding:.85rem 1rem;border-radius:8px;border:1px solid #d6c48a;background:#fbf4dd;color:#5a4a12;font-size:.95rem;line-height:1.45}
@media (prefers-color-scheme:dark){.prelim-banner{border-color:#6b5a1f;background:#2a2410;color:#e8d9a3}}
.verdictband{margin:0 0 1.6rem}
.verdict-line{max-width:60ch;color:var(--text);font-size:var(--step-1);font-weight:500;line-height:1.35;margin:0 0 var(--space-4)}
.expo{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);padding:var(--space-4)}
.expo h2{font-size:var(--step-0);font-weight:600;font-family:var(--font-display);margin:0 0 var(--space-3)}
.expo-bar{display:flex;height:22px;border-radius:4px;overflow:hidden;gap:2px;background:var(--bg-2)}
.expo-bar .seg{display:block;min-width:6px}
.expo-bar .crit{background:var(--crit)}
.expo-bar .high{background:color-mix(in oklab,var(--crit),var(--bg) 32%)}
.expo-bar .med{background:var(--warn)}
.expo-bar .low{background:var(--surface-3)}
.expo-key{display:flex;flex-wrap:wrap;gap:.4rem var(--space-4);margin-top:var(--space-3);font-family:var(--font-mono);font-size:.76rem;color:var(--text-muted)}
.expo-key span{display:inline-flex;align-items:center}
.expo-key i{display:inline-block;width:9px;height:9px;border-radius:2px;margin-right:.45rem}
.expo-key .k-crit i{background:var(--crit)}.expo-key .k-high i{background:color-mix(in oklab,var(--crit),var(--bg) 32%)}
.expo-key .k-med i{background:var(--warn)}.expo-key .k-low i{background:var(--surface-3)}
.reach-sum{margin-top:var(--space-4);padding-top:var(--space-4);border-top:1px solid var(--border);color:var(--text);font-size:.94rem}
.reach-sum b{font-family:var(--font-display);font-weight:600}
.report-dek{color:var(--text-muted);font-size:.9rem;margin:0 0 1rem}

/* reach ladder */
.reach{display:flex;flex-direction:column;gap:.4rem}
.rungs{display:flex;gap:3px}
.rungs i{display:block;width:24px;height:18px;border-radius:2px;border:1px solid var(--border-strong);background:transparent}
.rungs i:nth-child(1){--heat:var(--accent)}
.rungs i:nth-child(2){--heat:color-mix(in oklab,var(--accent),var(--ember-hi) 25%)}
.rungs i:nth-child(3){--heat:color-mix(in oklab,var(--accent),var(--ember-hi) 50%)}
.rungs i:nth-child(4){--heat:color-mix(in oklab,var(--accent),var(--ember-hi) 75%)}
.rungs i:nth-child(5){--heat:var(--ember-hi)}
.reach[data-proof="exploited"][data-reach="1"] .rungs i:nth-child(-n+1),
.reach[data-proof="exploited"][data-reach="2"] .rungs i:nth-child(-n+2),
.reach[data-proof="exploited"][data-reach="3"] .rungs i:nth-child(-n+3),
.reach[data-proof="exploited"][data-reach="4"] .rungs i:nth-child(-n+4),
.reach[data-proof="exploited"][data-reach="5"] .rungs i:nth-child(-n+5){background:var(--heat);border-color:transparent}
.reach[data-proof="confirmed"][data-reach="1"] .rungs i:nth-child(-n+1),
.reach[data-proof="confirmed"][data-reach="2"] .rungs i:nth-child(-n+2),
.reach[data-proof="confirmed"][data-reach="3"] .rungs i:nth-child(-n+3),
.reach[data-proof="confirmed"][data-reach="4"] .rungs i:nth-child(-n+4),
.reach[data-proof="confirmed"][data-reach="5"] .rungs i:nth-child(-n+5){background:color-mix(in oklab,var(--heat),transparent 32%);border-color:transparent}
.reach[data-proof="potential"][data-reach="1"] .rungs i:nth-child(-n+1),
.reach[data-proof="potential"][data-reach="2"] .rungs i:nth-child(-n+2),
.reach[data-proof="potential"][data-reach="3"] .rungs i:nth-child(-n+3),
.reach[data-proof="potential"][data-reach="4"] .rungs i:nth-child(-n+4),
.reach[data-proof="potential"][data-reach="5"] .rungs i:nth-child(-n+5){background:transparent;border-color:var(--heat)}
.reach-label{font-family:var(--font-mono);font-size:.68rem;letter-spacing:.04em;color:var(--text-muted)}
.reach-label b{color:var(--ember-hi);font-weight:500}
/* a potential finding is a signature, so its label reads "would reach" and stays unlit */
.reach[data-proof="potential"] .reach-label{color:var(--text-dim)}
.reach[data-proof="potential"] .reach-label b{color:var(--text-muted)}

/* rich finding card (report) */
.findings.report{gap:var(--space-3)}
.rcard{--sev:var(--text-muted);display:block;background:var(--surface);border:1px solid var(--border);border-left:3px solid var(--sev);border-radius:var(--radius);overflow:hidden;padding:0}
.rcard.sev-critical,.rcard.sev-high{--sev:var(--crit)}
.rcard.sev-medium{--sev:var(--warn)}
.rcard.sev-low,.rcard.sev-info{--sev:var(--text-muted)}
.rcard details{margin:0}
.rcard summary{display:grid;grid-template-columns:auto 1fr auto;gap:.9rem;align-items:start;padding:var(--space-3) var(--space-4);cursor:pointer;list-style:none}
.rcard summary::-webkit-details-marker{display:none}
.rcard summary::marker{content:""}
.rcard summary:focus-visible{outline:2px solid var(--accent);outline-offset:-2px;border-radius:var(--radius)}
.r-main{min-width:0}
.r-meta{display:flex;flex-wrap:wrap;align-items:center;gap:.45rem .75rem;margin-bottom:.3rem}
.r-cat{font-family:var(--font-mono);font-size:.72rem;letter-spacing:.03em;color:var(--text-muted)}
.r-proof{font-family:var(--font-mono);font-size:.66rem;letter-spacing:.05em;padding:.1rem .4rem;border-radius:3px}
.r-proof.exploited{color:var(--accent);border:1px solid var(--ember-line)}
.r-proof.confirmed{color:var(--good);border:1px solid color-mix(in oklab,var(--good),transparent 60%)}
.r-proof.potential{color:var(--text-dim);border:1px solid var(--border-strong)}
.r-title{font-family:var(--font-display);font-weight:600;font-size:var(--step-1);line-height:1.2;letter-spacing:-.01em}
.r-summary{color:var(--text-muted);font-size:.9rem;margin-top:.35rem;max-width:60ch}
.r-badge{font-family:var(--font-mono);font-size:.64rem;letter-spacing:.06em;text-transform:uppercase;padding:.24rem .5rem;border-radius:3px;white-space:nowrap;align-self:start}
.sev-critical .r-badge{background:var(--crit);color:var(--accent-ink)}
.sev-high .r-badge{background:transparent;color:var(--crit);border:1px solid color-mix(in oklab,var(--crit),transparent 45%)}
.sev-medium .r-badge{background:color-mix(in oklab,var(--warn),transparent 82%);color:var(--warn)}
.sev-low .r-badge,.sev-info .r-badge{background:var(--surface-3);color:var(--text-muted)}
.r-body{padding:0 var(--space-4) var(--space-4);border-top:1px solid var(--border)}
.r-body>*{max-width:var(--measure)}
.r-body p{margin-top:var(--space-3);color:var(--text);font-size:.94rem}
.r-body b.lbl{font-family:var(--font-display);font-weight:600;color:var(--text)}
@media(max-width:720px){.rcard summary{grid-template-columns:1fr}.r-reach{order:3}.r-badge{order:-1;justify-self:start}}

/* ============ what we checked (FCD-015) ============ */
/* the result stamp: one word, the line under it, and the rule behind both */
.cov-verdict{margin:0 0 var(--space-4)}
.stamp{display:inline-flex;align-items:baseline;gap:var(--space-3);border:1px solid var(--border-strong);
  border-radius:var(--radius);padding:var(--space-2) var(--space-3)}
.stamp .k{font-family:var(--font-mono);font-size:.66rem;letter-spacing:.16em;text-transform:uppercase;color:var(--text-muted)}
.stamp b{font-family:var(--font-display);font-weight:700;font-size:var(--step-1);line-height:1}
.stamp-pass{border-color:color-mix(in oklab,var(--good),transparent 55%)}
.stamp-pass b{color:var(--good)}
.stamp-pass-with-findings{border-color:color-mix(in oklab,var(--warn),transparent 45%)}
.stamp-pass-with-findings b{color:var(--warn)}
.stamp-fail{border-color:color-mix(in oklab,var(--crit),transparent 35%)}
.stamp-fail b{color:var(--crit)}
.cov-line{margin:var(--space-3) 0 0;color:var(--text);font-size:.96rem;max-width:var(--measure)}
.cov-rule{margin-top:var(--space-2)}
.cov-rule summary{font-family:var(--font-mono);font-size:.74rem;letter-spacing:.04em;color:var(--text-muted);cursor:pointer;list-style:none}
.cov-rule summary::-webkit-details-marker{display:none}
.cov-rule summary::marker{content:""}
.cov-rule summary:hover{color:var(--ember-hi)}
/* the disclosure caret, drawn from two borders so it turns with the panel */
.cov-rule summary::before{content:"";display:inline-block;width:.4rem;height:.4rem;margin-right:.5rem;
  border-right:1px solid currentColor;border-bottom:1px solid currentColor;transform:translateY(-2px) rotate(-45deg);
  transition:transform var(--dur) var(--ease)}
.cov-rule[open] summary::before{transform:translateY(-4px) rotate(45deg)}
.cov-rule summary:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:2px}
.cov-rule ol{margin:var(--space-2) 0 0;padding-left:1.1rem;color:var(--text-muted);font-size:.88rem}
.cov-rule li{margin-bottom:.3rem;max-width:var(--measure)}

.coverage{margin-top:1.2rem}
.cov-head{display:flex;justify-content:space-between;align-items:flex-start;gap:var(--space-5);flex-wrap:wrap}
.cov-head .muted{max-width:60ch}
/* the honest headline: the biggest true number of individual checks, and how many areas ran one */
.cov-headline{font-family:var(--font-display);font-weight:700;font-size:var(--step-2);letter-spacing:-.01em;margin:0 0 var(--space-2);font-variant-numeric:tabular-nums}
.cov-headline b{color:var(--accent)}
.cov-figs{display:flex;gap:var(--space-5)}
.cov-figs .c{display:flex;flex-direction:column;align-items:flex-end}
.cov-figs .n{font-family:var(--font-mono);font-weight:700;font-size:clamp(1.4rem,3vw,2rem);line-height:1;font-variant-numeric:tabular-nums}
.cov-figs .k{font-size:.74rem;color:var(--text-muted)}
.cov-figs .ok .n{color:var(--good)}
.cov-figs .crit .n{color:var(--crit)}
@media(max-width:640px){.cov-figs{gap:var(--space-4)}.cov-figs .c{align-items:flex-start}}

.areas{list-style:none;margin:var(--space-4) 0 0;padding:0}
.area{border-top:1px solid var(--border)}
.area summary{display:grid;grid-template-columns:auto 1fr auto;gap:var(--space-3);align-items:baseline;
  padding:var(--space-3) 0;cursor:pointer;list-style:none}
.area summary::-webkit-details-marker{display:none}
.area summary::marker{content:""}
.area summary:hover .a-name{color:var(--ember-hi)}
.area summary:focus-visible{outline:2px solid var(--accent);outline-offset:-2px;border-radius:var(--radius)}
.area .mk{width:15px;height:15px;display:block;align-self:start;margin-top:.2rem}
.area .mk.pass{color:var(--good)}.area .mk.fail{color:var(--crit)}.area .mk.na{color:var(--text-dim)}
.a-main{min-width:0}
.a-name{font-family:var(--font-display);font-weight:600;font-size:.98rem;display:block;transition:color var(--dur) var(--ease)}
.a-what{display:block;color:var(--text-muted);font-size:.86rem;margin-top:.2rem;max-width:64ch}
.a-tally{font-family:var(--font-mono);font-size:.72rem;color:var(--text-dim);white-space:nowrap;font-variant-numeric:tabular-nums}
.a-tally::after{content:"";display:inline-block;width:.4rem;height:.4rem;margin-left:.7rem;
  border-right:1px solid currentColor;border-bottom:1px solid currentColor;transform:translateY(-2px) rotate(-45deg);
  transition:transform var(--dur) var(--ease)}
.area details[open] .a-tally::after{transform:translateY(-4px) rotate(45deg)}
.area summary:hover .a-tally::after{color:var(--ember-hi)}
@media(max-width:720px){.area summary{grid-template-columns:auto 1fr}.a-tally{grid-column:2;white-space:normal}}
.a-body{padding:0 0 var(--space-4) calc(15px + var(--space-3))}
.cov-withheld{color:var(--text-muted);font-size:.88rem;margin:0;max-width:var(--measure)}
table.checks{width:100%;border-collapse:collapse;font-size:.82rem}
table.checks th{text-align:left;font-family:var(--font-mono);font-weight:400;font-size:.7rem;letter-spacing:.08em;
  text-transform:uppercase;color:var(--text-dim);padding:.3rem .6rem .3rem 0;border-bottom:1px solid var(--border)}
table.checks td{padding:.35rem .6rem .35rem 0;border-bottom:1px solid var(--border);color:var(--text);vertical-align:top}
table.checks .tgt{font-family:var(--font-mono);font-size:.76rem;color:var(--text-muted);word-break:break-all}
table.checks .out{font-family:var(--font-mono);font-size:.76rem;white-space:nowrap}
table.checks .out.pass{color:var(--good)}
table.checks .out.fail{color:var(--crit)}
table.checks .out.skipped,table.checks .out.not-applicable{color:var(--text-dim)}
table.checks .why{color:var(--text-dim);white-space:normal}
@media(max-width:640px){table.checks .out{white-space:normal}}

/* methodology note */
.note.report-note{margin-top:1.2rem;border:1px solid var(--ember-line)}
.proofdefs{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:.8rem;margin:1rem 0}
.pdf-item{background:var(--bg-2);border:1px solid var(--border);border-radius:var(--radius);padding:.8rem}
.pdf-item h3{font-family:var(--font-mono);font-size:.78rem;letter-spacing:.05em;margin:0 0 .35rem}
.pdf-item.exploited h3{color:var(--accent)}.pdf-item.confirmed h3{color:var(--good)}.pdf-item.potential h3{color:var(--text-dim)}
.pdf-item p{font-size:.85rem;color:var(--text-muted);margin:0}

/* ============ the account area (FCD-023) ============ */
/* A statement of account from a firm that keeps proper books: steady, ruled, countable. Every
   value in the statement is set in the forensic mono and every label around it is prose, because a
   payment is the same kind of object as a scan finding, and it is treated as evidence. */

/* No page-level overflow:hidden. Hiding a sideways scroll would hide the fault from the responsive
   gate while the content stayed unreachable; the fixes are the min-width:0 below and the scroller
   around the statement. This one line stops a wide asset doing it. */
img,svg{max-width:100%}
/* A <select> takes its intrinsic width from its longest option, and the country list contains
   "South Georgia & South Sandwich Islands". The label wrapping it is the grid item, and a grid item
   defaults to min-width:auto, so that intrinsic width became the column's floor and pushed the
   whole document 34px sideways at 320px. Measured in Chromium: the label goes 320px to 251px and
   the document stops scrolling. Same failure class as the .acct-main / .acct-side pair. */
.form label,.row label{min-width:0}
input,select{max-width:100%;min-width:0}

/* Visually hidden, by clipping. NEVER position:absolute: an absolutely positioned child of a table
   cell resolves against the page, escapes the table's own overflow-x wrapper and drags the document
   sideways on a phone. This codebase has had that bug once already. */
.sr-only{display:inline-block;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}

.topright{display:flex;align-items:center;gap:var(--space-3)}
.toplink{display:inline-flex;align-items:center;min-height:44px;padding:0 .1rem;background:transparent;
  border:0;font-family:var(--font-mono);font-size:.78rem;color:var(--text-muted);cursor:pointer;
  text-decoration:underline;text-decoration-color:var(--border-strong);text-underline-offset:4px}
.toplink:hover{color:var(--accent);text-decoration-color:var(--accent)}
.toplink:focus-visible{outline:2px solid var(--ember-hi);outline-offset:2px;border-radius:2px}

.acct-grid{display:grid;grid-template-columns:1.15fr .85fr;gap:var(--space-4);align-items:start}
/* The single most important pair of lines here. A grid child defaults to min-width:auto, so one
   unbreakable string inside the statement would widen the column, widen the grid, and scroll the
   whole document sideways on a phone. */
.acct-main,.acct-side{min-width:0}
.acct-side{display:flex;flex-direction:column;gap:var(--space-4)}
@media(max-width:860px){.acct-grid{grid-template-columns:1fr}}

.ledger-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
.ledger{width:100%;border-collapse:collapse;font-size:.86rem}
.ledger caption{position:static}
.ledger th{text-align:left;font-family:var(--font-mono);font-weight:400;font-size:.7rem;
  letter-spacing:.08em;text-transform:uppercase;color:var(--text-muted);
  padding:.3rem .6rem .3rem 0;border-bottom:1px solid var(--border)}
.ledger td{padding:.6rem .6rem .6rem 0;border-bottom:1px solid var(--border);
  color:var(--text);vertical-align:top}
.ledger .when{font-family:var(--font-mono);font-variant-numeric:tabular-nums;
  color:var(--text-muted);white-space:nowrap}
/* Never truncate the subject: a shortened host on a payment record is a lie about what was bought. */
.ledger .what{overflow-wrap:anywhere}
.ledger .num{text-align:right;font-family:var(--font-mono);font-weight:500;
  font-variant-numeric:tabular-nums;white-space:nowrap}
.ledger tbody tr{--rule:var(--border-strong)}
.ledger tbody tr[data-status="paid"]{--rule:var(--good)}
.ledger tbody tr[data-status="pending"]{--rule:var(--accent)}
/* The state rule sits on the first cell in table mode: a border-left on a <tr> under
   border-collapse:collapse is not reliable. In stacked mode it moves to the row. */
.ledger tbody td:first-child{border-left:2px solid var(--rule);padding-left:.7rem}
.ledger .foot td{border-bottom:0;border-top:1px solid var(--border-strong);
  padding-top:.7rem;color:var(--text-muted);font-family:var(--font-mono)}
.ledger .foot .num{color:var(--text);font-weight:700;font-size:.95rem}
.ledger .skel td{color:var(--text-dim);font-family:var(--font-mono)}
.inv{font-family:var(--font-mono);font-size:.82rem;color:var(--accent);white-space:nowrap;
  text-decoration:underline;text-decoration-style:dotted;text-underline-offset:3px}
.inv:hover{color:var(--ember-hi)}
.inv:focus-visible{outline:2px solid var(--ember-hi);outline-offset:2px;border-radius:2px}
.inv-none{font-family:var(--font-mono);font-size:.8rem;color:var(--text-muted)}
.ledger-note{color:var(--text-muted);font-size:.82rem;margin:.7rem 0 0;max-width:var(--measure)}
.ledger-empty{color:var(--text);margin:1rem 0 0;max-width:var(--measure)}
.btn-more{margin-top:var(--space-4);min-height:44px;background:transparent;border:1px solid var(--border-strong);
  color:var(--text);font-weight:400;font-size:.86rem}
.btn-more:hover{border-color:var(--accent);color:var(--accent);transform:none;box-shadow:none}
.btn-more:focus-visible{outline:2px solid var(--ember-hi);outline-offset:2px}

/* The rail is not a card. It is a flex column of two cards, and the gap between them is the grid's. */
.card.account h2{margin-bottom:.6rem}
.card.account .muted{max-width:var(--measure)}
.card.account .row{grid-template-columns:1fr}
.sec-block{border-top:1px solid var(--border);padding-top:var(--space-4);margin-top:var(--space-4)}
.sec-block:first-of-type{border-top:0;padding-top:0;margin-top:var(--space-3)}
.sec-block h3{font-family:var(--font-display);font-weight:600;font-size:1rem;margin:0 0 .7rem}
.sec-block.mfa{margin-top:var(--space-4)}
.sec-block .form{margin:0}
.reset-line{color:var(--text);margin:0 0 var(--space-3);max-width:var(--measure);line-height:1.55}

/* Show / Hide: the words, because an eye glyph is ambiguous about which state it means. It sits
   inside the label after the input, so it is in the tab order where a person expects it. */
.pw-field{position:relative}
.pw-field input{padding-right:4.2rem}
.pw-toggle{position:absolute;right:.4rem;bottom:.3rem;min-height:38px;padding:0 .7rem;
  background:transparent;border:1px solid var(--border-strong);border-radius:var(--radius);
  color:var(--text-muted);font-family:var(--font-mono);font-size:.74rem;cursor:pointer}
.pw-toggle:hover{border-color:var(--accent);color:var(--accent)}
.pw-toggle:focus-visible{outline:2px solid var(--ember-hi);outline-offset:2px}

/* Below 700px the five columns cannot hold, so each row stacks and every label moves into its own
   cell. thead goes, and the explicit ARIA roles in the markup are what keep the table a table:
   changing the display of a table part strips its implicit role in several engines. */
@media(max-width:700px){
  .ledger,.ledger thead,.ledger tbody,.ledger tfoot,.ledger tr,.ledger td{display:block;width:100%}
  .ledger thead{display:none}
  .ledger tbody tr{border-left:2px solid var(--rule);border-bottom:1px solid var(--border);
    padding:.7rem 0 .7rem .7rem}
  .ledger tbody td{border-bottom:0;border-left:0;padding:.15rem 0;
    display:grid;grid-template-columns:8.5rem 1fr;gap:.6rem;align-items:baseline}
  .ledger td::before{content:attr(data-label);font-family:var(--font-mono);font-size:.7rem;
    letter-spacing:.08em;text-transform:uppercase;color:var(--text-muted)}
  .ledger .num{text-align:left}
  .ledger .when{white-space:normal}
  /* A grid item stretches by default, so the status pill became a full-width bar the moment the
     row stacked. Only the two real elements are pinned to the start: doing it with justify-items
     on the cell would give the anonymous text items a max-content width, which is how a long
     unbreakable subject would push the document sideways again. */
  .ledger .shield,.ledger .inv{justify-self:start}
  .ledger .foot td{border-top:0}
  .ledger tfoot tr.foot{border-top:1px solid var(--border-strong);padding-top:.7rem;
    display:flex;justify-content:space-between;gap:.6rem}
  .ledger tfoot td::before{content:none}
  /* 44px on touch only: on a desktop this is a mouse target in a dense table. */
  .inv{display:inline-flex;align-items:center;min-height:44px}
}
@media(max-width:520px){#topState{display:none}}
@media(max-width:400px){
  .brand em{display:none}
  .ledger tbody td{grid-template-columns:1fr}
  .ledger td::before{margin-bottom:.1rem}
}

/* The statement lands as a statement: rows fade in, in order, and the stagger caps at six so a
   full page does not take a second to arrive. Opacity only. A transform on a <tr> is not reliably
   composited, and a statement that lands crooked in one browser is worse than one that fades. */
@media (prefers-reduced-motion: no-preference){
  .ledger tbody tr{animation:rowIn 220ms var(--ease) backwards}
  .ledger tbody tr:nth-child(1){animation-delay:0ms}
  .ledger tbody tr:nth-child(2){animation-delay:40ms}
  .ledger tbody tr:nth-child(3){animation-delay:80ms}
  .ledger tbody tr:nth-child(4){animation-delay:120ms}
  .ledger tbody tr:nth-child(5){animation-delay:160ms}
  .ledger tbody tr:nth-child(n+6){animation-delay:200ms}
  @keyframes rowIn{from{opacity:0}to{opacity:1}}
}

/* the one orchestrated moment: reach ladders fill in a staggered wave on report load */
@media (prefers-reduced-motion: no-preference){
  .findings.report .rungs i{animation:litIn 320ms var(--ease) backwards}
  .findings.report .rcard:nth-child(1) .rungs{--d:0ms}.findings.report .rcard:nth-child(2) .rungs{--d:80ms}
  .findings.report .rcard:nth-child(3) .rungs{--d:160ms}.findings.report .rcard:nth-child(4) .rungs{--d:240ms}
  .findings.report .rcard:nth-child(5) .rungs{--d:320ms}.findings.report .rcard:nth-child(n+6) .rungs{--d:400ms}
  .rungs i:nth-child(1){animation-delay:calc(var(--d,0ms) + 0ms)}
  .rungs i:nth-child(2){animation-delay:calc(var(--d,0ms) + 55ms)}
  .rungs i:nth-child(3){animation-delay:calc(var(--d,0ms) + 110ms)}
  .rungs i:nth-child(4){animation-delay:calc(var(--d,0ms) + 165ms)}
  .rungs i:nth-child(5){animation-delay:calc(var(--d,0ms) + 220ms)}
  @keyframes litIn{from{opacity:0;transform:scaleX(.2);transform-origin:left}to{opacity:1;transform:scaleX(1)}}
}

/* FCD-029 the clean scan record. One block under the verdict, in the console register: the same
   card, the same ember action, the same 44px targets as every other control here. */
.recordblock{display:flex;flex-direction:column;gap:var(--space-2)}
.recordblock .k{color:var(--text-muted);font-size:.9rem;line-height:1.5;max-width:var(--measure)}
.recordblock .k.refused{color:var(--text-dim)}
.recordblock .btn-record{align-self:flex-start;min-height:44px}
.recordblock .record-code{font-family:var(--font-mono);font-size:1.1rem;letter-spacing:.04em;
  font-variant-numeric:tabular-nums;display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--space-2)}
.recordblock .record-code .k{font-size:.78rem;letter-spacing:.06em;text-transform:uppercase}
.recordblock .record-code b{color:var(--text);font-weight:500;word-break:break-word}
.recordblock .record-url code{font-family:var(--font-mono);font-size:.82rem;color:var(--accent);
  word-break:break-all}
.recordblock .record-actions{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2) var(--space-4);
  margin-top:var(--space-2)}
.recordblock .record-actions .lnk{color:var(--text-muted);font-size:.82rem;font-family:var(--font-mono);
  text-decoration:underline;text-underline-offset:2px;background:none;border:0;cursor:pointer;
  min-height:44px;display:inline-flex;align-items:center;padding:0}
.recordblock .record-actions .lnk:hover{color:var(--accent)}
.recordblock .record-actions .lnk:focus-visible{outline:2px solid var(--ember-hi);outline-offset:3px}
.recordblock .btn-copy-record{min-height:44px;padding:0 .9rem;font-size:.82rem;background:transparent;
  border:1px solid var(--border-strong);color:var(--text)}
.recordblock .btn-copy-record:hover{border-color:var(--accent);color:var(--accent)}
.recordblock .btn-record[aria-busy="true"]{opacity:.7;cursor:progress}
/* the destructive control is quiet and kept away from the two a customer uses every day, so it is
   never the thing a hand reaches for by habit */
.recordblock .btn-withdraw{color:var(--text-dim);margin-left:auto}
.recordblock .btn-withdraw:hover{color:var(--crit)}
.recordblock p{margin:0}
.recordblock .err:empty{display:none}
/* ---- FCD-033: the fix list --------------------------------------------------------------------
   A service engineer's job sheet: ruled, ordered, worked top to bottom, with a signature against
   each line when the work is checked. The one bold move is the spine: a card cannot mark itself
   done, so there is no checkbox anywhere on this surface, and a station fills solid only when our
   own probe ran and found nothing. Where the owner did something we are structurally unable to
   test, the station fills as an outline instead, so "we proved this" and "you told us this" are
   two visibly different marks on the same record and stay different forever.

   Every measure on this surface is min(var(--measure),100%). --measure is 64ch, which is wider
   than a 390px viewport, so a bare max-width:var(--measure) on a paragraph carrying a customer's
   own path is a horizontal scrollbar on every phone. */
.platform,.packcard,.recordcard{margin-top:var(--space-4)}
.plat-fields{display:flex;flex-direction:column;gap:var(--space-3);margin-bottom:var(--space-3)}
.plat-f label{display:block;font-size:var(--step--1);color:var(--text-muted);margin-bottom:var(--space-1)}
.plat-f select{width:100%;max-width:26rem;min-height:var(--target);background:var(--bg-2);color:var(--text);
  border:1px solid var(--border-strong);border-radius:var(--radius);padding:0 var(--space-2);font:inherit}
.plat-f select:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.plat-ev{color:var(--text-muted);font-size:var(--step--1);margin:var(--space-1) 0 0;max-width:min(var(--measure),100%)}

.pack-head{border-bottom:1px solid var(--border);padding-bottom:var(--space-3);margin-bottom:var(--space-4)}
.pack-contents{color:var(--text);max-width:min(var(--measure),100%);line-height:1.6;margin:var(--space-2) 0 0;overflow-wrap:anywhere}
.pack-first{color:var(--text);max-width:min(var(--measure),100%);margin:var(--space-2) 0 0;
  overflow-wrap:anywhere}
.pack-progress{color:var(--text-muted);font-variant-numeric:tabular-nums;margin:var(--space-2) 0 0}
.pack-buy{display:flex;flex-direction:column;gap:var(--space-2);align-items:flex-start;margin-bottom:var(--space-4)}
.pack-buy .muted{margin:0;max-width:min(var(--measure),100%)}
.pack-unavailable{color:var(--text-muted);max-width:min(var(--measure),100%);margin:0 0 var(--space-4);line-height:1.6}

/* The spine is one continuous rule down the left edge with a station on it at the vertical centre
   of each card. Nothing else on this page is continuous. */
/* The four local custom properties, all resolving to existing tokens, so this surface adds no
   global token of its own. */
.pack{--station-open:var(--text-dim);--station-proven:var(--good);--station-declared:var(--text-muted);
  --station-blocked:var(--warn);display:block}
/* No margin between groups. The air above a destination heading is PADDING inside the heading
   row, which has a rail cell of its own, so the spine runs unbroken from the first card to the
   last. A margin here would have left a 32px break in the line at every group boundary. */
.pack-group{margin:0}
.pack-group h3{font-family:var(--font-display);font-weight:600;font-size:var(--step-0);margin:0;
  padding:var(--space-5) 0 var(--space-3);text-wrap:balance}
.pack-group:first-child h3{padding-top:0}
/* Every row is the same two columns, the heading rows included, so the rule down the left runs
   unbroken through a destination heading and the worksheet reads as one continuous line. */
.fixrow{display:grid;grid-template-columns:32px minmax(0,1fr);column-gap:var(--space-3);align-items:stretch}
.pack-col{min-width:0}
.railcell{position:relative;justify-self:center;width:2px;background:var(--border);align-self:stretch}
/* At the vertical centre of its own card, so the marker reads as belonging to that card rather
   than to the line between two of them. */
.station{position:absolute;top:50%;left:50%;width:14px;height:14px;margin:-7px 0 0 -7px;border-radius:50%;
  border:2px solid var(--station-open);background:var(--bg);box-sizing:border-box}
.station[data-state="proven"]{border-color:var(--station-proven);background:var(--station-proven)}
.station[data-state="declared"]{border-color:var(--station-declared);
  background:radial-gradient(circle at 50% 50%,var(--station-declared) 0 3px,var(--bg) 3px)}
.station[data-state="blocked"]{border-color:var(--station-blocked);
  background:repeating-linear-gradient(45deg,var(--station-blocked) 0 2px,var(--bg) 2px 4px)}
.railcell[data-state="proven"]{background:color-mix(in srgb,var(--station-proven) 60%,transparent)}
.railcell[data-state="declared"]{background:color-mix(in srgb,var(--station-declared) 40%,transparent)}
.railcell[data-state="blocked"]{background:color-mix(in srgb,var(--station-blocked) 40%,transparent)}

/* Every sentence on this surface may carry the customer's own path, and a path has no spaces in
   it. Without this, one 200 character path sets the min-content width of its paragraph and the
   whole page scrolls sideways. break-word rather than anywhere, so ordinary prose still breaks at
   its spaces and only an unbreakable run is split. */
.fixcard p,.fixcard li,.pack-head p,.ledger .what,.plat-ev,.notfix p,.fc-proveline,.proofline{
  overflow-wrap:break-word}

.fixcard{--sev:var(--text-muted);background:var(--surface);border:1px solid var(--border);
  border-left:3px solid var(--sev);border-radius:var(--radius-lg);padding:var(--space-4);
  margin:0 0 var(--space-4);min-width:0}
.fixcard.sev-critical,.fixcard.sev-high{--sev:var(--crit)}
.fixcard.sev-medium{--sev:var(--warn)}
.fixcard[data-state="proven"]{border-left-color:var(--station-proven)}
/* minmax(0,1fr), never 1fr. A grid track's automatic minimum is its content's min-content size,
   so a heading carrying a path at the validator's 200 character ceiling would push the card, the
   worksheet and the whole page sideways. This is the rule that keeps the body from ever scrolling
   horizontally, and it is why the browser gate measures document.body.scrollWidth. */
.fc-head{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:var(--space-3);align-items:start;
  margin-bottom:var(--space-2)}
.fc-title{font-family:var(--font-display);font-weight:600;font-size:var(--step-1);margin:0;line-height:1.25;
  text-wrap:balance;overflow-wrap:anywhere;word-break:break-word;min-width:0}
.fc-what{color:var(--text);max-width:min(var(--measure),100%);line-height:1.6;margin:0 0 var(--space-2);overflow-wrap:anywhere}
.fc-meta{color:var(--text-muted);font-size:var(--step--1);font-variant-numeric:tabular-nums;margin:0}
.fc-undo{color:var(--text-muted);border-top:1px solid var(--border);padding-top:var(--space-2);
  margin:var(--space-3) 0;max-width:min(var(--measure),100%);line-height:1.55}
.fc-where{font-family:var(--font-display);font-weight:600;font-size:var(--step-0);margin:var(--space-3) 0 var(--space-2)}
.fc-degraded{color:var(--text-muted);font-size:var(--step--1);margin:0 0 var(--space-2);max-width:min(var(--measure),100%)}
.fixcard .own-steps{margin:0 0 var(--space-3)}
.fixcard .own-steps li{align-items:flex-start}
.fc-step{max-width:min(var(--measure),100%);line-height:1.55;overflow-wrap:anywhere}

/* The paste block is the only mono element in this product set at body size. It is deliberate:
   mono is metadata everywhere else, and here it is the work. The thing the owner has to select and
   copy is the largest, highest contrast block on the card and the prose around it is quieter. */
.paste{background:var(--bg-2);border:1px solid var(--border);border-radius:var(--radius);
  font-family:var(--font-mono);font-size:var(--step-0);line-height:1.55;padding:var(--space-3);
  overflow-x:auto;white-space:pre;tab-size:2;margin:var(--space-2) 0 0;user-select:all;max-width:100%}
.paste figcaption{font-family:var(--font-body);font-size:var(--step--1);color:var(--text-muted);
  margin:0 0 var(--space-2);white-space:normal;user-select:text}
.paste-actions{display:flex;align-items:center;gap:var(--space-2);flex-wrap:wrap;margin-top:var(--space-2)}
.paste-actions .btn-copy{min-height:34px;padding:0 var(--space-2);font-size:var(--step--1);background:transparent;
  border:1px solid var(--border-strong);color:var(--text);border-radius:var(--radius);cursor:pointer}
.paste-actions .btn-copy:hover{border-color:var(--accent);color:var(--accent)}
.paste-actions .btn-copy:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

.fc-prove{display:flex;flex-direction:column;gap:var(--space-2);align-items:flex-start;
  border-top:1px solid var(--border);padding-top:var(--space-3);margin-top:var(--space-3)}
/* align-items:flex-start keeps the button its own width, and it also sizes every sibling to its
   max-content, which a sentence carrying a 200 character path uses to push the page sideways. */
.fc-prove>*,.pack-buy>*{max-width:100%}
.fc-prove .btn{min-height:var(--target)}
.fc-proveline{color:var(--text-muted);font-size:var(--step--1);margin:0;max-width:min(var(--measure),100%)}
.proofline{font-size:var(--step-0);line-height:1.55;margin:0;max-width:min(var(--measure),100%);color:var(--text)}
.proofline[data-outcome="closed"]{color:var(--good)}
.proofline[data-outcome="blocked"]{color:var(--warn)}
.proofline[data-outcome="open"],.proofline[data-outcome="unowned"]{color:var(--text)}
.proofline[data-outcome="unverifiable"]{color:var(--text-muted)}
.handoff,.notfix{margin-top:var(--space-3);border-top:1px solid var(--border);padding-top:var(--space-2)}
.handoff summary,.notfix summary{cursor:pointer;color:var(--text-muted);font-size:var(--step--1)}
.handoff summary:hover,.notfix summary:hover{color:var(--accent)}
.handoff summary:focus-visible,.notfix summary:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.handoff textarea{width:100%;min-height:11rem;resize:vertical;background:var(--bg-2);color:var(--text);
  border:1px solid var(--border-strong);border-radius:var(--radius);padding:var(--space-2);
  font-family:var(--font-mono);font-size:var(--step--1);line-height:1.6;margin-top:var(--space-2)}
.handoff textarea:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.notfix p{color:var(--text-muted);max-width:min(var(--measure),100%);line-height:1.55;margin:var(--space-2) 0 0}

.rescan{border-top:1px solid var(--border);padding-top:var(--space-4);margin-top:var(--space-4)}
.rescan h3{font-family:var(--font-display);font-weight:600;font-size:var(--step-0);margin:0 0 var(--space-2)}
.rescan .muted{max-width:min(var(--measure),100%)}
.ledger{list-style:none;margin:var(--space-3) 0 0;padding:0}
.ledger li{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:var(--space-3);padding:var(--space-2) 0;
  border-bottom:1px solid var(--border);align-items:baseline}
.ledger .when{font-family:var(--font-mono);font-size:var(--step--1);color:var(--text-muted);
  font-variant-numeric:tabular-nums;white-space:nowrap}
.ledger .what{min-width:0;overflow-wrap:anywhere}
.ledger .mark{font-size:var(--step--1);white-space:nowrap;color:var(--text-muted)}
.ledger .mark[data-outcome="closed"]{color:var(--good)}
.ledger .mark[data-outcome="blocked"]{color:var(--warn)}

@media (max-width:720px){
  .pack,.fixrow{grid-template-columns:20px minmax(0,1fr);column-gap:var(--space-2)}
  .station{width:12px;height:12px;margin:-6px 0 0 -6px}
  .fc-head{grid-template-columns:1fr}
  .fc-head .sev{order:-1;justify-self:start}
  .ledger li{grid-template-columns:1fr;gap:var(--space-1)}
}
@media (max-width:560px){
  .paste-actions{align-items:stretch}
  .paste-actions .btn-copy{width:100%}
  .pack-buy .btn,.rescan .btn{width:100%}
}
@media (max-width:520px){
  .pack-group h3{padding-top:var(--space-4)}
}

/* One orchestrated moment, and it belongs to the proof: when a re-check returns closed the station
   fills and the rule below it grows downward. Transform and colour only. Nothing else on this
   surface animates, because the report already owns the page-load moment with its reach ladder. */
@media (prefers-reduced-motion:no-preference){
  .railcell{transform-origin:top}
  .railcell[data-state="proven"],.railcell[data-state="declared"],.railcell[data-state="blocked"]{
    animation:railfill var(--dur-slow) var(--ease) both}
  .fixcard{transition:border-left-color var(--dur) var(--ease)}
  .station{transition:background-color var(--dur-slow) var(--ease),border-color var(--dur) var(--ease)}
}
@keyframes railfill{from{transform:scaleY(0)}to{transform:scaleY(1)}}
.r-fixline{color:var(--text-muted);font-size:var(--step--1);margin:var(--space-1) 0 0;max-width:min(var(--measure),100%)}

/* ---- FCD-028: the quote document -------------------------------------------------------------
   The diff IS the sales page. That is affordable because the patch is deterministic: it comes out
   of a template rather than a model, so every line can be rendered before anybody pays, and the
   line they read is the line that gets committed. Everything here is built to be READ, not skimmed:
   the diff is set solid so a hunk reads as one block, and the added lines carry a colour that is
   mixed into the warm ground rather than a browser green on white. */
.fixnote{margin:.6rem 0 0;font-size:.86rem;max-width:var(--measure)}
.fixquote{margin-top:var(--space-4);display:flex;flex-direction:column;gap:var(--space-4)}
.fixlinkage{background:var(--surface-3);border:1px solid var(--border);border-radius:var(--radius);
  padding:.8rem 1rem;margin:0;font-size:.9rem;line-height:1.55;max-width:var(--measure)}
.fixitems{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--space-3)}
.fixitem{border-left:3px solid var(--border-strong);padding-left:.9rem}
/* One colour per verdict, and only two of the five are coloured at all: the one we will change and
   the one we refuse. Colouring all five turns a document into a chart. */
.fixitem-attempted{border-left-color:var(--good)}
.fixitem-refused,.fixitem-stale{border-left-color:var(--crit)}
.fixitem-h{margin:0 0 .25rem;font-family:var(--font-mono);font-size:.86rem;color:var(--text);
  word-break:break-word}
.fixitem .muted{margin:0;font-size:.86rem;line-height:1.55;max-width:var(--measure)}
.fixwarn{margin:.4rem 0 0;font-size:.86rem;color:var(--warn);max-width:var(--measure)}
/* The diff scrolls INSIDE its own box. A long line in somebody else's source must never make the
   dashboard scroll sideways on a phone, which is the fault this project has shipped four times. */
.diff{margin:.6rem 0 0;padding:.7rem .8rem;background:var(--surface-3);border-radius:var(--radius);
  overflow-x:auto;font-family:var(--font-mono);font-size:.78rem;line-height:1.45;white-space:pre;
  max-height:22rem;overflow-y:auto}
.diff-file{color:var(--text-muted);font-size:.72rem;letter-spacing:.04em;text-transform:uppercase;
  margin:.4rem 0 .3rem}
.diff-file:first-child{margin-top:0}
.diff-add{color:var(--text);background:color-mix(in oklab, var(--surface-3), var(--good) 12%)}
.fixproof{margin:.5rem 0 0;font-family:var(--font-mono);font-size:.78rem}
.fixproof-gone{color:var(--good)}
.fixproof-standing{color:var(--warn)}
.fixproof-worse{color:var(--crit)}
.fixproof-untested{color:var(--text-dim)}
.fixbuy{border-top:1px solid var(--border);padding-top:var(--space-3)}
.fixprice{margin:0 0 .5rem;font-family:var(--font-display);font-size:1.15rem;color:var(--text)}
.fixbuys{margin:0 0 .9rem;padding-left:1.1rem;color:var(--text-muted);font-size:.86rem;
  line-height:1.6;max-width:var(--measure)}
.fixbuys li{margin:.2rem 0}
.fixverdict{border-top:1px solid var(--border);padding-top:var(--space-3)}
.fixverdict-line{margin:0;font-family:var(--font-display);font-size:1.05rem;line-height:1.4;
  max-width:var(--measure)}
#fixVerifyBtn{margin-top:.8rem}
/* The code answer sits under the server answer, quieter than it: on most findings the server is
   where the fix lives, and the code line is the one that most often says no. */
.r-codefix{margin:.2rem 0 0;font-size:.82rem;color:var(--text-dim);max-width:var(--measure)}
.mfa-why{margin:.4rem 0 .8rem;font-size:.84rem;max-width:var(--measure)}
/* FCD-042: the recovery codes, shown once. Monospace and generously spaced because these get
   written down by hand and read back a year later under stress. */
.recovery{margin-top:var(--space-3);border-top:1px solid var(--border);padding-top:var(--space-3)}
.recovery h3{margin:0 0 .4rem;font-size:1rem}
.recovery-codes{list-style:none;margin:.6rem 0 .9rem;padding:0;display:grid;
  grid-template-columns:repeat(auto-fill,minmax(9.5rem,1fr));gap:.45rem}
.recovery-codes li{font-family:var(--font-mono);font-size:1rem;letter-spacing:.06em;
  background:var(--surface-3);border-radius:var(--radius);padding:.45rem .6rem;text-align:center}
.mfa-low{color:var(--warn);font-size:.86rem;max-width:var(--measure)}

/* FCD-045: the dependency section. Free, outside the quote, and styled as a reading list rather
   than a dashboard: these are exact versions out of the customer's own lockfile, so the useful
   thing is the name and the identifier, not a colour. */
.deps{margin:var(--space-4) 0 0;padding-top:var(--space-4);border-top:1px solid var(--border)}
.deps-h{margin:0 0 .5rem;font-size:.95rem}
.deps-note{margin:0 0 .8rem;font-size:.9rem;line-height:1.55;max-width:var(--measure)}
.deps-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.7rem}
.deps-item{border-left:3px solid var(--border-strong);padding-left:.9rem}
/* Only the one that needs attention first is coloured. An unevaluated row is deliberately not
   coloured at all: it is a gap of ours and it should not read as a verdict about them. */
.deps-high{border-left-color:var(--crit)}
.deps-item-h{margin:0 0 .2rem;font-family:var(--font-mono);font-size:.86rem;color:var(--text);
  word-break:break-word}
.deps-item .muted{margin:0;font-size:.82rem;line-height:1.5;max-width:var(--measure);
  word-break:break-word}
.deps-src{margin:.9rem 0 0;font-size:.78rem;line-height:1.5;max-width:var(--measure)}

/* FCD-034: the depth control. Styled as a quiet ledger, not a call to action — a deeper scan is a
   deliberate choice an owner makes, and the design puts the words they are agreeing to in front of
   the button rather than the button in front of the words. */
.depth{border-top:1px solid var(--border);padding-top:var(--space-4);margin-top:var(--space-4)}
.depth h3{font-family:var(--font-display);font-weight:600;font-size:var(--step-0);margin:0 0 var(--space-2)}
.depth .muted{max-width:min(var(--measure),100%)}
.depth-ledger{list-style:none;margin:var(--space-3) 0;padding:0;display:flex;flex-direction:column;gap:.5rem}
.depth-ledger li{position:relative;padding-left:1.1rem;font-size:.9rem;line-height:1.55;
  max-width:min(var(--measure),100%)}
.depth-ledger li::before{content:"";position:absolute;left:0;top:.55em;width:.4rem;height:.4rem;
  border:1px solid var(--border-strong);border-radius:50%}
.depth-actions{display:flex;flex-wrap:wrap;gap:var(--space-2);margin-top:var(--space-2)}
.btn--ghost{background:transparent;border:1px solid var(--border-strong);color:var(--text)}
/* The exploited(reached) sub-label, where a deeper scan walked through a confirmed hole. It reads
   as a qualifier on the proof word, not as a fourth rung. */
.reached{font-size:.72rem;letter-spacing:.04em;text-transform:uppercase;color:var(--good);
  margin-left:.4rem}

/* FCD-032: the delta band. Set in the same restrained register as the coverage ledger — a normal
   result is a quiet result, and the accent lights only where a check we did not have before reached
   something. */
.delta .delta-line{font-size:.95rem;line-height:1.55;margin:0 0 var(--space-3);max-width:min(var(--measure),100%)}
.delta-causes{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.5rem}
.delta-cause{position:relative;padding-left:1.1rem;font-size:.88rem;line-height:1.5;
  font-family:var(--font-mono);font-variant-numeric:tabular-nums;color:var(--text-muted)}
.delta-cause::before{content:"";position:absolute;left:0;top:.5em;width:.4rem;height:.4rem;
  border-radius:50%;background:var(--border-strong)}
/* Only the one that means "a check we did not have reached you" takes the accent. The rest are the
   ordinary machinery of a site that changed or a corner we cannot attribute. */
.delta-check-new{color:var(--text)}
.delta-check-new::before{background:var(--accent)}
.delta-rule{margin-top:var(--space-3);font-size:.82rem}
.delta-rule summary{cursor:pointer;color:var(--text-muted)}
.delta-rule ul{margin:.6rem 0 0;padding-left:1.1rem;line-height:1.5;color:var(--text-muted)}
