
  :root {
    color-scheme: dark;
    --bg:#0B1220; --panel:#111827; --inset:#0E1626; --raised:#131C2E; --sunken:#0A101C;
    --text-1:#F9FAFB; --text-2:#D1D5DB; --text-3:#94A3B8;
    --blue:#3B82F6; --purple:#8B5CF6; --green:#22C55E;
    --v-warn:#F59E0B; --v-fail:#EF4444;
    --solid-ok:#15803D; --solid-bad:#B91C1C;
    --border:rgba(148,163,184,.13); --border-hover:rgba(148,163,184,.26);
    --fs-td:15px; --fs-th:12.5px; --fs-kvk:12.5px; --fs-kvv:14px;
    --fs-obs:14.5px; --fs-cap:14px; --fs-name:16px; --fs-kind:13.5px; --fs-badge:12.5px;
    --radius:12px; --radius-sm:10px;
    --shadow:0 1px 2px rgba(0,0,0,.30), 0 6px 20px rgba(0,0,0,.28);
    --mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  }
  * { box-sizing:border-box; }
  html,body { margin:0; background:var(--bg); color:var(--text-1);
    font:14px/1.5 -apple-system,BlinkMacSystemFont,Segoe UI,Inter,Roboto,Helvetica,Arial,sans-serif;
    -webkit-font-smoothing:antialiased; }
  .wrap { max-width:1180px; margin:0 auto; padding:24px; }
  .mono { font-family:var(--mono); }
  a { color:#7CB0F8; text-decoration:none; } a:hover { text-decoration:underline; }

  .navrow { display:flex; align-items:center; justify-content:space-between; gap:12px;
    font-size:13px; margin-bottom:16px; }
  .navrow a { color:var(--text-3); } .navrow a:hover { color:var(--text-2); }

  .topbar { display:flex; align-items:flex-start; justify-content:space-between; gap:20px; margin-bottom:14px; }
  .page-header { display:flex; align-items:center; gap:14px; }
  .brand-tile { width:46px; height:46px; flex:0 0 auto; border-radius:var(--radius);
    display:grid; place-items:center; color:var(--blue);
    background:rgba(59,130,246,.12); border:1px solid rgba(59,130,246,.28); }
  .page-header h1 { font-size:30px; font-weight:600; margin:0; letter-spacing:-.02em; line-height:1.1; }
  .page-header .subtitle { font-size:14px; color:var(--text-2); margin:4px 0 0; }

  .runcard { flex:0 0 auto; width:288px; background:var(--panel);
    border:1px solid var(--border); border-radius:var(--radius-sm); padding:2px 12px; box-shadow:var(--shadow); }
  .runrow { display:flex; align-items:baseline; justify-content:space-between; gap:12px;
    padding:5px 0; border-bottom:1px solid var(--border); }
  .runrow:last-child { border-bottom:none; }
  .runrow .k { font-size:10px; text-transform:uppercase; letter-spacing:.06em;
    color:var(--text-3); font-weight:600; white-space:nowrap; }
  /* .rv, not .v -- .v is the verdict badge and would draw a pill outline here. */
  .runrow .rv { font-family:var(--mono); font-size:11.5px; color:var(--text-2);
    text-align:right; word-break:break-all; }

  .toolgrid { display:grid; grid-template-columns:1fr 1fr; gap:12px; }
  .feature-card { background:var(--panel); border:1px solid var(--border); border-radius:var(--radius);
    padding:16px; box-shadow:var(--shadow); display:flex; gap:14px; align-items:flex-start;
    transition:border-color .16s ease, transform .16s ease; }
  .feature-card:hover { border-color:var(--border-hover); transform:translateY(-1px); }
  .feature-card .tile { width:44px; height:44px; border-radius:var(--radius-sm); }
  .feature-card .title-row { display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-bottom:6px; }
  .feature-card h3 { font-size:var(--fs-name); font-weight:700; margin:0; letter-spacing:-.01em; }
  .feature-card p { font-size:14px; color:var(--text-2); margin:0; line-height:1.5; }
  .feature-card code { font-family:var(--mono); font-size:13.5px; color:var(--text-1); }
  .badge { font-size:12px; font-weight:600; padding:2px 9px; border-radius:999px; border:1px solid transparent; }
  .badge.purple { color:#C4B5FD; background:rgba(139,92,246,.14); border-color:rgba(139,92,246,.30); }
  .badge.green  { color:#86EFAC; background:rgba(34,197,94,.14);  border-color:rgba(34,197,94,.30); }

  .tile { width:34px; height:34px; flex:0 0 auto; border-radius:9px; display:grid; place-items:center;
    background:rgba(148,163,184,.07); border:1px solid var(--border); }
  .tile.blue   { color:var(--blue);   border-color:rgba(59,130,246,.32); background:rgba(59,130,246,.09); }
  .tile.purple { color:var(--purple); border-color:rgba(139,92,246,.32); background:rgba(139,92,246,.09); }
  .tile.green  { color:var(--green);  border-color:rgba(34,197,94,.32);  background:rgba(34,197,94,.09); }

  /* Self-contained tabs (no external JS/CSS): radios toggle sibling panels via :checked. */
  .tabradio { position:absolute; opacity:0; pointer-events:none; }
  .tabbar { display:flex; gap:4px; border-bottom:1px solid var(--border); margin:18px 0 16px; }
  .tabbar label { cursor:pointer; padding:10px 18px; font-size:14px; font-weight:600; color:var(--text-3);
    border:1px solid transparent; border-bottom:none; border-radius:10px 10px 0 0; margin-bottom:-1px;
    transition:color .15s ease, background .15s ease; }
  .tabbar label:hover { color:var(--text-2); }
  #tab-guardrails:checked ~ .tabbar label[for="tab-guardrails"],
  #tab-survey:checked ~ .tabbar label[for="tab-survey"] {
    color:var(--text-1); background:var(--panel);
    border-color:var(--border); border-bottom:1px solid var(--panel); }
  /* The radios are visually hidden (opacity:0) so they show no native focus ring;
     mirror :focus-visible onto the label so keyboard users can see the focused tab. */
  #tab-guardrails:focus-visible ~ .tabbar label[for="tab-guardrails"],
  #tab-survey:focus-visible ~ .tabbar label[for="tab-survey"] {
    outline:2px solid var(--blue); outline-offset:-2px; }
  .tabpanel { display:none; }
  #tab-guardrails:checked ~ #panel-guardrails { display:block; }
  #tab-survey:checked ~ #panel-survey { display:block; }

  .gate { display:flex; align-items:center; gap:13px; border-radius:var(--radius);
    padding:14px 16px; margin-bottom:12px; border:1px solid; border-left-width:3px; }
  .gate .gate-icon { width:30px; height:30px; border-radius:50%; display:grid; place-items:center; flex:0 0 auto; }
  .gate .gate-text { font-size:14.5px; color:var(--text-2); }
  .gate .gate-text strong { display:block; font-size:15.5px; font-weight:700; letter-spacing:.02em; margin-bottom:1px; }
  .gate.ok  { background:rgba(34,197,94,.08); border-color:rgba(34,197,94,.26); border-left-color:var(--green); }
  .gate.ok .gate-icon { background:rgba(34,197,94,.16); color:var(--green); }
  .gate.ok .gate-text strong { color:#86EFAC; }
  .gate.bad { background:rgba(239,68,68,.08); border-color:rgba(239,68,68,.26); border-left-color:var(--v-fail); }
  .gate.bad .gate-icon { background:rgba(239,68,68,.16); color:var(--v-fail); }
  .gate.bad .gate-text strong { color:#FCA5A5; }

  .info-banner { display:flex; gap:12px; align-items:flex-start; background:rgba(59,130,246,.07);
    border:1px solid rgba(59,130,246,.26); border-left:3px solid var(--blue);
    border-radius:var(--radius); padding:13px 16px; margin-bottom:12px; }
  .info-banner > svg { flex:0 0 auto; color:var(--blue); margin-top:2px; }
  .info-banner p { margin:0; font-size:14px; color:var(--text-2); line-height:1.5; }
  .info-banner strong { color:var(--text-1); font-weight:600; }

  .stale { display:flex; gap:12px; align-items:flex-start; background:rgba(239,68,68,.10);
    border:1px solid rgba(239,68,68,.30); border-left:3px solid var(--v-fail);
    border-radius:var(--radius); padding:13px 16px; margin-bottom:12px;
    font-size:14px; color:var(--text-2); }
  .stale strong { color:#FCA5A5; }
  .stale a { color:#FCA5A5; text-decoration:underline; }

  .panel { background:var(--panel); border:1px solid var(--border); border-radius:var(--radius);
    padding:16px; box-shadow:var(--shadow); margin-bottom:12px; }
  .panel > h2 { font-size:17px; font-weight:600; margin:0 0 12px; letter-spacing:-.01em;
    display:flex; align-items:center; gap:9px; }
  .count { font-size:12px; font-weight:600; color:var(--text-3); background:var(--inset);
    border:1px solid var(--border); border-radius:999px; padding:1px 10px; }

  /* overflow-x:auto, not hidden: the latest-run table has nine columns with
     non-wrapping headers, so clipping would put the rightmost columns and the
     report links out of reach on a narrow viewport. A scroll container still
     clips to the border-radius. */
  .table-wrap { border:1px solid var(--border); border-radius:var(--radius-sm); overflow-x:auto; }
  table { width:100%; border-collapse:separate; border-spacing:0; }
  th { text-align:left; padding:10px 12px; font-size:var(--fs-th); font-weight:600;
    text-transform:uppercase; letter-spacing:.06em; color:var(--text-3);
    background:var(--inset); border-bottom:1px solid var(--border); white-space:nowrap; }
  td { padding:11px 12px; font-size:var(--fs-td); border-bottom:1px solid var(--border);
    color:var(--text-2); vertical-align:top; }
  tbody tr:last-child td { border-bottom:none; }
  tbody tr:hover td { background:rgba(148,163,184,.035); }
  /* Numeric headers right-align with their cells so a value sits under its label. */
  th.num, td.num { text-align:right; font-variant-numeric:tabular-nums; }
  td.mono { font-family:var(--mono); font-size:14px; color:var(--text-1); }
  td.wrap-any { word-break:break-word; }
  td.empty { color:var(--text-3); font-style:italic; }
  .dash { color:var(--text-3); }

  /* Verdict badge: tinted, never solid. fail and error share one red. */
  .v { display:inline-block; padding:2px 10px; border-radius:999px;
    font:600 var(--fs-badge) var(--mono); border:1px solid transparent; white-space:nowrap; }
  .v.pass  { color:#86EFAC; background:rgba(34,197,94,.13);  border-color:rgba(34,197,94,.32); }
  .v.warn  { color:#FCD34D; background:rgba(245,158,11,.13); border-color:rgba(245,158,11,.34); }
  .v.fail, .v.error { color:#FCA5A5; background:rgba(239,68,68,.13); border-color:rgba(239,68,68,.34); }
  .v.neutral { color:var(--text-3); background:rgba(148,163,184,.10); border-color:rgba(148,163,184,.24); }

  /* Baseline status: the only solid fill on the page. */
  .pill { display:inline-block; padding:3px 11px; border-radius:999px;
    font-size:var(--fs-badge); font-weight:600; color:#fff; white-space:nowrap; }
  .pill.ok, .pill.pass { background:var(--solid-ok); }
  .pill.bad, .pill.fail { background:var(--solid-bad); }

  .kcard { background:var(--inset); border:1px solid var(--border); border-radius:var(--radius-sm);
    margin-bottom:10px; overflow:hidden; }
  .kcard:last-child { margin-bottom:0; }
  .kcard.wc { --accent:var(--purple); }
  .kcard.cs { --accent:var(--green); }
  .kcard.nu { --accent:var(--blue); }
  .kcard > summary { list-style:none; cursor:pointer; user-select:none; display:flex;
    align-items:center; gap:11px; flex-wrap:wrap; padding:12px 14px; transition:background .14s ease; }
  .kcard > summary::-webkit-details-marker { display:none; }
  .kcard > summary:hover { background:rgba(148,163,184,.04); }
  .kcard > summary:focus-visible { outline:2px solid var(--blue); outline-offset:-2px; }
  .kcard[open] > summary { border-bottom:1px solid var(--border); }
  .kcard summary .name { font-family:var(--mono); font-weight:700; font-size:var(--fs-name); color:var(--text-1); }
  .kcard summary .kind { font-size:var(--fs-kind); color:var(--text-3); }
  .kcard summary .findings { font-size:13px; color:var(--text-3); background:rgba(148,163,184,.07);
    border:1px solid var(--border); border-radius:999px; padding:2px 10px; }
  .kcard summary .findings.has { color:#FCD34D; border-color:rgba(245,158,11,.30); background:rgba(245,158,11,.08); }
  .kcard summary .spacer { flex:1 1 auto; }
  .chevron { color:var(--text-3); transition:transform .2s ease; flex:0 0 auto; }
  details[open] > summary .chevron { transform:rotate(180deg); }
  .kcard-body { padding:14px; }

  /* Borderless label/value facts. Bordered boxes in a row read as tabs.
     Sized to content rather than uniformly: equal-width tracks gave a 1-char
     Findings the same width as a 51-char Recipe, so short facts sat on ~555px
     of dead space while Commit and Recipe wrapped for want of ~330px. Flex
     trades the column alignment between rows for giving each fact the width it
     needs. Derived from content on purpose -- a per-field width table would be
     wrong as soon as Run and Date grow. */
  .kv { display:flex; flex-wrap:wrap; gap:12px 28px;
    padding-bottom:14px; margin-bottom:14px; border-bottom:1px solid var(--border); }
  /* min-width:0 lets a long value wrap inside its own item instead of forcing
     the row wider; max-width keeps the widest of them within the panel. */
  .kv > span { flex:0 1 auto; min-width:0; max-width:100%; }
  .kv .k { display:block; font-size:var(--fs-kvk); color:var(--text-3); text-transform:uppercase;
    letter-spacing:.05em; font-weight:600; margin-bottom:3px; }
  .kv .val { display:block; font-size:var(--fs-kvv); color:var(--text-1); }
  /* break-all, not break-word. Both break a 40-char SHA or a 136-char
     digest-pinned image ref once the item is narrower than the token, but the
     soft wrap opportunities break-word introduces are not counted toward
     min-content, so each mono fact would keep the whole token as its intrinsic
     minimum and the row would hold only for as long as the min-width:0 above
     survives. break-all's breaks do count, and breaking between characters is
     what a token with no word boundaries wants anyway. */
  .kv .val.mono { font-family:var(--mono); word-break:break-all; }

  .observation { font-size:var(--fs-obs); color:var(--text-2); line-height:1.5;
    background:rgba(148,163,184,.05); border-left:2px solid rgba(148,163,184,.26);
    border-radius:0 8px 8px 0; padding:10px 13px; margin-bottom:14px; }
  .observation.warn { border-left-color:var(--v-warn); background:rgba(245,158,11,.06); }
  .observation.fail, .observation.error { border-left-color:var(--v-fail); background:rgba(239,68,68,.06); }
  .observation .lbl { display:block; font-size:12px; color:var(--text-3); text-transform:uppercase;
    letter-spacing:.06em; font-weight:600; margin-bottom:3px; }
  .observation .msg { font-family:var(--mono); font-size:14px; word-break:break-word; color:var(--text-1); }

  /* Holds the command and nothing else. With the label inside, this box read as
     a code block whose first token was "REPRODUCE", and selecting it to copy
     picked the label up along with the command. The label sits above it now. */
  .repro { display:block; background:var(--sunken);
    border:1px solid var(--border); border-radius:8px; padding:10px 13px; margin-bottom:14px; }
  .repro code { font-family:var(--mono); font-size:14px; color:#A5D6FF; word-break:break-all; }

  /* A section heading. Must not share colour, case and weight with the th
     beneath it -- and has to own its own separation. With margin-top:0 the space
     above a heading was whatever the previous element happened to leave (14px,
     against the 8px binding the heading to its own content), so sections ran
     together; and it was delegated to a `.cap + .table-wrap` adjacency rule, so
     inserting anything between a heading and its table silently deleted the gap.
     24px here makes separation ~3x the binding and independent of what precedes. */
  .cap { display:flex; align-items:center; gap:9px; font-size:var(--fs-cap); font-weight:700;
    text-transform:uppercase; letter-spacing:.06em; color:var(--text-1); margin:24px 0 8px; }
  .cap:first-child { margin-top:0; }
  .cap::before { content:""; width:3px; height:15px; border-radius:2px;
    background:var(--accent, var(--text-3)); flex:0 0 auto; }
  .card-foot { display:flex; justify-content:flex-end; font-size:13px; }

  details.panel { padding:0; }
  details.panel > summary { list-style:none; cursor:pointer; user-select:none; display:flex;
    align-items:center; gap:10px; padding:15px 16px; font-size:17px; font-weight:600; }
  details.panel > summary::-webkit-details-marker { display:none; }
  details.panel > summary:hover { background:rgba(148,163,184,.03); }
  details.panel > summary:focus-visible { outline:2px solid var(--blue); outline-offset:-2px; }
  details.panel[open] > summary { border-bottom:1px solid var(--border); }
  details.panel > summary .spacer { flex:1 1 auto; }
  .panel-body { padding:16px; }

  .chips { display:grid; grid-template-columns:repeat(3, 1fr); gap:12px; }
  .chip { background:var(--inset); border:1px solid var(--border); border-radius:var(--radius-sm);
    padding:13px 15px; display:flex; gap:12px; align-items:center;
    transition:border-color .16s ease, background .16s ease; }
  .chip:hover { border-color:var(--border-hover); background:var(--raised); }
  .chip .circle { width:34px; height:34px; flex:0 0 auto; border-radius:50%; display:grid; place-items:center; }
  .chip .circle.blue   { background:rgba(59,130,246,.14); color:var(--blue);   box-shadow:0 0 0 1px rgba(59,130,246,.24) inset; }
  .chip .circle.purple { background:rgba(139,92,246,.14); color:var(--purple); box-shadow:0 0 0 1px rgba(139,92,246,.24) inset; }
  .chip .circle.green  { background:rgba(34,197,94,.14);  color:var(--green);  box-shadow:0 0 0 1px rgba(34,197,94,.24) inset; }
  .chip .h { font-size:14px; font-weight:600; color:var(--text-1); display:block; }
  .chip .d { font-size:13px; color:var(--text-3); display:block; margin-top:2px; line-height:1.4; }

  .two-col { display:grid; grid-template-columns:1.85fr 1fr; gap:12px; align-items:start; margin-bottom:12px; }
  .two-col > .panel { margin-bottom:0; }

  /* Same reachability rule as .table-wrap: the five steps are fixed-width, so a
     narrow viewport scrolls the band instead of spilling it out of its panel. */
  .flow { display:flex; align-items:flex-start; justify-content:space-between; gap:4px;
    padding:2px 0; overflow-x:auto; }
  .step { display:flex; flex-direction:column; align-items:center; text-align:center; width:104px; }
  /* Solid, deepened fills: white on the identity accents at 85% alpha measured
     2.99:1 for green (WCAG AA needs 4.5:1 for this 11.5px bold text). These
     opaque shades clear it -- blue 5.2:1, purple 5.7:1, green 5.0:1. */
  .step-num { width:21px; height:21px; border-radius:50%; display:grid; place-items:center;
    font-size:11.5px; font-weight:700; margin-bottom:7px; color:#fff; }
  .step-num.blue { background:#2563EB; }
  .step-num.purple { background:#7C3AED; }
  .step-num.green { background:#15803D; }
  .step .tile { width:46px; height:46px; border-radius:var(--radius-sm); }
  .step .label { font-size:13px; font-weight:600; color:var(--text-1); margin-top:9px; line-height:1.25; }
  .step .desc { font-size:12px; color:var(--text-3); margin-top:4px; line-height:1.35; }
  .flow-arrow { color:rgba(148,163,184,.42); font-size:15px; margin-top:46px; flex:0 0 auto; }

  .panel-note { margin-top:14px; display:flex; align-items:center; gap:10px; background:var(--inset);
    border:1px solid var(--border); border-radius:var(--radius-sm); padding:11px 14px;
    font-size:13px; color:var(--text-2); }
  .panel-note svg { flex:0 0 auto; color:var(--text-3); }

  details.notes > summary { justify-content:space-between; }
  details.notes ul { list-style:none; margin:0; padding:0 16px 15px; display:flex; flex-direction:column; gap:11px; }
  details.notes li { display:flex; gap:9px; align-items:flex-start; font-size:13px; color:var(--text-2); line-height:1.45; }
  .check { flex:0 0 auto; width:17px; height:17px; border-radius:50%; display:grid; place-items:center;
    margin-top:1px; background:rgba(34,197,94,.14); color:var(--green);
    box-shadow:0 0 0 1px rgba(34,197,94,.26) inset; }

  .statline { display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin-bottom:12px; }
  .statline .lead { font-size:14px; color:var(--text-2); margin-right:4px; }
  .kgroup-title .kname { font-family:var(--mono); font-size:16px; }
  .survey-empty { font-size:14px; color:var(--text-2); margin:8px 0; }

  @media (max-width:1000px) {
    .topbar { flex-direction:column; } .runcard { width:100%; }
    .two-col { grid-template-columns:1fr; }
    .flow { flex-wrap:wrap; justify-content:center; gap:10px; }
  }
  @media (max-width:720px) { .toolgrid, .chips { grid-template-columns:1fr; } }

  .wrap { max-width:900px; }
  /* `.cap`'s heading bar is `var(--accent, var(--text-3))`, and --accent is only
     defined on the root dashboard's kernel cards. These pages have no such
     ancestor, so every bar fell back to exactly the grey of the th text beneath
     it -- leaving nothing to tell a section heading from a table header. Scoped
     here rather than on `.cap` so the root dashboard keeps its per-kind hues. */
  .panel { --accent:var(--blue); }
  .note { margin:0 0 14px; color:var(--text-3); font-size:13px; }
  .note a { color:#7CB0F8; }
  /* One rebuild recipe per artifact: path, what it is, the commands as a real
     block, then the caveat. These pages had no multi-line code affordance at
     all, which is how the commands ended up as inline <code> runs inside a
     prose sentence. pre-wrap so a long command is never hidden off-screen, and
     so a soft wrap does not become a newline when the block is copied. */
  .rb { margin:0 0 18px; }
  /* The closing note belongs to the section, not to a gap, so the final block
     sits 8px above it. Marked by class rather than `:last-of-type`, which keys
     off the tag and not the class: whether it matched depended on what other
     divs the panel happened to emit afterwards, and on a real page it never did
     -- a case with rebuild blocks has built refs, so it also has the
     "Artifacts not published" `.table-wrap` sitting after them. */
  .rb-last { margin-bottom:8px; }
  .rb .path { margin:0 0 4px; font-family:var(--mono); font-size:13.5px;
    color:var(--text-1); word-break:break-all; }
  .rb .what { margin:0 0 8px; color:var(--text-3); font-size:13px; }
  .rb .caveat { margin:0; color:var(--text-3); font-size:13px; }
  .rb pre { margin:0 0 8px; background:var(--sunken); border:1px solid var(--border);
    border-radius:8px; padding:11px 13px; }
  .rb pre code { display:block; font-family:var(--mono); font-size:13px;
    color:#A5D6FF; white-space:pre-wrap; overflow-wrap:anywhere; }
