Skip to content

feat(theme): named theme system v1 (11 themes)#58

Closed
nakamoto-hiru wants to merge 24 commits intoOpen-ACP:developfrom
lngdao:hiru-themesystem
Closed

feat(theme): named theme system v1 (11 themes)#58
nakamoto-hiru wants to merge 24 commits intoOpen-ACP:developfrom
lngdao:hiru-themesystem

Conversation

@nakamoto-hiru
Copy link
Copy Markdown
Contributor

Summary

Replaces the 3-option theme picker (light / dark / system) with an OpenCode-style named theme system. Ships v1 with 11 curated themes; architecture scales to many more without code changes.

Architecture

Two HTML attributes drive styling:

  • data-theme="<id>" — selects the palette CSS block from src/openacp/styles/themes/<id>.css
  • data-mode="light" | "dark" — derived from the theme's mode; drives Tailwind dark: variant and shared avatar-token fallbacks

Each theme overrides ~55 tokens (Background + Foreground + Border + Semantic + Syntax + Markdown). Avatar tokens are shared per data-mode — agent/user colors stay consistent across theme changes. Shadows and shadcn aliases live in :root.

Themes shipped

Light Dark
Default Light Default Dark
Catppuccin Latte Catppuccin Mocha
GitHub Light GitHub Dark, AMOLED Dark, Tokyo Night
Gruvbox Dark, Nord Dark, One Dark

UX

Settings → Appearance now has a single grouped Select (Default / Dark / Light) replacing the Light/Dark/System Tabs. Legacy store values ("light" / "dark" / "system") migrate lazily + silently to valid ThemeIds; legacy theme-hint localStorage key migrates to theme-id in the pre-paint script.

Dev-mode safety net

verifyThemeRegistry() runs at startup in DEV builds — warns if a theme is missing its CSS block or if the pre-paint MODES lookup drifts from the registry.

Out of scope (documented as follow-up)

  • Terminal theming (terminal-renderer.tsx hardcoded colors)
  • Inline-style hardcoded hex in composer.tsx / review-panel.tsx
  • User-defined themes / accent override
  • Search/filter in dropdown (deferred until theme count > 20)

Files

  • New: src/openacp/lib/themes.ts (registry + helpers + migration, 15 unit tests), 11 per-theme CSS files under src/openacp/styles/themes/
  • Modified: settings-store.ts, theme.css, index.css, index.html, settings-appearance.tsx, app.tsx, ds-demo/app.tsx, docs/design/DESIGN.md

Test plan

  • Settings → Appearance: dropdown shows 3 groups (Default / Dark / Light) with correct themes in each
  • Switch through all 11 themes → no console errors, no layout shift, avatars render, code blocks highlight
  • Hard refresh (Cmd+R) on each theme → no flash-of-wrong-theme
  • Legacy migration: preload localStorage theme = "light" → reload → console shows [theme] migrated "light" → "default-light"
  • DS demo (/ds-demo.html): light/dark toggle still works via new data-theme + data-mode attrs
  • pnpm build clean, pnpm test → 31/31 pass

Branch commits tell a story: spec + plan docs → registry + foundation (Tasks 1–8) → 9 themes (Tasks 9–17) → polish + docs (Tasks 18–19) → review fixes (ds-demo regression + contrast tweaks for AMOLED/GitHub/Nord).

@nakamoto-hiru
Copy link
Copy Markdown
Contributor Author

Mistakenly opened against upstream; will re-open on the fork (lngdao/OpenACP-App).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant