Problem: Users read the Bible in different environments — bright rooms, dark rooms, before bed. A single color scheme can't serve all contexts. Some users also have visual preferences or accessibility needs.
Solution: Four color themes: Dark, Light, Sepia, and High Contrast. Each defines 23 color tokens covering text, backgrounds, accents, and interactive elements. Themes switch instantly via Settings or comfort profiles.
Not included: Custom user-defined themes or per-page theming. These are four curated presets.
User flow:
Comfort profiles (shortcuts):
Edge cases:
Theme palettes (23 tokens each):
| Token | Dark | Light | Sepia | High Contrast |
|---|---|---|---|---|
| Background | #1a1a2e | #ffffff | #f5f0e8 | #000000 |
| Text | #e0e0e0 | #1a1a2e | #3d3329 | #ffffff |
| Verse numbers | muted | muted | muted | bright |
Application: CSS custom properties set on <html> element via class: .theme-dark, .theme-light, .theme-sepia, .theme-high-contrast.
Theme definitions (apps/web/src/lib/theme/colors.ts):
themes: Record<ThemeName, ThemePalette> with 4 themes, 23 color tokens eachCSS (apps/web/src/lib/theme/themes.css):
:root/.theme-dark, .theme-light, etc.Switching (settings.svelte.ts):
setTheme(name) updates settings + persist()(app)/+layout.svelte binds a $effect on settings.theme → updates document.documentElement.classNameComfort profiles: setComfortProfile(profile) applies theme + fontSize + fontWeight together.
Files:
apps/web/src/lib/theme/colors.ts — theme palettesapps/web/src/lib/theme/themes.css — CSS custom propertiesapps/web/src/lib/stores/settings.svelte.ts — setTheme(), setComfortProfile()apps/web/src/routes/(app)/+layout.svelte — theme class bindingapps/web/src/routes/(app)/settings/+page.svelte — theme picker UICurrent: DONE Milestone: v3 Priority: Core — essential for user comfort and accessibility
History:
Dependencies: