The anti-FOUC script must be generated, not hand-written
The first-paint theme fix is deferred. When implemented, its script must be generated from the Active Theme module to avoid duplicating validation and CSS-variable mappings.
The Active Theme is applied to the DOM after hydration, so a visitor with a stored or shared Theme sees the default Theme paint first and then swap. Next.js names this pattern and its fix directly: an inline <script> in the Root Layout's <head> that reads storage and sets the DOM before first paint, paired with suppressHydrationWarning. app/layout.tsx currently has neither, and context.tsx's mount effect is exactly the "why not useEffect" case the Next.js guide warns about — useLayoutEffect would not help either, since it still runs after hydration.
Fixing this is deferred. The decision recorded here is a constraint on how it gets fixed whenever it does: the inline script must be generated from lib/theme/active-theme.ts's variable mapping, never hand-written.
A hand-written script would be a second place that knows the storage key, the 32 colour variable names, the shadow derivations, and the OKLCH clamp — which is precisely the duplication the Active Theme seam was built to eliminate. It would also drift silently: the failure mode is a wrong colour for one frame on first load, which nobody notices in review and no test catches.
This is why the module's core is pure, has no 'use client', and imports no React. It can be executed at build time to emit the script.
Consequences
Until this lands, a visitor arriving on a share link or returning with a stored Theme sees one frame of the default Theme. On a fast connection this reads as a flicker rather than a broken page, which is why it was ranked below the write path.
The fix is not free once taken: generating a script at build time means the Theme applied before hydration and the Theme applied by the provider must agree exactly, including clamping. Any divergence between them is a flash that looks identical to the one being fixed.