Theme
Design your own
On this page (11)
Design your own theme

The Theme Designer edits every token on this site's own components and its six example apps, live - colours for light and dark, Google Fonts, radius, shadows. Save it by name to this site's theme menu, or export the CSS for your project.

§Surface / Foreground pairs

Every surface token pairs with a foreground token for text/icons placed on it.

§Utility tokens

--bordervar(--border)
--inputvar(--input)
--ringvar(--ring)

§Radius scale

Set --radius to retheme all border radii. The derived values are computed from it.

--radiusbase (0.625rem)
--radius-smradius − 4px
--radius-mdradius − 2px
--radius-lgbase (--radius)
--radius-xlradius + 4px

§Sidebar tokens

Full sidebar token set for sidebar-specific theming. Same surface/foreground pair convention.

§Chart tokens

Five chart colors for data visualization.

--chart-1var(--chart-1)
--chart-2var(--chart-2)
--chart-3var(--chart-3)
--chart-4var(--chart-4)
--chart-5var(--chart-5)

§Typography tokens

Font stacks as CSS custom properties. Themes can override these to change typography globally.

The quick brown fox--font-sansvar(--font-sans)
The quick brown fox--font-serifvar(--font-serif)
The quick brown fox--font-monovar(--font-mono)

§Shadow scale

Theme-aware shadows available as CSS custom properties.

--shadow-2xsvar(--shadow-2xs)
--shadow-xsvar(--shadow-xs)
--shadow-smvar(--shadow-sm)
--shadowvar(--shadow)
--shadow-mdvar(--shadow-md)
--shadow-lgvar(--shadow-lg)
--shadow-xlvar(--shadow-xl)
--shadow-2xlvar(--shadow-2xl)

§Spacing & Tracking

Base units that control all spacing and letter-spacing utilities.

--spacing0.25rem (4px)
Aa Bb Cc--tracking-normal0em

§Customization

There are two ways to customize the theme:

1. Swap the entire theme

Design the theme, export its :root and .dark CSS variable blocks, and load them after (or instead of) default-semantic-tokens.css. Every component updates instantly. Two tools write that shape:

  • The Theme Designer (recommended) - built into these docs. You see the theme on this system's components while you design it: the whole site follows every edit, and a preview shows a sample of every section at once - or a whole example app (Admin Dashboard, Messenger, Issue Tracker, Notes & Docs, Status Page, Desktop) - and doubles as the editor: click a colour to change it. Contrast badges flag text that fails WCAG AA on its surface; the radius is the same in light and dark (as every theme here must be); any Google Font can be picked, and the export carries its @import. Save a theme by name and it sits on top of this site's theme menu, in your browser - or import a tweakcn export and refine it here.
  • tweakcn.com - works too: its exports use the same token names, so they drop in unchanged. Its preview renders shadcn/ui's React components, not these, so check the result here (paste it into the designer's Import).
Open the Theme Designer

2. Override individual tokens

Add a stylesheet afterdefault-semantic-tokens.css and override specific variables:

<link rel="stylesheet" href="default-semantic-tokens.css">
<style>
  :root {
    --primary: oklch(0.55 0.2 250);
    --primary-foreground: oklch(1 0 0);
    --radius: 0.5rem;
  }
</style>

§Theme files

Every tweakcn preset ships as a generated stylesheet in dist/theme/<id>.css - the same :root + .dark token shape as default-semantic-tokens.css. Link one instead of the token file to ship a fixed theme:

<!-- instead of theme/utils/default-semantic-tokens.css -->
<link rel="stylesheet" href="theme/claude.css" />

...or load it at runtime on top of the token file - inserting a <link id="theme-css"> right after it re-themes every component instantly (later source order wins the cascade; the file's own .dark block keeps dark mode working, so no re-apply on toggle). The Theme Switcher component wraps exactly that mechanism in an accessible dropdown, with persistence (a df$.store.persisted store) and a State API. On this site the picker in the header does the same.

// the preset link sits right after the token file - later source order wins
df$('#theme-css').remove();
df$('link[href$="default-semantic-tokens.css"]')
  .after('<link id="theme-css" rel="stylesheet" href="theme/claude.css">');
// presets with fonts ship a resource sidecar - loadTheme() adds those <link>s too
df$.shadcn.loadTheme?.('claude');

The preset files are generated from the docs' theme dataset (src/documentation/runtime/themes.ts) by scripts/build.ts - verify's theme files fresh gate keeps them in lockstep. For your own themes, export one from the Theme Designer (or tweakcn) and link it the same way.

§Dark mode

The theme file includes both :root (light) and .dark (dark) values. To toggle dark mode, add or remove class="dark" on the <html> element. Every token switches automatically - no per-component overrides needed. See the Dark Mode page for system preference detection, persisting the choice (a df$.store.persisted store), and a step-by-step toggle implementation.

Comments, ideas or improvements? Edit this page's source on GitHub