Design System
My personal design system

One visual language
for everything I build.

Quiet by default, sharp on purpose.

Tokens are the core. Color, type, spacing, radius, motion. They map straight to CSS, Odoo, Android and Figma. Components use only tokens, so re-theming is a one-line change.

3
Portable layers
20+
Components
2
Themes, one core
0
Emoji, ever

Principles

Four rules keep it coherent.

The whole thing holds together because a few decisions are non-negotiable. Break one and it stops being reusable.

Tokens, never raw values

Components use var(--c-accent) and var(--sp-4), never hex or px. That's what turns a re-theme into a one-line change.

Core + themes

Spacing, type, radius and motion are shared and fixed. A theme only changes the --c-* color tokens. Nothing else moves.

Compounding, not copying

A new reusable pattern goes back into the system, never a one-off in some project. Every build leaves it a bit better than it found it.

No emoji. Icons are Lucide

Emoji render differently on every platform and can't be themed. Everything uses Lucide via .ds-icon. It inherits currentColor and sizes to the text.


Where it pays off

Why it matters with AI

Most of what I build now starts with a prompt. A design system keeps the output mine, not the model's.

AI stays on brand

Ask an LLM for a screen and it picks new colors and spacing every time. Point it at the tokens and it builds from one vocabulary. The system is the memory the model doesn't have.

One contract, many frontends

Headless splits the backend that serves data from the frontends that render it. A web app, an Odoo portal, docs, an Android screen. They all read the same tokens, so they match without anyone syncing hex codes by hand.

A new portal is an afternoon

Stand up a client portal or a microsite and it's themed and AA-accessible from the first commit. Swap the theme and every surface follows. No restyling from scratch.


The portable core

Tokens

The raw values every project shares. These swatches read live from the active theme. Flip the toggle and watch the whole core re-map.

Color

Type scale

Display 30
Heading 24
Subhead 18
Body 15 — the quick brown fox jumps over the lazy dog.
Small 13.5 — supporting copy and metadata.
Eyebrow 11 / uppercase

Spacing & radius

Elevation

sh-1
sh-pop

Built on the core

Components

Every primitive is built from tokens alone. Buttons, cards, tiles, badges, callouts, forms, tables. All themeable for free.

Buttons

Badges, chips & meter

accent good warn info 42
Revenue
€128k
Uptime
99.9%
Queue
17
Overdue
3

Callouts — four tones

Info: a left accent bar plus a faint wash marks the most important line.
Good: confirmations and healthy states read in the success tone.
Warn: attention without alarm.
Danger: blocking problems and destructive actions.

Form field & segmented

We never share it.

Table

ProjectOwnerStatusProgress
Research hubDouweLive100%
Xapti assessmentDouweIn review82%
My Stack siteDouweDraft40%

One core, two skins

Themes

Dark is the default, for dashboards and internal tools. Light is tuned to WCAG AA for docs and web. Only the color tokens differ. Spacing, type, radius and motion never move.

Dark

Internal tools, dashboards
default

Deep near-black surfaces, a blue→violet signature gradient, verified AA text contrast at 16.9:1.

Light

Docs, light web UIs
AA

Soft off-white surfaces, small-text contrast lifted to AA. Same components, re-mapped through the light color tokens.

Try it: hit the toggle top-right. The whole page above re-themes live, because nothing on it hard-codes a color.

See for yourself

Source

The whole system is three small CSS files, about 25 KB. No build step, nothing to install. This is the actual source this page runs on.

View raw
Loading…