# Dark Mode Dark mode is a first-class theme, not an invert filter. It is a deep teal-neutral palette defined under `.dark` in `app/globals.css`. ## Mechanism | Piece | Detail | | --- | --- | | Strategy | `class` on `html` via `next-themes` | | Provider | `components/theme-provider.tsx` | | Default | `light` | | System | `enableSystem` | | Variant | `@custom-variant dark (&:is(.dark *));` | | Toggle | `components/theme-toggle.tsx` | ## Palette intent | Role | Light | Dark | | --- | --- | --- | | Canvas | `#ffffff` | `#141818` | | Card / popover | `#ffffff` | `#1c2424` | | Surface | `#f7f7f7` | `#1a2222` | | Primary | `#29a19c` (unchanged) | `#29a19c` | | Secondary | `#044343` | `#243535` | | Borders | `#e4e4e4` | white @ ~12% alpha | | Muted text | `#5c5c5c` | `#999999` | Primary brand teal stays constant for recognition; surrounding neutrals shift. ## Implementation rules 1. Style with semantic tokens only (`bg-background`, `text-muted-foreground`, `border-border`, …). 2. Use `dark:` variants only when semantic tokens are insufficient (e.g. `dark:hover:shadow-glow-primary`, header glass tweaks). 3. Never gate entire components behind duplicated light/dark markup trees unless media differs (`next/image` theme backgrounds). 4. Test both themes before shipping UI. 5. Charts and decorative strokes should use `chart-*` or primary mixes that remain visible on dark surfaces. ## Transitions Body background/color transitions use `0.3s ease`. Do not disable theme transitions globally (`disableTransitionOnChange={false}`). ## Forbidden - `bg-white text-black` hardcodes. - `dark:bg-black` overrides that fight the teal-neutral system. - Assuming pure inversion of light colors will look correct. ## Related - [colors.md](./colors.md) - [accessibility.md](./accessibility.md) - [gradients.md](./gradients.md)