1---
2/**
3 * Pre-paint theme initializer + browser-chrome metadata. Mirrors
4 * Starlight's default ThemeProvider contract so its built-in
5 * `<ThemeSelect>` (and our marketing nav toggle) keep working.
6 *
7 * Reads `localStorage["starlight-theme"]` first, falls back to
8 * `prefers-color-scheme`, and writes `data-theme` on <html> before any
9 * paint to avoid a flash. Imported by both the Starlight head override
10 * and the marketing layout so navigating between docs and marketing
11 * pages doesn't drop the user's theme.
12 *
13 * Also emits the `color-scheme` and `theme-color` meta tags so iOS /
14 * Android paint the URL bar / status bar / bottom nav with the page
15 * background instead of falling back to the OS-default white in dark
16 * mode.
17 *
18 * Exposes `window.StarlightThemeProvider.updatePickers(theme)` so the
19 * `<starlight-theme-select>` web component can sync its UI when storage
20 * or system preference changes.
21 */
22---
23
24<meta name="color-scheme" content="light dark" />
25{/* Cream parchment for light, deep walnut for dark — matches `--alc-bg`
26 in tokens.css. The browser picks based on `prefers-color-scheme` so
27 iOS Safari's URL bar / Android's status bar tint correctly even
28 before the inline script writes `data-theme`. */}
29<meta
30 name="theme-color"
31 content="#f5efe3"
32 media="(prefers-color-scheme: light)"
33/>
34<meta
35 name="theme-color"
36 content="#14110d"
37 media="(prefers-color-scheme: dark)"
38/>
39
40<script is:inline>
41 window.StarlightThemeProvider = (() => {
42 const storageKey = "starlight-theme";
43 const read = () => {
44 try {
45 return localStorage.getItem(storageKey);
46 } catch {
47 return null;
48 }
49 };
50 const resolve = (pref) => {
51 if (pref === "light" || pref === "dark") return pref;
52 return window.matchMedia("(prefers-color-scheme: dark)").matches
53 ? "dark"
54 : "light";
55 };
56 const apply = () => {
57 document.documentElement.dataset.theme = resolve(read() || "auto");
58 };
59 apply();
60
61 // Re-resolve when the system theme changes and the user is on "auto".
62 window
63 .matchMedia("(prefers-color-scheme: dark)")
64 .addEventListener("change", () => {
65 const stored = read();
66 if (!stored || stored === "auto") apply();
67 });
68
69 return {
70 updatePickers(theme = read() || "auto") {
71 document
72 .querySelectorAll("starlight-theme-select")
73 .forEach((picker) => {
74 const select = picker.querySelector("select");
75 if (select) select.value = theme;
76 const tmpl = document.querySelector("#theme-icons");
77 const newIcon =
78 tmpl && tmpl.content.querySelector("." + theme);
79 if (newIcon) {
80 const oldIcon = picker.querySelector("svg.label-icon");
81 if (oldIcon) oldIcon.outerHTML = newIcon.outerHTML;
82 }
83 });
84 },
85 };
86 })();
87</script>