:root{
  --bg:#0f1116; --panel:#171a22; --panel2:#1d212b; --ink:#e8eaf0; --dim:#9aa1b2;
  --line:#2c313f; --accent:#f0c05a; --obl:#6fb7ff; --ecc:#ff8f6b; --coup:#a98bff;
  --ok:#7ddc9a; --warn:#ff7a7a; --plate:#20242f;
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{background:var(--bg);color:var(--ink);
  font:15px/1.55 ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;}
header.top{padding:18px 20px 10px;border-bottom:1px solid var(--line);background:var(--panel)}
.brand h1{margin:0;font-size:26px;letter-spacing:.2px}
.tag{margin:6px 0 0;color:var(--dim);max-width:76ch}
.tag em{color:var(--accent);font-style:normal}
nav.tabs{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}
.tab{background:var(--panel2);color:var(--dim);border:1px solid var(--line);border-radius:7px;
  padding:7px 13px;font:inherit;font-size:14px;cursor:pointer}
.tab:hover{color:var(--ink)}
.tab[aria-pressed="true"]{background:var(--accent);color:#1a1405;border-color:var(--accent);font-weight:600}
main{display:grid;grid-template-columns:270px minmax(0,1fr);gap:16px;padding:16px 20px 28px;align-items:start}
.panel{background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:14px}
.controls{position:sticky;top:12px}
.ctl{margin-bottom:12px}
.ctl label{display:block;font-size:12.5px;color:var(--dim);margin-bottom:4px;letter-spacing:.2px}
.ctl output{color:var(--ink);font-variant-numeric:tabular-nums;font-weight:600}
.ctl input[type=range]{width:100%;accent-color:var(--accent)}
.knob input[type=range]{accent-color:var(--obl)}
.ctl select{width:100%;background:var(--panel2);color:var(--ink);border:1px solid var(--line);
  border-radius:6px;padding:6px;font:inherit}
.buttons{display:flex;flex-wrap:wrap;gap:6px}
.buttons button{flex:1 1 46%;background:var(--panel2);color:var(--ink);border:1px solid var(--line);
  border-radius:6px;padding:7px 6px;font:inherit;font-size:12.5px;cursor:pointer}
.buttons button:hover{border-color:var(--accent);color:var(--accent)}
.buttons button.on{background:var(--accent);color:#1a1405;border-color:var(--accent)}
.view{min-width:0}
.canvas-wrap{width:100%;overflow-x:auto;display:flex;justify-content:center}
canvas{display:block;max-width:100%;height:auto;background:var(--plate);border-radius:8px}
.readout{margin-top:12px;display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:10px}
.card{background:var(--panel2);border:1px solid var(--line);border-radius:8px;padding:9px 11px}
.card .k{font-size:11.5px;color:var(--dim);text-transform:uppercase;letter-spacing:.6px}
.card .v{font-size:19px;font-variant-numeric:tabular-nums;margin-top:3px}
.card .n{font-size:12px;color:var(--dim);margin-top:3px}
.card.hot .v{color:var(--accent)}
.card.obl .v{color:var(--obl)}
.card.ecc .v{color:var(--ecc)}
.card.coup .v{color:var(--coup)}
/* THE PROSE PANELS MUST SPAN BOTH GRID TRACKS. When the control column is hidden on
   these two views its grid item disappears, and without this the prose becomes the first
   item and is laid out inside the 270px control track — 30 characters wide with the whole
   right-hand side empty. Every offline assertion passed while that was true; a screenshot
   is what showed it. */
#view-findings,#view-help{grid-column:1 / -1}
.prose{line-height:1.62;max-width:none}
.prose h2{font-size:19px;margin:22px 0 8px;color:var(--accent)}
.prose h2:first-child{margin-top:2px}
.prose h3{font-size:15px;margin:16px 0 6px;color:var(--ink)}
.prose p{margin:8px 0;color:#cfd4e0}
.prose ul{margin:8px 0;padding-left:20px;color:#cfd4e0}
.prose li{margin:4px 0}
.prose code{background:var(--panel2);padding:1px 5px;border-radius:4px;font-size:13px}
.prose .lede{color:var(--ink);font-size:16px}
table{border-collapse:collapse;width:100%;margin:10px 0;font-size:13.5px}
th,td{border:1px solid var(--line);padding:6px 9px;text-align:left;vertical-align:top}
th{background:var(--panel2);color:var(--dim);font-weight:600;font-size:12.5px;
  text-transform:uppercase;letter-spacing:.4px}
td.num{text-align:right;font-variant-numeric:tabular-nums}
.tablewrap{overflow-x:auto}
.verdict{border-left:3px solid var(--warn);padding-left:11px;margin:10px 0;color:#cfd4e0}
.verdict.ok{border-left-color:var(--ok)}
.swatch{display:inline-block;width:11px;height:11px;border-radius:2px;margin-right:6px;
  vertical-align:baseline}
.sw-full{background:var(--accent)} .sw-obl{background:var(--obl)}
.sw-ecc{background:var(--ecc)} .sw-coup{background:var(--coup)}
.foot{border-top:1px solid var(--line);padding:12px 20px 26px;color:var(--dim);font-size:12.5px}
.foot p{margin:0}
pre.verbatim{background:var(--panel2);border:1px solid var(--line);border-radius:8px;
  padding:11px;overflow-x:auto;font-size:12px;line-height:1.45;color:#cfd4e0;white-space:pre}
@media (max-width:860px){
  main{grid-template-columns:minmax(0,1fr)}
  .controls{position:static}
  /* on a phone the controls panel is ~900px tall; without this the first screen shows no
     dial at all. Put the picture first and the sliders under it. */
  .view{order:-1}
}
