Design tokens
All values (colors, sizes, radii, shadows, spacing) are CSS custom properties defined in
tokens.css. Components never use hardcoded values —
they always reference a token. Override any token to adapt WebBlocks UI to your brand.
Rule: Always use tokens in your own components too.
Never hardcode a color, size, or radius that could change with a theme switch.
Surfaces & text
| Token | Default (light) | Usage |
| --wb-bg | #f4f6fb | Page background |
| --wb-surface | #ffffff | Cards, panels, modals |
| --wb-surface-2 | #edf1f7 | Subtle backgrounds, table rows |
| --wb-surface-3 | #e2e8f2 | Hover states, dividers |
| --wb-text | #18212f | Primary text |
| --wb-muted | #5a6a84 | Secondary text, labels, placeholders |
| --wb-border | #d6e0ee | All borders and dividers |
Semantic colors
| Token | Variants | Usage |
| --wb-success | -dark · -soft | Success alerts, badges, icons |
| --wb-warning | -dark · -soft | Warning alerts, caution states |
| --wb-danger | -dark · -soft | Error states, destructive actions |
| --wb-info | -dark · -soft | Informational alerts, hints |
Spacing scale (4px base)
| Token | Value | Token | Value |
| --wb-s1 | 4px | --wb-s8 | 32px |
| --wb-s2 | 8px | --wb-s10 | 40px |
| --wb-s3 | 12px | --wb-s12 | 48px |
| --wb-s4 | 16px | --wb-s16 | 64px |
| --wb-s5 | 20px | --wb-s20 | 80px |
| --wb-s6 | 24px | — | — |
Border radius
| Token | Value |
| --wb-r-sm | 5px |
| --wb-r-md | 9px |
| --wb-r-lg | 14px |
| --wb-r-xl | 20px |
| --wb-r-full | 9999px (pill/circle) |
Typography
| Token | Description |
| --wb-font | Body font stack (Inter, system-ui fallbacks) |
| --wb-font-heading | Heading font stack (same as body by default) |
| --wb-font-mono | Monospace stack (Cascadia Code, Menlo, Consolas) |
| --wb-font-size-xs/sm/md/lg/xl | 0.75 / 0.875 / 1 / 1.125 / 1.25 rem |
Shadows
| Token | Usage |
| --wb-shadow-sm | Subtle lift (cards, inputs) |
| --wb-shadow-md | Dropdowns, popovers |
| --wb-shadow-lg | Modals, drawers |
| --wb-shadow-xl | Command palette, elevated overlays |
Z-index scale
| Token | Value | Usage |
| --wb-z-dropdown | 100 | Dropdowns, popovers, tooltips |
| --wb-z-modal | 200 | Modals, drawers, confirmation dialogs |
| --wb-z-toast | 300 | Toast notifications |
Overriding tokens
Override any token in your own CSS by targeting :root
or a scoped selector:
/* Global override */
:root {
--wb-font: 'Geist', sans-serif;
--wb-r-md: 12px;
}
/* Scoped override — only affects one section */
.my-hero {
--wb-accent: #8b5cf6;
}
Accent colors
Set data-accent on the <html>
element to switch the entire UI to a different color scheme. Each accent defines 12 tokens.
Click a swatch above to preview the accent on this page.
Accent token set (12 tokens per accent)
| Token | Usage |
| --wb-accent | Primary accent — button backgrounds, active states |
| --wb-accent-hover | Hover state for accent-colored elements |
| --wb-accent-active | Active / pressed state |
| --wb-accent-soft | Tinted background (badges, chips) |
| --wb-accent-softer | Very light tint (page sections, callouts) |
| --wb-accent-border | Accent-tinted border |
| --wb-accent-text | Accent text on light background |
| --wb-accent-on | Text color on accent background (always white or near-white) |
| --wb-accent-ring | Focus ring color |
| --wb-accent-ring-rgb | RGB values for rgba() focus ring with opacity |
| --wb-accent-selection | Text selection background |
| --wb-accent-glow-rgb | RGB values for glow effects |
Backward compatibility: --wb-primary,
--wb-primary-dark, and --wb-primary-soft
are aliases that map to their --wb-accent* equivalents.
In new code, always use --wb-accent*.
Dark mode
Dark mode is controlled by the data-mode attribute on
<html>. Three values are supported.
| Value | Behaviour |
| light | Always light mode |
| dark | Always dark mode |
| auto | Follows prefers-color-scheme system setting |
How dark mode works
Dark mode overrides surface, text, and border tokens via a
[data-mode="dark"] selector in dark.css.
All component styles automatically inherit the new values — there are no separate dark-mode class variants needed.
<!-- Static -->
<html data-mode="dark">
<!-- Toggled by the user -->
<button data-wb-mode-cycle>Toggle mode</button>
<!-- Set programmatically -->
<script>WBTheme.setMode('dark');</script>
localStorage persistence: WBTheme persists the user's
mode preference in localStorage under the key
wb-mode and restores it on next page load.
Set the initial data-mode in HTML to avoid a flash of the wrong mode.
Presets
Presets are named bundles that set multiple axes at once — radius, shadow, density, font, and border.
Use them as starting points for a consistent look; individual axes can still override any preset value.
| Preset | Radius | Shadow | Density | Font | Border |
| modern | default | default | default | modern | subtle |
| minimal | sharp | flat | compact | system | subtle |
| rounded | soft | soft | comfortable | modern | none |
| bold | sharp | default | default | modern | bold |
| editorial | sharp | flat | comfortable | editorial | medium |
<!-- Apply "rounded" preset, override accent only -->
<html data-preset="rounded" data-accent="rose">
<!-- Apply "minimal", override radius to soft -->
<html data-preset="minimal" data-radius="soft">
Presets are applied in CSS cascade order before individual axis attributes,
so individual axes always win.
Theme axes
Beyond dark mode and accent, five additional axes let you tune the visual personality of your UI.
Radius — data-radius
| Value | Effect |
| sharp | Reduces all border radii — more structured, enterprise feel |
| soft | Increases all border radii — friendly, consumer-facing feel |
Density — data-density
| Value | Effect |
| compact | Reduces padding across buttons, inputs, table rows — more content per screen |
| comfortable | Increases padding — more breathing room, better for touch |
Shadow — data-shadow
| Value | Effect |
| flat | Removes shadows — border-based depth, clean and minimal |
| soft | Increases shadow blur and opacity — more elevated, premium feel |
Font — data-font
| Value | Font stack |
| system | Native OS font stack — no web font loaded |
| modern | Inter (CDN) — clean, highly legible |
| editorial | Playfair Display (CDN) + Inter — editorial, publishing feel |
Border — data-border
| Value | Effect |
| none | Removes borders — surfaces defined by shadows only |
| subtle | Light borders (default) |
| medium | Medium-weight borders |
| bold | Heavy borders — strong visual structure |
| dashed | Dashed borders — distinctive, technical feel |
Combining all axes
<!-- Maximum customisation without a single line of custom CSS -->
<html
data-mode="dark"
data-accent="royal"
data-preset="rounded"
data-density="comfortable"
data-font="modern"
>
Custom token overrides
For brand-specific customization that goes beyond the built-in axes, override tokens directly in your own CSS.
/* ── Brand font ──────────────────────────────────── */
:root {
--wb-font: 'DM Sans', sans-serif;
--wb-font-heading: 'DM Serif Display', serif;
}
/* ── Custom accent (outside the 8 built-ins) ─────── */
:root {
--wb-accent: #0f766e;
--wb-accent-hover: #0d6e66;
--wb-accent-active: #0b605a;
--wb-accent-soft: #ccfbf1;
--wb-accent-softer: #f0fdf4;
--wb-accent-border: #5eead4;
--wb-accent-text: #0d6e66;
--wb-accent-on: #ffffff;
--wb-accent-ring: rgb(15 118 110);
--wb-accent-ring-rgb: 15 118 110;
--wb-accent-selection: #ccfbf1;
--wb-accent-glow-rgb: 15 118 110;
}
/* ── Tighter spacing for a dense data grid ───────── */
.my-data-table {
--wb-s3: 0.5rem;
--wb-s4: 0.75rem;
}