Skip to content

Add Folio, Newsprint and Walnut editorial themes - #453

Closed
parsakhaz wants to merge 1 commit into
mainfrom
themes-editorial
Closed

Add Folio, Newsprint and Walnut editorial themes#453
parsakhaz wants to merge 1 commit into
mainfrom
themes-editorial

Conversation

@parsakhaz

Copy link
Copy Markdown
Member

Lane: light: simple-plan → prepare-pr

Direction: editorial / print & material — the calm lane of the five-PR theme batch. Three print-and-paper themes: Folio (cream paper & ink, light), Newsprint (cool grey stock, light), Walnut (vellum on walnut, dark). Low saturation, generous tonal steps, one accent used only for links, the active-tab rule, the primary button and the focus ring. Meant to be the calmest, most readable themes in the batch.

The themes

id name base vibe bg · surface · text · accent · terminal bg
folio Folio light Paper & ink — warm cream stock, near-black ink, one vermilion rubrication accent, faint rule lines #f6f0e4 · #fbf7ee · #1f1b17 · #b3321c · #fbf7ee
newsprint Newsprint light Cool grey-white stock, graphite type, halftone-grey surfaces, one dark ink-blue accent #f1f2f0 · #f8f8f6 · #24272b · #1f4e8c · #f8f8f6
walnut Walnut dark Deep warm brown-black, parchment type, brass accent (dark ink text on brass buttons) #1a1512 · #221c18 · #ede1cd · #c9a24d · #120e0b

Each screenshot is the same mocked session: sidebar, Review (diff) panel open, terminal dock replaying an ANSI sample so all 16 palette slots are visible.

Folio

folio

Newsprint

newsprint

Walnut

walnut

Appearance picker

The three carry a one-line description under the name (the other twelve don't yet — see "Two calls for you" below).
appearance picker

Regenerate: THEME_SCREENSHOT_DIR=screenshots/themes pnpm test -- tests/theme-screenshots.spec.ts (tests/theme-screenshots.spec.ts, Playwright + the mocked Electron API).

Before you cherry-pick

Two kinds of change in this PR. Only the first is per-theme; full file list under "What changed".

  • Theme-onlycolors.css, effects.css, index.css, monaco-overrides.css, the theme registrations, and the two picker lists. Every lane touches these files, so expect merge conflicts here across the five PRs.
  • Cross-cutting, unique to this lane — pick deliberately; each bullet says whether the themes depend on it:
    • isLightTheme replaces the hardcoded theme === 'light' || 'light-rounded' checks in the diff viewer, editor and logo. Needed by Folio and Newsprint (light-based) — without it, any new light-based theme (these two, or another lane's) gets a dark diff view and dark editor.
    • SelectItem gains an optional description — this is what puts the one-liners in the picker. Only needed if the picker descriptions stay (second call below).
    • LogsView now reads the theme's terminal palette instead of its own hardcoded one. Applies to every theme, not just these three — existing themes' logs change to their own terminal palettes too.
    • ThemeProvider stamps theme classes in useLayoutEffect, so the terminal and logs no longer see the previous theme's classes on a switch. Independent fix, not specific to the three themes.

Two calls for you:

  • Flat shell, on purpose. Folio/Newsprint/Walnut keep the edge-to-edge layout of the base light/dark themes rather than the islanded panel borders/radii Dusk/Forge/Terracotta use — a printed sheet is one surface with rule lines. Comments in effects.css / index.css record this so it isn't read as an omission.
  • Picker descriptions. Only these three have one (the brief asked for it). If the batch lands, either the other twelve get one or the descriptions come out, so the list reads evenly.

Contrast (measured, WCAG ratios)

text / bg muted / bg link / bg primary button label muted / bg, high-contrast on lowest ANSI / terminal bg
folio 15.1 6.2 6.5 6.2 (white on vermilion) 8.0 5.6
newsprint 14.6 5.9 7.4 7.4 (white on ink blue) 7.3 5.4
walnut 14.0 7.0 8.3 9.4 (ink on brass) 7.9 4.8

Targets: text ≥ 4.5, UI/ANSI ≥ 3, high-contrast muted ≥ 7 — every cell above clears its target. The ratios are enforced by a new vitest, not measured by hand (see "Tests").

What changed

Theme-only (the merge-conflict zone):

  • frontend/src/styles/tokens/colors.css — primitive ramps + full :root.folio / :root.newsprint / :root.walnut blocks covering the union of every variable light and terracotta override (118 in each block: backgrounds, surfaces, text, borders, interactive/focus, status, buttons, cards, forms, modal, navigation, scrollbar, tab indicator, terminal palette + selection), plus :root.high-contrast.<theme> blocks at the end so they win over the base light/dark high-contrast blocks.
  • effects.css (print-like radii, no drop shadows), index.css (underline tab indicator, Monaco editor vars), monaco-overrides.css kept in sync.
  • Registration: Theme union + THEME_CLASSES (themeContextValue.ts), both index.html bootstrap scripts, frontend/src/types/config.ts, main/src/types/config.ts (two unions).
  • Pickers: AppearanceSettings.tsx and HomePage.tsx entries.

Cross-cutting (the detail behind the bullets above):

  • THEME_CLASSES is now exported from themeContextValue.ts and is the single source for ThemeProvider's valid-theme set and class removal list; isLightTheme(theme) is derived from it.
  • DiffViewer, FileEditor (Monaco vs/vs-dark) and usePaneLogo hardcoded theme === 'light' || 'light-rounded'. They now use isLightTheme. Without this, any new light-based theme gets a dark diff view and dark editor.
  • LogsView had its own hardcoded GitHub/Tailwind 16-colour ANSI palette. It now reads the theme's --color-terminal-* tokens via getTerminalTheme(), so log colours match the terminal in every theme (existing themes' logs change to their own terminal palettes too).
  • ThemeProvider stamps theme classes in useLayoutEffect instead of useEffect. React runs child passive effects before the parent's, so TerminalPanel's useEffect(() => getTerminalTheme(), [theme]) — and the new LogsView read — saw the previous theme's classes (the same trap PR fix: restore contrast correction for themes and CLI output, add high-contrast mode #362 hit for high-contrast). Layout effects run before any passive effect and before paint.
  • SelectItem (ui/Select.tsx) gains an optional description rendered under the label, outside ItemText so the trigger still shows just the name. Items without a description render exactly as before.

Tests:

  • frontend/src/styles/themeContrast.test.ts (vitest, already in CI via pnpm --filter frontend test) parses colors.css, resolves each theme's cascade (same-specificity source order, alpha compositing, var() chains) and asserts: all 15 themes — muted text ≥ 4.5 on --color-bg-primary, ≥ 7 with .high-contrast; the three new themes — text on 16 surfaces, links/status/focus/accent, button label vs bg in every state, all 16 ANSI colours vs terminal bg, and a token-coverage check (no half-theme fallbacks). It also asserts colors.css block order matches THEME_CLASSES so the cascade model can't silently drift.
  • frontend/src/contexts/themeClasses.test.ts pins both index.html bootstrap copies to THEME_CLASSES (PR fix: restore contrast correction for themes and CLI output, add high-contrast mode #362 found that copy had drifted).
  • tests/theme-screenshots.spec.ts produces the four PNGs above.

Checks

  • pnpm typecheck ✓ · pnpm lint ✓ (exit 0) · pnpm --filter frontend test 214/214 ✓
  • Playwright: theme-screenshots, dropdown-keyboard-nav, settings, accessibility, sidebar-compact ✓. One pre-existing failure in settings.spec.ts ("discards remote subview drafts…") also fails on a clean checkout and is unrelated (Remote Access host-setup flow).
  • No new dependencies.

Review

Claude implementation-reviewer, against the plan. Its blocker — Walnut's 700→600 ramp step had collapsed to 1.02:1, making secondary-button hover and active rows invisible — is fixed, as are its smaller items (LogsView palette, layout-effect ordering, cascade-order assertion, index.html sync test, "flat shell is intentional" comments). The Codex review lane could not run: the Codex account is at its usage limit until Aug 19.

Manual testing

  • Cycle Folio → Newsprint → Walnut from Settings → Appearance and from the Home page dropdown; sidebar, tab bar, editor, diff view, terminal, logs and modals all recolour (no dark panels inside the light themes).
  • Toggle High contrast on each; muted sidebar/section text steps up without a hue shift.
  • Open a Claude/Codex panel on each and confirm dim/coloured CLI output stays legible.
  • Relaunch on each theme — no light/dark flash (bootstrap in index.html is synced).
  • Switch theme with a Logs panel open — log ANSI colours change immediately, no reopen needed.

Three print-and-paper themes: Folio (cream paper & ink, light),
Newsprint (cool grey stock, graphite, ink-blue accent, light) and
Walnut (warm brown-black, parchment, brass accent, dark). Full token
coverage incl. high-contrast blocks, terminal palettes and Monaco vars.

- Export THEME_CLASSES and derive isLightTheme from it; DiffViewer,
  FileEditor and usePaneLogo no longer hardcode the two light ids
- LogsView reads the theme's terminal palette instead of a fixed one
- ThemeProvider stamps classes in a layout effect so descendants'
  effects read fresh tokens
- SelectItem gains an optional description line; pickers describe the
  three new themes
- Add vitest contrast gate (themeContrast.test.ts), index.html sync test
  and a Playwright screenshot spec; commit screenshots/themes/*.png
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@github-actions

Copy link
Copy Markdown

React Doctor found 2 new issues in 1 file · 2 warnings · score 68 / 100 (Needs work) · 2 fixed · vs main

2 warnings

src/components/panels/editor/FileEditor.tsx

  • ⚠️ L63 Many related useState calls prefer-useReducer
  • ⚠️ L1195 Many related useState calls prefer-useReducer

Reviewed by React Doctor for commit 53ca092. See inline comments for fixes.

parsakhaz added a commit that referenced this pull request Aug 18, 2026
…families (#459)

Consolidates #451, #453, #454, #456 and themes-a11y into one batch: synthwave, acid, tokyo-rain, folio, newsprint, walnut, amber-crt, teletype, dot-matrix, haar, abyss, understory, colorblind-safe, low-fatigue, high-legibility. Pickers read one grouped THEME_OPTIONS list; pnpm theme:contrast gates all 15; pnpm theme:screenshots regenerates screenshots/themes/batch/.
@parsakhaz

Copy link
Copy Markdown
Member Author

Superseded by #459 (merged as 867795a), which consolidated all five theme branches — these themes are on main with their palettes unchanged. Closing without merge.

@parsakhaz parsakhaz closed this Aug 18, 2026
@parsakhaz
parsakhaz deleted the themes-editorial branch August 18, 2026 23:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant