theme(M2): walking skeleton — Appearance section with 2 presets + live preview - #9
Merged
Merged
Conversation
…ve preview
Second milestone of the Superghost theme system rebuild
(plans/gleaming-wobbling-rainbow.md M2). Proves the architecture
end-to-end: pick a preset in Settings → mini-preview AND the actual
app sidebar recolor in the same render frame.
What this adds:
- `Sources/AppearanceSection.swift` — the new Settings section.
Reads from `ThemeStore` via `@EnvironmentObject`; renders the panel
header, a miniature Superghost layout (sidebar + terminal stripes
painted with `theme.tokens`), and a horizontal preset strip.
- `Sources/BuiltInThemes.swift` — Tokyo Night (dark) and Catppuccin
Latte (light), both fully specified (chrome tokens hand-chosen, not
derived). Includes a small registry API (`all`, `preset(withId:)`,
`defaultPreset(for:)`) that M4 grows.
- `SettingsNavigationTarget.appearance` for deep-linking to the
section. `SettingsRootView` now injects `ThemeStore.shared` as an
environment object so the whole Settings tree can observe it.
- `AppearanceSection()` inserted in `SettingsView.body` between the
"App" card and "Workspace Colors" header — chosen position keeps the
legacy "Sidebar Appearance" section visible for now (M3 absorbs it).
- `ThemeStore.applyTheme(_:)` now also writes `sidebarTintHex` /
`sidebarTintHexDark` / `sidebarTintHexLight` so existing
`SidebarBackdrop` (`@AppStorage`-driven) reacts to preset switches
without a restart. This is the bridge until M5 swaps those readers
to read from `ThemeStore` directly; the legacy keys stay frozen per
plan §2.5.
- Three new tests: preset → cardSurface lands in legacy
`sidebarTintHex`; applying a light theme doesn't clobber the dark
per-mode key; every shipped curated theme clears AA contrast for
`inkBody` on `cardSurface`.
Drift called out:
- The plan's M2 acceptance asks for "two existing chrome surfaces"
(sidebar + TabItemView accent). Only the sidebar is wired this
milestone; the accent is left for M5 (chrome migration) where it
belongs with the rest of the literal-replacement work — wiring it
through a bespoke UserDefaults bridge now would be throwaway code.
- The plan's M2 test ("ContentView::sidebarBackgroundForActiveTheme()
returns #1a1b26") references a function that doesn't exist today.
We test the observable bridge instead: `sidebarTintHex` equals the
expected hex after `applyTheme(.tokyoNight)`. Same intent, tested
against real behavior.
- Tokyo Night's `inkCaption` shipped at #737aa2 from the start (plan
defers the bump to M6 for R1). Doing it early so the walking
skeleton already meets AA on captions.
Build verified: `xcodebuild ... -scheme cmux` (BUILD SUCCEEDED) and
`xcodebuild ... -scheme cmux-unit ... build-for-testing` (TEST BUILD
SUCCEEDED) both pass.
Co-Authored-By: Claude Opus 4.7 (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.
Reopened replacement for #2, which GitHub auto-closed when its base branch (
theme/m1-foundation, the head of #1) was deleted on merge.Summary
Test plan
🤖 Generated with Claude Code