## Context

The site currently uses a single dark theme defined via CSS variables in `site/public/styles/global.css` (e.g., `--bg0`, `--bg1`, `--fg`, `--muted`, `--stroke`, `--accent`). There is no existing theme selection mechanism (no `data-theme` attribute, no persisted preference).

The site shell uses a sticky `.site-header` and a per-page `.subnav` row (when present). A theme switcher notch must be fixed-positioned such that it does not overlap the header and leaves enough space for the subnav region.

## Goals / Non-Goals

**Goals:**
- Provide three themes: `dark`, `light`, `high-contrast`.
- Allow switching themes via a floating notch on the right side of the screen positioned below the primary nav bar and not overlapping the subnav area.
- Make switching feel premium:
  - hover animation on the notch
  - smooth theme transitions (without an abrupt flash)
- Ensure accessibility:
  - keyboard operable
  - visible focus
  - respects `prefers-reduced-motion`
  - high contrast theme is meaningfully higher contrast, not just a color swap
- Persist the user's selection across page loads.

**Non-Goals:**
- Rebuild the entire visual system or rewrite all CSS to a design-token framework.
- PWA theming (manifest/theme-color) beyond what is required to implement UI themes.
- Adding user accounts or server-side persistence of theme preference.

## Decisions

### 1. Theme selection mechanism: `data-theme` on `<html>`
Use `document.documentElement.dataset.theme = "dark" | "light" | "high-contrast"`.

Rationale:
- Works cleanly with CSS variables.
- Scopes theme styles across the entire page without specificity fights.

Alternatives considered:
- Adding theme classes to `body` (works, but html-scoped variables are simpler for form control theming).

### 2. Token strategy: override existing CSS variables per theme
Keep the existing variable names and provide theme-specific overrides:
- `:root` remains the default (dark)
- `html[data-theme="light"] { ... }`
- `html[data-theme="high-contrast"] { ... }`

Rationale:
- Minimizes churn in existing CSS.
- Enables incremental migration of any remaining hard-coded colors to tokens.

### 3. Default theme resolution order
On first load, resolve the active theme in this order:
1) stored user preference (`localStorage.theme`)
2) forced colors / high-contrast OS mode (if detected) -> `high-contrast`
3) system color scheme -> `light` if `prefers-color-scheme: light`, else `dark`

Rationale:
- User choice wins.
- If the user is in a forced/high-contrast environment, defaulting to high-contrast aligns with accessibility intent.

### 4. Prevent flash of wrong theme with a tiny head script
Insert a small inline script in the document `<head>` that sets `data-theme` before first paint.

Rationale:
- Avoids "flash" where the page renders in dark before switching to light/high-contrast.

Trade-off:
- Inline scripts can constrain future CSP hardening; keep script small and self-contained.

### 5. Smooth transitions without animating on every page load
Use a transient attribute/class (e.g., `data-theme-transition="on"`) only during user-initiated theme changes.

Implementation shape:
- When switching: set `data-theme-transition="on"`, update `data-theme`, then remove after ~250ms.
- CSS applies transitions for color/background/border/shadow only when the attribute is present.

Rationale:
- Avoids "everything animates" feeling during initial load.
- Avoids subtle jank on navigation.

### 6. Notch UI: fixed-position, expands on hover/focus
Implement the switcher as a fixed-position control at the right edge:
- Default collapsed: a small vertical tab.
- On `:hover` and `:focus-within`: expands into a small panel exposing the three theme options.

Accessibility decisions:
- Use a real `<button>` to open/close (for touch) OR a `<fieldset role="radiogroup">` with three radio-like buttons.
- Ensure it is reachable via keyboard and has clear `aria-label`s.

Placement decisions:
- Use a CSS variable `--theme-notch-top` to position it.
- A small inline script computes this based on `.site-header` height and, if a `.subnav` exists near the top, positions below it.

### 7. High Contrast theme semantics
The high-contrast theme will be a dedicated palette (not only increased brightness) with:
- strong background/foreground contrast
- high visibility focus ring
- more assertive stroke borders

Additionally, handle OS forced-colors mode:
- In `@media (forced-colors: active)`, prefer system colors and avoid gradients that reduce clarity.

## Risks / Trade-offs

- **[Notch overlaps content]** -> compute top offset from header/subnav; provide safe-area padding; add responsive rules for small viewports.
- **[Theme transitions reduce readability]** -> scope transitions to a short window and limit properties; disable via `prefers-reduced-motion`.
- **[High contrast breaks brand feel]** -> keep layout/typography unchanged and only adjust palette and borders.
- **[CSP constraints]** -> keep head script minimal and consider moving to an external script if CSP hardening becomes a priority.
