Port the new UI design, and fix the load path it exposed - #5
Merged
Conversation
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 <noreply@anthropic.com>
Minor rather than major: the redesign was explicitly required to retain every feature, so nothing was removed or broken, and the app gained the header readout strip and its Mode reading. A 2.0.0 would signal a break to anyone reading the tag, and there is not one. The rail footer string is the single source of truth. release.mjs derives both the tag and the asset filename from it (v1.1.0, EDIWorkbench-v1.1.0.html), and lint rule 9 pins its shape; the README links /releases/latest rather than a pinned tag, so nothing else needed editing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
IPerception
added a commit
that referenced
this pull request
Aug 21, 2026
* chore: tidy the source-interchange copy Uppercase the drop-zone label through text-transform rather than literal caps, so case stays in the stylesheet like the app's other uppercase runs. Tracked at .06em to sit alongside .card-title, the only other large-size uppercase in the UI. Rename the sample link from "Use sample" to "Load a sample". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs: retake the README screenshots on the v1.1.0 UI The four screenshots still showed the pre-redesign interface: none of them had the new masthead or the readout strip. Retaken against the same sample files so the existing alt text still describes what is on screen. Two things changed beyond the styling: - The Claims table was clipped on the right in the old capture, cutting off the claim total column. It now fits, so the alt text gains that column. - The old Tree capture reported cob_loops.edi as 51 segments / 1.3 KB. The file is 44 segments / 1,244 bytes and has never been edited; those were the figures for patient_and_cob.edi, loaded before it. The readout went stale on load and the filename did not. Fixed by the load path work in #5, and the new capture reads correctly. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Restyles the browser app to the design generated in Claude, while keeping every
feature added since that design was made. Both halves were the requirement: the
design was built from an early version and covers roughly half of what the app
now does.
Ships as v1.1.0.
Design
design's own values, recovered from the
LIGHT/DARKmaps in its scriptblock — those tokens are applied at runtime and never written as CSS, which is
why they first appeared undefined. The design re-tints toward blue on the
way to dark rather than desaturating; deriving dark by preserving the light
theme's neutral hue produced a flat charcoal that read visibly dull.
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
-2variants take chip texton its own wash from ~3.8:1 to ~9:1 — AA rather than not.
for both weights against 44 KB unsubsetted.
web/embed-font.pyis the tool.SIL OFL 1.1, no Reserved Font Name; the copyright, licence and URL ride in the
font's own name table, because the single HTML file travels detached from this
repo and a repo-only
OFL.txtcannot discharge that.border-radiusremoved; the masthead moved into a full-width headercarrying 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.
--step-row, separate from the chromescale — Document, Tree, Claims and Checks read at 14px.
The grid ground is deliberately not on
.stage.ROW_His 24 andTREE_ROW_His 28 against a 28px grid: on the Tree that rules every row, and onthe Document the two pitches beat with a 168px period that crawls as a
virtualized list scrolls.
Fixes
selectTabpaints the row list beforerenderDocumentrebuilds it, so astale
visiblewas indexed against the new document's segments and threw outof
renderRow— abortingloadFilebeforerenderDocumentandupdateReadouts. The file name changed, nothing else did, and no errorreached the screen. The tree half of this reset always existed, which is why
the Tree tab never had the bug.
windowRangehad no upper clamp, which is what made that silent: itreturned
first: 8325against a total of 31, and the slice came back empty.selecting a claim welded the list to the tab strip.
.claims-scrolland the outline height cap were hand-tallied constantsdescribing chrome that had changed height. Both now measure it.
Tests
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 every static check in
lint.mjs. Verified by removing the state reset andwatching the assertion go red.
another number now derive it instead.
lint.mjsrule 8 rewritten: the mask and theme toggles are asserted to sit inthe page header rather than outside
.rail-body, which no longer exists. Thebug it guards has happened once, so it is re-expressed, not dropped.
Verification
node web/tests/all.mjs— all 9 suites green.python -m unittest— 11 tests,green. The app is 290 KB, up from 256 KB; 20.6 KB of that is the embedded font.
Checked before staging that no design source material is committed: the
generated
web/fonts/face.cssis gitignored, anddocs/notes/— the artifact,its 44 unpacked assets and 39 source
.woff2files — stays out.Merging deploys to the live Pages demo, which tracks
mainrather than the tag.🤖 Generated with Claude Code