Summary
Implement a comprehensive theme management system in OpenWork, adapted from OpenCode's proven architecture. This will enable users to choose from 15+ pre-built themes (Dracula, Nord, Gruvbox, Catppuccin, etc.) and import custom themes via JSON files.
Why
- User demand: Users want more than just light/dark mode - they want personalized themes
- OpenCode parity: OpenCode already has 37 production-ready themes we can adapt
- Slick UI: Aligns with "premium feel" requirement from VISION.md
- Non-breaking: Fully backward compatible with existing Radix color system
- Helps Susan: Non-technical users can easily customize appearance without coding
Current State
OpenWork currently only supports light/dark/system mode switching via apps/app/src/app/theme.ts. No theme registry, no custom themes, no theme schema.
Proposed Solution
Adapt OpenCode's theme system (packages/ui/src/theme/desktop-theme.schema.json) for OpenWork:
Features
- ✅ 15 pre-built themes at launch (Dracula, Nord, Gruvbox, Catppuccin, Tokyo Night, etc.)
- ✅ Theme picker UI in Settings > Appearance
- ✅ Custom theme import via JSON file drag & drop
- ✅ Hot reload for theme changes
- ✅ Workspace-specific themes via
.openwork/theme.json
- ✅ Full backward compatibility (Radix colors as fallback)
Schema (matches OpenCode)
{
"$schema": "https://openwork.ai/theme.json",
"name": "Dracula",
"id": "dracula",
"light": {
"palette": {
"neutral": "#ffffff",
"ink": "#1a1a1a",
"primary": "#3b7dd8",
"success": "#3d9a57",
"warning": "#d68c27",
"error": "#d1383d",
"info": "#318795"
},
"overrides": { ... }
},
"dark": { ... }
}
Scope
Included
- Theme types and JSON schema (
packages/types/src/theme.ts)
- Theme registry and loader (
apps/app/src/app/theme-registry.ts)
- 15 default themes ported from OpenCode
- Enhanced theme application engine (
apps/app/src/app/theme.ts)
- Theme variable CSS layer (
apps/app/src/styles/theme-variables.css)
- Theme context provider (SolidJS)
- Theme picker UI in Settings > Appearance
- Theme preview cards
- Theme import dialog
- Tauri commands for theme file I/O
- File watcher for hot reload
- Unit tests and accessibility tests
Out of Scope (Future)
- Theme editor UI
- Theme marketplace/sharing
- Syntax highlighting theme support (can be added later)
- Theme inheritance/extension system
Testing Plan
Automated
- Unit tests for theme validator
- Accessibility tests (WCAG 2.1 AA contrast ratios via axe-core)
- Visual regression tests (Playwright screenshots)
Manual
- Navigate to Settings > Appearance
- Verify 15 themes display in grid
- Click each theme - verify it applies correctly
- Switch between light/dark/system modes
- Import custom theme JSON via drag & drop
- Verify hot reload by editing custom theme file
- Test workspace-specific theme in
.openwork/theme.json
Evidence
Will provide:
- Screenshots of theme picker UI
- Video of theme switching flow
- Accessibility test results
Implementation Plan
See THEME_IMPLEMENTATION_PLAN.md in repo root for complete details.
Timeline
- Phase 1: Schema & Types (2 days)
- Phase 2: Registry & Storage (2 days)
- Phase 3: Application Engine (3 days)
- Phase 4: UI Components (3 days)
- Phase 5: Tauri Integration (2 days)
- Phase 6: Persistence (2 days)
- Phase 7: Testing (3 days)
- Total: ~17 days
Alignment with Principles
✅ Parity: Uses OpenCode's exact theme schema
✅ Server-consumption first: Theme files are JSON, consumed by app
✅ Transparency: Theme settings visible in UI
✅ Least privilege: Themes only affect appearance, no file access
✅ Graceful degradation: Falls back to Radix colors if theme fails
✅ Progressive disclosure: Simple theme picker, advanced import hidden
Decision Framework Answers
- Is it easy to test? Yes - Chrome MCP + pnpm:dev for UI testing with screenshots
- Is there an existing opencode equivalent? Yes - complete theme system with 37 themes
- How does it improve UX? Susan can personalize workspace without coding
Risk
- Low risk: Purely visual feature, no data mutation
- Rollback: Simple - revert PR, no migration needed
- Performance: Themes cached, switch time < 100ms
Branch Name
feat(app): theme-management-system
Labels
Summary
Implement a comprehensive theme management system in OpenWork, adapted from OpenCode's proven architecture. This will enable users to choose from 15+ pre-built themes (Dracula, Nord, Gruvbox, Catppuccin, etc.) and import custom themes via JSON files.
Why
Current State
OpenWork currently only supports light/dark/system mode switching via
apps/app/src/app/theme.ts. No theme registry, no custom themes, no theme schema.Proposed Solution
Adapt OpenCode's theme system (
packages/ui/src/theme/desktop-theme.schema.json) for OpenWork:Features
.openwork/theme.jsonSchema (matches OpenCode)
{ "$schema": "https://openwork.ai/theme.json", "name": "Dracula", "id": "dracula", "light": { "palette": { "neutral": "#ffffff", "ink": "#1a1a1a", "primary": "#3b7dd8", "success": "#3d9a57", "warning": "#d68c27", "error": "#d1383d", "info": "#318795" }, "overrides": { ... } }, "dark": { ... } }Scope
Included
packages/types/src/theme.ts)apps/app/src/app/theme-registry.ts)apps/app/src/app/theme.ts)apps/app/src/styles/theme-variables.css)Out of Scope (Future)
Testing Plan
Automated
Manual
.openwork/theme.jsonEvidence
Will provide:
Implementation Plan
See
THEME_IMPLEMENTATION_PLAN.mdin repo root for complete details.Timeline
Alignment with Principles
✅ Parity: Uses OpenCode's exact theme schema
✅ Server-consumption first: Theme files are JSON, consumed by app
✅ Transparency: Theme settings visible in UI
✅ Least privilege: Themes only affect appearance, no file access
✅ Graceful degradation: Falls back to Radix colors if theme fails
✅ Progressive disclosure: Simple theme picker, advanced import hidden
Decision Framework Answers
Risk
Branch Name
feat(app): theme-management-systemLabels
enhancementuisettings