- panel-grid.js (new): exports mountPanels({host, controls, stems}) → {destroy}.
Moved createPanel + shared control wiring + linked-hover + pad-to-match
time mapping out of compare.js. Stem-count-agnostic; works for 1, 2, or N.
- Panel DOM is cloned from <template id=compare-panel-tpl> on each page.
- compare.js is now a ~10-line shim: parse ?a=&b=, call mountPanels.
- Per-panel color is viridis-sampled by index/N (middle viridis for N=1,
ends-of-palette for N=2, linear lerp for N≤8, cycle at N≥9). Set as
--panel-color on the panel element; CSS reads it for tag/time-seg.
- Homepage <dialog id=run-modal> + run-modal.js hijack the 'embedding' link
(plain click → modal; meta/ctrl/middle-click still opens plotly HTML).
Dialog close disposes every panel's renderer/geometry/material.
- .compare-grid → repeat(auto-fit, minmax(360px, 1fr)) handles N=1..many,
replaces the <900px one-column media rule.
- Runs list: relabel Prefect's 'Late' state as 'Queued' — more honest
description of what the runner is doing at the concurrency cap.