Colors
Neutral ink for almost everything, and one accent for the few things that should stand out.
Warm neutrals and a few clear colors. Lower steps are lighter. The ramps stay the same in both themes; what changes is which step each role picks.
Ink and accent
Most of an interface is text, surfaces, and controls, and all of that is neutral. The main action is the darkest thing on the page, so it needs no color to be found.
Invite teammates
Theyโll join as editors. About roles
The accent, primary, is for state and direction: a checked box, a link, keyboard focus, and the rare brand action such as upgrading. Because it appears so seldom, it always means something.
Do
Ink carries the action. The accent marks only whatโs on and where to go.
Donโt
When every button is the accent, none of them leads, and the link gets lost.
The roles
Components never reach for a shade directly. They use roles, and each theme decides which shade fills each role. Switch the theme in the header and every swatch below changes with it.
Surfaces
Text
Controls
Accent
Status
Lines and code
Build it
The theme file sets each role once per theme. Components only ever name the role:
123456789101112:root { --primary: var(--blue-600); --primary-foreground: var(--neutral-0); --control: color-mix(in srgb, var(--neutral-1000) 4%, transparent);}
.dark { --primary: var(--blue-600); --control: color-mix(in srgb, var(--neutral-0) 6%, transparent);}
/* Components use bg-primary, bg-control, text-muted-foreground. */To use your own accent, override primary, its hover and foreground, and ring after the theme import. Then check the contrast in both themes.
12345678910111213:root { --primary: var(--green-700); --primary-hover: var(--green-800); --primary-foreground: var(--neutral-0); --ring: var(--green-700);}
.dark { --primary: var(--green-300); --primary-hover: var(--green-200); --primary-foreground: var(--green-950); --ring: var(--green-300);}Dark mode is one class on the root element. Set it before the first render to avoid a flash.
1document.documentElement.classList.toggle("dark", isDark)