Redesign the window around one design system - #21
Merged
Merged
Conversation
The window read as three apps glued together: violet pills and cards in the viewer, a host panel the unified window never showed, and egui's own menus in the stream toolbar. Every screen now takes its colours, type, spacing, radii and elevation from crates/ui, in the product site's black, white and hairlines, set in Geist and Geist Mono. - crates/ui is a real design system: surface levels, three text strengths, one primary (white), status tones, the logo violet only for focus and progress, a 4-point spacing scale, a type scale, three radii, two elevations. Buttons come in five kinds; menus, tabs, switches, sliders, notices, tags and keycaps are drawn here, report themselves to accesskit and show a focus ring. Contrast is tested. - The unified window has tabs: Machines, Sharing and Settings. Sharing is the host's page (setup, status, paired devices, options, log), which the unified window used to leave unreachable. - The machine list, connection progress, failures, empty and Tailscale states, Settings and the stream overlay are rebuilt on it, with shorter, honest copy that names the right kind of machine. - The idle window no longer repaints on a timer, the Tailscale probe and the host's network calls are off the UI thread, and the host poller repaints only when something changed. - The snapshot harness builds every screen headless with default settings (it used to read the real client.toml) and renders each state at 640x420, 1280x800 and 1920x1200, at 1x and 2x; unignored tests check every state fits with no overlapping controls. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
body, titled_card, toggle and steps had no callers after the redesign, and card_frame, focus_ring and paint_icon are only used inside the kit, so they are private now. A component that nothing draws is one more thing to keep consistent for no gain. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Every install is a viewer now, but the connection errors and the path explanations still said "this Mac", and told people to "open BroLink Host and run setup", a window and a button that no longer exist. They now say "this machine" and point at the Sharing tab, and each error ends with what to do. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
egui focuses widgets in the order they are made, and a right-to-left layout makes the rightmost first, so Tab went to a machine's menu before its Connect button, and through the stream toolbar from Disconnect backwards. Controls on the right are now laid out left to right and pushed against the edge, measured on the previous pass (a changed width discards the pass, so nothing is ever drawn misplaced). A key that expires within 30 days now shows at the top of the machine list, with the other things that need doing, rather than under it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The guides still sent people to "Set up this PC", the status pill, the This PC card and a Settings card the unified window does not have, and described the toolbar's old Mouse, Keys and quick-profile controls. They now describe what is on screen: the Machines, Sharing and Settings tabs, a machine's … menu, the toolbar and its More menu on narrow windows, and the grouped Settings. CONTRIBUTING says what the snapshot run renders and where new visual elements go. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
When a stream's picture is black and the machine says its HDR desktop is the cause, the fix was a quiet text button after "Restart stream", which on its own cannot help, and the headline kept saying "Asking the PC why…" after the PC had answered. The fix is now the primary button, Restart stream is secondary, and the stale half of the headline goes once the answer is in. The snapshot run renders this overlay. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
An iPhone or Android device on the tailnet showed "BroLink isn't installed", which sends someone looking for an app that does not exist. It now says phones and tablets can't share a desktop. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Every problem found on 4.0.2, with its severity and what happened to it, the tokens and components the screens are now built from, and what is left or could not be verified without running the app. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
After a successful setup the Sharing page kept a card titled "Sharing is set up" with another Run setup again button and a note that "the list above clears" when there was no list. It now shows one line that other machines can connect. The power switch no longer mentions waking on a Mac, which BroLink does not do, and Settings' update row is labelled for what it shows. The changelog's size figure is now measured: the macOS release binary went from 12,167,440 to 11,689,120 bytes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
At 640x420, the smallest window, the stream toolbar's More menu ran past the bottom edge: "Command acts as Ctrl" and the PC's power items were cut off, and Tab could move focus onto them without showing them. Stream performance ran off the bottom as well, and both stream panels sat partly under the toolbar. Menus now choose where to open in crates/ui: below their control when they fit, above it when there is more room there (a machine's menu near the foot of the list), and capped at that side's room, scrolling inside with the scroll bar showing when neither side has room for all of it. Dropdown lists, Stream settings, Stream performance and the restart and install questions are capped the same way, below the toolbar. A control scrolls into view when Tab reaches it, and focus rings are no longer cut off at a window's edge. Tests open the More, Keys, Mouse, PC and machine menus, both panels, the questions and a dropdown at 640x420 (the separate toolbar menus from the narrowest width that shows them), Tab to the last item and check by rect that it and the whole menu or panel are on screen. The snapshot run renders each of those states at 1x and 2x. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The failed-connection card's "Dismiss" sat 12 points right of the text above it. A quiet button's label is inset by the button's padding, and with no fill or outline to show the box, the label is what the eye lines up. Actions under a notice now go in an action row that pulls a quiet button leading a line back by that padding; filled and outlined buttons still line up by their edge. Checking the other notices and cards turned up two more: a notice with no actions (Tailscale isn't connected, Installing a BroLink update) kept an empty row's height at its foot, and the setup card's "Get Tailscale" link started at the card's edge instead of under the checklist item it belongs to. The empty row now takes no room, and the link sits in the item's text column. A test checks the label of a quiet action and the edge of a filled one against the notice's title. Co-Authored-By: Claude Opus 5.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.
Redesign of the whole UI: a real design system in
crates/ui, every screen and state rebuilt on it, the stream overlay reworked, and a snapshot harness that covers all of it. The full audit (every finding, severity, state) and the design system are indocs/design/AUDIT.md.Biggest finds
client.toml/host.toml, and the relay-state renders were identical because the card was off-screen.tailscale --versionprocess spawn on the UI thread every 2 s when Tailscale is missing.What changed
crates/ui: colour, type (Geist + Geist Mono, OFL; replaces Inter), spacing, size, radius and elevation tokens; buttons in five kinds, popup menus, tabs, segmented, switch, slider, select, rows, notices/banners, tags, keycaps, disclosure. Each has accesskit info and a focus ring. Contrast is tested.Outside the UI files (small, listed for the merge)
client/src/session.rs: error strings only (7 messages).client/src/path.rs:Path::tone()mapping (a relay is amber, not red) and three "this Mac" strings, with tests.client/src/update.rs: one "this Mac" string.client/src/share.rs:LocalSharetrimmed to the summary fields, plus aSharePagetrait.host/src/product.rs: hosts the Sharing page, and syncs only on change.host/src/app.rspoller: repaints only when the status changes.Not verified here
The real app was not launched (rules). Unverified: rendering over a live picture, real DPI and font hinting on Windows, VoiceOver/Narrator, IME. Windows-only code is covered by CI's
test-windows.🤖 Generated with Claude Code