Themes

A theme in PresetUI is a list of colour values — nothing more. There is no theme provider, no config file, and no JavaScript involved. Every component reads the same tokens, so replacing the values replaces the look of the whole kit.

Palettes

Click a palette to apply it to this page. The docs chrome changes too, because the site is built from the same components you'd be copying.

click a palette to apply it

Neutrallight
Midnightdark
Oceanlight
Emberdark
Paperlight
Violetdark

The two tiers

Core tokens are required. Every component reads them, and a missing one breaks that component everywhere.

TokenUsed for
--color-surfacePage and component backgrounds
--color-fgPrimary text
--color-mutedSecondary text, placeholders, icons
--color-borderBorders, dividers, subtle fills
--color-accentPrimary buttons, selected states, focus rings
--color-accent-fgText on top of accent
--color-dangerDestructive actions and error states

Optional tokens power specific variants. They ship in the theme file, but you can delete them if you don't use the variants that need them.

TokenNeeded by
--color-successAlert and Badge, variant="success"
--color-warningAlert and Badge, variant="warning"

If you delete an optional token and use its variant anyway, the background renders empty. Tailwind can't generate a utility for a token that doesn't exist, and it fails quietly rather than erroring.

Dark mode

Dark mode is not a second set of tokens — it is the same names with different values, applied under a dark class on <html>:

@theme {
  --color-surface: #ffffff;
  --color-fg: #0a0a0a;
}

.dark {
  --color-surface: #0a0a0a;
  --color-fg: #fafafa;
}

That is why no component contains a single dark: utility. They don't know which mode they're in, and they don't need to.

Adding your own token

Define it alongside the others, then use it in a component like any Tailwind colour:

@theme {
  --color-brand: #6d28d9;
  --color-brand-fg: #ffffff;
}
<button className="bg-brand text-brand-fg">Upgrade</button>

Remember to add the value under .dark too, or your token will keep its light value when the rest of the page goes dark.

Building a palette that holds up

The kit's contrast comes from the relationship between the tokens, not from any single value: