/* Ported from the original portal's reader (prototype/spectriad_proto/
   portal_ui.py STYLE): same palette, measures, and affordances; selectors
   adapted to this slice's markup. */

body{max-width:76rem;margin:0 auto 2.5rem;padding:0 1.25rem;
  font:15px/1.5 system-ui;background:#f5f7fa;color:#17202a}
/* Public deployments expose the evidence snapshot, never mutation controls.
   The server independently rejects every non-read request; this rule keeps
   the presentation aligned with that trust boundary. */
body.public-readonly form{display:none}
nav.portal{display:flex;align-items:center;gap:.25rem;
  border-bottom:1px solid #d9dee7;padding:.7rem 0;margin-bottom:1rem}
nav.portal .brand{font-weight:700;font-size:1.1rem;margin-right:.8rem}
nav.portal .brand .tri{color:#245b93}
nav.portal a.tab{color:#245b93;text-decoration:none;padding:.3rem .7rem;
  border-radius:6px}
nav.portal a.tab.on{background:white;border:1px solid #d9dee7;
  font-weight:600;color:#17202a}
nav.portal .identity{margin-left:auto;font-size:.88rem;color:#667085}
section{background:white;border:1px solid #d9dee7;border-radius:10px;
  padding:1rem 1.4rem;margin:1rem 0}
h1{font-size:1.45rem;margin:.2rem 0}h2{font-size:1.05rem}
table{border-collapse:collapse;width:100%;font-size:.88rem}
th,td{text-align:left;padding:.45rem .5rem;border-bottom:1px solid #eef2f6;
  vertical-align:top}
code{font-family:ui-monospace,monospace;font-size:.84em}
a{color:#245b93}.meta{color:#667085}.hint{color:#667085;font-size:.85rem}
.warn{color:#a3312a}
pre{background:#f8fafc;border:1px solid #eef2f6;border-radius:6px;
  padding:.6rem .8rem;overflow-x:auto;font-size:.84rem;line-height:1.45}

/* Status badges (pill), coloured by evidence state. */
.badge{display:inline-block;padding:.1rem .55rem;border-radius:999px;
  background:#eef2f6;font-size:.8rem;white-space:nowrap;
  text-decoration:none;color:#4a5462}
.badge.st-drafted{background:#f1f3f6;color:#5b6470}
.badge.st-no-verdict{background:#fdf3e2;color:#8a5700;
  border:1px dashed #e6c98a}
.badge.st-passing{background:#e7f4ea;color:#176b3a}
.badge.st-failing{background:#fbe9e7;color:#a12622;font-weight:600}
.badge.st-attention{background:#fdf3e2;color:#a3552e}

/* Server-side syntax colouring: comments, strings, keywords, names. */
.tok-c{color:#6a737d;font-style:italic}.tok-s{color:#22732c}
.tok-k{color:#7c4dbe}.tok-n{color:#245b93}

/* Document list. */
.reader-files{width:auto;min-width:32rem}
.reader-files td,.reader-files th{padding:.3rem .6rem}
/* The pinned commit, as a subtitle under the file it pins. */
.file-rev{display:block;margin-top:.1rem;font-size:.8rem;color:#667085}
.file-rev a{color:#667085}
section.synthetic{border-style:dashed}

/* The PBT index: one row per registered test, read across rather than
   down, so the cells hold fields instead of prose. */
.pbt-index{width:auto;min-width:44rem}
.pbt-index td,.pbt-index th{padding:.4rem .6rem;vertical-align:middle}
.pbt-index th{font-size:.74rem;font-weight:600;color:#8c96a4;
  text-transform:lowercase}
.pbt-index td .metric+.metric{margin-left:.7rem}
/* A filename is one token to scan, not four lines of wrapped text. */
.pbt-index td code{font-size:.8rem;white-space:nowrap}
/* The pass under test, under the id it belongs to. */
.pbt-stage{display:block;font-size:.8rem;color:#667085;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  max-width:22rem}
/* What a batch's rows add up to, above the batch. */
.pbt-group-counts{display:flex;flex-wrap:wrap;gap:1.1rem;
  margin:.3rem 0 .7rem}
.synthetic-note{background:#fff6e0;border:1px dashed #d8b44a;
  border-radius:6px;padding:.4rem .7rem;font-size:.9rem}

/* The Reader: one documentation file rendered as a document, at a
   reading measure rather than the portal's full width. */
.reader-doc{max-width:46rem;background:white;border:1px solid #d9dee7;
  border-radius:10px;padding:1rem 2rem 4.5rem 6.2rem;margin:1rem auto}
@media (max-width:60rem){.reader-doc{padding-left:3.6rem}}

/* The source line each block starts at, in a gutter inside the page. The
   anchors, the condition cards and the drafts all cite this document by
   line, so the lines a reader is asked to follow are on the page. */
.doc-block{position:relative}
.doc-line{position:absolute;left:-2.9rem;width:2.2rem;text-align:right;
  color:#a3adbb;font:.7rem/1.9 ui-monospace,monospace;text-decoration:none;
  font-variant-numeric:tabular-nums;user-select:none}
.doc-line:hover{color:#245b93}
.reader-doc h1{font-size:1.35rem;margin:1.2rem 0 .4rem}
.reader-doc h2,.reader-doc h3{margin:1.1rem 0 .3rem}
.reader-doc pre code{font-size:1em}
.reader-doc blockquote{margin:.6rem 0;padding-left:.8rem;
  border-left:3px solid #d9dee7;color:#4a5462}
.reader-doc table{width:auto;border:1px solid #d9dee7}
.reader-doc th,.reader-doc td{border:1px solid #d9dee7}
.reader-doc img{max-width:100%}

/* A quoted span: the words a statement committed to reading. The SIDE
   is in the colour — amber for an output-side property, blue for an
   input-side generator constraint. */
/* box-decoration-break:clone is what makes a multi-line highlight look
   like a selection: every line box gets its own background, ending where
   its text ends rather than at the column edge. */
mark.q{background:#fff3c4;padding:.05em .1rem;border-radius:3px;
  -webkit-box-decoration-break:clone;box-decoration-break:clone;
  color:inherit}
mark.q.in{background:#ddebff}
/* Inside a code block the highlight follows the code's own lines. */
.q-block pre mark.q{padding:0;border-radius:0;background:#fff3c4}
.q-block.in pre mark.q{background:#ddebff}

/* An anchored line range, for claims citing whole passages rather than
   exact words. Ben, 2026-09-03: the highlight is a LINE HIGHLIGHT on the
   words, as in the original portal -- not a bordered box. The text carries
   the same amber/blue as mark.q and nothing draws a container around it. */
/* The anchored range itself carries NO background: the highlight lives on
   the text inside it (mark.q above), so it hugs the words instead of
   painting a box out to the column edge. */
.q-block{scroll-margin-top:4rem;position:relative}
/* Badges that could not ride a word, trailing the passage they belong to. */
.q-tail{margin:.15rem 0 0;line-height:1}

/* The badge riding the highlight: the gear (this passage has a property
   test), the test's confidence, and the way into the PBT. */
sup.q-num{display:inline-flex;align-items:center;gap:.16rem;
  background:#fff3c4;border:1px solid #e6c98a;border-radius:4px;
  font-size:.62rem;line-height:1.35;padding:0 .22rem;margin-left:.12rem;
  color:#6b4a00;cursor:pointer;vertical-align:super}
sup.q-num .q-gear{font-size:.78rem;line-height:1}
sup.q-num .q-conf{font-variant-numeric:tabular-nums}
/* An estimate that was never made must not look like one that was. */
sup.q-num .q-conf.pending{font-style:italic;opacity:.7}
/* Which PBT a badge belongs to, wherever the badge appears. */
.q-id{font-size:.62rem;font-weight:700;letter-spacing:.04em;
  font-family:ui-monospace,monospace}
p.meta>.q-id,.q-pop .q-id{background:#fff3c4;border:1px solid #e6c98a;
  border-radius:4px;color:#6b4a00;padding:0 .22rem}
sup.q-num.in{background:#ddebff;border-color:#8fb6e6;color:#123a6b}
sup.q-num:focus{outline:2px solid #d98a08}
.q-tail sup.q-num{vertical-align:baseline;font-size:.7rem;
  padding:.05rem .3rem}

/* The verification glyph on the badge: whether this PBT has actually been
   run, and whether it passed. The glyph is CSS content keyed off the state
   class, so one badge builder serves every state. */
sup.q-num .q-ver::after{content:"\25CB";opacity:.55}
sup.q-num.verified .q-ver::after{content:"\2713";opacity:1}
sup.q-num.failing .q-ver::after{content:"\2717";opacity:1}
sup.q-num.verified{box-shadow:0 0 0 2px #176b3a;color:#176b3a}
sup.q-num.failing{box-shadow:0 0 0 2px #a3312a;color:#a3312a}

/* The badge popover: the mini test report, server-rendered so hovering
   costs no request and works with the panel closed. */
.q-anchor{position:relative}
.q-pop{display:none;position:absolute;left:0;top:1.5em;z-index:20;
  min-width:15rem;max-width:22rem;background:#fff;
  border:1px solid #d9dee7;border-radius:6px;
  box-shadow:0 2px 10px rgba(15,23,42,.14);padding:.45rem .6rem;
  font-size:.76rem;font-weight:400;font-style:normal;line-height:1.5;
  color:#17202a;white-space:normal;text-align:left}
.q-anchor:hover>.q-pop,.q-anchor:focus-within>.q-pop,
.q-anchor.pinned>.q-pop{display:block}
.q-anchor.dismissed>.q-pop{display:none}
.q-pop>span{display:block}
.q-pop .warn{color:#8a5700}
sup.q-num .q-pop{vertical-align:baseline}

/* The number badge on a claim card, matching the mark's palette. */
.q-badge{display:inline-block;min-width:1.1rem;text-align:center;
  background:#fff3c4;border:1px solid #e6c98a;border-radius:4px;
  font-size:.72rem;padding:0 .25rem;margin-right:.35rem}
.q-badge.in{background:#ddebff;border-color:#8fb6e6;color:#123a6b}

/* Cross-highlighting: hovering any one of a claim's marks, badges or
   cards lights all of them. */
mark.q.xhl,.q-badge.xhl,sup.q-num.xhl{box-shadow:0 0 0 2px #d98a08}
mark.q.in.xhl,.q-badge.in.xhl,sup.q-num.in.xhl{box-shadow:0 0 0 2px #2f6fb8}
.card.block-claim.xhl{box-shadow:0 0 0 2px #d98a08}
.card.block-claim.in.xhl{box-shadow:0 0 0 2px #2f6fb8}

/* What the document holds, at its head instead of in a sticky footer, and
   in the SAME card as the figures that describe it. */
.reader-chips .badge{cursor:pointer}
.doc-head .doc-title{display:flex;align-items:baseline;gap:1rem;
  justify-content:space-between;flex-wrap:wrap}
.doc-head .doc-back{font-size:.82rem;white-space:nowrap}

/* The PBT panel. Opening it slides the page left rather than covering
   it, and the slide is a margin on the centred page, so the reading
   measure never changes: the document moves, its text does not re-wrap.
   The push takes only the room the centred page has spare, so a viewport
   with none to give falls back to the overlay. */
body{transition:margin-right .18s ease-out}
body.drawer-push{margin-right:var(--reader-push,0px)}
.reader-drawer{position:fixed;top:0;right:0;bottom:0;z-index:16;
  width:min(40rem,100vw);overflow:auto;background:#f5f7fa;
  border-left:1px solid #d9dee7;box-shadow:-4px 0 18px rgba(15,23,42,.16);
  padding:0 1rem 2rem .9rem;transform:translateX(100%);
  transition:transform .18s ease-out}
.reader-drawer[hidden]{display:none}
.reader-drawer.open{transform:none}
.reader-drawer.resizing{transition:none}
.reader-shell.resizing{user-select:none}
.reader-drawer .drawer-head{display:flex;justify-content:flex-start;
  gap:.2rem;align-items:center;padding:.5rem 0 0}
.reader-drawer .drawer-close,.reader-drawer .drawer-expand{border:0;
  background:none;font-size:1rem;line-height:1;color:#667085;
  cursor:pointer;padding:.2rem .4rem}
.reader-drawer .drawer-close:hover,
.reader-drawer .drawer-expand:hover{color:#17202a}
.reader-drawer .drawer-page{font-size:.78rem;margin-left:.4rem}
.reader-grip{position:fixed;top:0;bottom:0;z-index:17;width:14px;
  cursor:ew-resize;touch-action:none;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:4px}
.reader-grip[hidden]{display:none}
.reader-grip::before{content:'';position:absolute;left:6px;top:0;
  bottom:0;width:2px;background:#d9dee7}
.reader-grip:hover::before,.reader-grip.dragging::before{left:5px;
  width:4px;background:#9aa5b5}
.reader-grip span{position:relative;width:4px;height:4px;
  border-radius:50%;background:#b7c0cd}
.reader-grip:hover span,.reader-grip.dragging span{background:#67707e}
.reader-backdrop{position:fixed;inset:0;z-index:15;
  background:transparent;pointer-events:none}
.reader-backdrop[hidden]{display:none}
.reader-shell.drawer-open .reader-drawer.expanded{position:fixed;
  top:0;right:0;bottom:0;width:calc(100vw - 5rem);max-width:none;
  max-height:none;margin:0;border-radius:0;transform:none;
  box-shadow:-4px 0 24px rgba(15,23,42,.28)}
.reader-shell.expanded .reader-backdrop:not([hidden]){
  background:rgba(15,23,42,.25);pointer-events:auto}

/* One NL statement and its formalization is ONE object: boxed and
   tinted so its contents read as contained by it. */
.card.block-claim{border:1px solid #d9dee7;background:#f7f9fc;
  border-radius:8px;padding:0 .8rem .7rem;margin:.7rem 0}
.card.block-claim .card-head{margin:0 -.8rem .5rem;padding:.4rem .8rem;
  border-bottom:1px solid #e3e9f2;background:#eef3f9;
  border-radius:8px 8px 0 0;font-size:.82rem}
.block-claim pre{background:#fff;border:1px solid #e3e9f2}
.card.block-claim.flash{animation:target-flash 2.4s ease-out}

/* Preconditions and postconditions side by side: the two halves of one
   test, stated once as column headings. */
.pbt-grid{display:grid;grid-template-columns:1fr 1fr;gap:1.2rem;
  align-items:start}
.pbt-col{min-width:0}
.pbt-col pre{overflow-x:auto}
.pbt-col>h3{font-size:.72rem;font-weight:600;color:#8c96a4;
  margin:.2rem 0 .1rem;letter-spacing:.04em;text-transform:lowercase}
.pbt-col>h4{font-size:.8rem;margin:.7rem 0 .2rem;color:#4a5462}
@media (max-width:1100px){.pbt-grid{grid-template-columns:1fr}}
.reader-drawer .pbt-grid{grid-template-columns:1fr}
.reader-drawer.expanded .pbt-grid{grid-template-columns:1fr 1fr}

/* A quoted documentation passage inside a card. */
.wo-quote{border-left:3px solid #d9dee7;background:#fff;
  border-radius:0 6px 6px 0;padding:.1rem .8rem;margin:.4rem 0}
.wo-quote>*:first-child{margin-top:.4rem}
.wo-quote>*:last-child{margin-bottom:.4rem}
.wo-quote pre{font-size:.8rem}

/* The dashboard's stats strip: one line of facts. */
.block-strip{display:flex;flex-wrap:wrap;gap:.9rem;font-size:.82rem;
  color:#4a5462}

/* The run report's numbers as tiles: the number first, its definition
   in the title. */
.stat-tiles{display:grid;gap:.5rem;margin:.4rem 0 .2rem;
  grid-template-columns:repeat(auto-fill,minmax(9rem,1fr));
  max-width:46rem}
.stat-tile{border:1px solid #e5e8ec;border-radius:6px;background:#fff;
  padding:.4rem .6rem}
.stat-tile .stat-num{display:block;font-size:1.3rem;font-weight:600;
  line-height:1.2;color:#17202a}
.stat-tile .stat-lab{display:block;font-size:.78rem;color:#4a5462;
  margin-top:.1rem}
.stat-tile.warn .stat-num{color:#a3312a}
.stat-group{font-size:.76rem;font-weight:600;letter-spacing:.04em;
  color:#4a5462;text-transform:lowercase;margin:.7rem 0 0}

/* Per-seed evidence. */
.outcome.o-accepted{color:#176b3a}
.outcome.o-rejected{color:#8a5700}
.outcome.o-crashed,.outcome.o-machinery_error{color:#a12622}
.verdict.v-PASS{color:#176b3a;font-weight:600}
.verdict.v-FAIL{color:#a12622;font-weight:600}
.verdict.v-NO_VERDICT{color:#8a5700}
.verdict.v-BOUNDARY_ERROR{color:#a3552e;font-weight:600}
details>summary{cursor:pointer;color:#245b93}
details h4{margin:.6rem 0 .2rem;font-size:.8rem}
/* The subordinate tier: a fold inside a fold, or evidence under a report.
   Quieter than a detail-fold, but carrying the same caret, so every
   disclosure in the app opens the same way. */
details.artifact-fold>summary,details.sample-pair>summary,
details.seed-table>summary,details.quiet-fold>summary{color:#667085;
  font-size:.85rem;margin:.6rem 0 .2rem;list-style:none;
  display:flex;align-items:center;gap:.35rem}
details.artifact-fold>summary::-webkit-details-marker,
details.sample-pair>summary::-webkit-details-marker,
details.seed-table>summary::-webkit-details-marker,
details.quiet-fold>summary::-webkit-details-marker{display:none}
details.artifact-fold>summary::before,details.sample-pair>summary::before,
details.seed-table>summary::before,details.quiet-fold>summary::before{
  content:"\25B8";color:#b0b8c4;font-size:.64rem;line-height:1;
  transition:transform .12s ease-out}
details.artifact-fold[open]>summary::before,
details.sample-pair[open]>summary::before,
details.seed-table[open]>summary::before,
details.quiet-fold[open]>summary::before{transform:rotate(90deg)}
details.artifact-fold>summary:hover,details.sample-pair>summary:hover,
details.seed-table>summary:hover,details.quiet-fold>summary:hover{color:#17202a}

/* Where a jump landed: brief, so the mark does not outlive the
   navigation that explained it. */
.q-block:target,.q-block.flash,mark.q.flash{
  animation:target-flash 2.4s ease-out}
@keyframes target-flash{
  0%,55%{box-shadow:0 0 0 2px #d98a08}
  100%{box-shadow:none}}

/* Wayfinding: a 59,000px document with six highlights in it is unreadable
   without a way to step between them. The walk rides the document's own
   gutter beside the line numbers, so it travels with the page when the
   panel pushes it left instead of sitting on the window (Ben, 2026-09-09).
   The slot is a zero-height sticky child at the top of the document, which
   is what keeps the rail at eye level without occupying a row of text. */
.reader-rail-slot{position:sticky;top:4.6rem;height:0;z-index:5}
.reader-rail{position:absolute;left:-5.5rem;top:0;width:2.5rem;
  display:flex;flex-direction:column;align-items:center;gap:.2rem;
  background:#fff;border:1px solid #d9dee7;border-radius:8px;
  box-shadow:0 1px 4px rgba(15,23,42,.07);padding:.3rem .2rem}
.reader-rail button{border:1px solid #e1e6ee;background:#fff;
  border-radius:5px;color:#245b93;cursor:pointer;font-size:.8rem;
  line-height:1;padding:.15rem .4rem;width:100%}
.reader-rail button:hover{background:#eef3f9}
.reader-rail button:disabled{color:#c7cedb;cursor:default;background:#fff}
.reader-rail .reader-pos{color:#4a5462;font-size:.72rem;
  font-variant-numeric:tabular-nums;text-align:center;letter-spacing:-.02em}
.reader-rail .reader-here{font-size:.58rem;letter-spacing:.03em;
  color:#6b4a00;background:#fff3c4;border:1px solid #e6c98a;border-radius:4px;
  padding:0 .18rem;min-height:.9rem;width:100%;text-align:center;
  font-family:ui-monospace,monospace;box-sizing:border-box}
.reader-rail .reader-here:empty{visibility:hidden}
.reader-rail .reader-scope{font-size:.55rem;color:#8c96a4;cursor:pointer;
  display:flex;flex-direction:column;align-items:center;gap:.05rem;
  border-top:1px solid #eef2f6;padding-top:.2rem;width:100%}
.reader-rail .reader-scope:hover{color:#245b93}
.reader-rail .reader-scope input{margin:0;transform:scale(.85)}
/* No gutter left to ride: the rail returns to the corner of the window. */
@media (max-width:60rem){
  .reader-rail-slot{position:fixed;left:0;bottom:.6rem;top:auto;height:auto}
  .reader-rail{position:static;left:auto;width:auto;flex-direction:row;
    align-items:center;box-shadow:0 2px 8px rgba(15,23,42,.12);
    margin-left:.6rem}
  .reader-rail button,.reader-rail .reader-here{width:auto}
  .reader-rail .reader-scope{flex-direction:row;border-top:0;
    border-left:1px solid #eef2f6;padding:0 0 0 .3rem;width:auto}
}

/* A figure that was not measured. One look for every such absence, so a
   placeholder can never be mistaken for a number. */
.pending{color:#8a5700;font-size:.85rem;font-style:italic}
.stat-tile.pending-tile .stat-num{font-size:.95rem;font-weight:600;
  color:#8a5700;font-style:italic}

/* The confidence legend: the estimator written out, and which part of it
   the displayed number actually uses. */
.legend{background:#fbfcfd;border:1px solid #e5e8ec;border-radius:8px;
  padding:.6rem .9rem;margin:.8rem 0;font-size:.85rem}
.legend h3{font-size:.86rem;margin:0 0 .3rem;text-transform:lowercase;
  color:#4a5462}
.legend p{margin:.3rem 0}
.legend .formula{font-family:ui-monospace,monospace;font-size:.84em;
  background:#f8fafc;border:1px solid #eef2f6;border-radius:6px;
  padding:.35rem .6rem;margin:.3rem 0;display:block;overflow-x:auto}
.legend .v0{color:#8a5700}

/* --- Metric fields ------------------------------------------------------
   A figure that came out of the data should read as a reading, not as a
   sentence (Ben, 2026-09-09): the value takes the weight and the tabular
   figures, the label stays subordinate, and every view of the same number
   is built from these three rules so none of them can drift. */
.metric{display:inline-flex;align-items:baseline;gap:.3rem;min-width:0}
.metric-v{font-size:.98rem;font-weight:600;color:#17202a;
  font-variant-numeric:tabular-nums;white-space:nowrap}
.metric-v .metric-of{font-size:.82em;font-weight:400;color:#98a2b1}
.metric-l{font-size:.74rem;color:#667085;white-space:nowrap}
.metric.up .metric-v{color:#176b3a}
/* A figure that is a violation count, not a gain. */
.metric.warn .metric-v{color:#a12622}
/* What a run added on top of a baseline. Zero is stated, not coloured. */
.metric-d{font-size:.74rem;font-weight:600;color:#98a2b1;
  font-variant-numeric:tabular-nums;background:#f2f4f7;border-radius:4px;
  padding:0 .3rem;white-space:nowrap}
.metric-d.up{color:#176b3a;background:#e7f4ea}
/* The proportion behind a ratio. An unmeasured one draws no bar at all,
   because an empty bar reads as zero and zero is a measurement. */
.meter{display:block;height:3px;border-radius:2px;background:#eceff4;
  min-width:2.5rem}
.meter>i{display:block;height:100%;border-radius:2px;background:#8fb6e6}
.meter.empty{background:transparent}
/* One measured quantity on one line: value, bar, share, gain. */
.metric-line{display:grid;grid-template-columns:auto 1fr auto auto;
  align-items:center;gap:.4rem;margin:.15rem 0}
.metric-line .metric{min-width:6.2rem}
.metric-line .metric-p{font-size:.74rem;color:#8c96a4;
  font-variant-numeric:tabular-nums}
.metric-line .pending{grid-column:2/-1;font-size:.78rem}

/* A disclosure whose closed state is already the answer: the live figures
   ride the bar, so the fold is a panel first and a disclosure second. */
.metric-fold{border:1px solid #e5e8ec;border-radius:8px;background:#fff;
  margin:.8rem 0}
.metric-fold>summary{list-style:none;display:flex;flex-wrap:wrap;
  align-items:center;gap:.4rem 1.1rem;padding:.5rem .75rem;cursor:pointer;
  color:inherit;border-radius:8px}
.metric-fold>summary::-webkit-details-marker{display:none}
.metric-fold>summary::before{content:"\25B8";color:#98a2b1;font-size:.7rem;
  line-height:1;transition:transform .12s ease-out}
.metric-fold[open]>summary::before{transform:rotate(90deg)}
.metric-fold[open]>summary{border-bottom:1px solid #eef2f6;
  border-radius:8px 8px 0 0;background:#fbfcfd}
.metric-fold>summary:hover{background:#f6f8fb}
.metric-fold .fold-title{font-weight:600;font-size:.88rem;margin-right:.2rem}
.metric-fold .fold-metrics{display:flex;flex-wrap:wrap;
  align-items:baseline;gap:.4rem 1.1rem}
.metric-fold .fold-body{padding:.1rem .75rem .7rem}
.metric-fold .fold-body>p:first-child{margin-top:.5rem}

/* The three figures that describe a document, at its head. */
.doc-stats{display:flex;flex-wrap:wrap;gap:.4rem 1.4rem;margin:.5rem 0 .2rem}

/* A recorded identifier and what it identifies: the counterpart to a
   metric for a run id, a timestamp, a binary, a revision. */
.fact-row{display:flex;flex-wrap:wrap;gap:.5rem 1.6rem;margin:.5rem 0}
.fact{display:flex;flex-direction:column;gap:.05rem;min-width:0}
.fact-l{font-size:.68rem;color:#98a2b1;letter-spacing:.03em;
  text-transform:lowercase}
.fact-v{font-size:.84rem;color:#17202a}
.fact-v code{font-size:.86em}

/* The head of a PBT: what it IS, then what it says. The title is the
   formalized statement, a sentence long, and at heading size it filled
   three lines before the reader reached a figure. */
.pbt-head{margin:0 0 .9rem}
.pbt-head .pbt-id{display:flex;align-items:center;gap:.45rem;margin:0}
.pbt-head .pbt-id>.q-id{background:#fff3c4;border:1px solid #e6c98a;
  border-radius:4px;color:#6b4a00;padding:0 .22rem}
.pbt-statement{font-size:1.02rem;font-weight:500;line-height:1.5;
  margin:.35rem 0 0;max-width:52rem}

/* Section heads inside a PBT: an eyebrow over a rule, so the three parts
   of the view separate without shouting. */
section>h2{font-size:.78rem;font-weight:600;letter-spacing:.06em;
  text-transform:uppercase;color:#8c96a4;margin:1.5rem 0 .5rem;
  padding-bottom:.3rem;border-bottom:1px solid #eef2f6}

/* A disclosure that opens supporting detail: a control, not a link in a
   list of links. */
/* Closed, it is a control and takes only the room its label needs; open,
   it is a panel and takes the width its content asks for. */
details.detail-fold{border:1px solid #e5e8ec;border-radius:6px;
  background:#fff;margin:.4rem 0;width:fit-content;max-width:100%}
details.detail-fold[open]{width:auto}
details.detail-fold>summary{list-style:none;display:flex;align-items:center;
  gap:.4rem;padding:.35rem .6rem;cursor:pointer;font-size:.84rem;
  color:#4a5462;border-radius:6px}
details.detail-fold>summary::-webkit-details-marker{display:none}
details.detail-fold>summary::before{content:"\25B8";color:#98a2b1;
  font-size:.68rem;line-height:1;transition:transform .12s ease-out}
details.detail-fold[open]>summary::before{transform:rotate(90deg)}
details.detail-fold>summary:hover{background:#f6f8fb;color:#17202a}
details.detail-fold[open]>summary{border-bottom:1px solid #eef2f6;
  border-radius:6px 6px 0 0}
details.detail-fold>*:not(summary){padding:0 .7rem}
details.detail-fold>*:not(summary):last-child{padding-bottom:.5rem}

/* The source-and-coverage table at the head of a document. */
.cov-table{width:auto;min-width:34rem;border-bottom:1px solid #dfe5ee}
.cov-table td,.cov-table th{padding:.45rem .6rem}
/* A file is one row group: its counts and the source lines it earned. The
   rule falls BETWEEN files, never between a file and its own source lines,
   and a band carries the pair so the eye keeps them together. */
.cov-table tbody{border-top:1px solid #dfe5ee}
.cov-table tbody>tr>td{border-bottom:0}
.cov-table tbody:nth-of-type(odd)>tr>td{background:#f6f9fc}
.cov-table th{font-size:.74rem;font-weight:600;color:#8c96a4;
  text-transform:lowercase;letter-spacing:.02em;border-bottom-color:#e1e6ee}
.cov-table td{vertical-align:middle}
.cov-delta{font-variant-numeric:tabular-nums}
.cov-delta.up{color:#176b3a;font-weight:600}

/* A build-root path runs to a hundred characters and only its last segment
   is what a reader is looking for. The directory stays, but yields. */
.cov-file{display:inline-block;max-width:26rem;font-size:.8rem}
.cov-file .cov-dir{color:#a3adbb;overflow-wrap:anywhere}
.cov-file .cov-name{color:#17202a;font-weight:600}
a:hover .cov-file .cov-name{text-decoration:underline}
/* Which PBT earned the row: the same tag its badges carry, always on its
   own line so the eye finds it in the same place down the column. */
.q-id.row-owner{display:block;width:fit-content;margin-top:.25rem;
  background:#fff3c4;border:1px solid #e6c98a;border-radius:4px;
  color:#6b4a00;padding:0 .22rem}

/* What one minimized input bought, and the way to it. */
.coverage-input{display:flex;flex-direction:column;align-items:flex-start;
  gap:.1rem}
.coverage-input .gain{font-size:.82rem;font-weight:600;color:#176b3a;
  font-variant-numeric:tabular-nums}
.coverage-input .meta{font-size:.74rem}
.coverage-input .cov-actions{display:flex;flex-wrap:wrap;gap:.25rem;
  margin-top:.2rem}

/* Coverage is primarily code evidence. Counts remain in the summary row;
   the following row shows only the source neighborhoods the PBT added. */
.cov-table tr.coverage-source-row>td{padding:0 .6rem .55rem 1.5rem;border-top:0}
.coverage-source{max-width:72rem}
.coverage-source>summary{cursor:pointer;color:#176b3a;font-size:.8rem;
  font-weight:600;width:fit-content}
.coverage-source>pre{margin:.45rem 0 0;padding:.35rem 0;overflow:auto;
  border:1px solid #e1e6ee;border-radius:5px;background:#f7f9fb}
.coverage-source-line{display:grid;grid-template-columns:4.25rem minmax(max-content,1fr) auto;
  min-height:1.35rem;padding:0 .65rem 0 0}
.coverage-source-line.newly-covered{background:#dff3e5;
  box-shadow:inset 3px 0 #2f8f55}
.coverage-source-line.newly-covered-branch{background:#fff3d6;
  box-shadow:inset 3px 0 #c98712}
.coverage-source-line.newly-covered.newly-covered-branch{
  background:linear-gradient(90deg,#dff3e5,#fff3d6)}
.coverage-source-line code{white-space:pre;color:#26313d;background:none;
  padding:0}
.coverage-branch-outcomes{display:flex;gap:.25rem;align-items:center;padding-left:.75rem}
.coverage-branch-outcome{align-self:center;padding:.05rem .32rem;border-radius:3px;
  background:#f2d18b;color:#714600;font:600 .67rem/1.25 system-ui,sans-serif;
  white-space:nowrap}
.coverage-line-number{padding-right:.75rem;text-align:right;color:#8c96a4;
  user-select:none;font-variant-numeric:tabular-nums}
.coverage-source-gap{display:block;padding-left:1.85rem;color:#8c96a4}
.coverage-source-fallback{padding:.35rem 0;color:#176b3a;font-size:.8rem}
.coverage-source-fallback .meta{margin-left:.35rem;color:#7d8794}

/* The excerpt a PBT operationalizes, at the head of its view. */
.pbt-excerpt{background:#fff;border:1px solid #e3e9f2;border-radius:8px;
  padding:.1rem .9rem;margin:.5rem 0}
.pbt-excerpt>*:first-child{margin-top:.5rem}
.pbt-excerpt>*:last-child{margin-bottom:.5rem}

/* One condition: its NL text, its DSL, its conforming example. */
/* The condition's own words. Rendered markdown, so the source's line
   breaks must NOT be preserved -- pre-wrap here broke every paragraph at
   the column the document happened to wrap at. */
.cond-nl{margin:.35rem 0}
.cond-nl>*:first-child{margin-top:0}
.cond-nl>*:last-child{margin-bottom:0}
.cond-dsl{margin:.35rem 0}
.card.block-claim .cond-lines{font-size:.75rem}

/* An artifact fold sitting inline in a table cell. */
details.inline-fold{display:inline-block;vertical-align:top}
details.inline-fold summary{color:#245b93}

/* The head names every PBT on the document, and a document can carry six.
   The strip scrolls inside itself rather than growing down the page. */
.reader-chips{display:flex;gap:.4rem;overflow-x:auto;min-width:0;
  padding-bottom:.2rem;margin:.5rem 0 .2rem}
.reader-chips .badge{white-space:nowrap}

/* The passages one postcondition was derived from, listed on its card. */
.cond-source{display:inline-flex;align-items:center;margin-right:.5rem}

/* Local workflow controls: keep review text readable at the document measure. */
section form { display: grid; gap: 0.8rem; max-width: 48rem; margin: 1rem 0; }
section form label { display: grid; gap: 0.3rem; }
section form input, section form select, section form textarea {
  font: inherit; padding: 0.45rem; max-width: 100%; box-sizing: border-box;
}
section form textarea { min-height: 6rem; resize: vertical; }
section form button { justify-self: start; padding: 0.5rem 1rem; font: inherit; cursor: pointer; }

.coverage-action{display:inline-block;border:1px solid #d9dee7;
  background:#fff;border-radius:5px;padding:.15rem .5rem;font-size:.78rem;
  text-decoration:none;white-space:nowrap;color:#245b93}
.coverage-action:hover{background:#eef3f9;border-color:#b9c6d8}
.coverage-input + .coverage-input{margin-top:.7rem;padding-top:.6rem;
  border-top:1px solid #eef2f6}

.input-example-line{display:inline}
.input-annotation{display:inline-block;margin-left:.5rem;border-radius:50%;
  padding:0 .4rem;background:#d9eaff;color:#184b82;text-decoration:none}
/* Where an annotation badge lands: brief, like every other jump. */
.card.block-claim:target{animation:target-flash 2.4s ease-out}

/* Frozen breadth-pilot evidence. Source selections retain line breaks. */
.pilot-highlight{white-space:pre-wrap;border-left:4px solid #8fb6e6;
  background:#f4f8ff;padding:.7rem 1rem;font-family:inherit}
.pilot-sampled{background:linear-gradient(90deg,#f1f3f6 0,#f1f3f6 .28rem,transparent .28rem);
  scroll-margin-top:4rem}
.pilot-sample-badge{display:inline-block;margin:.15rem .35rem .25rem 0;
  padding:.08rem .45rem;border:1px solid #aab3c0;border-radius:999px;
  background:#f1f3f6;color:#4a5462;font-size:.7rem;text-decoration:none}
.pilot-sample-badge:hover{border-color:#667085;color:#245b93}

/* Autonomous experiment: readable evidence for a shared-screen walkthrough. */
.autonomous-code{white-space:pre-wrap;overflow-wrap:anywhere;max-height:75vh;
  overflow:auto;background:#f7f9fc;border:1px solid #dfe5ee;border-radius:8px;
  padding:1rem;font-size:.83rem;line-height:1.5}
.autonomous-summary{display:flex;flex-wrap:wrap;gap:1rem;margin:1.2rem 0}
.autonomous-summary>div{padding:1rem 1.3rem;background:#f4f7fb;border:1px solid #dfe5ee;border-radius:8px}
.autonomous-summary strong{font-size:1.6rem;display:block}
.autonomous-review{background:#fff8e7;border-left:4px solid #c78c22;padding:.8rem 1rem;margin:1rem 0}
.autonomous-evidence{overflow-wrap:anywhere}
.autonomous-evidence li{margin:.35rem 0}

/* Coverage opens to a fixed depth, not to a fixed number of files: a file
   earning fifty source lines is three times the height of one earning two,
   so a count cuts at a different place on every document. The rest stay in
   the page and one control away (Ben, 2026-09-14). */
.cov-peek{position:relative}
.cov-peek-toggle{position:absolute;width:1px;height:1px;opacity:0;
  margin:0;pointer-events:none}
.cov-peek-window{position:relative}
.cov-peek-toggle:not(:checked)~.cov-peek-window{max-height:19rem;overflow:hidden}
/* The cut has to read as a cut: whatever row crosses the line fades into the
   panel rather than ending on a hard edge. */
.cov-peek-fade{display:none;position:absolute;left:0;right:0;bottom:0;
  height:4.5rem;pointer-events:none;
  background:linear-gradient(to bottom,rgba(255,255,255,0),#fff 85%)}
.cov-peek-toggle:not(:checked)~.cov-peek-window .cov-peek-fade{display:block}
.cov-peek-toggle:checked~.cov-peek-more .cov-peek-open,
.cov-peek-toggle:not(:checked)~.cov-peek-more .cov-peek-close{display:none}
.cov-peek-more{display:block;width:fit-content;min-width:13rem;
  margin:.3rem 0 .3rem;padding:.3rem .7rem;cursor:pointer;
  border:1px solid #dbe1ea;border-radius:6px;background:#f6f8fb;
  color:#42506a;font-size:.78rem;font-weight:600;text-align:center}
.cov-peek-more:hover{background:#eef2f8;color:#17202a;border-color:#c7d0dd}
.cov-peek-toggle:focus-visible~.cov-peek-more{outline:2px solid #2f6fdb;
  outline-offset:2px}
/* A table shorter than the window needs neither the fade nor the control;
   reader.js marks it once it can measure. Without script the control stays,
   and opens a table that was already open. */
.cov-peek-fits .cov-peek-toggle:not(:checked)~.cov-peek-window{max-height:none}
.cov-peek-fits .cov-peek-toggle~.cov-peek-window .cov-peek-fade,
.cov-peek-fits .cov-peek-more{display:none}

/* A packaged PR carries two kinds of code, and both are read here before
   they are read anywhere else: the coverage hunks it earns and the LIT test
   it adds. A hunk uses the SAME green as the source highlight above it, so
   one gain looks like one thing whether it is read on the document or in
   the PR (Ben, 2026-09-14). */
.cov-diff{display:block}
.diff-line{display:block;padding:0 .5rem;margin:0 -.5rem}
.diff-line.diff-add{background:#dff3e5;box-shadow:inset 3px 0 #2f8f55}
.diff-line.diff-hunk{color:#8c96a4}
.diff-mark{color:#2f8f55;font-weight:700}
.diff-ctx>.diff-mark{color:transparent}
.diff-lineno{color:#8c96a4;user-select:none;font-variant-numeric:tabular-nums}
/* Ours, not the source line's: a reviewer must not copy it into their editor
   thinking it was there. */
.diff-note{color:#714600;font-style:italic}
/* `// CHECK:` is not a comment however much it looks like one: it states the
   output the test asserts. Grey italic would hide half the test. */
.tok-lit{color:#b2430f;font-weight:600}
