fix(claude): theme new Claude Design System components#2285
Conversation
|
Thanks for your contribution! Was this pull request made with the assistance of LLM tools? That needs to be disclosed as per our pull request template: https://github.com/catppuccin/userstyles/blob/main/.github/PULL_REQUEST_TEMPLATE/userstyle-update.md. |
|
Yes, it was, sorry -- I tried to get Claude to draft a PR description for me and it just created the PR unbidden instead. I had it help me pick apart the CSS changes using Claude in Chrome, and it was trivial to write the patch by just treating the existing user styles as a mapping from old colors to new ones and applying that to the classes that weren't yet covered. |
Claude.ai now renders dropdowns, tooltips, dialogs, popovers, banners, and all of Claude Code (file viewer, diff viewer, buttons, HUD, sidebar) through internal component systems with their own CSS custom properties, entirely separate from the --bg-*/--text-*/--accent-* variables this userstyle already themes: - "Claude Design System" (.cds-root) -- used across claude.ai and Claude Code for overlays. Maps its surface/text/border/fill/on-color/ git-status/chart tokens onto the palette. - "Epitaxy" (.epitaxy-root) -- the broader design system wrapping all of Claude Code. Overrides the --z0..--z6 surface ramp and --t0..--t9 text-opacity ladder that nearly everything else derives from, plus a few dark-mode-only literals that bypass that ramp (prompt/compose box, destructive-action red, brand accent). - .dframe-root/.dframe-sidebar -- re-declares surface tokens a second time closer to the sidebar itself, shadowing the .epitaxy-root-level override; fixed at the point of shadowing. Also fixes @-moz-document to match a.claude.ai, since Claude Code renders its entire UI inside a cross-origin iframe on that subdomain that the existing claude.ai-only rule never reached. Closes catppuccin#2261.
0ab3dae to
843fc15
Compare
I don't think this is true. |
|
@scarcekoi would you be able to confirm that this fixes all of your issues in #2171? |
|
It looks like the graphs and charts remain unthemed: |
|
I don't really use the charts. Can you tell me how to bring one up? I was being optimistic based on the CSS variable names. 😅 |
|
I'm pretty sure they're technically on another website, but when I tried to theme them, I just could not get it to work: 884083d |

🔧 What does this fix? 🔧
Claude.ai now renders dropdowns, tooltips, dialogs, popovers, banners, and all of Claude Code (file viewer, diff viewer, buttons, HUD, sidebar) through internal component systems that define their own independent CSS custom properties — entirely separate from the
--bg-*/--text-*/--accent-*variables this userstyle already themes. This PR covers four separate but related root causes:1. Claude Code isn't matched at all.
claude.ai/coderenders its entire UI inside a cross-origin iframe served froma.claude.ai/isolated-segment.html. The@-moz-documentrule only namedclaude.ai, so userstyle managers may never inject into that frame — this is why some users saw Claude Code completely unstyled, not just missing the newer component systems below. Fixed by addingdomain("a.claude.ai")to the rule.2. "Claude Design System" (
.cds-root) — used for dropdowns, tooltips, dialogs/modals, popovers, and banners across claude.ai and Claude Code. Its tokens weren't touched by the existing overrides, so the account menu, model picker, Settings modal (all tabs), tooltips, and notification/limit banners rendered with Claude's raw default colors instead of Catppuccin. Covers:--cds-surface-0..3,-panel,-popover)primary/secondary/muted/disabled/accent/danger/success/warning/pro/git-status)--cds-on-*)--cds-clay), recolored to match the accent for consistency with the existing logo-color override3. "Epitaxy" (
.epitaxy-root) — a broader internal design system wrapping the entirety of Claude Code. Nearly everything (panels, popovers, HUD, sliders, switches, tooltips, button depth colors, the diff viewer, menus) derives from a--z0..--z6surface ramp and a--t0..--t9text-opacity ladder viavar(), so overriding those primitives directly (rather than each individual leaf token) fixes the whole dependency graph at once. Also explicitly overrides a handful of dark-mode-only literals that bypass that ramp entirely:--surface-primary-elevated,--surface-prompt-blur,--surface-prompt-focus-hover(the chat compose box)--core-red/--core-red-hover(destructive-action red, was Claude's own red regardless of theme)--accent-brand(used both ashsl(from ...)/relative-color syntax and directly via an inlinefill: var(--accent-brand)style on the sparkle/logo glyph — needs a real color, not an H S% L% triple)4.
.dframe-root/.dframe-sidebar— a further-nested scope (used by Claude Code's sidebar and card components) that re-declares--df-sidebar-bg/--df-surface-primarya second time, directly on.dframe-sidebaritself, shadowing whatever.dframe-rootsays. Fixed by overriding at the actual point of shadowing rather than the ancestor.Closes #2171.
Closes #2261.
Verification
lib.lessfor all 4 flavors, light and dark, and against a local checkout of the actual site's CSS bundles (c6a992d55-CxTHAcqo.cssfor CDS,c1f7a9f2d-2jd2YVVi.cssfor Epitaxy/dframe) to build the token maps from ground truth rather than guessing from sampled runtime values.deno task lint— passes clean.a.claude.aiframe is genuinely cross-origin (confirmed via a blockedcontentDocumentaccess), explaining why some users saw zero theming there before the domain fix.fill: var(--accent-brand)) renders in the accent color instead of falling back to black from an invalid triple value.🗒 Checklist 🗒