Build
Theming
A handful of tokens carry the whole look. Change the accent, the radius or the typeface once, and every component follows in light and dark.
On this page
Tokens#
Components never use fixed colors, only tokens. Every token has one value for light and one for dark, so every component works in both modes without an extra line. As Tailwind classes they look like this.
| Class | Paired with | What it does |
|---|---|---|
| bg-background | text-foreground | The page and its text. |
| bg-surface, bg-surface-2 | text-foreground | Quiet areas set off from the page, such as a band or a code panel. |
| bg-card | text-card-foreground | Cards and panels. |
| bg-muted | text-muted-foreground | Muted areas and secondary text. |
| border-border | border-border-strong | Hairlines, and the stronger edge on hover. |
| bg-primary | text-primary-foreground | The accent, for the main button and active states. |
| text-success, text-destructive | bg-warning, text-info | States such as saved, error, warning and note. |
Every value with swatches is on the Theming page. Shadows come through shadow-[var(--shadow-sm)] up to --shadow-lg, the light top edge through var(--highlight).
Accent#
The accent colors main buttons, active states, chart lines and small lights. Seven ready accents are there, data-accent picks one, on the html element for the whole page or on any other element for just that area.
- Blueblue
- Violetviolet
- Cyancyan
- Emeraldgreen
- Sunsetorange
- Roserose
- Neutralneutral
<html class="dark" data-accent="violet">
<!-- Only this area in green -->
<section data-accent="green">…</section>Dark mode as the default#
The kit starts dark. Without a class kit.css shows light mode, class="dark" on the html element switches to dark. Write the class straight into the markup and dark mode is there with the first paint.
<html lang="en" class="dark" data-accent="blue">When visitors may switch, a small script in the head remembers the choice. A toggle only flips the class.
<script is:inline>
// In <head>, before the first paint. Dark stays unless someone chose light.
const saved = localStorage.getItem('theme');
document.documentElement.classList.toggle('dark', saved !== 'light');
</script>function toggleTheme() {
const dark = document.documentElement.classList.toggle('dark');
localStorage.setItem('theme', dark ? 'dark' : 'light');
}Your own brand color#
Your brand color becomes the accent, tuned for light and dark.
Compute the color system
aiw theme --colors brand=#1f6febaiw themecomputes an OKLCH scale in eleven steps, measures the WCAG contrast of every step and writessrc/styles/theme.csswith the accent for both modes, plus DTCG tokens intokens/colors.tokens.json.Import it after kit.css
/* src/styles/global.css */ @import "tailwindcss"; @import "@fontsource-variable/inter"; @import "./kit.css"; @import "./theme.css";Leave out data-accent
With your own color the html element carries only
class="dark". A ready accent would win over your color in dark mode.
By hand it is two tokens per mode. In the color lab you set them with sliders and copy the CSS.
:root {
--primary: oklch(0.56 0.17 200);
--primary-foreground: oklch(0.985 0 0);
}
.dark {
--primary: oklch(0.69 0.14 200);
--primary-foreground: oklch(0.18 0.03 200);
}Radius#
One value drives every corner. --radius is the base, rounded-sm up to rounded-2xl follow from it. Smaller values look factual, larger ones soft.
:root {
--radius: 0.5rem; /* default 0.75rem */
}Typeface#
The kit works with one typeface for everything, code included, figures set tabular. The stack starts with SF Pro Display on Apple devices and takes Inter everywhere else, self-hosted by aiw add kit.
Bring your own typeface with aiw fonts add, self-hosted with fallback metrics against layout shift, and set it as --font-sans.
aiw fonts add Manrope:root {
--font-sans: "Manrope Variable", system-ui, sans-serif;
}