Skip to content
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
f67cffc
Fix light/dark mode based on browser default
reniejoshi Aug 1, 2026
e4ed058
Merge branch 'main' into fix-light/dark-mode-based-on-browser-default
reniejoshi Aug 1, 2026
e41b5f8
Merge branch 'main' of https://github.com/frcsoftware/frcsoftware.org…
reniejoshi Sep 1, 2026
29ec814
Merge branch 'main' of https://github.com/frcsoftware/frcsoftware.org…
reniejoshi Sep 2, 2026
ee9bafd
Merge branch 'main' into fix-light/dark-mode-based-on-browser-default
reniejoshi Sep 2, 2026
3fe2ee3
Merge branch 'main' into fix-light/dark-mode-based-on-browser-default
reniejoshi Sep 4, 2026
803f58c
Apply copilot suggestion
reniejoshi Sep 4, 2026
a9525e5
Improve theme application logic on scheme change
reniejoshi Sep 4, 2026
03d344c
Merge branch 'main' into fix-light/dark-mode-based-on-browser-default
reniejoshi Sep 5, 2026
73210b8
Merge branch 'main' into fix-light/dark-mode-based-on-browser-default
reniejoshi Sep 5, 2026
9a31bb2
Merge branch 'main' into fix-light/dark-mode-based-on-browser-default
reniejoshi Sep 5, 2026
1b6ccbb
Merge branch 'main' into fix-light/dark-mode-based-on-browser-default
reniejoshi Sep 6, 2026
fb31048
Merge branch 'main' into fix-light/dark-mode-based-on-browser-default
reniejoshi Sep 6, 2026
322e8b5
Merge branch 'main' into fix-light/dark-mode-based-on-browser-default
Adrianamm Sep 7, 2026
2af4fd3
Merge branch 'main' into fix-light/dark-mode-based-on-browser-default
samfreund Sep 14, 2026
6ac103a
Fix linting errors
reniejoshi Sep 14, 2026
9bd029e
Merge branch 'main' into fix-light/dark-mode-based-on-browser-default
Adrianamm Sep 16, 2026
56cac28
Merge branch 'main' into fix-light/dark-mode-based-on-browser-default
Adrianamm Sep 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions src/starlightOverrides/Header.astro
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,89 @@ const { hasSidebar } = Astro.locals.starlightRoute;
})();
</script>

<script is:inline>
(() => {
const storageKey = 'starlight-theme';

const getStoredTheme = () => {
try {
return localStorage.getItem(storageKey);
} catch {
return null;
}
};
const setStoredTheme = (/** @type {'light' | 'dark'} */ value) => {
try {
localStorage.setItem(storageKey, value);
} catch {
/* ignore */
}
};

const applyTheme = (
/** @type {'light' | string} */ theme,
store = false,
) => {
const html = document.documentElement;
const normalized = theme === 'light' ? 'light' : 'dark';

html.dataset.theme = normalized;
// Only persist an explicit user choice. Browser-derived themes must
// stay un-stored so the site keeps following the OS/browser setting.
if (store) setStoredTheme(normalized);
if (window.StarlightThemeProvider?.updatePickers) {
window.StarlightThemeProvider.updatePickers(normalized);
}
};

const colorScheme = window.matchMedia('(prefers-color-scheme: light)');
const getPreferredTheme = () =>
colorScheme.matches ? 'light' : 'dark';

const init = () => {
const stored = getStoredTheme();
const explicit =
stored === 'light' || stored === 'dark' ? stored : null;

applyTheme(explicit || getPreferredTheme());

// Follow OS/browser changes unless the user has explicitly chosen a theme.
const onSchemeChange = () => {
const stored = getStoredTheme();
if (stored !== 'light' && stored !== 'dark') {
applyTheme(getPreferredTheme());
}
};
if (!explicit) {
if (typeof colorScheme.addEventListener === 'function') {
colorScheme.addEventListener('change', onSchemeChange);
} else if (typeof colorScheme.addListener === 'function') {
colorScheme.addListener(onSchemeChange);
}
}

document.querySelectorAll('[data-theme-toggle]').forEach((btn) => {
btn.addEventListener('click', () => {
const current =
document.documentElement.dataset.theme ||
getPreferredTheme();
const next = current === 'dark' ? 'light' : 'dark';
applyTheme(next, true);
});
});
};

if (
document.readyState === 'complete' ||
document.readyState === 'interactive'
) {
init();
} else {
document.addEventListener('DOMContentLoaded', init);
}
})();
</script>

<style>
/* Override the parent .header styles from Starlight */
:global(.header) {
Expand Down
Loading