Foundations · Colors

Two palettes, one variable name.

Every color resolves through a CSS custom property. Change data-theme on <html> and components keep the same token names in both modes.

Dark preview

Dark mode sample

Body copy reads cleanly on this surface. The accent dot reads as intentional, not noise.

Accent

Light preview

Light mode sample

Body copy reads cleanly on this surface. The accent dot reads as intentional, not noise.

Accent

Surfaces

6 tokens

Backgrounds move from page to card to nested surfaces. Use the least prominent token that works.

--bg

Darkoklch(0.145 0 0)Lightoklch(0.98 0.005 80)

--card

Darkoklch(0.205 0 0)Lightoklch(1 0 0)

--surface

Darkoklch(0.18 0 0)Lightoklch(1 0 0)

--surface-2

Darkoklch(0.17 0 0)Lightoklch(0.975 0.003 80)

--surface-3

Darkoklch(0.16 0 0)Lightoklch(0.955 0.004 80)

--button

Darkoklch(0.22 0 0)Lightoklch(0.96 0 0)

Text

5 tokens

Use primary for headings, secondary for body copy, and muted for metadata.

--primary

Darkoklch(0.985 0 0)Lightoklch(0.18 0 0)

--secondary

Darkoklch(0.87 0 0)Lightoklch(0.32 0 0)

--muted

Darkoklch(0.62 0 0)Lightoklch(0.50 0 0)

--body

Darkoklch(0.91 0 0)Lightoklch(0.22 0 0)

--code-text

Darkoklch(0.86 0 0)Lightoklch(0.28 0 0)

Borders

2 tokens

Use border for quiet containers and border-strong for visible controls.

--border

Darkrgba(255,255,255,0.10)Lightrgba(10,10,10,0.08)

--border-strong

Darkrgba(255,255,255,0.18)Lightrgba(10,10,10,0.18)

Brand

2 tokens

Use the accent for active filters, live states, and high-signal hover feedback.

--accent

Darkoklch(0.78 0.09 60)Lightoklch(0.55 0.13 40)

--accent-soft

Darkoklch(0.78 0.09 60 / 0.14)Lightoklch(0.55 0.13 40 / 0.10)