The site is a Jekyll static site using the Minimal Mistakes theme (v4.27.0, loaded as a remote theme). The theme ships with multiple pre-built SCSS skins, including dirt (currently active, light mode) and dark. Both skins are already compiled into the CSS output — the active skin is selected at build time via minimal_mistakes_skin in _config.yml.
Since the site is static, runtime skin-switching cannot rely on server-side logic. The solution must be entirely client-side: inject the dark skin’s CSS variables alongside the default, and toggle a class on <html> to activate them.
Goals:
localStorageprefers-color-scheme: dark on first visit (before any user choice)Non-Goals:
<html> rather than swapping <link> stylesheetsDecision: Add dark-mode color overrides as a [data-theme="dark"] CSS block in a custom stylesheet. Toggling the data-theme attribute on <html> activates dark mode.
Rationale: Swapping <link> tags causes a flash and a second network request. A class/attribute toggle on an already-loaded stylesheet is instant and FOUT-free when the script runs in <head>.
Alternative considered: Changing minimal_mistakes_skin per-page via front matter — this would require a full page reload and cannot be user-toggled at runtime.
<head> to prevent FOUTDecision: Place a small inline <script> in _includes/head/custom.html that reads localStorage (and falls back to prefers-color-scheme) and sets data-theme on <html> synchronously before the browser renders anything.
Rationale: Async or deferred scripts run after layout/paint, causing the wrong theme to flash. An inline script in <head> blocks rendering briefly but eliminates FOUT entirely.
Decision: Keep minimal_mistakes_skin: dirt in _config.yml (the compiled light skin). Add a custom _sass/custom/_dark-override.scss (included via assets/css/main.scss) that overrides color variables when [data-theme="dark"] is set on <html>.
Rationale: The Minimal Mistakes remote theme compiles a single skin per build. We cannot inject a second skin at build time without forking the theme. CSS custom properties (or SCSS-compiled overrides with high specificity) achieve the same visual result without forking.
Alternative considered: Forking the theme to output two skin stylesheets — too much maintenance overhead.
Decision: Add a button to _includes/masthead.html (in the nav area) with a sun/moon icon that calls toggleDarkMode().
Rationale: The masthead is persistent across all pages and the most conventional location for a theme toggle.
_includes/masthead.html must be copied locally to modify. Any upstream masthead changes in future theme versions will not be picked up automatically → Mitigation: Track the theme version (4.27.0) and review the file on upgrades.[data-theme="dark"] with sufficient specificity; test visually._includes/masthead.html from the remote theme into the local _includes/ directory (so it can be modified).assets/js/dark-mode.js with toggle, persistence, and OS-preference logic._sass/custom/_dark-override.scss with color variable overrides under [data-theme="dark"].assets/css/main.scss (or equivalent custom entry point)._includes/head/custom.html.bundle exec jekyll serve.Rollback: Remove the added files and revert _includes/masthead.html and _includes/head/custom.html. No database or config changes to undo.
fa-sun / fa-moon are available.)