mac UI/UX pass 1: design system, render loop, tool-window shell, tree/tabs, preview - #471
Merged
Merged
Conversation
… on behaviour and scope
… target per surface is what binds
…el, shell surface snapshots Surfaces render inside real off-screen HostedWindows windows now: List rows only populate in a window, NavigationSplitView and .toolbar need one, and vibrancy materials draw black off-screen (neutralized to their plain colour, the Reduce-Transparency ground). DesignFixtures builds a deterministic demo project (3 pages, extra tabs, synthetic TeX diagnostics) with machine preferences pinned. StatusBar/EditorPane/PreviewPane/PreviewHeader lose 'private' so the loop can render them alone. Implementation-Agent: Claude Fable (lane mac-ui-design, linux-primary) Commit-Executor: Claude Fable (direct git, observed Cursor usage limit) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xd5Hmwh5GHNTiAmHUJ1MZu
…splay macOS 26 glass materials (NSContainerConcentricGlassEffectView and friends, wrapping every NavigationSplitView sidebar) never reach cacheDisplay or CALayer.render — the sidebar snapshotted blank white. CGWindowListCreateImage of our own off-screen window composites what the user actually sees, needs no Screen Recording permission for the calling process's windows, and turned out deterministic across runs (asserted green immediately after recording). The symbol is bound with dlsym because it is deprecated and Swift cannot silence a deprecation without deprecating every caller; ScreenCaptureKit is not a substitute here because it does need the permission. Baseline PNGs of the current design are recorded for all nine surfaces, both appearances. Implementation-Agent: Claude Fable (lane mac-ui-design, linux-primary) Commit-Executor: Claude Fable (direct git, observed Cursor usage limit) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xd5Hmwh5GHNTiAmHUJ1MZu
The token file from context/style-guide.md — spacing scale, radii, row heights, type sizes, semantic colours (all defined on AppKit semantic colours so light/dark/follow-system are structural), interaction-state opacities, split minimums, preview page constants, motion durations gated on ReduceMotion — plus FileTypeStyle, the IntelliJ-style colour-coded file identity used from step 3 on. Migrated in this pass: ContentView (status bar, preview header, capture and bridge bars, sheets), DocumentTabBar, WorkspaceSidebar, ProblemsPanel, DiagnosticsPanel, CommandPalette, PreviewView, PreviewV2View, PreviewZoom, WordCountStatusView, EditorIntelligence (gutter paints + quick info), EditorPreferences, ProjectSearchPanel, MathHoverPreview. Values were snapped to the token scale where they were within a point or two (14→12, 10→8, 5→4/6, 3→2), which the re-recorded snapshots show as sub-pixel-to-2pt shifts; captions standardise on the 11pt secondary token. Secondary windows (Nearby, CaptureInbox, scaffolds, history, citation rename) migrate when their surfaces are touched. Implementation-Agent: Claude Fable (lane mac-ui-design, linux-primary) Commit-Executor: Claude Fable (direct git, observed Cursor usage limit) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xd5Hmwh5GHNTiAmHUJ1MZu
…tool column, three-chip toolbar, 900pt minimum IntelliJ's structure with Xcode's restraint (design-principles §1/§4): a left icon rail toggles the tool windows; the tool column stacks the Project tree above the Outline (which ships collapsed); Problems left the column — its homes are the bottom panel and the status-bar badge; regions separate by hairlines and one tonal shift, and the status bar spans the window. NavigationSplitView is gone (its macOS 26 glass sidebar also never reached the off-screen render loop). The title bar now carries the chrome budget: Compile (producer menu behind its chevron), Export, Commands, plus the Captures toggle. The v2-pane and dark-preview switches moved into the preview header; Find in Project, Rename Citation, Durable History and Nearby ride their menus, shortcuts and the palette, which the toolbar tooltips still name. Below the width where both columns fit, the preview collapses to a toggle (tab bar to show, preview header to come back) instead of being crushed; the window minimum drops from 1200 to 900pt. FocusOrder gains the rail as pane 1 and the help text follows reality; CommandTableTests pin the new structure. Implementation-Agent: Claude Fable (lane mac-ui-design, linux-primary) Commit-Executor: Claude Fable (direct git, observed Cursor usage limit) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xd5Hmwh5GHNTiAmHUJ1MZu
'main.tex › Résumé of a small journey › At the café' — the enclosing sectioning chain at the caret (DocumentOutline.breadcrumb, unit-tested: ancestors are the nearest preceding lower level, a following section closes its siblings' subsections, the preamble shows none). Environments and labels stay out: the lexical scan records no \end positions, and a segment that may already be closed would lie. Segments click through to their section; the outline rescan is edit-debounced and caret moves only re-pick the chain from cached items. Indicators (word count, latency, route, revisions, problem counts) move to the trailing side, IntelliJ-fashion. Implementation-Agent: Claude Fable (lane mac-ui-design, linux-primary) Commit-Executor: Claude Fable (direct git, observed Cursor usage limit) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xd5Hmwh5GHNTiAmHUJ1MZu
… 24pt tree rows FileTypeStyle is now the one vocabulary for what a file is — .tex blue (entry filled), .bib purple, .cls/.sty teal, .pdf red, images green, generated grey — used identically by the project tree and the tab strip (design-principles §6: colour is identity, never decoration). Tree and outline rows drop to 24pt with full-row hover and selection highlights. Tabs get the Islands treatment (§5): the active tab is a filled rounded card raised out of the recessed strip (hairline + soft shadow), inactive tabs are icon + name with no chrome, the close control appears only on hover and on the active tab, and the modified state is the filled dot. The per-tab durable-revision counter, the edited/saved caption and the byte/UTF-16 readout leave the strip — the dot, tooltips and the status bar already carry them (Xcode restraint: an arguable element loses). Implementation-Agent: Claude Fable (lane mac-ui-design, linux-primary) Commit-Executor: Claude Fable (direct git, observed Cursor usage limit) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xd5Hmwh5GHNTiAmHUJ1MZu
… pointer-over; Fit Page (⌘⇧9) Design-principles §8: at rest the header shows only the page indicator and zoom percentage, dimmed, plus quiet state — the fixed-slot compile spinner, a FIXTURE/HISTORICAL badge only when the pages are not the worker's current result, staleness text and capability warnings. On pointer-over the second tier fades in place (150ms ease-out, gated on Reduce Motion, no reflow): zoom −/+, Fit Width, the new Fit Page, and the preview-scoped v2/dark switches. Producer name and layout-capability detail moved into the header tooltip. No error cards in this column, before or after. The page indicator rides the anchoring probe (the page under the viewport's top edge, reported only on change); Fit Page is a real command — table entry, View menu, ⌘⇧9, palette, README row — computed from the pane geometry the preview already reports. Toolbar-location claims in the table and README now match the three-chip toolbar. Implementation-Agent: Claude Fable (lane mac-ui-design, linux-primary) Commit-Executor: Claude Fable (direct git, observed Cursor usage limit) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xd5Hmwh5GHNTiAmHUJ1MZu
Contributor
|
daniel-parent: overlap notes, nothing blocking. I test-merged this head against my open Mac PRs.
Merge in whatever order suits you. If #471 lands first I'll rebase all three onto it the same hour. If you'd rather land my smaller three first, their heads are I'm not starting any new Mac UI work while this design pass is in flight; my new lanes are compiler, math-layout, render-pipeline and CLI. |
This was referenced Sep 14, 2026
d-q222
added a commit
that referenced
this pull request
Sep 14, 2026
…to Line / :N Merged origin/main (includes #471/#476 design system and scoped command palette). The only conflict was CommandPalette.swift. Resolution: keep #476's PaletteScope / PaletteEntry structure and DS tokens. Re-added this PR's Go to Line command in perform(), plus :N as a query prefix that emits a lineJump palette entry. No clash — #476 uses ':' only in internal ids (file:, cmd:), not as a typed prefix. GoToLineSheet restyled onto DS tokens. Tests (apps/mac): swift test --filter 'GoToLineTests|CommandTableTests|CommandPalette' Executed 18 tests, with 2 failures — both DesignSnapshots ShellSnapshotTests.testCommandPalette (known-failing class on this Mac). swift test --skip-build --filter 'GoToLineTests|CommandTableTests' --skip DesignSnapshots Executed 17 tests, with 0 failures (CommandTableTests 8, GoToLineTests 9). Next: push this branch; then PR #411 problems-order in its own worktree. Implementation-Agent: cursor-agent cursor-grok-4.6 Commit-Executor: cursor-agent Lane-Owner: daniel-parent (mac-m5pro-dq222) Co-authored-by: Cursor <cursoragent@cursor.com>
d-q222
added a commit
that referenced
this pull request
Sep 14, 2026
…rseded UI Merged origin/main (includes #471/#476 Problems panel). Conflicts were ProblemsPanel.swift and DiagnosticsPanel.swift. Kept only EditorDiagnostics.listBucket grouping: author errors (0), then warnings (1), then FlashTeX gaps (2), stable within each bucket. groups() feeds the panel, copy-text, and stepOccurrence, so next/previous occurrence and ⌘⌥] land on the first error rather than an earlier gap. goToDiagnostic still walks underlined marks in document order (it does not iterate groups). Status-bar badges remain counts, not a list. Dropped as superseded by #476: count chips (including zeros), the old header/row chrome, the DiagnosticsListView chip caption, and the 180 pt idealHeight (#476 already tokens this at DS.Layout.problemsIdealHeight). Kept #476's "N not implemented" gap count rendering. Adapted WorkspaceShellTests off the 180 pt assertion. Added testThreeGapsThenWarningThenErrorListsTheErrorFirst. Tests (apps/mac): swift test --filter 'EditorDiagnostics|ProblemsPanel|DiagnosticsPanel|CommandTable' Executed 60 tests, 7 skipped, 2 failures — both DesignSnapshots ShellSnapshotTests.testProblemsPanel (known-failing class on this Mac). Product suites all passed (DiagnosticsPanelTests 15, CommandTableTests 8, EditorDiagnostics* green). swift test --skip-build --skip NearbyInterfaceTests --skip NearbyLANInterfaceTests --skip DesignSnapshots Executed 1220 tests, with 135 tests skipped and 0 failures. RustPDFExportPipeTests: 4 passed including testTimeoutTerminatesAStuckWriter (1.002 s); no isolation re-run. Next: push this branch. Implementation-Agent: cursor-agent cursor-grok-4.6 Commit-Executor: cursor-agent Lane-Owner: daniel-parent (mac-m5pro-dq222) Co-authored-by: Cursor <cursoragent@cursor.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.
First half of the design pass from the installed design kit (
context/design-principles.md,context/style-guide.md,references/), steps 1–4 of the order of work in.claude/agents/ui-ux-implementer.md.What's here
Tests/DesignSnapshots): surfaces render in real off-screen HostedWindows windows and are captured through the window server (CGWindowListCreateImageof our own window —cacheDisplay/CALayer.renderpaint macOS 26 glass subtrees blank). Deterministic (record-then-assert green, 3× stability run); reference PNGs committed for nine surfaces × both appearances.DesignSystem.swift(step 1): spacing/radii/row-height/type tokens, semantic colours on AppKit semantic colours, state opacities, layout minimums, preview page constants, Reduce-Motion-gated durations, andFileTypeStyle(colour-coded file identity). Main-window chrome carries no raw numeric/colour literals; secondary windows (Nearby, CaptureInbox, scaffolds, history) migrate when touched.FocusOrder/help text/CommandTableTestsupdated together.main.tex › Chapter › Sectionat the caret, clickable, edit-debounced scan (unit-tested chain logic).N / M+ zoom % at rest, dimmed; controls (−/+, Fit Width, new Fit Page ⌘⇧9, v2/dark) fade in on pointer-over without reflow; FIXTURE/HISTORICAL badges only as state; producer/capability detail in tooltips. Page indicator rides the existing anchor probe.Gates
swift buildclean;CommandTableTests(README/command-table/menu parity),OutlineStructureTests,PreviewAnchoringTests,PreviewZoomTestsgreen; full suite 1223 tests / 137 skipped / effectively 0 failures (two were stale snapshot references from a concurrent re-record mid-run; the dedicated re-run is green 3×).Steps 5–8 (problems panel + gutter fix-it, outline/palette/completion, find/settings, states + full light-dark pass) follow on a stacked branch.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Xd5Hmwh5GHNTiAmHUJ1MZu