:root {
  color-scheme: light;
  --ink: #17201d;
  --muted: #69736e;
  --paper: #ede9df;
  --paper-deep: #e2ddd1;
  --panel: rgba(249, 247, 241, 0.82);
  --line: rgba(27, 42, 36, 0.16);
  --green: #236957;
  --green-soft: #70a68e;
  --rust: #bb4c2e;
  --amber: #d49a36;
  --mono: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

* { box-sizing: border-box; }
html, body { min-height: 100%; margin: 0; }

body {
  color: var(--ink);
  font-family: var(--sans);
  background:
    radial-gradient(circle at 9% 4%, rgba(38, 105, 87, 0.09), transparent 28rem),
    radial-gradient(circle at 92% 84%, rgba(187, 76, 46, 0.08), transparent 32rem),
    var(--paper);
}

button, input { font: inherit; }

.shell { width: min(1500px, calc(100% - 52px)); margin: 0 auto; padding: 30px 0 22px; }

.masthead { display: flex; align-items: center; justify-content: space-between; gap: 28px; }

.brand-lockup { display: flex; align-items: center; gap: 16px; }
.mark {
  display: grid; place-items: center;
  width: 46px; height: 46px; border-radius: 13px;
  background: var(--green); color: var(--paper);
  font-family: var(--mono); font-weight: 700; letter-spacing: 0.06em;
}
.eyebrow {
  margin: 0 0 2px; font-family: var(--mono); font-size: 11px;
  letter-spacing: 0.16em; color: var(--muted);
}
h1 { margin: 0; font-size: 26px; letter-spacing: -0.015em; }

.runtime-pill {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 7px 14px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--panel); font-family: var(--mono); font-size: 12px;
}
.runtime-pill i { width: 8px; height: 8px; border-radius: 50%; background: var(--amber); }
body[data-engine="ready"] .runtime-pill i { background: var(--green); }
body[data-engine="failed"] .runtime-pill i { background: var(--rust); }

.banner {
  display: flex; align-items: baseline; gap: 12px;
  margin: 18px 0 0; padding: 11px 16px;
  border: 1px solid rgba(212, 154, 54, 0.5); border-left: 4px solid var(--amber);
  border-radius: 8px; background: rgba(212, 154, 54, 0.12);
  font-size: 13px; line-height: 1.5;
}
/* `display: flex` above outranks the user-agent's `[hidden] { display: none }` rule, so
   without this the hidden banners render anyway -- which showed a permanent REFUSED bar
   over a page that had refused nothing. Measured in the browser, not reasoned about. */
.banner[hidden] { display: none; }
.banner b { font-family: var(--mono); font-size: 11px; letter-spacing: 0.12em; white-space: nowrap; }
.banner.error { border-color: rgba(187, 76, 46, 0.5); border-left-color: var(--rust); background: rgba(187, 76, 46, 0.12); }
/* The provenance banner is neutral when the curve was computed here and warns only when
   it was not -- a placeholder or a fallback file. Colour carries the same information the
   label does, so the two cannot drift apart. */
.banner.warn { border-color: rgba(187, 76, 46, 0.5); border-left-color: var(--rust); background: rgba(187, 76, 46, 0.12); }

.intro { display: flex; align-items: center; justify-content: space-between; gap: 28px; margin: 18px 0 20px; }
.intro p { margin: 0; max-width: 74ch; line-height: 1.6; font-size: 14.5px; }
.pipeline {
  display: flex; align-items: center; gap: 7px;
  font-family: var(--mono); font-size: 11px; color: var(--muted); white-space: nowrap;
}
.pipeline span { padding: 4px 9px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel); }
.pipeline b { color: var(--green-soft); }

.laboratory { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 22px; align-items: start; }

.stage-wrap { position: relative; }
#stage {
  display: block; width: 100%; aspect-ratio: 40 / 24;
  border: 1px solid var(--line); border-radius: 14px;
  background: linear-gradient(180deg, #f7f4ec, #e9e4d8);
  cursor: grab; touch-action: none;
}
#stage:active { cursor: grabbing; }

.stage-topline {
  position: absolute; top: 12px; left: 14px; right: 14px;
  display: flex; justify-content: space-between;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em; color: var(--muted);
  pointer-events: none;
}
.stage-topline b { color: var(--ink); }
.live-dot {
  display: inline-block; width: 7px; height: 7px; margin-right: 7px;
  border-radius: 50%; background: var(--green);
}
.aim-copy {
  position: absolute; bottom: 14px; left: 14px;
  font-family: var(--mono); font-size: 11px; color: var(--muted); pointer-events: none;
}
.aim-copy span { display: block; letter-spacing: 0.12em; color: var(--ink); }

.inspector { display: grid; gap: 14px; }
.gate-card, .curve-card {
  padding: 14px 16px; border: 1px solid var(--line); border-radius: 12px; background: var(--panel);
}
.gate-row { display: flex; align-items: baseline; gap: 10px; margin: 2px 0 10px; }
.verdict { font-family: var(--mono); font-size: 20px; letter-spacing: 0.04em; }
.verdict[data-state="pass"] { color: var(--green); }
.verdict[data-state="fail"] { color: var(--rust); }
.gate-row span { font-size: 12px; color: var(--muted); }

dl.ledger { display: grid; gap: 3px; margin: 0; font-family: var(--mono); font-size: 11.5px; }
dl.ledger > div { display: flex; justify-content: space-between; gap: 10px; padding: 1px 0; }
dl.ledger > div.rule { margin-top: 4px; padding-top: 5px; border-top: 1px solid var(--line); }
dl.ledger dt { color: var(--muted); }
dl.ledger dd { margin: 0; font-variant-numeric: tabular-nums; }

.meter { height: 5px; margin: 10px 0 5px; border-radius: 999px; background: var(--paper-deep); overflow: hidden; }
.meter i { display: block; height: 100%; width: 0; background: var(--green); transition: width 90ms linear; }
.meter i[data-state="fail"] { background: var(--rust); }

.gate-card small, .curve-card small { display: block; margin-top: 6px; font-size: 11px; line-height: 1.5; color: var(--muted); }

#curve { display: block; width: 100%; margin-bottom: 8px; }

.controls { display: flex; flex-wrap: wrap; align-items: center; gap: 26px; margin: 20px 0 8px; }
.control-group { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.controls label { font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em; color: var(--muted); }
.controls output { color: var(--ink); font-variant-numeric: tabular-nums; }
.controls input[type="range"] { width: 118px; accent-color: var(--green); }
.controls .check { display: inline-flex; align-items: center; gap: 6px; }
button {
  padding: 8px 16px; border: 1px solid var(--green); border-radius: 8px;
  background: var(--green); color: var(--paper); cursor: pointer;
  font-family: var(--mono); font-size: 12px; letter-spacing: 0.06em;
}
button:hover { background: #1c5647; }
.telemetry { font-family: var(--mono); font-size: 11px; color: var(--muted); }
.telemetry b { color: var(--ink); }

footer {
  display: flex; align-items: center; justify-content: space-between; gap: 28px;
  margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line);
  font-size: 12px; color: var(--muted);
}
footer p { margin: 0; }
footer span { font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.1em; }

@media (max-width: 1080px) {
  .laboratory { grid-template-columns: 1fr; }
  .intro { flex-direction: column; align-items: flex-start; }
}

dl.ledger dt i { font-style: normal; opacity: 0.7; }
.verdict[data-state="dilated"] { color: var(--amber); }
.verdict[data-state="declared"] { color: var(--rust); }
.verdict[data-state="refused"] { color: var(--rust); }
.degrade-group { padding: 6px 12px; border: 1px dashed var(--line); border-radius: 8px; }
.controls input[type="range"][disabled] { opacity: 0.4; }

/* ---------------------------------------------------------------- the species palette
   The colour of a swatch and the size of its disc are not decoration: both come from
   `species_palette.json`, which `holon-chem` generates. The radius is DERIVED from each
   element's own computed homonuclear curve and the colour is a DECLARED ramp in Z, and
   the panel says which is which rather than leaving a reader to guess. */
.palette-section {
  margin: 22px 0 4px; padding: 16px 18px 14px;
  border: 1px solid var(--line); border-radius: 14px; background: var(--panel);
}
.palette-head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.palette-head .eyebrow { margin: 0; }
.palette-note { font-family: var(--mono); font-size: 11px; color: var(--muted); text-align: right; }

.palette { display: flex; flex-wrap: wrap; gap: 10px; margin: 12px 0 4px; }
.swatch {
  display: grid; grid-template-rows: auto auto; justify-items: center; gap: 4px;
  min-width: 64px; padding: 8px 6px 6px;
  border: 1px solid var(--line); border-radius: 11px;
  background: transparent; cursor: pointer;
  transition: border-color 120ms ease, background 120ms ease;
}
.swatch:hover { background: rgba(255, 255, 255, 0.5); }
.swatch[aria-checked="true"] { border-color: var(--green); background: rgba(35, 105, 87, 0.10); }
.swatch:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }
/* The disc's diameter is set inline from the derived radius, so what is on screen and
   what the engine computed cannot drift apart. The box is fixed so the row stays even. */
.swatch .disc-box { display: grid; place-items: center; width: 46px; height: 46px; }
.swatch .disc { border-radius: 50%; }
.swatch .label { font-family: var(--mono); font-size: 12px; letter-spacing: 0.04em; }
.swatch .label b { font-weight: 600; }
.swatch .label i { font-style: normal; color: var(--muted); font-size: 10px; }
/* An element whose own homonuclear pair does not bind: the ring says so before the
   detail panel does, because "helium bounces off everything" is the finding. */
.swatch[data-bound="false"] .disc { box-shadow: 0 0 0 2px var(--paper), 0 0 0 3px var(--rust); }

.palette-detail { display: flex; flex-wrap: wrap; gap: 18px 32px; align-items: flex-start; margin-top: 8px; }
.palette-detail .ledger { flex: 1 1 320px; margin: 0; }
.palette-detail dt i { font-style: normal; opacity: 0.7; }
.palette-rule { flex: 1 1 280px; margin: 0; font-size: 11px; line-height: 1.6; color: var(--muted); }
.banner.warn { border-color: rgba(212, 154, 54, 0.5); border-left-color: var(--amber); }

/* ---------------------------------------------------------------- the bank table
   One row per loaded curve. Deliberately dense and monospaced in the numeric columns:
   these are provenance figures a reader compares against a referee, not decoration. */
.bank-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.78rem;
}
.bank-table th {
  text-align: left;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-size: 0.62rem;
  opacity: 0.6;
  padding: 0.25rem 0.5rem 0.25rem 0;
  border-bottom: 1px solid currentColor;
}
.bank-table td {
  padding: 0.22rem 0.5rem 0.22rem 0;
  border-bottom: 1px solid rgba(127, 127, 127, 0.25);
  font-variant-numeric: tabular-nums;
}
.bank-table td.num { font-family: ui-monospace, "SFMono-Regular", Menlo, monospace; }
.bank-table .route-dmrg { font-weight: 600; }
.swatch[data-available="false"] { opacity: 0.35; }
