- /compare accepts ?stem=…&stem=… (repeated) for 2-8 runs; legacy ?a=&b=
still works. compare.js parses multi-stem; template drops stem_a/_b
data attrs that were unused.
- compare-select.js: MAX bumped to 8, button enables at 2-8 selected.
URL emitted as ?stem=… per selection.
- runs list gets a dataset/algorithm chip filter bar above #runs-slot
(pattern ported from metrics.js). Chips reflect the union of values in
the current list; selection state persists across htmx swaps. Non-
matching rows get .filtered-out (display:none).
- _runs.html li now carries data-embedder/data-generator so the filter
can key on them.
- per-run checkbox when embedding HTML exists; cap at 2 selected
- sticky 'compare selected' button opens /compare?a=&b= in new tab
- selection state persists across the 3s htmx poll via a Set keyed by stem
- /compare stub validates stems, renders scaffolding (three.js UI next)