Skip to content

visual-qa: flash of wrong theme (FOUC) — theme restore runs at end of <body>, flashes on every view-transition navigation #29

Description

@vedantggwp

Found in W1d first-ever visual QA (v0.5.0, dist/present.js) of the agent-sdk-claude site. Full report: .growth/truth/W1d-visual-qa.md.

Symptom

On load, and again on every cross-document navigation, a visitor whose stored theme differs from their OS prefers-color-scheme sees the whole page paint in the OS-default theme, then snap to their chosen theme.

Trail

  • Present generator emits the theme-restore script (localStorage['grimoire-theme']theme-light/theme-dark class) at line 359 of 387 — the very end of <body>, after </main>/</footer>. Nothing theme-related is in <head> (grep-confirmed).
  • Default theme comes from @media (prefers-color-scheme); the stored override is applied only when that end-of-body script runs.
  • The site uses native cross-document View Transitions (assets/style.css: @view-transition, ::view-transition-old(root), ::view-transition-new(root)). Because each navigation re-parses the document and re-runs the late restore, the wrong-theme frame can be captured in the transition snapshot → visible flash per navigation.

Repro

  1. Open the site, toggle to the theme opposite your OS scheme (persists to localStorage).
  2. Reload / navigate between pages. Observe a flash of the wrong theme before it corrects.
  • Not hit when there's no stored theme or it matches the OS scheme.

Impact

Severity: HIGH for a demo (it's the brief's #1 "no unstyled flashes / view transitions don't flash" check; recurs on every navigation once a theme has been chosen).

Fix

Emit a tiny blocking inline script in <head> that reads localStorage['grimoire-theme'] and sets the class on document.documentElement before first paint (standard anti-FOUC pattern). Keep the existing toggle wiring in body.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions