Custom themes: effortUltra (ultracode/effort status badge) ignores theme overrides — always renders built-in purple

Open 💬 1 comment Opened Jun 23, 2026 by stevedekorte

Summary

Custom themes (~/.claude/themes/<slug>.json referenced via "theme": "custom:<slug>") apply their overrides correctly everywhere in the UI except the effort / ultracode status badge in the bottom-right of the input box.

That badge always renders the built-in base palette color for effortUltra (for a dark-based theme, the hardcoded rgb(135,0,255) purple), regardless of any effortUltra value in the custom theme. No override value and no restart changes it.

Environment

  • Claude Code v2.1.186 (native install)
  • macOS (Darwin 25.3.0)
  • "theme": "custom:minimal", custom theme with "base": "dark"

Repro

  1. Create ~/.claude/themes/mine.json:

``json
{ "name": "Mine", "base": "dark", "overrides": { "effortUltra": "rgb(200,200,200)" } }
``

  1. Set "theme": "custom:mine" in ~/.claude/settings.json.
  2. Enable ultracode ("ultracode": true) so the effort badge is shown.
  3. Restart Claude Code and look at the bottom-right ultracode badge.

Expected: badge text is gray rgb(200,200,200).
Actual: badge text is the built-in purple rgb(135,0,255). The override is silently ignored, while every other override in the same file applies correctly (the rest of the UI is fully grayscale).

Root cause

Function names below are minified/build-specific to 2.1.186 — the logic is the point.

The badge is rendered (function Aml) by, in effect:

let t = G3(getConfig("theme","dark").value);   // t = resolved theme for "custom:minimal"
return Co("effortUltra", t)("ultracode");        // colorize the text "ultracode"
  • G3("custom:minimal") ends up returning the base name string "dark". The custom-theme registry (mEn) stores slug → base only (mEn.set(t.slug, t.base)), and sAi(slug) returns that base string — so the resolver yields "dark", not the merged theme.
  • Co("effortUltra", "dark") resolves the key via rz("dark")["effortUltra"], where rz() returns the raw built-in dark palette (effortUltra: "rgb(135,0,255)"). It never consults the theme's overrides.

By contrast, the rest of the UI resolves colors through the merged palette built by tAi(rz(base), theme.overrides) (e.g. the React useMemo around the theme provider), which is why all other overrides apply. The effort/ultracode badge path bypasses that merge.

Consequence for any custom: theme:

  • base: "dark" → badge stuck on rgb(135,0,255)
  • base: "dark-daltonized" → stuck on rgb(175,135,255)
  • 16/256-color terminals → stuck on ansi:magenta / ansi:magentaBright

In every case the user's effortUltra override is ignored.

Suggested fix

Resolve the badge color against the merged theme palette (base + overrides) — the same palette the rest of the UI uses — rather than rz(resolveTheme(...)). Equivalently, pass the resolved/merged theme object (not the base-name string) into the color lookup for the effort/ultracode badge in Aml.

Impact

Cosmetic, but it makes grayscale / monochrome and accessibility-oriented custom themes impossible to finish: the always-purple effort badge can't be neutralized by any theme setting.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗