feat: custom theme system with 18 built-in themes#294
Merged
backnotprop merged 6 commits intomainfrom Mar 15, 2026
Merged
Conversation
Consolidate CSS theming into a single source of truth (packages/ui/theme.css) and introduce a multi-theme architecture where each theme defines both dark and light mode variants. Users can pick a color palette (theme) and separately toggle dark/light mode within it. - Extract shared color tokens, Tailwind bridge, and base styles into packages/ui/theme.css - Replace hardcoded oklch values with token references (oklch from var syntax) - Fix 3 light-mode bugs in review-editor diff colors - Create 15 built-in themes: Plannotator (default), Claude+, Soft Pop, Adwaita, Caffeine, Cyberdyne, Cyberfunk, Doom 64, Dracula, Gruvbox, PaulMillr, Quantum Rose, Solar Dusk, Terminal, Tinacious - Expand ThemeProvider to manage colorTheme + mode independently - Add Theme tab to Settings with mode toggle, search, and swatch grid - Dark-only themes (Dracula, Terminal, etc.) suppress light class to prevent broken styling; light-only themes (Tinacious) force it - Cookie persistence: plannotator-color-theme for palette, existing key for mode - Include theme conversion script for FinSitter theme adaptation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…4/Tokyo Night Theme curation: - Replace Cyberdyne with Synthwave '84 (from robb0wen/synthwave-vscode) - Replace Cyberfunk with Catppuccin (Mocha dark + Latte light), Rosé Pine (dark + Dawn light), Monokai Pro (dark only), Tokyo Night (Storm + Day) - Rewrite Gruvbox from canonical source (morhetz/gruvbox) - Rewrite Adwaita from canonical VS Code theme (piousdeer/vscode-adwaita) - Rewrite PaulMillr from Ghostty canonical palette Theme fixes: - Fix faded Send Feedback button on Solar Dusk, Quantum Rose, Caffeine (accent colors were too dark/invisible at 15% opacity) - Fix Dracula/Terminal/PaulMillr/Tinacious light mode breakage — dark-only themes now suppress .light class via modeSupport in ThemeProvider - Fix code block backgrounds — use --code-bg token instead of --muted - Add faint green grid overlay for Terminal theme - Alphabetize theme registry (Plannotator first) Code review diff theming: - Pass theme colors into @pierre/diffs shadow DOM via unsafeCSS prop - Dynamic themeType based on resolved mode 18 built-in themes: Plannotator, Absolutely, Adwaita, Caffeine, Catppuccin, Doom 64, Dracula, Gruvbox, Monokai Pro, PaulMillr, Quantum Rose, Rosé Pine, Soft Pop, Solar Dusk, Synthwave '84, Terminal, Tinacious, Tokyo Night Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove 340px cap on theme grid, bump content area from 70vh to 85vh so all themes are visible without scrolling. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… up DiffViewer From /simplify review: - Export Mode type from ThemeProvider, import in ThemeTab (was duplicated) - Add resolvedMode to context — consumers no longer re-query matchMedia - Memoize context value with useMemo, setters with useCallback (prevents unnecessary re-renders of all useTheme consumers) - Consolidate DiffViewer's two pierre state vars into single object - Use resolvedMode from context in DiffViewer instead of classList check - Format crammed single-line extended tokens in 4 theme CSS files Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…e class
P1: Marketing site inline script now sets theme-{name} class on <html>
before first paint (reads plannotator-color-theme cookie). Without this,
CSS tokens under .theme-* selectors were never active.
P2: System mode effect now re-reads matchMedia.matches immediately when
entering system mode, not just on future changes. Fixes stale resolvedMode
when OS preference changed while pinned to explicit dark/light.
P3: ThemeProvider applies theme class synchronously during render (not in
a passive useEffect) to prevent flash of unstyled content on hard refresh.
Also extracted resolveThemeClasses to module scope to avoid useCallback.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add Quick Copy button to annotation panel footer (splits horizontally with existing Quick Share). Copies annotations wrapped with the deny preamble so output is paste-ready for agent sessions. - Export Modal annotations copy also wraps with deny preamble - Extract wrapFeedbackForAgent() utility in parser.ts as single source of truth for the preamble text - Fix desktop import icon to match mobile (arrow-into-document, not download) - Comment out code review agent badge — unreliable across multiple harnesses Co-Authored-By: Claude Opus 4.6 (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.
Summary
packages/ui/theme.css) — color tokens defined once, imported by all three apps (editor, review-editor, marketing)oklch(from var(--token) l c h / alpha)).theme-{name}/.theme-{name}.lightCSS classescolorTheme+modeindependently — users pick a palette, then toggle mode within it.lightclass; light-only themes (Tinacious) force itunsafeCSSfor code review diff themingplannotator-color-themefor palette, existingplannotator-themefor mode18 built-in themes: Plannotator, Absolutely, Adwaita, Caffeine, Catppuccin, Doom 64, Dracula, Gruvbox, Monokai Pro, PaulMillr, Quantum Rose, Rosé Pine, Soft Pop, Solar Dusk, Synthwave '84, Terminal, Tinacious, Tokyo Night
Canonical sources: Gruvbox (morhetz/gruvbox), Adwaita (piousdeer/vscode-adwaita), Synthwave '84 (robb0wen/synthwave-vscode), Catppuccin/Rosé Pine/Monokai Pro/PaulMillr/Tokyo Night (Ghostty themes)
Test plan
🤖 Generated with Claude Code