forge: in-app light / e-ink theme toggle #8

Merged
pedromcaraujo merged 1 commit from feat/light-eink-theme into main 2026-07-17 10:56:33 +01:00

Summary

Pedro uses Forge a lot on a Boox (e-ink), where the dark-only Tokyo Night theme
is close to the worst case: reflective displays render best as black-on-white,
dark backgrounds look muddy, and blinking cursors / glows / shadows ghost badly.

This adds a light / e-ink theme toggle in the sidebar header that flips both
styling layers:

  • Chrome — new :root[data-theme="light"] palette. Introduced semantic
    tokens (--sel-bg, --sel-fg, --on-accent) so text-on-coloured-surfaces
    flip cleanly instead of hardcoding #15161e/#fff.
  • Terminal — re-themes xterm.js at runtime via the existing
    frame.contentWindow.term handle. The deploy's configured dark palette
    (myServices.forge.theme) is captured once as baseTheme, so toggling back
    to dark restores a customised palette exactly — no duplicated theme in JS.
  • E-ink hygiene — light mode kills the cursor blink, the status-dot glow,
    the palette drop-shadow, and the dropzone transition.
  • Per-device (localStorage), restored before first paint to avoid a flash,
    and re-applied on every iframe load so it survives channel switches. Updates
    the PWA theme-color too.

Test plan

  • Both inline scripts parse cleanly under Node.
  • Live on a Forge deploy: toggle flips chrome + terminal, persists across
    reload, survives channel switches.
  • On the Boox: black-on-white is high-contrast, no cursor blink, no ghost
    trails on the status dot / palette.
  • A customised myServices.forge.theme deploy round-trips (light → dark
    restores the configured palette).
## Summary Pedro uses Forge a lot on a Boox (e-ink), where the dark-only Tokyo Night theme is close to the worst case: reflective displays render best as black-on-white, dark backgrounds look muddy, and blinking cursors / glows / shadows ghost badly. This adds a **light / e-ink theme toggle** in the sidebar header that flips both styling layers: - **Chrome** — new `:root[data-theme="light"]` palette. Introduced semantic tokens (`--sel-bg`, `--sel-fg`, `--on-accent`) so text-on-coloured-surfaces flip cleanly instead of hardcoding `#15161e`/`#fff`. - **Terminal** — re-themes xterm.js at runtime via the existing `frame.contentWindow.term` handle. The deploy's configured dark palette (`myServices.forge.theme`) is captured once as `baseTheme`, so toggling back to dark restores a customised palette exactly — no duplicated theme in JS. - **E-ink hygiene** — light mode kills the cursor blink, the status-dot glow, the palette drop-shadow, and the dropzone transition. - Per-device (`localStorage`), restored before first paint to avoid a flash, and re-applied on every iframe load so it survives channel switches. Updates the PWA `theme-color` too. ## Test plan - [x] Both inline scripts parse cleanly under Node. - [ ] Live on a Forge deploy: toggle flips chrome + terminal, persists across reload, survives channel switches. - [ ] On the Boox: black-on-white is high-contrast, no cursor blink, no ghost trails on the status dot / palette. - [ ] A customised `myServices.forge.theme` deploy round-trips (light → dark restores the configured palette).
A sun/moon button in the sidebar header flips both the launcher chrome
(CSS custom properties via an <html> data-theme attribute) and the
terminal (xterm.js palette re-themed at runtime through the iframe's
"term" handle) to a high-contrast black-on-white theme tuned for e-ink
readers like the Boox.

The choice is per-device (localStorage), restored before first paint to
avoid a flash, and re-applied on every iframe load so it survives channel
switches. Light mode also drops the effects that ghost on e-ink: the
cursor blink, the status-dot glow, the palette shadow, and transitions.

The dark default still follows the deploy's myServices.forge.theme -- it's
captured from the live terminal as the baseline, so toggling back restores
a customised palette exactly.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
pedromcaraujo/forge!8
No description provided.