Adds Material's dark scheme to the docs site and makes it the default, with a toggle in the header to switch back to light.
What changed
mkdocs.yml now declares two palette entries, slate first:
dark (slate) is first, and Material takes the first entry as the default, so the site opens dark.
a sun icon in the header switches to light; a moon switches back. Material remembers the choice in localStorage, so the toggle sticks across pages and visits.
docs/dc-brand.css gains two dark-scheme rules:
Hue. Material derives its dark greys from a --md-hue variable. Pointing it at the brand slate (206deg) instead of Material's neutral 225deg gives the whole scheme the same cast as the header. The light scheme does not use the variable (its greys are unsaturated), so it is untouched.
Links. The brand slate is unreadable on a dark background, so the dark scheme uses a light tint of it (#9fb5c6) for body links. Green stays the accent, which keeps link hover visible in both schemes - if links were green as well, hover would do nothing.
Dark is the default regardless of the operating system preference, because neither entry carries a media query. Material only follows prefers-color-scheme when one does.
Contrast, over the dark background
Measured from the rendered page (rgb(30, 36, 41)), with alpha composited:
Element
Contrast
Body text
8.8:1
Body links
7.4:1
Inline code
7.2:1
Accent green (hover, focus)
5.6:1
Header text on the brand slate
10.2:1
All above the 4.5:1 that body text needs.
The light scheme is unchanged
A pixel diff of a local mkdocs build of this branch against one of main, both rendering light:
configuration page: 254 differing pixels, all inside the header toggle icon (x 1036-1057, y 14-37)
header strip at 2x: 824 differing pixels, all inside the toggle icon (x 2072-2114, y 28-74)
home page: the same 254 header pixels, plus 900 pixels inside the video placeholder where the loading spinner animates between captures
So the only thing the light scheme gains is the toggle.
Screenshots
From a local mkdocs build, 1920x1200 (and 480px for mobile).
Header, 2x - the toggle
Before (no toggle):
Dark - sun icon:
Light - moon icon:
Home - dark (the new default)
Home - light
Configuration page - dark
Configuration page - light
Mobile, 480px - dark
Mobile, 480px - light
Notes for the reviewer
The toggle is present at 480px too, at 40x40.
The header stays the brand slate in both schemes, so the site keeps its identity in dark mode.
Admonition colours are still Material's semantic set, unchanged in both schemes.
No CI runs on this repo's PRs - publish.yml publishes on push to main - so nothing gates this but review.
Adds Material's dark scheme to the docs site and makes it the default, with a toggle in the header to switch back to light.
## What changed
`mkdocs.yml` now declares two palette entries, slate first:
- **dark (slate) is first, and Material takes the first entry as the default**, so the site opens dark.
- a sun icon in the header switches to light; a moon switches back. Material remembers the choice in `localStorage`, so the toggle sticks across pages and visits.
`docs/dc-brand.css` gains two dark-scheme rules:
- **Hue.** Material derives its dark greys from a `--md-hue` variable. Pointing it at the brand slate (`206deg`) instead of Material's neutral `225deg` gives the whole scheme the same cast as the header. The light scheme does not use the variable (its greys are unsaturated), so it is untouched.
- **Links.** The brand slate is unreadable on a dark background, so the dark scheme uses a light tint of it (`#9fb5c6`) for body links. Green stays the accent, which keeps link hover visible in both schemes - if links were green as well, hover would do nothing.
Dark is the default regardless of the operating system preference, because neither entry carries a `media` query. Material only follows `prefers-color-scheme` when one does.
## Contrast, over the dark background
Measured from the rendered page (`rgb(30, 36, 41)`), with alpha composited:
| Element | Contrast |
|---|---|
| Body text | 8.8:1 |
| Body links | 7.4:1 |
| Inline code | 7.2:1 |
| Accent green (hover, focus) | 5.6:1 |
| Header text on the brand slate | 10.2:1 |
All above the 4.5:1 that body text needs.
## The light scheme is unchanged
A pixel diff of a local `mkdocs build` of this branch against one of `main`, both rendering light:
- configuration page: 254 differing pixels, all inside the header toggle icon (x 1036-1057, y 14-37)
- header strip at 2x: 824 differing pixels, all inside the toggle icon (x 2072-2114, y 28-74)
- home page: the same 254 header pixels, plus 900 pixels inside the video placeholder where the loading spinner animates between captures
So the only thing the light scheme gains is the toggle.
## Screenshots
From a local `mkdocs build`, 1920x1200 (and 480px for mobile).
### Header, 2x - the toggle
Before (no toggle):

Dark - sun icon:

Light - moon icon:

### Home - dark (the new default)

### Home - light

### Configuration page - dark

### Configuration page - light

### Mobile, 480px - dark

### Mobile, 480px - light

## Notes for the reviewer
- The toggle is present at 480px too, at 40x40.
- The header stays the brand slate in both schemes, so the site keeps its identity in dark mode.
- Admonition colours are still Material's semantic set, unchanged in both schemes.
- No CI runs on this repo's PRs - `publish.yml` publishes on push to `main` - so nothing gates this but review.
The docs site only offered Material's light scheme. This adds the dark
scheme and makes it the default.
- palette: two entries, slate first, each with a toggle. Material takes the
first entry as the default, so the site opens dark and a sun icon in the
header switches to light (and a moon switches back).
- dc-brand.css: the dark scheme's greys are derived from a hue variable, so
it is pointed at the brand slate (206deg) rather than Material's neutral
225deg, which gives the whole scheme the same cast as the header.
- dc-brand.css: the brand slate is unreadable on a dark background, so the
dark scheme uses a light tint of it (#9fb5c6) for body links. Green stays
the accent, which keeps link hover visible in both schemes.
Contrast, over the dark background rgb(30, 36, 41): body text 8.8:1, body
links 7.4:1, inline code 7.2:1, accent green 5.6:1, header text 10.2:1. The
light scheme is unchanged.
allan
merged commit c800145ead into main2026-09-28 23:44:54 +00:00
allan
deleted branch docs/dark-mode-toggle2026-09-28 23:44:54 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Adds Material's dark scheme to the docs site and makes it the default, with a toggle in the header to switch back to light.
What changed
mkdocs.ymlnow declares two palette entries, slate first:localStorage, so the toggle sticks across pages and visits.docs/dc-brand.cssgains two dark-scheme rules:--md-huevariable. Pointing it at the brand slate (206deg) instead of Material's neutral225deggives the whole scheme the same cast as the header. The light scheme does not use the variable (its greys are unsaturated), so it is untouched.#9fb5c6) for body links. Green stays the accent, which keeps link hover visible in both schemes - if links were green as well, hover would do nothing.Dark is the default regardless of the operating system preference, because neither entry carries a
mediaquery. Material only followsprefers-color-schemewhen one does.Contrast, over the dark background
Measured from the rendered page (
rgb(30, 36, 41)), with alpha composited:All above the 4.5:1 that body text needs.
The light scheme is unchanged
A pixel diff of a local
mkdocs buildof this branch against one ofmain, both rendering light:So the only thing the light scheme gains is the toggle.
Screenshots
From a local
mkdocs build, 1920x1200 (and 480px for mobile).Header, 2x - the toggle
Before (no toggle):
Dark - sun icon:
Light - moon icon:
Home - dark (the new default)
Home - light
Configuration page - dark
Configuration page - light
Mobile, 480px - dark
Mobile, 480px - light
Notes for the reviewer
publish.ymlpublishes on push tomain- so nothing gates this but review.