diff --git a/AGENTS.md b/AGENTS.md
index 52ce6aa..93b5672 100755
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -96,8 +96,13 @@ ship twice — re-introducing one is a regression, not a style choice.
reference elsewhere, so this one still needs your attention.
- **The pre-paint theme script in `index.html` and `src/ui/theme.ts` must
agree.** The script cannot import the module — it has to run before any module
- loads — so it repeats the storage key and the fallback logic.
- → `src/ui/theme.test.ts`
+ loads — so it repeats the storage key and the fallback logic. Both set two
+ things, not one: the `.dark` class and ``, which
+ must also match the `color-scheme` declarations in `src/index.css`. The meta
+ tag is what Dark Reader reads to decide the app already has a dark theme;
+ without it, it samples the painted colours and inverts our dark palette a
+ second time. → `src/ui/theme.test.ts`, which runs the real script out of the
+ HTML rather than matching its text.
- **Anything derived from the base path is asserted for both a root and a
subpath deploy:** the manifest (`src/manifest.test.ts`), the font URLs
(`src/fontCss.test.ts`), the icons (`src/icons.test.ts`), and the service
diff --git a/src/index.html b/src/index.html
index 232f5c6..8e94235 100644
--- a/src/index.html
+++ b/src/index.html
@@ -11,6 +11,12 @@
+
+
diff --git a/src/ui/theme.test.ts b/src/ui/theme.test.ts
index d37adfc..1423e75 100644
--- a/src/ui/theme.test.ts
+++ b/src/ui/theme.test.ts
@@ -10,6 +10,7 @@ import {
THEME_KEY,
applyResolvedTheme,
isThemePreference,
+ prefersDark,
readThemePreference,
resolveTheme,
storeThemePreference,
@@ -18,8 +19,27 @@ import {
beforeEach(() => {
localStorage.clear();
document.documentElement.classList.remove("dark");
+ for (const meta of document.querySelectorAll('meta[name="color-scheme"]')) {
+ meta.remove();
+ }
});
+function colorSchemeMeta(): string | null {
+ return document.querySelector('meta[name="color-scheme"]')?.getAttribute("content") ?? null;
+}
+
+/**
+ * Lifts the inline pre-paint script out of index.html and runs it for real,
+ * rather than matching its text. The module script below it carries
+ * attributes, so a bare `