loading
On this page
  1. Colors
  2. Surfaces
  3. Text
  4. Accent
  5. Borders
  6. Typography
  7. Font families
  8. Where these live
playbook EN / ID 🇮🇩 Baca dalam Bahasa Indonesia

Design tokens

Every color, font, and typography size this site uses — rendered live so the whole system stays visible to itself.

Design tokens are the atoms of a theme. Change one, and every component referencing it shifts together. This post renders every token defined in src/styles/global.css so the whole system is visible at once — and so I catch anything that drifts in either light or dark mode when I tune it.

Toggle the theme using the button in the nav (or let it follow your OS) and every swatch on this page flips with you. That’s the whole point of semantic tokens: the same names, different values per mode.

Colors

Every color is a CSS variable scoped to :root for light mode and .dark for dark mode. Components reference tokens by purpose, not by value, so the mode can swap underneath without touching a single component file.

Surfaces

Backgrounds and card panels. The primary background is what holds the page together; everything else is a layered variation on it.

—bg

Primary page background

—bg-secondary

Secondary background, subtle contrast

—card-bg

Card and tag pill background

—tag-bg

Legacy tag background (warm tone)

Text

Three levels of reading emphasis. Primary for the content itself, secondary for captions and supporting copy, muted for mono meta labels and dates.

—text

The quick brown fox jumps over the lazy dog

—text-secondary

The quick brown fox jumps over the lazy dog

—text-muted

The quick brown fox jumps over the lazy dog

—tag-text

The quick brown fox jumps over the lazy dog

Accent

The warm gold that defines the brand. --accent is the base; --accent-hover is the interactive state; --accent-light is a desaturated variant for underlines and subtle highlights.

—accent
Primary accent
—accent-hover
Hover state
—accent-light
Desaturated

A sample of the accent in context:

This is body text with a highlighted phrase and an

underlined link

using the accent color family.

Borders

Two border weights, from primary (for section dividers) to subtle (for card separators).

—border

Primary section dividers

—border-light

Card separators, subtle rules

Typography

Eight semantic text tokens. Each maps to both a font-size and a matching line-height via Tailwind 4’s @theme directive, so tuning the scale is a single-file change.

The rule: name by purpose, never by size. When I replaced every text-[Npx] in the codebase with these tokens, the home page got easier to reason about overnight.

text-lead

The quick brown fox jumps

text-name

The quick brown fox jumps

text-heading

The quick brown fox jumps over

text-card

The quick brown fox jumps over

text-body

The quick brown fox jumps over the lazy dog

text-caption

The quick brown fox jumps over the lazy dog

text-meta

The quick brown fox jumps over the lazy dog

text-micro

The quick brown fox jumps over the lazy dog

TokenSizeLine heightUsed for
text-micro10px1.4Tag pills, type badges
text-meta11px1.5Dates, mono meta labels
text-caption14px1.55Card descriptions
text-body16px1.65Main reading register
text-card17px1.35Post and project card titles
text-heading18px1.3Section headings
text-name20px1.15Hero name
text-lead22px1.5Hero tagline

Font families

Two families, no more: a sans for reading and a mono for metadata, code, and anything that wants to feel “system-native.”

—font-sans

Geist — A clean, modern sans designed for interfaces. The quick brown fox jumps over the lazy dog. 0123456789

—font-mono

Geist Mono — A monospace for code and meta. The quick brown fox jumps over the lazy dog. 0123456789

Where these live

Every token in this post is defined in a single file:

src/styles/global.css

The typography scale lives in the @theme block at the top. The color palette lives in @layer base with two blocks — :root for light mode and .dark for dark mode. Components reference tokens via Tailwind utilities (text-body, bg-[var(--bg)], border-[var(--border)], etc.) so there are no hardcoded values anywhere in the component tree.

If a token looks wrong on this page in either mode, the fix goes into that one file and every component updates on the next reload.


This post intentionally has featured: false. It’s a reference, not a showcase — it shouldn’t pressure its way onto the home page’s featured list. Find it through /content or the design-system tag.

← Back to all content