feat(web): light theme — three-way picker, paper tokens, AA xterm palette - #89
feat(web): light theme — three-way picker, paper tokens, AA xterm palette#89dchaudhari7177 wants to merge 1 commit into
Conversation
684a149 to
cd3b01c
Compare
Three-way theme choice in Settings (Dark / True black / Light), replacing the OLED checkbox: - theme.ts: ThemeName gains "light"; stored-value validation keeps unknown values falling back to dark; applyTheme sets data-theme for any non-default theme. - tokens.css: a [data-theme=light] block — paper surfaces, ink text, darkened hairlines; the coral accent shifts to its deep value for contrast on paper; warn/err darkened for AA. The code card stays a dark panel deliberately. - TerminalView: light mode swaps the FULL xterm palette (One Light-derived), not just the background — the dark ANSI ramp would be unreadable on paper. Live switch keeps working via rc-theme-change. - theme.test.ts extended for the new value, fallback, and meta mirror. Closes burakgon#67
cd3b01c to
b58372c
Compare
|
Thanks for putting this together. I pulled the PR branch locally and tested it through the real I did find one gap in the terminal contrast guarantee. I implemented the fix as a small extension to the Ghostty canvas renderer rather than attempting to rewrite all 256 palette entries, since that still would not cover truecolor output. The renderer now accepts an optional minimum contrast value and evaluates the final foreground against the actual cell background after inverse and selection handling. It also accounts for faint alpha, understands both the runtime's The focused follow-up is here: dchaudhari7177#1 I verified the result with all 87 affected tests, the workspace typecheck, scoped ESLint, |
Closes #67
Adds the light theme along the exact seams the issue points at:
pwa/theme.ts—ThemeNameis now"dark" | "oled" | "light", withTERMINAL_BGandTHEME_COLORentries for light (#f6f6f7).loadThemekeeps the stored-value validation pattern: anything other than"oled"/"light"falls back todark.applyThemesetsdata-theme="light"; dark still removes the attribute so the:rootdefault stays the single source of truth.styles/tokens.css— a[data-theme="light"]block flips ink → paper:--bg #f6f6f7, white cards, black-wash hairlines, text at 15.9:1 / 6.2:1 / 4.7:1. Coral handling follows the issue's AA note: coral fills (primary buttons, brand glyph) keep brand coral — dark ink on coral reads ~7:1 — while coral used as text/status (--accent,--iris,--awaiting) darkens to#c2481d(4.6:1 on paper).color-scheme: lightflips native form controls/scrollbars. Every ratio below was computed against#f6f6f7.settings/SettingsPanel.tsx— the OLED checkbox becomes a three-way Theme select (Dark / True black (OLED) / Light), using the existingrc-settings__field+rc-settings__controlidiom from Session order. Still applies instantly throughsetTheme(no save button, no reload).chat/TerminalView.tsx— a fullLIGHT_THEMExterm palette (same shape asTHEME): ink-on-paper foreground#383a42(10.5:1), selection#c9d0da, and ANSI hues darkened so ordinary terminal text meets WCAG AA — red 5.0, green 4.6, yellow 4.9, blue 5.0, magenta 5.7, cyan 5.5, white-gray 4.7.terminalTheme()resolves the palette at mount and in therc-theme-changelistener, so an open terminal restyles live without a remount. The.xterm-viewportseam already followsvar(--bg).Tests —
theme.test.tsextended per acceptance criteria: light round-trip +data-theme, unknown stored value ("solarized") falls back to dark, theme-color meta mirrors#f6f6f7,TERMINAL_BGcovers all three themes.Verification
pnpm typecheckclean; theme + storage-migration tests pass (10/10).packages/websuite: the only failures are the known flaky-under-load Windows ones (App/TerminalView/SessionList timeouts +keeps compact stacked remaining-limit rows), reproduced identically on a cleanmaincheckout on this machine.screenshot.html?scene=newsessionharness withdata-theme="light": body paints paperrgb(246,246,247), ink textrgb(27,27,31), picker surfaces flip to translucent white.Left the stretch "system" (
prefers-color-scheme) option out per the issue — happy to follow up with it as a separate PR.