Skip to content

feat(web): add modular theme library - #5226

Open
StiensWout wants to merge 26 commits into
pingdotgg:mainfrom
StiensWout:t3code/modular-theme-system
Open

feat(web): add modular theme library#5226
StiensWout wants to merge 26 commits into
pingdotgg:mainfrom
StiensWout:t3code/modular-theme-system

Conversation

@StiensWout

@StiensWout StiensWout commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Summary

T3 Code now has a token-based theme foundation that can grow from maintainer themes into user-created themes across the web client and desktop app.

  • Adds Default, T3 Chat, and T3 Grove maintainer themes, with light and dark variants where supported and a global Follow system preference.
  • Adds a theme library for selecting, creating, editing, renaming, deleting, importing, and exporting personal themes.
  • Supports guided theme editing for common roles and an advanced editor with a color picker and JSON upload/paste.
  • Applies semantic theme tokens across app surfaces and actions, including the composer send button, placeholders, secondary labels, muted icons, terminals, diffs, file previews, errors, warnings, updates, and splash screens.
  • Keeps theme choices after reloads and preserves the original artwork banner.

Closes #418

Screenshots

The library views show the maintainer themes alongside personal-theme cards.

View Default T3 Chat T3 Grove (Light) T3 Grove (Dark)
Workspace home Default theme workspace T3 Chat theme workspace T3 Grove light theme workspace T3 Grove dark theme workspace
Theme library Default theme library T3 Chat theme library T3 Grove light theme library T3 Grove dark theme library
Theme editor Default guided theme editor T3 Chat guided theme editor T3 Grove light guided theme editor T3 Grove dark guided theme editor
Advanced color picker Default advanced color picker T3 Chat advanced color picker T3 Grove light advanced color picker T3 Grove dark advanced color picker
JSON import and paste Default JSON import and paste T3 Chat JSON import and paste T3 Grove light JSON import and paste T3 Grove dark JSON import and paste
Delete confirmation Default themed delete confirmation T3 Chat themed delete confirmation T3 Grove light themed delete confirmation T3 Grove dark themed delete confirmation

Verification

  • Checked the theme library, guided editor, advanced color picker, JSON import/paste, and delete confirmation in light and dark mode.
  • Confirmed Follow system keeps the mode choice global, leaves mode previews visible, and selects cards rather than individual circles.
  • Confirmed light/dark selection does not change card dimensions or shift the grid.
  • Passed web typecheck, lint, formatting, and production build.

Note

Add modular theme library with custom themes, follow-system support, and semantic design tokens

  • Introduces themePalette.ts with a full theme system: built-in themes (T3 Chat, T3 Grove), custom theme parsing/serialization, variant support, and contrast validation.
  • Rewrites the boot script in index.html to resolve and apply themes before first paint, setting data-theme-id/data-theme-selected on the root element, CSS boot variables, and meta[name="theme-color"].
  • Adds a ThemeLibrary UI in the Appearance settings panel (replacing a simple dropdown), backed by a new ThemeSettings.tsx module with theme card and editor helpers.
  • Extends useTheme.ts with explicit followSystem state, setFollowSystem/refreshTheme API, palette application via applyThemePalette, snapshot caching, and cross-tab storage sync for custom themes.
  • Adds semantic CSS tokens in index.css (--message-*, --code-*, --terminal-*, --error-*, --warning-*, --update-*, --placeholder, --secondary-label, --icon-muted) and migrates all components from opacity-modulated muted-foreground classes to these named tokens.
  • Terminal in ThreadTerminalDrawer.tsx now reads theme CSS variables for background, foreground, cursor, and selection.
  • Risk: Boot script changes affect every page load; theme resolution now depends on localStorage structure — malformed or missing keys fall back to OS preference.

Macroscope summarized f52a34c.


Note

Medium Risk
Large cross-app UI refactor plus synchronous boot-time localStorage parsing; behavior changes on theme storage failure and many visual surfaces, but no auth or data-handling logic.

Overview
Adds a token-based theming system with maintainer themes (Default, T3 Chat, T3 Grove), personal themes in localStorage, and a Follow system preference separate from the stored theme id.

Appearance settings swaps the light/dark/system dropdown for a theme library (select, create, edit, import/export JSON, delete) with guided (canvas + accent) and advanced color editors.

Boot script in index.html now mirrors runtime theme resolution—custom themes, t3-chat / t3-grove, legacy t3-chat-dark, follow-system, splash --boot-* variables, and OS fallback on storage errors (replacing the previous always-dark catch).

useTheme applies palettes via applyThemePalette, syncs t3code:theme-follow-system, listens for custom-theme storage changes, and exposes setFollowSystem / refreshTheme; setTheme returns success/failure.

Across the UI, hard-coded opacity grays and ad-hoc blues/ambers are replaced with semantic classes (text-secondary-label, text-icon-muted, text-placeholder, bg-message, bg-message-action, text-error, text-warning, text-update, --code-background, --terminal-*). Composer send actions use message-action tokens instead of primary/stage-backdrop artwork on the send button.

Diff panels, file previews, and the terminal drawer read code/terminal CSS variables so themed palettes affect those surfaces.

Reviewed by Cursor Bugbot for commit f52a34c. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 11741116-aefd-400a-9950-8e0830c1ffb6

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Aug 2, 2026
Comment thread apps/web/src/components/settings/SettingsPanels.tsx Outdated
Comment thread apps/web/src/hooks/useTheme.ts
Comment thread apps/web/src/themePalette.ts Outdated
Comment thread apps/web/src/components/chat/MessagesTimeline.tsx Outdated
Comment thread apps/web/src/components/settings/SettingsPanels.tsx Outdated
Adds semantic theme roles, persisted light and dark variants, personal theme import and creation, contrast-safe surfaces, and themed message actions. Includes the T3 Chat palette, follow-system behavior, splash handling, and the theme library UI.
@StiensWout
StiensWout force-pushed the t3code/modular-theme-system branch from e0f79e4 to 607dd6b Compare August 2, 2026 11:52
Comment thread apps/web/src/hooks/useTheme.ts Outdated
Comment thread apps/web/src/hooks/useTheme.ts Outdated
Comment thread apps/web/src/components/settings/SettingsPanels.tsx Outdated
Comment thread apps/web/src/components/settings/SettingsPanels.tsx Outdated
Comment thread apps/web/src/themePalette.ts
Comment thread apps/web/src/themePalette.ts Outdated
Comment thread apps/web/src/index.css Outdated
@StiensWout
StiensWout marked this pull request as ready for review August 2, 2026 12:27
Comment thread apps/web/index.html
Comment thread apps/web/index.html Outdated
Comment thread apps/web/index.html
@macroscopeapp

macroscopeapp Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a complete modular theme library with new user-facing workflows for creating, editing, and importing custom themes. The 4100+ line addition includes new UI components, storage patterns, boot script changes, and a CSS variable architecture. New features of this scope warrant human review.

You can customize Macroscope's approvability policy. Learn more.

Comment thread apps/web/src/components/settings/SettingsPanels.tsx Outdated
Comment thread apps/web/src/components/settings/SettingsPanels.tsx Outdated
Comment thread apps/web/src/components/settings/SettingsPanels.tsx Outdated
Comment thread apps/web/src/components/settings/SettingsPanels.tsx Outdated
Comment thread apps/web/src/components/settings/SettingsPanels.tsx Outdated
Comment thread apps/web/src/components/settings/SettingsPanels.tsx Outdated
Comment thread apps/web/src/components/settings/SettingsPanels.tsx Outdated
Comment thread apps/web/src/components/settings/SettingsPanels.tsx Outdated
Comment thread apps/web/src/components/settings/SettingsPanels.tsx Outdated
Comment thread apps/web/src/themePalette.ts
Comment thread apps/web/src/themePalette.ts
Comment thread apps/web/src/components/settings/SettingsPanels.tsx Outdated
Comment thread apps/web/src/components/settings/SettingsPanels.tsx Outdated
Comment thread apps/web/index.html Outdated
Comment thread apps/web/index.html
StiensWout and others added 5 commits August 3, 2026 09:34
Full review pass over the modular theme system:

- Rewrite the index.html boot script to mirror runtime resolution exactly:
  clamp built-in themes to their available modes (T3 Chat is light-only),
  treat unrecognized preferences as the system default, follow the OS in
  the storage-failure fallback, and honor corrupted follow-system values
  the same way the runtime does. Add a boot/runtime parity test that
  evaluates the inline script against resolveThemeAppearance.
- Keep the color picker's hue when a grey/white/black echo round-trips,
  open hand-tuned themes in advanced mode so guided regeneration cannot
  silently discard their palettes, and regenerate every saved appearance
  when toggling Advanced off.
- Cache the useTheme snapshot instead of reading localStorage on every
  consumer render, and share one storage/matchMedia listener pair.
- Restore hover and emphasis states lost in the token migration
  (message action hover, provider update pill, sidebar read/unread,
  plan-mode toggle) and fix message-foreground tokens used on
  background surfaces.
- Extract the theme library/editor into ThemeSettings.tsx, memoize the
  color rows, reuse the Alert component and shared isThemeColor, drop
  the dead StageBackdropButtonArt and themePreferenceForSystem, and make
  stored-theme parsing tolerant of unknown roles from other builds.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 3 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit a096aba. Configure here.

Comment thread apps/web/index.html
Comment thread apps/web/src/components/settings/ThemeSettings.tsx
Comment thread apps/web/src/components/settings/ThemeSettings.tsx
- The boot script no longer follows the OS for a `:system`-suffixed
  preference when follow-system is explicitly off, matching the runtime;
  covered by two new parity cases.
- setTheme/setFollowSystem report write success, so the follow-system
  toggle leaves the theme preference untouched when its write fails, and
  removing the active theme keeps it installed when the selection cannot
  be moved off it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comment thread apps/web/index.html Outdated
StiensWout and others added 3 commits August 3, 2026 11:18
The document ships light-media, dark-media, and plain theme-color metas;
the browser reads whichever matches the OS, so mutating only the first
element left themed chrome colors unapplied on a dark OS. Both the boot
script and syncBrowserChromeTheme now write the resolved color to every
matching meta.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Swap the light palette to t3.chat's actual tokens — #a84370 primary,
#db2777 ring, #501854 foreground, #faf5fa background, and its pink
surface family — for the deeper pink accents of the product. The boot
splash and managed-editor fallbacks follow, and a contrast guard test
keeps the key pairings readable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Themes and UI cusomization

1 participant