955c30a864
Repair-forward for the accidental push at 959f249, which put the PRE-review
version of the browser-widget work onto main. The three defects review found
are all in the version main currently carries; this is the delta that
supersedes it.
1. `categoryList` did not call `indicator()`. It inlined U+25B8/U+25BE, the
SMALL triangles, where `indicator()` — the page's declared ONE spelling —
the page's own grid group headers, and src/ui/category_panel.rs all draw
U+25B6/U+25BC. The browser's category panel disagreed with the TUI's and
with its own grid, inside the file whose comment says "only this spelling
is the page's".
2. Two specs pinned the divergent pair, so the obvious cure would have failed
tests that shipped with the feature. widgets.spec.js AND pointer.spec.js —
the latter written on a different branch, which had grown the same wrong
assertions independently. Three files converging on a spelling nothing
compares is design-principles §5's predicted failure, observed. Proved
discriminating by running the corrected specs against the pre-fix bundle,
where they fail with `Received string: "▸ Product (4) R"`.
The pointer.spec.js line is in this PR and not a later one because main
already carries that file: without it this change leaves CI red. It is one
assertion corrected by the same rule as its sibling, not feature work.
3. `el.tiles.hidden` was a no-op, removed with its false comment. `#tiles`
declares `display: flex`, an author-origin rule that beats the UA sheet's
`[hidden] { display: none }`, so the guard never hid anything. Worth
knowing before restoring it: `#tiles` being ALWAYS laid out is why its
height never changes and it stays out of the ResizeObserver feedback path.
Also `playwright.config.js` takes IMPROVISE_HARNESS_PORT (default 8099, so CI
is unchanged). The hard-coded port plus `reuseExistingServer` let Playwright
silently ADOPT a server left by another worktree and test THAT tree. It fired
in both directions in one session: a false negative (a fix reported absent)
and — the dangerous half — a false POSITIVE, 5 passed against a tree verified
to contain no #tiles at all. A failure sends you looking; a false pass prompts
nobody.
The evidence prose records all of it, plus the ResizeObserver acyclicity proof
that retires "argued, not tested" there: frameCost.cols is row header LEVELS
(independent of projected rows) and frameCost.rows derives from the column
window, so cols -> rows and nothing depends on rows. No cycle to oscillate.
Gates: 1359 Rust tests, rustfmt, comment-run and evidence linters, 21/21
Chromium harness (on a private port, so not another checkout's tree).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>