Theming Components - Krate Docs
You're viewing an older version ().
Krate Docs

Recolour @krate/components with CSS custom properties.

#Theming Components

Every @krate/components style reads --krate-* CSS custom properties, so a whole theme change is just a few declarations. You usually only need to set one variable:

:root {
  --krate-primary: #6366f1;
}

Hover states, focus rings, active tabs/radios/toggles, and the compiler's CSS-signal active colours are all derived from --krate-primary, so they update automatically.

#Why overrides always work

The library's defaults are emitted at zero specificity (:where(:root){…}), so any rule of yours — a plain :root, [data-theme], a wrapper class, whatever — wins no matter which stylesheet loads first. There is no ordering footgun.

Tip

Put your overrides in a global stylesheet (e.g. src/styles/global.css). They beat the bundle even if the bundle loads later.

#Quick start

:root {
  --krate-primary: #6366f1;   /* accent: buttons, links, checkboxes, active state */
  --krate-radius: 10px;       /* corner radius */
}

Dark mode is handled per scheme; override it the same way if needed:

@media (prefers-color-scheme: dark) {
  :root { --krate-primary: #818cf8; }
}

#Tokens

#Brand

TokenDefaultDerived?
--krate-primary#f97316— (set this)
--krate-primary-hoverprimary darkened 15%yes
--krate-primary-fg#ffffffno (text on primary)
--krate-focus-ringvar(--krate-primary)yes
--krate-danger / --krate-danger-hover#ef4444 / derivedhover derived
--krate-success#22c55eno
--krate-warning#f59e0bno

#Surfaces and text

TokenLightDark
--krate-bg#ffffff#09090b
--krate-fg (aliased by --krate-text)#09090b#fafafa
--krate-muted (aliased by --krate-text-muted)#71717a#a1a1aa
--krate-surface#f4f4f5#18181b
--krate-surface-hover#e4e4e7#27272a
--krate-border#e4e4e7#27272a
--krate-card-bg#ffffff#18181b
--krate-overlayrgba(9,9,11,.4)rgba(0,0,0,.6)

#Layout and code

TokenDefault
--krate-fontInter, system-ui, …
--krate-radius / --krate-radius-lg8px / 12px
--krate-code-bg / --krate-code-text#18181b / #fafafa

#Light and dark

The defaults follow the OS via prefers-color-scheme, and can be forced with a data-theme attribute on <html>:

<html data-theme="dark">

[data-theme="dark"] / [data-theme="light"] win over the media query. Your own overrides (zero-superseding) still win over both.

#Per-component tweaks

Any component class can be styled directly — the theme sets the baseline:

.krate-button-primary { border-radius: 9999px; }
.krate-card { box-shadow: 0 8px 30px rgba(0, 0, 0, 0.08); }

#CSS signals

Active tabs, selected radios, and pressed toggles use --krate-css-active (falling back to --krate-primary) and the derived --krate-active* colours, so changing --krate-primary recolours them too. To style the active state independently, set --krate-css-active (and optionally --krate-css-active-fg).

#With Tailwind

Because the tokens are plain CSS variables, Tailwind v4's @theme can consume them:

@theme {
  --color-brand: var(--krate-primary);
}

Last updated: 2026-10-16

Contributors: Noinkin