Dark Mode
Light values sit on :root. Dark values apply through [data-color-scheme="dark"] and, when the page is not pinned, prefers-color-scheme: dark (see src/assets/scss/abstracts/_css-vars.scss).
Pin a page
Add one Nunjucks variable at the top of the page file:
{% set colorScheme = "dark" %} {# or "light" #}
The layout writes data-color-scheme on <html>. A pinned attribute always wins over the saved preference and the OS setting. Every page shipped with Rasuke 1.0 currently pins "dark" (including 404); removing the line makes that page follow the visitor's system + saved choice.
Runtime toggle
public/assets/js/vendors/color-modes.js loads in <head> before first paint. It:
- looks for
[data-color-scheme-toggle]buttons (for example the offcanvas menu theme switch) and syncsaria-pressed+aria-label(data-label-to-light/data-label-to-dark); - persists the choice in
localStorageunderrasuke-color-scheme; - applies a stored choice on load without removing a scheme pinned by the page template;
- adds the
jsclass (andis-transition-inwhen the page transition will play) before the first frame, so nothing flashes; - if the page is not pinned and nothing is saved, follows
prefers-color-schemevia CSS.
Write mode-safe CSS
Sections never reference a mode. Bind semantic tokens and they flip automatically:
.about-2 {
background-color: var(--color-surface-subtle);
color: var(--color-text-primary);
border-color: var(--color-border-base);
}
Do not write a dark-only hex in SCSS. If a new color must differ by mode, add both light and dark values in tokens.json. The brand orange #FF6A3A, cream #FCF7F3, and footer surface #1B1B1B are intentionally identical in both modes.