Theming
Light, dark and your brand – all about tokens, nothing about selectors.
Two themes, one token set
All colours come from --nk-* tokens. The light theme lives on :root, the dark one on [data-theme="dark"]. The theme toggle in the header sets the attribute and remembers the choice in the browser.
Without JavaScript the page follows the system preference: a generated mirror of the dark block applies via prefers-color-scheme.
Setting your brand
The one line that recolours everything:
:root { --nk-accent: #2f8f5b; }
[data-theme="dark"] { --nk-accent: #5cbf87; }
@media (prefers-color-scheme: dark) {
:root:not([data-theme]) { --nk-accent: #5cbf87; }
}
The third block is the no-JS path. Forget it and, without JavaScript and with a dark OS preference, the brand stays on the foundation blue.
Colour roles: tag, tint, colour
Each of the nine hues (gray, brown, orange, yellow, green, blue, purple, pink, red) comes in three roles:
| Token | Role | Example |
|---|---|---|
--nk-tint-<hue> | soft surface | notice banners, highlight pill, progress tracks |
--nk-color-<hue> | coloured text and marks | code tokens, deltas, the “copied” state |
--nk-tag-<hue>-bg / -text | the pair of a .nk-tag | status chips in tables |
The tag tokens belong together: the tag text is near-black on a saturated fill and does not work as a text colour. To tint a surface or colour a text, use tint or colour.
What you should not do
- Write colour values directly into components – the guard
npm run check:colorswill complain. - Set tokens on a subtree – custom properties are replaced where they are declared and never reach the
:roottokens. - Copy or edit
notionkit.css– updates are a version bump.
Serif headlines
If you like the look of twenty.com: set --nkw-font-display in brand.css to a serif stack. Body text stays system sans.