As a user I want a dark mode so I can use the archive comfortably in low-light environments #64

Closed
opened 2026-03-25 11:34:06 +01:00 by marcel · 0 comments
Owner

User Journey

A user opens the archive in their browser. If their OS is set to dark mode, the UI renders in dark colors immediately — no flash of white. If their OS is set to light mode, the UI renders in light colors.

In the navigation bar, next to the language selector, a toggle button shows a moon icon (light mode) or a sun icon (dark mode). Clicking it switches the theme immediately and persists the choice across page reloads and browser sessions. The chosen theme overrides the OS preference until the user clicks the toggle again.

The PDF viewer adapts too: light in light mode, dark in dark mode. All pages — documents, persons, conversations, admin, login — respond to the theme.


E2E Scenarios

Scenario: Theme follows system preference by default
  Given I have no saved theme preference
  And my OS is set to dark mode
  When I open the archive
  Then the page renders with a dark background immediately (no flash)

Scenario: Manual dark mode toggle
  Given I am on any page with light mode active
  When I click the theme toggle button in the nav bar
  Then the UI switches to dark mode
  And the toggle icon changes from moon to sun

Scenario: Theme persists across reloads
  Given I have manually switched to dark mode
  When I reload the page
  Then the UI is still in dark mode

Scenario: Manual light mode toggle
  Given I am in dark mode
  When I click the theme toggle button
  Then the UI switches to light mode
  And the toggle icon changes from sun to moon

Implementation notes

Token system (layout.css only — no hardcoded values anywhere)

Utility Light Dark
bg-canvas #f0efe9 #0d0d0d
bg-surface #ffffff #1a1a1a
bg-overlay #ffffff #242424
bg-muted #f5f4ef #252525
border-line #e4e2d7 #2e2e2e
border-line-2 #eeede8 #222222
text-ink #012851 #f0efe9
text-ink-2 #6b7280 #9ca3af
text-ink-3 #9ca3af #6b7280
bg-/text-accent #a1dcd8 (mint) #00c7b1 (CI turquoise)
bg-/text-primary #012851 (navy) #a1dcd8 (mint)
text-primary-fg #ffffff #012851
bg-pdf-bg #ebebeb #1e1e1e
bg-pdf-ctrl #d8d8d8 #2a2a2a
text-pdf-text #333333 #d1d1d1

Approach

  • tailwind.config.js keeps only the content glob — all colors/fonts in layout.css
  • @theme inline maps semantic tokens to CSS variables → Tailwind generates bg-surface, text-ink, etc.
  • :root = light defaults; @media (prefers-color-scheme: dark) :root:not([data-theme=light]) + [data-theme=dark] = dark
  • Inline <script> in app.html applies saved theme before first paint
  • All 35 .svelte files use only semantic token utilities — zero bg-[#...], text-gray-*, raw bg-white/text-brand-navy
## User Journey A user opens the archive in their browser. If their OS is set to dark mode, the UI renders in dark colors immediately — no flash of white. If their OS is set to light mode, the UI renders in light colors. In the navigation bar, next to the language selector, a toggle button shows a moon icon (light mode) or a sun icon (dark mode). Clicking it switches the theme immediately and persists the choice across page reloads and browser sessions. The chosen theme overrides the OS preference until the user clicks the toggle again. The PDF viewer adapts too: light in light mode, dark in dark mode. All pages — documents, persons, conversations, admin, login — respond to the theme. --- ## E2E Scenarios ``` Scenario: Theme follows system preference by default Given I have no saved theme preference And my OS is set to dark mode When I open the archive Then the page renders with a dark background immediately (no flash) Scenario: Manual dark mode toggle Given I am on any page with light mode active When I click the theme toggle button in the nav bar Then the UI switches to dark mode And the toggle icon changes from moon to sun Scenario: Theme persists across reloads Given I have manually switched to dark mode When I reload the page Then the UI is still in dark mode Scenario: Manual light mode toggle Given I am in dark mode When I click the theme toggle button Then the UI switches to light mode And the toggle icon changes from sun to moon ``` --- ## Implementation notes ### Token system (`layout.css` only — no hardcoded values anywhere) | Utility | Light | Dark | |---|---|---| | `bg-canvas` | `#f0efe9` | `#0d0d0d` | | `bg-surface` | `#ffffff` | `#1a1a1a` | | `bg-overlay` | `#ffffff` | `#242424` | | `bg-muted` | `#f5f4ef` | `#252525` | | `border-line` | `#e4e2d7` | `#2e2e2e` | | `border-line-2` | `#eeede8` | `#222222` | | `text-ink` | `#012851` | `#f0efe9` | | `text-ink-2` | `#6b7280` | `#9ca3af` | | `text-ink-3` | `#9ca3af` | `#6b7280` | | `bg-/text-accent` | `#a1dcd8` (mint) | `#00c7b1` (CI turquoise) | | `bg-/text-primary` | `#012851` (navy) | `#a1dcd8` (mint) | | `text-primary-fg` | `#ffffff` | `#012851` | | `bg-pdf-bg` | `#ebebeb` | `#1e1e1e` | | `bg-pdf-ctrl` | `#d8d8d8` | `#2a2a2a` | | `text-pdf-text` | `#333333` | `#d1d1d1` | ### Approach - `tailwind.config.js` keeps only the `content` glob — all colors/fonts in `layout.css` - `@theme inline` maps semantic tokens to CSS variables → Tailwind generates `bg-surface`, `text-ink`, etc. - `:root` = light defaults; `@media (prefers-color-scheme: dark) :root:not([data-theme=light])` + `[data-theme=dark]` = dark - Inline `<script>` in `app.html` applies saved theme before first paint - All 35 `.svelte` files use only semantic token utilities — zero `bg-[#...]`, `text-gray-*`, raw `bg-white`/`text-brand-navy`
marcel changed title from feat(frontend): dark mode with system-preference detection and manual toggle to As a user I want a dark mode so I can use the archive comfortably in low-light environments 2026-03-25 11:38:51 +01:00
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: marcel/familienarchiv#64