Frontend redesign - #17
Merged
Merged
Conversation
The map's chrome has no unit tests, so "did that CSS change break the
building dialog at 1024px" was only answerable by looking, which meant in
practice it went unanswered.
ui_shots.py captures 17 UI states (empty, loaded, each dialog, each tool
panel, three narrow viewports) and pixel-diffs them against a previous
run, so a refactor can be checked state by state:
py tools/ui_shots.py --serve --out ui_shots/before
...change things, rebuild dist...
py tools/ui_shots.py --serve --out ui_shots/after --baseline ui_shots/before
ui_behaviour.py covers what a screenshot cannot: that dialogs are real
modals, that the hover tooltip still paints above one, that Escape peels
exactly one layer, that opening a dock never resizes the map.
Both run against dist/ and take --serve and --headed. Their output is
gitignored; the baselines are local, since committing PNGs of the whole
UI would bloat the repo for little gain.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The chrome had grown one implementation per feature: four separate modal
dialogs, five progress bars, six list-row shapes, thirteen copies of the
same accent-button declaration, three private copies of el(). Each was
reasonable alone; together they meant "make the panels match" was a
manual job that was never finished. Everything also floated over the map
as free-standing cards, so a working session looked like a scatter of
unrelated windows.
Design tokens (map.css :root)
The whole colour/type/spacing/radius vocabulary in one block. 19
distinct font sizes -> 8 steps, 11 radii -> 5, 25 !important -> 0, and
~180 raw hex literals down to 17 genuine one-offs.
Primitives (ui.css + ui.js)
.btn/.field/.dlg/.row/.bar/.toggleSwitch/.chev and UI.el/UI.dialog/
UI.onEscape. ui.css loads BEFORE map.css so a feature rule of equal
specificity can override a primitive without !important.
Native <dialog>
The four modals use showModal(), which hands the browser the focus
trap, focus restore, Escape, background inertness and top-layer
stacking -- the last of which removed the hand-maintained z-index
ladder entirely. Escape is no longer six document handlers coordinated
by e.defaultPrevented with priority set by <script> order; layers now
register explicitly. The hover tooltip became a top-layer popover,
since no z-index can reach above a modal dialog.
Docked layout
An app bar across the window, the layers dock pinned left, the tool
dock (altitude rail + paste/network panels, one at a time) pinned
right. The docks OVERLAY the map rather than taking grid columns, and
#map always fills the area below the app bar. That is deliberate: as
grid columns, every dock toggle resized the map and Leaflet's
invalidateSize re-centred it, sliding the world ~141px sideways. Two
rounds of compensation code were written and both reverted; not
resizing the map removes the problem instead of correcting for it.
See docs/dock-map-anchoring.md before changing this.
The layers dock push-navigates between the category list and one
category's contents instead of opening a second column, so browsing
costs the map nothing and there is no half-empty pane.
Also fixed along the way
- #logoButton was a button with a title, a pointer cursor and no click
handler anywhere; it is a brand mark now.
- The altitude rail's width was reserved even while hidden, showing as
a dead black strip beside the map before any save was loaded.
- The empty state was ~700px of void with the drop zone marooned at
the bottom.
- The search field kept its query after committing a result.
- Delete in the selection bar looked identical to Copy.
- No layout media queries existed at all; there are now breakpoints at
1200/980/820/620px.
- Accessibility: combobox roles on the search field, inert on the
off-screen dock pane, aria-labels on icon-only buttons.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
CONTRIBUTING gains map.css / ui.css / ui.js in the project layout (with the rule that new chrome reuses the primitives rather than restyling its own), the two new tools, and how to run the UI guards. dock-map-anchoring.md records why the docks overlay the map instead of taking grid columns. Two attempts at compensating for Leaflet re-centring the map on a dock toggle were written and reverted, the second one worse than the bug it fixed, and the geometry-in-headless testing that green-lit it was measuring the wrong thing. That is worth writing down: without it the obvious "improvement" is to turn the docks back into columns and walk straight into it again. Co-Authored-By: Claude Opus 5 (1M context) <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.
No description provided.