Skip to content

handbook: add light mode, theme toggle, and accessibility color themes #104

@nerdalytics

Description

@nerdalytics

The handbook is dark-only. There is no light mode, no theme toggle, and no accommodation for color vision deficiencies. The foundation for theming is solid: all colors are defined as CSS custom properties in a single @theme block (Tailwind CSS v4), not scattered as hardcoded hex values. Changing the theme means changing 10 variables.

Current color palette

Variable Hex Role
navy #0a0e1a Primary background
navy-light #0f1629 Code blocks, panels
navy-border #1e2a42 Borders
teal #14d4d4 Primary accent
blue #0f3fcf Secondary accent
blue-mid #5ba3f5 Links, function names
lime #c2cf0e Comments, strings
green #78ddb6 Gradient accent
text #c8d2e0 Body text
text-muted #8899b4 Secondary text

33 .svelte files reference these through semantic Tailwind classes (text-text, bg-navy). Swapping the underlying variables handles most components without touching their markup.

Work items

1. Light mode palette and toggle

Define a second set of CSS custom properties in app.css for light mode. Add a toggle to +layout.svelte and persist the choice in localStorage. Include a blocking <script> in app.html to prevent flash of wrong theme on load.

2. Shiki code highlighting

shiki-beacon-theme.json has its own hardcoded hex values for syntax tokens. Shiki renders at build time via mdsvex, so runtime theme switching requires one of two approaches: generate both themes and toggle with CSS, or use Shiki's css-variables theme mode so token colors follow the same CSS custom properties as the rest of the page.

3. Hardcoded hex values outside @theme

A few places bypass the theme system:

  • app.css has #e8edf5 hardcoded in ~6 places for prose headings and strong text
  • static/favicon.svg has inline gradient stops matching theme colors
  • Scattered text-[#e8a46e] arbitrary values in versioned landing page code snippets

These should be extracted into the @theme block so they follow the active theme.

4. Accessibility color themes

The current palette leans on teal and lime, which can be hard to distinguish for some types of color vision deficiency. Possible additions:

  • High contrast: push all text/background contrast ratios to 7:1+ (current text-muted on navy is ~5.8:1, passes AA but not AAA)
  • Protanopia / Deuteranopia / Tritanopia: replace teal/lime/green accents with distinguishable alternatives for each CVD type

Each accessibility theme is another set of CSS custom property values. The toggle UI becomes a dropdown instead of a binary switch. The choice should persist across sessions.

5. Scrollbar and animation colors

Scrollbar styling in app.css uses hardcoded references that should follow the theme. Gradient animation keyframes already use CSS variables and would update automatically.

Effort estimate

Task Effort
CSS variable light palette Small
Theme toggle + persistence Small
Shiki dual-theme or CSS variables Medium
Extract hardcoded hex to variables Small
Accessibility themes (CVD, high contrast) Medium-Large
Visual testing across all 33 components Medium

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions