Colors
Summary
No colour is picked by hand. A few seeds go in, and Material Design 3 computes every role from them, for light and dark alike. shadcn's tokens are then pointed at those roles.
The swatches below are live: toggle the scheme of this site to see the dark palette.
Seeds
Everything on this page derives from these, in
md3.ts:
colorMatch is Material Theme Builder's "stay true to my color inputs": each seed keeps its
chroma, and lands in its container role. It takes the place of a scheme. The two neutral seeds
look nothing like the grey ramps they produce, by design: under colorMatch a neutral ramp takes
an eighth of its seed's chroma, so a seed carries eight times what comes back.
The posters below follow the same seed: this site's theme is built from it, colorMatch, the
neutrals and error included, so what they render is the palette md3.ts ships.
Poster
Material's scheme poster of the palette: each
role, and on it the role meant to go on it. Every one is a Tailwind colour, bg-<role> /
text-<role>.
shadcn tokens
shadcn's tokens keep their names: bg-background, text-primary, border-border… all work as
usual. Each one is pointed at an MD3 role, the same poster with shadcn's names on it:
The sidebar-* tokens follow their counterparts: sidebar-primary is primary,
sidebar-accent is accent, sidebar-border is border, sidebar-ring is ring.
Everything shadcn has no name for is there too, under its MD3 name: bg-surface-dim,
bg-tertiary-container, text-on-surface-variant…
Custom colours
Colours Material has no role for — a brand palette, status levels — are declared next to the
seeds, as customColors. Each one becomes four roles, <name>, on-<name>,
<name>-container and on-<name>-container, computed for light and dark like the others, plus
eleven shades, <name>-50 … <name>-950. blend harmonizes it toward the source seed;
without it the colour stays true to its hex. For custom colours of your own, do not edit the
installed md3.ts: spread pmndrsMtb into your config, add yours there, and name them in the
@plugin body — md3-base's docs walk through it.
Twelve are declared this way, in this order: the seven brand colours, then the five alert colours. The brand colours are not blended, the alert colours are.
Brand colours
The seven brand colours are none of them blended: each stays its exact hex. Lime is also the
source seed, and red also drives the error role. Their shade utilities take over Tailwind's
stock palettes of the same names.
Alert colours
The five alert colours are the design system's semantic roles. Use them for GitHub alerts
(> [!NOTE]…), hints, badges and statuses. They are seeded with GitHub's alert hues, so a
reader recognises them at a glance.
They are blended: each is pulled toward the source seed. So it keeps its meaning and still
sits in the palette, this one or that of any library that reseeds it. A brand colour would not
do. cyan is not a note, and unblended, its container is far too loud for an alert's
background.
Each seed can be overridden from the environment, as the primary can with THEME_PRIMARY; the
baked theme is always built without them, so it ships the seeds above.
To change any custom colour, edit customColors in
md3.ts, run
npm run build, and update these tables. The swatches above are this site's own theme, which
the docs engine computes with the same custom colours.
Tonal palettes
Under the roles sit Material's tonal palettes: one ramp per seed — primary, secondary,
tertiary, neutral, neutral-variant, error — and one per custom colour, each taken at the
same 28 tones, from 100, white, down to 0, black. A role is an alias onto one of these tones:
surface is neutral-98 in light and neutral-6 in dark, lime is lime-40 and lime-100.
The one exception is a container under colorMatch, in light: it is its seed's own hex, which
no tone of the ramp matches exactly.
The tones themselves have no scheme: the swatches below are the same in light and dark. Each one
is a CSS variable, --md-ref-palette-<palette>-<tone>, with no Tailwind utility of its own —
reach one with an arbitrary value, bg-(--md-ref-palette-neutral-variant-60). Prefer a role where
one fits: a role follows the scheme, a tone does not.
primarysecondarytertiaryneutralneutral-varianterrorlimetealcyanpurpleredorangeyellownotetipimportantwarningcautionFigma tokens
The same palette, for designers: light and dark as two modes of one Figma variable collection,
in DTCG files. Every role is the hex the CSS gives it, alias for
alias. Install them next to your code, into design/tokens/pmndrs/ at the root of your project:
pnpm dlx shadcn@latest add pmndrs/design-system/figma-tokens#v0.9.0Or download them: light, dark.
The same item carries the other foundations: type, spacing, radius and motion as a second variable
collection, Foundations.tokens.json,
and the text and shadow styles as a file for Tokens Studio,
Styles.tokens.json.
The item's
docs walk
through both imports.
Reseeding
The palette is computed, never written by hand: change the seeds in
md3.ts and run
npm run build; the baked CSS of the registry and the
Figma tokens follow.
For a palette of your own, install md3-base instead of theme and emit the roles from your seeds:
pnpm dlx shadcn@latest add pmndrs/design-system/md3-base#v0.9.0