* draft(tui): add theme interface and Claude/Codex presets proposal Introduces the Theme interface alongside the initial specifications and styling models for the Claude (card-based, warm) and Codex (high-density, split-screen cyberpunk) layout presets. Detailed design plans are documented in docs/THEMES.md. * fix(tui): implement Claude/Codex themes on the existing palette system theme.go had replaced the tuiTheme/buildTheme/palette architecture every renderer depends on with a standalone Theme interface using the wrong lipgloss import, breaking the build and orphaning the existing theme registry, /theme command, and picker. Revert theme.go to the working implementation and add claude and codex as real palette entries in theme_palettes.go, following the file's own extension pattern. Both pass the WCAG AA contrast and gray-ramp invariants asserted across the whole registry, and are picked up automatically by --theme, ZERO_THEME, /theme, and the picker. Rewrite docs/THEMES.md to describe the actual palette-registry architecture instead of the removed interface. * fix(tui): rename Claude/Codex to neutral Dune/Neon, ensure WCAG AA contrast compliance, and add tests * style(tui): gofmt theme_select_test.go (drop trailing whitespace) The ubuntu smoke run fails on gofmt -l; this clears the only unformatted file in the draft so CI goes green. * test(tui): cover the CLI/env resolution path for the dune and neon presets TestNewThemePresetsWired only checked lookupTheme and the IsDark grouping. Add coverage for the actual --theme/ZERO_THEME precedence path (resolveThemeMode) and confirm applyTheme swaps zeroTheme to each preset's own palette rather than a built-in fallback. * fix(tui): raise Dune/Neon palette contrast and fix theme docs Darken dune's accent, blue, and red tokens so the selected-row caret, local-model dot, and diff deletion text clear WCAG AA against selBg and delBg, including after ANSI-256 downsampling. Also correct THEMES.md's description of bare /theme (it opens a live-preview picker, not a list), and add the dune/neon names to the ZERO_THEME/--theme tables in README.md and README_ZH.md. * fix(tui): keep Dune and Neon readable after ANSI-256 downsampling - Dune's accent becomes #724028: still AA on selBg and panel in truecolor (5.46:1 and 7.03:1), and its xterm-256 quantization (#444444) now clears AA on quantized selBg at 6.47:1 where the previous #7c4712 quantized to #875f00 at 3.81:1. Blue already survived quantization at 4.67:1. - Neon's diff bands move to hexes that quantize to distinct green and red xterm entries (addBg #083c10 -> #005f00, delBg #3c0810 -> #5f0000, addBgWord #147828 -> #008700, delBgWord #74202e -> #870000) instead of collapsing to the same grays, while keeping every truecolor invariant. - New TestExtendedThemeANSI256Contrast quantizes the palette tokens the way a 256-color terminal does and asserts the Dune selected-row pairs stay AA and the Neon bands keep their green/red identity and mutual separation. - docs/THEMES.md is now linked from the Documentation sections of both READMEs, and the Unreleased changelog inventory says twelve themes and names dune and neon. * fix(tui): keep Neon diff content AA after quantization, fix error border - faintest becomes #74c468: line numbers now quantize to #87d75f, which clears AA on the xterm-green addBg (#005f00) where the old #58af69 quantized to 2.95:1, while staying dimmer than faint so the gray ramp stays monotonic. - addInk becomes #ecffdc, quantizing to #ffffd7 for 4.60:1 on the word band's #008700 (was 4.29:1). Both rendered diff-content pairs are now asserted in the ANSI-256 test instead of documented as omissions. - cardErr becomes #9a4042: 3.01:1 against the panel (2.43:1 before) and 3.65:1 quantized, meeting the 3:1 non-text component threshold, with the border surface asserted in both renderings. - docs/THEMES.md no longer claims the extended invariants run against the whole registry: it now says new palettes must be added to the per-palette contrast tests or given equivalent coverage.
1.8 KiB
TUI Themes
Zero's TUI ships a set of built-in color themes. Pick one with --theme <name>,
the ZERO_THEME environment variable, or the /theme <name> command while
running. auto (the default) follows the terminal's detected background.
Run /theme with no argument to open a picker: move through the list to
live-preview each theme, press Enter to apply the highlighted one, or Esc to
cancel and restore the previously active theme. Run /theme list to print
the active theme and the registered names without opening the picker.
Dune (dune)
A warm sand-and-cream palette: sand/cream surface, charcoal ink, and a soft amber accent.
Neon (neon)
A neon-on-black palette: pitch-black surface, bright green ink, and a cyan accent.
Adding a theme
Every theme is a palette (a table of color hex tokens) plus one entry in
themeRegistry, both in internal/tui/theme_palettes.go. buildTheme in
internal/tui/theme.go turns a palette into the resolved lipgloss.Style
set every renderer reads from the active zeroTheme. Adding a theme means
adding a new palette{...} literal, a themeRegistry entry, and test
coverage for the new palette (see below).
Registry-wide tests in internal/tui/theme_select_test.go assert the basic
WCAG AA text tokens, the gray-ramp order, the diff word-span pairs, and the
selected-row band for every entry. The rendered-surface invariants beyond
those (permission surfaces, selected-row secondary text, diff gutters, and
the xterm-256 downsampling checks) are asserted per palette, not against the
whole registry: TestExtendedThemeContrastInvariants and
TestExtendedThemeANSI256Contrast enumerate the palettes they cover. A new
theme must be added to those tests (or given equivalent palette-specific
assertions), or CI can stay green while its permission, selected-row, and
diff surfaces ship unreadable.