Docs
Theming
Components only use colour tokens, never raw colours. Change the tokens and every component follows, in both themes.
Tokens
| Token | Used for | Light | Dark |
|---|---|---|---|
| --background / --foreground | Page | #f4f1ea / #11110f | #0f0f0d / #f2efe7 |
| --card | Panels | #ffffff | #191916 |
| --muted / --muted-foreground | Quiet fills, secondary text | #ebe7dd / #5f5b52 | #24231f / #a7a294 |
| --primary | Main buttons, done states | #11110f | #f2efe7 |
| --border / --input / --ring | Lines, fields, focus | #dcd6c8 / #d3ccbb / #ff5a1f | #302f2a / #3a3832 / #ff6b35 |
| --destructive | Reject, errors | #d23a26 | #ff5b45 |
| --signal | Needs a human. The Loopkit accent. | #ff5a1f | #ff6b35 |
| --ok | Approved, passing, healthy | #138a4b | #3ccf7d |
| --warn | Near a limit, medium risk | #c98a00 | #f2b632 |
| --info | Tasks, tools, agents | #2952ff | #7b93ff |
The first seven rows are standard shadcn tokens. If you already use shadcn, your values win and only the last four are new.
Adding the Loopkit tokens by hand
css
:root {
--signal: #ff5a1f;
--signal-foreground: #ffffff;
--ok: #138a4b;
--warn: #c98a00;
--info: #2952ff;
}
.dark {
--signal: #ff6b35;
--signal-foreground: #11110f;
--ok: #3ccf7d;
--warn: #f2b632;
--info: #7b93ff;
}
@theme inline {
--color-signal: var(--signal);
--color-signal-foreground: var(--signal-foreground);
--color-ok: var(--ok);
--color-warn: var(--warn);
--color-info: var(--info);
}Rebrand in one line
--signal is the colour for “a human is needed”. Set it to your brand accent. Keep it different from --destructive so a request never looks like an error.
Fonts
Labels and data use font-mono. Big numbers use font-display; if you don't define it, they fall back to your sans font. This site uses Bricolage Grotesque, Geist and JetBrains Mono.
Dark mode
Components read the .dark class through the tokens. They don't need a theme provider.