Foundations
Theme modes
Light, dark and device preference are product states, not just screenshot variants.
On this page
Theme contract
| Property | Responsibility |
|---|---|
| data-color-mode | User choice: light, dark or system. |
| data-theme | Resolved light/dark presentation. |
| Site-specific storage key | Persists preference without mixing tenant settings. |
| Theme runtime | Applies stored mode and system preference; source toggle calls window.__siteTheme. |
| Admin scope | Root mode resolves scoped admin overrides too. |
Review protocol
- Check each screenshot in both source themes, including disabled controls, image placeholders and scrims.
- Review a fresh load before hydration and a preference change after hydration.
- Test storage failures and system preference changes; do not require successful local storage to render readable content.
- The isolated harness uses the native ThemeRuntime to set the chosen mode in a disposable browser context. It verifies resolved appearance and selected controls; cross-session persistence and system changes still require their own checks.
Source references
| File | Responsibility |
|---|---|
| lib/theme.ts | Audited Townwell implementation; use this file when extending this interface. |
| components/theme-runtime.tsx | Audited Townwell implementation; use this file when extending this interface. |
| components/theme-mode-toggle.tsx | Audited Townwell implementation; use this file when extending this interface. |
| components/theme-logo.tsx | Audited Townwell implementation; use this file when extending this interface. |
Examples from the app
Actual Boise Today and Townwell UI with synthetic editorial, business, review, media metadata and analytics. Existing Boise imagery; no live data changes. Captured at 2× resolution or higher. Select an image to inspect it full size.
Related topics
Source audit: 2026-10-07 · Revision ce8bc72b96da · Documentation v0.1