Skip to content

Dark Mode

How Cynosure implements dark mode as a semantic-token override — opt in once at the root and every component follows.

Dark mode in Cynosure is a semantic-token override, not a component prop. You opt in once at the root and every component follows.

import '@arshad-shah/cynosure-tokens/css'; // base + light
import '@arshad-shah/cynosure-tokens/css/dark'; // dark overrides
<ThemeProvider themes={['light', 'dark']} defaultTheme="system">
{children}
</ThemeProvider>

defaultTheme="system" matches the OS / browser preference via prefers-color-scheme: dark. Users can override with setTheme('dark') and Cynosure persists the choice.

Render the init script in the document <head> so the theme is applied before React hydrates — this avoids a light-then-dark flash on reload.

The getThemeInitScript() function exported from @arshad-shah/cynosure-react returns an inline script string. Embed it in your <head> before your framework’s React root boots.

@arshad-shah/cynosure-tokens/css/dark scopes its overrides to [data-theme='dark']. ThemeProvider writes data-theme="dark" on the <html> element when the resolved theme is dark. Every Cynosure component reads its colours from semantic tokens like --cynosure-color-accent-solid which are re-pointed by the dark stylesheet.

The practical implication: consumer CSS that uses Cynosure tokens gets dark mode for free. No .dark .my-component { … } rules to write.

ThemeProvider also sets the CSS color-scheme property to match the resolved theme. That hints the browser to render form controls, scrollbars, and the native :focus ring in the correct palette.

  • Images and media. Tokens cover colour; media you ship (screenshots, illustrations) may need light + dark variants. Use the CSS prefers-color-scheme media query or a React hook (useTheme()) to pick.
  • Third-party components. Components outside Cynosure read their own colour system. Wrapping them in Cynosure tokens requires a small CSS bridge.