How palette tokens work
Change a component's colours three ways, without editing its source. Variants, public CSS variables and private scoped variables, and how they fit together.
- customization
- tailwind
- css-variables
Colour is the first thing most people change when they adopt a component. We wanted that change to be possible without editing source, without a runtime theme provider, and without a component leaking colours into the rest of your site. The result is a small token system with three layers.
Layer one: variants are chosen at download time #
A component declares a set of variants, such as neutral or blue, and one default. A variant is a list of palette overrides for light mode, dark mode, or both.
The important detail is when a variant is applied. The catalogue exports every variant separately, so each one is its own artifact with its own digest. When you choose a variant, the colours are already in the files you receive. There is nothing to configure at runtime.
Variant values are also deliberately boring. They must be literal colours, either hex or oklch(...):
{
"id": "blue",
"label": "Blue",
"overrides": {
"light": { "accent": "oklch(0.55 0.18 260)" },
"dark": { "accent": "#60a5fa" }
}
}A variant cannot inject a selector, a URL or arbitrary CSS into exported code, because the schema rejects anything that is not a colour.
Layer two: public variables for your overrides #
Each customizable colour is a token with a key, such as accent, and a public variable, such as --component-accent. The public variable is the supported way to override a colour after you have copied the component.
Set it on any ancestor:
<section style="--component-accent: #0f766e">
<FeatureGrid {features} />
</section>Or set it once in your own stylesheet:
:root {
--component-accent: #0f766e;
}Because CSS custom properties inherit, the override applies to that component wherever it sits inside the element you chose, and to nothing else that does not read the variable.
Layer three: private variables inside the component #
Inside the component, each token also has a private variable, such as --_accent, declared in the entry file's scoped <style> block. The token's metadata lists the exact selectors where that declaration lives for light and dark mode.
The private variable is the component's internal name for the colour, and the selectors listed in the metadata show exactly how the public variable feeds into it in each mode. Treat private variables as implementation details: set the public one.
Where Tailwind fits #
The component's layout, spacing and typography are ordinary Tailwind utility classes in the markup. Tokens cover colours that are meant to be themed. If you want to change something that is not a token, edit the classes directly. It is your source now.
Check contrast after every change #
Whatever palette you start from, a token override is a new colour combination that nobody else has checked. After changing a colour, re-check text and control contrast in every appearance mode you enable. The accessibility responsibilities page has a short checklist.
The token names used in this article are illustrative. Each component lists its public tokens under Customization, and the customization guide covers the full picture.