Theming
Nothing in a component says dark:, and nothing
hardcodes a hex value. Every utility is built on tokens, so the whole system moves together.
Eight tones
Every tonal component takes the same tone prop.
<Button tone="danger">Delete</Button>
<Badge tone="warning" dot>Quota</Badge>
<Alert tone="success" title="Deployed" />
<Progress tone="violet" value={40} />Four steps each
Base, hover, light (a tinted surface) and border. Every one is a Tailwind utility: bg-accent, hover:bg-accent-hover, bg-accent-light, border-accent-border.
@theme {
--color-brand: #1c6358;
--color-brand-hover: #155047;
--color-brand-light: #e8f3f1;
--color-brand-border: #a8ccc5;
/* …and the same four steps for the other seven tones */
}The token names are the contract every style fills in — core and all 65 components are
written against them, so a style only ever changes the values. That is also why exactly one
style's theme.css may be imported: two would fight over
every colour.
Making it yours
Redeclare any token after importing the style's theme. Nothing else has to change — every
component reading brand follows, in whichever style
you picked.
@import 'tailwindcss';
@import '@nqmcreative/ui/matte/theme.css';
/* your brand, on top of the style's defaults */
@theme {
--color-brand: #0f766e;
--color-brand-hover: #115e59;
--color-brand-light: #ecfdf5;
--color-brand-border: #99f6e4;
}If you find yourself overriding most of the palette, that is a new style rather than a theme override — copy a style folder and change its markup too.
Light and dark
The root element decides:
| root | result |
|---|---|
| <html> | light — the default, on any OS |
| <html class="dark"> | dark, explicitly opted in |
ThemeToggle writes that class and remembers
the choice under nqm-theme:
<script lang="ts">
import { ThemeToggle } from '@nqmcreative/ui/matte';
</script>
<ThemeToggle />
<ThemeToggle variant="segmented" />One light frame on first load
app.html from the installation page prevents it — and its
key has to match what ThemeToggle writes.In your own components
Import the tone maps rather than writing colour classes by hand.
<script lang="ts">
import { toneSoft, toneFill, type Tone } from '@nqmcreative/ui/core';
let { tone = 'brand' }: { tone?: Tone } = $props();
</script>
<div class={toneSoft[tone]}>…</div>Never interpolate a class name
<!-- Tailwind only sees literal class strings -->
<div class="bg-{tone}">…</div> <!-- generates nothing -->
<div class={toneFill[tone]}>…</div> <!-- correct -->