Dark Theme

dark-themeFeatures15 lines

System-aware light/dark theming with a manual override, one hook for the whole app.

Current — as published in v1.3.2. Written by hand for Dark Theme, not generated.

The rule

  • Read colors through useTheme() / themeTokens[theme] — never hardcode a hex value in a component. A hardcoded #ffffff background is invisible in light mode and a solid white box in dark mode.
  • Three states, not two: light, dark, system. Default to system — overriding it should be something a user opts into, not the starting state.
  • The provider renders nothing (mobile) or nothing themed (web, via data-theme) until the stored preference loads. Do not remove that guard to "fix" a perceived flash — removing it reintroduces the flash it exists to prevent.
  • On web, toggle the theme via the data-theme attribute on <html>/documentElement, never a class — it is what [data-theme="dark"] selectors in CSS expect, and changing the mechanism silently breaks every rule written against it.

As each tool receives it

The same guidance, in the shape each editor reads. Cursor and Claude Code are written separately by hand; the rest are derived from the Cursor rule.

.cursor/rules/dark-theme.mdchand-written for this tool
.cursor/rules/dark-theme.mdc
---
description: Dark theme conventions
globs: ["src/theme/**/*.ts", "src/theme/**/*.tsx"]
alwaysApply: false
---

# Dark Theme

- Read colors through `useTheme()` / `themeTokens[theme]` — never hardcode a
  hex value in a component. A hardcoded `#ffffff` background is invisible in
  light mode and a solid white box in dark mode.
- Three states, not two: `light`, `dark`, `system`. Default to `system` —
  overriding it should be something a user opts into, not the starting state.
- The provider renders nothing (mobile) or nothing themed (web, via
  `data-theme`) until the stored preference loads. Do not remove that guard
  to "fix" a perceived flash — removing it reintroduces the flash it exists
  to prevent.
- On web, toggle the theme via the `data-theme` attribute on
  `<html>`/`documentElement`, never a class — it is what `[data-theme="dark"]`
  selectors in CSS expect, and changing the mechanism silently breaks every
  rule written against it.

What else this module writes

Selecting Dark Theme contributes more than a rule file — all of it merged with every other module you pick, with conflicts resolved rather than duplicated.

Dependencies
Depends on the rest of the stack — this module installs different packages depending on what else you select, so there is no single list to show.
Folders
src/theme/
Put this in your repo

Adds Dark Theme to a project this tool generated, without starting over. Files you have hand-edited are left alone.