From 467cbfe27d76ff3e81e4780c18225c653c0aa46d Mon Sep 17 00:00:00 2001 From: IPerception Date: Sun, 16 Aug 2026 19:52:22 -0400 Subject: [PATCH 1/2] feat: port the new UI design, and fix the load path it exposed Restyles the browser app to the design generated in Claude, keeping every feature added since that design was made. Both halves were the requirement: the design covers roughly half of what the app now does. Design - 24 themed tokens across all four theme blocks. Light and dark are both the design's own values, recovered from the LIGHT/DARK maps in its script block. Those tokens are applied at runtime and never written as CSS, which is why they first looked undefined. The design re-tints toward blue on the way to dark rather than desaturating; copying the light theme's neutral hue gave a flat charcoal that read dull. - The three identity hues the design has no colour for (shift, swap, deid) are generated at the measured lightness and chroma of its accent, per theme, so they sit at the same visual weight. New -2 variants take chip text on its own wash from about 3.8:1 to about 9:1, which is AA rather than not. - Barlow Condensed embedded, subset to the glyphs this app renders: 20.6 KB for both weights against 44 KB unsubsetted. web/embed-font.py is the tool. It is SIL OFL 1.1 with no Reserved Font Name, and the notices ride in the font's own name table because the single HTML file travels detached from this repo. - Every border-radius removed, the masthead moved into a full-width header with a mono readout strip, numbered rail stations, an accent rule under the selected tab, corner ticks on the four panels that do not repeat, and the graph-paper ground on the empty state only. - Data rows get their own size lever, --step-row, separate from the chrome scale: the Document list, the Tree, Claims and Checks read at 14px. Fixes - Loading a file left the previous document's view state in place. selectTab paints the row list before renderDocument rebuilds it, so a stale `visible` was indexed against the new document's segments and threw out of renderRow, aborting loadFile before renderDocument and updateReadouts. The file name changed, nothing else did, and no error reached the screen. The tree half of this reset always existed, which is why the Tree tab never had the bug. - windowRange had no upper clamp, which is what made that silent: it returned first 8325 against a total of 31, and the slice came back empty. - The Document filter scrolled out of reach while the outline stayed pinned, and selecting a claim welded the list to the tab strip. - .claims-scroll and the outline height cap were hand-tallied constants describing chrome that had changed height. Both now measure it. Tests - New render.mjs, a ninth suite: it drives the app against a thin DOM shim, including the load-over-load sequence the bug above lived in. Every other suite tests a pure function, and this class of fault was invisible to all of them and to lint. - Two assertions that wrote down a number which was really a consequence of another number now derive it instead. - lint rule 8 rewritten: the mask and theme toggles are asserted to sit in the page header rather than outside .rail-body, which no longer exists. The bug it guards has happened once, so it is re-expressed, not dropped. Co-Authored-By: Claude Opus 5 --- .gitignore | 7 + web/EDIWorkbench.html | 994 ++++++++++++++++++++++++++++++------------ web/embed-font.py | 160 +++++++ web/fonts/OFL.txt | 94 ++++ web/tests/all.mjs | 1 + web/tests/lint.mjs | 29 +- web/tests/render.mjs | 156 +++++++ web/tests/tree.mjs | 7 +- web/tests/virtual.mjs | 11 +- 9 files changed, 1177 insertions(+), 282 deletions(-) create mode 100644 web/embed-font.py create mode 100644 web/fonts/OFL.txt create mode 100644 web/tests/render.mjs diff --git a/.gitignore b/.gitignore index 92016de..1d06129 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,10 @@ docs/notes/ Thumbs.db desktop.ini .DS_Store + +# Generated font CSS. web/embed-font.py writes web/fonts/face.css, and its +# contents get pasted straight into the
- -