84 lines
3.6 KiB
Markdown
84 lines
3.6 KiB
Markdown
## Purpose
|
|
|
|
Define site-wide theme support (dark, light, high-contrast) using CSS tokens and an application mechanism that can switch across the entire UI.
|
|
|
|
## Requirements
|
|
|
|
### Requirement: Site themes
|
|
The site MUST support three themes:
|
|
- `dark`
|
|
- `light`
|
|
- `high-contrast`
|
|
|
|
Themes MUST be applied by setting a `data-theme` attribute on the root document element (`<html>`).
|
|
|
|
#### Scenario: Dark theme active
|
|
- **WHEN** `data-theme="dark"` is set on `<html>`
|
|
- **THEN** the site's background, text, and component styling reflect the dark palette
|
|
|
|
#### Scenario: Light theme active
|
|
- **WHEN** `data-theme="light"` is set on `<html>`
|
|
- **THEN** the site's background, text, and component styling reflect the light palette
|
|
|
|
#### Scenario: High contrast theme active
|
|
- **WHEN** `data-theme="high-contrast"` is set on `<html>`
|
|
- **THEN** the site uses a high-contrast palette with a clearly visible focus ring and high-contrast borders
|
|
|
|
### Requirement: Theme persistence
|
|
The site MUST persist the user's theme selection so it is retained across page loads and navigations.
|
|
|
|
Persistence MUST be stored locally in the browser (e.g., localStorage).
|
|
|
|
#### Scenario: Theme persists across reload
|
|
- **WHEN** the user selects `light` theme and reloads the page
|
|
- **THEN** the `light` theme remains active
|
|
|
|
### Requirement: Theme persistence works across visits with fallback
|
|
The site MUST persist the user's theme selection across visits so returning users see the last-selected theme.
|
|
|
|
The site MUST use client-side persistence and MUST support a fallback mechanism:
|
|
- Primary: `localStorage`
|
|
- Fallback: a client-side cookie
|
|
|
|
The effective theme selection order MUST be:
|
|
1) Stored theme in `localStorage` (if available)
|
|
2) Stored theme in a cookie (if localStorage is unavailable)
|
|
3) Default selection using environment signals
|
|
|
|
#### Scenario: LocalStorage persists across a later visit
|
|
- **WHEN** a user selects `light` theme and later returns to the site in the same browser
|
|
- **THEN** the site initializes in `light` theme before first paint
|
|
|
|
#### Scenario: Cookie fallback is used when localStorage is unavailable
|
|
- **WHEN** the browser environment blocks `localStorage` access and the user selects `dark` theme
|
|
- **THEN** the theme is persisted using a client-side cookie and is restored on the next visit
|
|
|
|
#### Scenario: No persistence available falls back to defaults
|
|
- **WHEN** both `localStorage` and cookie persistence are unavailable
|
|
- **THEN** the site falls back to default theme selection using environment signals
|
|
|
|
### Requirement: Default theme selection
|
|
If the user has not explicitly selected a theme, the site MUST choose a default theme using environment signals.
|
|
|
|
Default selection order:
|
|
1) If forced colors / high-contrast mode is active, default to `high-contrast`
|
|
2) Else if the system prefers light color scheme, default to `light`
|
|
3) Else default to `dark`
|
|
|
|
#### Scenario: No stored preference uses system settings
|
|
- **WHEN** the user has no stored theme preference
|
|
- **THEN** the site selects a default theme based on forced-colors and prefers-color-scheme
|
|
|
|
### Requirement: Theme switching transition
|
|
Theme changes initiated by the user MUST transition smoothly.
|
|
|
|
The transition MUST be disabled or substantially reduced when `prefers-reduced-motion: reduce` is set.
|
|
|
|
#### Scenario: Smooth transition on switch
|
|
- **WHEN** the user switches from `dark` to `light` theme
|
|
- **THEN** theme-affecting properties transition smoothly instead of abruptly switching
|
|
|
|
#### Scenario: Reduced motion disables theme animation
|
|
- **WHEN** `prefers-reduced-motion: reduce` is set and the user switches theme
|
|
- **THEN** the theme change occurs without noticeable animation
|