Follow-up to #35, which merged while I was still checking its output. You were right that the thumbnails looked wrong.
The light inbox screenshot was not light, and never had been. The one I replaced in #35 was dark too, so that pair in the README has been showing the dark theme twice since August.
The app was never at fault
update() in store/settings.ts calls applyTheme() synchronously, and the CSS does its job — measured in the page, data-theme="light" flips --bg from #0b1220 to #f6f8fa and the topbar with it.
It was setDeviceMetricsOverride
Swapping the theme under the emulation layer captures a mixed frame: the panes that re-rendered come out light while the rest of the chrome stays dark — with the DOM and computed styles insisting the whole page is light. That is why nothing I checked caught it. Tried and failed, in order:
clicking the app's own toggle
setting data-theme directly
pinning it against applyTheme with a MutationObserver
installing that pin via Page.addScriptToEvaluateOnNewDocument and reloading
a viewport nudge, then a forced reflow via display:none
Launching Chrome at --window-size=1420,790 and never calling setDeviceMetricsOverride renders the swap correctly on the first try. The compositor simply does not repaint everything a CSS-variable change touches while metrics are overridden.
What is here
docs/screenshots/inbox-light.jpg — genuinely light at last, same 1420x703
docs/screenshots-light.mjs — that one shot, via window size rather than emulation
docs/screenshots.mjs — no longer takes it, and the header now says which shots are taken elsewhere and why, so nobody reaches for Emulation here again
assertTheme() — checks the rendered background immediately before writing a themed file and throws if it disagrees. Without it the script wrote a dark screenshot under a light caption and reported success, which is how this survived unnoticed for months
Follow-up to #35, which merged while I was still checking its output. You were right that the thumbnails looked wrong.
**The light inbox screenshot was not light, and never had been.** The one I replaced in #35 was dark too, so that pair in the README has been showing the dark theme twice since August.
## The app was never at fault
`update()` in `store/settings.ts` calls `applyTheme()` synchronously, and the CSS does its job — measured in the page, `data-theme="light"` flips `--bg` from `#0b1220` to `#f6f8fa` and the topbar with it.
## It was `setDeviceMetricsOverride`
Swapping the theme under the emulation layer captures a **mixed frame**: the panes that re-rendered come out light while the rest of the chrome stays dark — with the DOM and computed styles insisting the whole page is light. That is why nothing I checked caught it. Tried and failed, in order:
1. clicking the app's own toggle
2. setting `data-theme` directly
3. pinning it against `applyTheme` with a `MutationObserver`
4. installing that pin via `Page.addScriptToEvaluateOnNewDocument` and reloading
5. a viewport nudge, then a forced reflow via `display:none`
Launching Chrome at `--window-size=1420,790` and never calling `setDeviceMetricsOverride` renders the swap correctly on the first try. The compositor simply does not repaint everything a CSS-variable change touches while metrics are overridden.
## What is here
- `docs/screenshots/inbox-light.jpg` — genuinely light at last, same 1420x703
- `docs/screenshots-light.mjs` — that one shot, via window size rather than emulation
- `docs/screenshots.mjs` — no longer takes it, and the header now says which shots are taken elsewhere and why, so nobody reaches for `Emulation` here again
- `assertTheme()` — checks the rendered background immediately before writing a themed file and throws if it disagrees. Without it the script wrote a dark screenshot under a light caption and reported success, which is how this survived unnoticed for months
**Merged** 2026-08-25 as coffey-labs/ihasmail@a9231a335ccc
<sub>Rebuilt from: git history, session transcript.</sub>
This repo is archived. You cannot comment on issues.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Follow-up to #35, which merged while I was still checking its output. You were right that the thumbnails looked wrong.
The light inbox screenshot was not light, and never had been. The one I replaced in #35 was dark too, so that pair in the README has been showing the dark theme twice since August.
The app was never at fault
update()instore/settings.tscallsapplyTheme()synchronously, and the CSS does its job — measured in the page,data-theme="light"flips--bgfrom#0b1220to#f6f8faand the topbar with it.It was
setDeviceMetricsOverrideSwapping the theme under the emulation layer captures a mixed frame: the panes that re-rendered come out light while the rest of the chrome stays dark — with the DOM and computed styles insisting the whole page is light. That is why nothing I checked caught it. Tried and failed, in order:
data-themedirectlyapplyThemewith aMutationObserverPage.addScriptToEvaluateOnNewDocumentand reloadingdisplay:noneLaunching Chrome at
--window-size=1420,790and never callingsetDeviceMetricsOverriderenders the swap correctly on the first try. The compositor simply does not repaint everything a CSS-variable change touches while metrics are overridden.What is here
docs/screenshots/inbox-light.jpg— genuinely light at last, same 1420x703docs/screenshots-light.mjs— that one shot, via window size rather than emulationdocs/screenshots.mjs— no longer takes it, and the header now says which shots are taken elsewhere and why, so nobody reaches forEmulationhere againassertTheme()— checks the rendered background immediately before writing a themed file and throws if it disagrees. Without it the script wrote a dark screenshot under a light caption and reported success, which is how this survived unnoticed for monthsMerged 2026-08-25 as coffey-labs/ihasmail@a9231a335c
Rebuilt from: git history, session transcript.