feat: support dark mode - #217
Merged
Merged
Conversation
Follows the OS setting on first visit and offers a toggle in the navbar, which persists the choice and from then on outranks the OS. Bootstrap 5.3's dark palette is driven entirely by data-bs-theme; the precompiled stylesheet we import carries no prefers-color-scheme rules at all. The media query is therefore read by an inline script in the head, which stamps the attribute on <html> before the first paint so the page never flashes the wrong theme. The three surfaces the site is made of - page, card, and code block - are now named as custom properties so the dark theme can swap all of them in one place. The brand red and green are redefined alongside them: both were darkened specifically to clear 4.5:1 against white and fall to 3.4:1 on a dark card, so the dark theme takes them the other way instead, to 6.4:1 and 5.5:1. The green keeps its hue and saturation; only its lightness moves. Code snippets ship both Plus themes at once via Shiki's dual-theme output, with the existing magenta keyword correction applied to each in its own magenta - the light one is illegible on a dark background. Screenshots, figures, and sponsor logos keep a white ground in both themes. Nearly all of them carry an alpha channel, and the sponsor marks are dark ink on transparency, so on a dark page they would otherwise have gone dark-on-dark. Recolouring them is not an option; several are other organisations' marks. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Removes --flix-bg-card, which was #ffffff light and #212529 dark - the same two values as --bs-body-bg, which .card, .list-group and .dropdown already resolve to. The card was being kept in step with a palette we do not own, by hand; .page now reads that token directly. The navbar had no name at all: its colour came from .bg-dark in light mode and from overriding --bs-dark-rgb underneath it in dark mode, two idioms for one surface, the second of them only to get out of the way of .bg-dark's !important. It becomes --flix-bg-navbar, painted by .menu, with .bg-dark dropped from the markup. The light value is what .bg-dark was already painting, so the light navbar is unchanged. The toggle no longer restates what base .btn computes for itself: it was setting background-color: transparent, which .btn already applies via --bs-btn-bg, on the strength of a comment claiming the --bs-btn-* tokens are undefined without a variant. They are not. Pointing --bs-btn-color and --bs-btn-hover-color at the navbar's colours does the same job and collapses the separate :hover rule. The two icon rules become one. The restore was dead: the button is a flex container, so whichever icon is left standing is blockified whatever its display says. The :not() form also leaves the moon showing if the script never runs, matching the light theme the page falls back to. Drops the `shiki` type import, which is not a dependency here and resolved only through astro, and derives each theme's name from the one it extends so the two cannot drift apart. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds dark mode across all ten pages. The site follows the OS setting on first visit and offers a toggle in the navbar; once used, the choice persists and outranks the OS from then on.
How it works
Bootstrap 5.3's dark palette is driven entirely by
data-bs-theme— the precompiled stylesheet we import contains noprefers-color-schemerules at all, so a pure-CSS approach would have needed a Sass build step and would have ruled out a manual toggle. Instead anis:inlinescript at the top of<head>readslocalStorage, falls back tomatchMedia, and stamps the attribute on<html>before the first paint, so there is no flash of the wrong theme.Colours
The three surfaces the site is made of — the page, the card, and the code blocks — are now named as custom properties, which is what lets the dark theme swap all of them in one place.
The brand red and green are redefined alongside them. Both were darkened specifically to clear 4.5:1 against white, as the comments in
global.cssrecord, and both fall to 3.4:1 on a dark card. The dark theme takes the same two colours the other way instead:.text-primary#a63839#ef8b8c.text-success#008938#00b34aThe green keeps hue 145 at full saturation exactly as the light one does; only its lightness moves. Ratios were measured rather than estimated, against a checker validated on the existing values the comments already state.
The navbar needs its own surface in dark mode:
.bg-darkresolves to#212529, which is also Bootstrap's dark--bs-body-bgand therefore the card, so the bar would have dissolved into the page behind it. Lifting it one step leaves inactive nav links at 5.20:1, down from 5.67:1 and still clear of 4.5.Code snippets
Snippets now ship both Plus themes at once through Shiki's dual-theme output. The existing correction that unifies Flix keywords on
keyword.control's magenta is applied to each theme in its own magenta — Light+'s#AF00DBis illegible on a dark background. Note that Astro renames Shiki's class toastro-codeon the way out, so the theme switch keys off that rather than the documented.shiki.Images
Screenshots, figures, and sponsor logos keep a white ground in both themes, via a single
.plateclass. Nearly every image on the site carries an alpha channel and the sponsor marks are dark ink on transparency, so on a dark page they would otherwise have gone dark-on-dark. Recolouring them was not an option — several are other organisations' marks. In light mode the plate is the colour of the card underneath, so it changes nothing there.Verification
astro checkandastro buildare both clean. Visually checked across all ten pages in both themes.🤖 Generated with Claude Code