ui: paint the whole frame from the brand palette, so a light terminal theme cannot bleed through - #93
Merged
Merged
Conversation
… theme cannot bleed through The palette was only half hardcoded. We paint our own near-black canvas, but most text reached ink with NO color prop (and often a bare dimColor), which leaves it on the TERMINAL default foreground: under a light theme that is near-black, on our near-black canvas. The transcript body is the worst of it, since styleFor leaves textColor off for the assistant, tool, thinking, system and notice kinds, which is most of a session. Three fixes: every Text now carries a brand hex, and secondary copy takes theme.muted instead of dimColor (\x1b[2m is dropped by a fair number of terminals once a 24-bit fg is set, the same reason the live pulse already swapped colors rather than dimming); the surfaces are quantized before they reach ink, because chalk sends any hex whose channels differ to the 256-color cube, whose darkest step is rgb(95,95,95), so all three warm brand surfaces collapsed onto one mid gray on a 256-color terminal; and markdown tables lose chalk.red heads and cli-table3 border: [gray], the last two colors that resolved through the user palette. Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The palette was only hardcoded halfway. The CLI paints its own near-black canvas (
theme.canvas), but most text reached ink with nocolorprop, often a baredimColor. Ink leaves an uncoloured<Text>on the terminal's default foreground — which under a light theme is near-black, on our near-black canvas. The transcript body is the worst of it:styleForlefttextColorundefined for theassistant,tool,tool_result,thinking,system,noticeandsummarykinds, i.e. most of a session. Reported by a user whose light-theme terminal madeagentunreadable.1. Every
<Text>carries a brand hex. Secondary copy takestheme.mutedinstead ofdimColor—\x1b[2mis dropped outright by a fair number of terminals once a 24-bit foreground is also set, which is the same reason the live pulse already swapped colours rather than dimming. A newspanColor()intranscriptRowsis the one choke point where a transcript span becomes a colour: pulse off-beat,dim, and no-colour-at-all all resolve to real hexes there, soRowLineloses its threedimColorprops andstyleForis untouched. Both composers' parent<Text>now sets a colour, so typed text isn't left on the terminal default and the inverse caret has a known pair to swap.2.
theme.tsquantizes the surfaces before ink sees them. chalk resolves a hex whose channels differ to the 256-colour cube, whose darkest step above black isrgb(95,95,95); it only reaches the 24-rung greyscale ramp whenr == g == b. The brand surfaces are warm greys, so on a terminal that does 256 colours but not truecolor (Terminal.app, tmux without RGB, mosh) all three collapsed onto cube index 59 at once: the canvas painted mid grey and every surface step — with it every "you are here" highlight — disappeared.surfaceFor()averages the channels below truecolor, putting each surface on its own rung (234/235/236). Truecolor is untouched; 16-colour terminals render both spellings as palette black.3. Markdown tables lose
chalk.redheads and cli-table3'sborder: ['gray']— the last two colours resolving through the user's own palette (cli-table3 can only colour borders by chalk name). Heads are bone + bold; the rules are painted muted after the table is drawn.npm run typecheckclean, 402/402 tests,npm run buildclean. Newtest/theme.test.tspins the surface-collapse regression; the markdown colour tests were confirmed to fail before the fix.Note: the reporter described the screen as "all red", and I could not reproduce a literally all-red frame — the only literal reds in the CLI were the markdown table headers (
chalk.red, fixed here) and error text. What is fully explained and fixed is the "super difficult to read": near-black text on our near-black canvas, plus the mid-grey surface collapse on 256-colour terminals. A screenshot would confirm nothing is left.Origin: written and verified as a handoff in ellipsis-dev/ellipsis#6048 (§7 there explains why it shipped as a patch — sandbox tokens could not reach this repo at the time). Applied here with
git amonto9d479f1, then re-verified: typecheck clean, 402/402, build clean, and the collapse reproduced (59,59,59authored →234,235,236quantized) before and after.🤖 Generated with Claude Code