Projects BibleWeb Atmosphere Color themes (dark/light)
Done

Color themes (dark/light)

Area: Atmosphere Milestone: v3

Context

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.

Functional

User flow:

  1. User goes to Settings → Display → Theme
  2. Chooses from: Dark | Light | Sepia | High contrast
  3. Entire app immediately switches to the selected theme
  4. Setting persists across sessions

Comfort profiles (shortcuts):

  • Standard → Light theme, Medium font
  • Comfortable → Sepia theme, Large font
  • Large & Clear → Sepia theme, XL font, bold weight

Edge cases:

  • Theme applies to all pages (reader, search, notes, settings, etc.)
  • Jesus' words gold (#fbbf24) works well on all four theme backgrounds
  • Cross-reference graph node colors are designed to be visible on all themes

UX & Design

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.

Technical

Theme definitions (apps/web/src/lib/theme/colors.ts):

  • Exports themes: Record<ThemeName, ThemePalette> with 4 themes, 23 color tokens each

CSS (apps/web/src/lib/theme/themes.css):

  • Static CSS custom properties per class: :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.className

Comfort profiles: setComfortProfile(profile) applies theme + fontSize + fontWeight together.

Files:

  • apps/web/src/lib/theme/colors.ts — theme palettes
  • apps/web/src/lib/theme/themes.css — CSS custom properties
  • apps/web/src/lib/stores/settings.svelte.tssetTheme(), setComfortProfile()
  • apps/web/src/routes/(app)/+layout.svelte — theme class binding
  • apps/web/src/routes/(app)/settings/+page.svelte — theme picker UI

Status

Current: DONE Milestone: v3 Priority: Core — essential for user comfort and accessibility

History:

  • BibleGame had Dark and Light themes
  • Web version added Sepia and High Contrast
  • Comfort profiles added as quick presets combining theme + font settings

Dependencies:

  • Requires: settings store (DONE)
  • Used by: all visual components reference CSS custom properties