Brand colors & fonts
Every theme is built on a small set of design tokens defined in src/styles/global.css. Change one variable, the whole theme reskins.
Where the tokens live
Section titled “Where the tokens live”@theme { /* Surfaces (tinted toward brand hue) */ --color-bg: oklch(99.5% 0.003 263); --color-surface: oklch(98% 0.005 263); --color-elevated: oklch(96% 0.007 263); --color-line: oklch(92% 0.01 263); --color-line-soft: oklch(95% 0.008 263);
/* Text */ --color-muted: oklch(62% 0.02 263); --color-soft: oklch(45% 0.025 263); --color-text: oklch(22% 0.02 263); --color-strong: oklch(15% 0.015 263);
/* Brand */ --color-brand: oklch(58% 0.234 263); --color-brand-hover: oklch(52% 0.225 263); --color-brand-active: oklch(46% 0.215 263); --color-brand-soft: oklch(95% 0.04 263); --color-brand-softer: oklch(97% 0.025 263); --color-brand-fg: oklch(99% 0 0);
/* Type */ --font-sans: "Geist Variable", ui-sans-serif, system-ui, -apple-system, sans-serif; --font-mono: "Geist Mono Variable", ui-monospace, "SF Mono", Menlo, monospace; --font-display: "Geist Variable", ui-sans-serif, system-ui, sans-serif;}These are CSS custom properties registered with Tailwind v4 via @theme. Tailwind generates utilities like bg-brand, text-strong, border-line-soft automatically — change the variable, every utility that references it updates.
Change the brand color
Section titled “Change the brand color”The third value in oklch(L C H) is the hue (in degrees, 0–360). Change just that:
| Hue | Color | oklch(58% 0.234 <h>) |
|---|---|---|
| 263 | Default blue | the shipped value |
| 25 | Red | warm red |
| 145 | Green | emerald |
| 200 | Teal | aqua |
| 290 | Violet | rich purple |
| 340 | Pink | hot magenta |
| 50 | Orange | warm orange |
Update every --color-brand-* and every --color-line* / --color-bg* / --color-surface* to the same hue — that’s what gives the theme its tinted neutral feel.
:root { --color-brand: oklch(58% 0.234 290); /* violet */ --color-brand-hover: oklch(52% 0.225 290); --color-brand-active: oklch(46% 0.215 290); --color-brand-soft: oklch(95% 0.04 290); --color-brand-softer: oklch(97% 0.025 290);
/* And the surfaces, all sharing the same hue: */ --color-bg: oklch(99.5% 0.003 290); --color-surface: oklch(98% 0.005 290); --color-elevated: oklch(96% 0.007 290); --color-line: oklch(92% 0.01 290); --color-line-soft: oklch(95% 0.008 290); /* …text colors too if you want a perfectly tinted neutral */}Change the typography
Section titled “Change the typography”Every theme uses three font families:
| Token | Default | Use |
|---|---|---|
--font-sans | Geist Variable | Body text, UI |
--font-display | Geist Variable | Headings (usually same as sans) |
--font-mono | Geist Mono Variable | Code blocks, KBD, anything monospaced |
Swap Geist for a different font
Section titled “Swap Geist for a different font”-
Pick a font on fontsource.org — they bundle variable web fonts as npm packages.
-
Install it:
npm install @fontsource-variable/inter -
Update the import at the top of
global.css:@import "tailwindcss";@import "@fontsource-variable/inter";@import "@fontsource-variable/geist-mono"; -
Update the variable:
--font-sans: "Inter Variable", ui-sans-serif, system-ui, sans-serif;--font-display: "Inter Variable", ui-sans-serif, system-ui, sans-serif;
That’s it. Every component already references --font-sans and --font-display — they’ll all pick up the new font on the next save.
Use different fonts for display vs body
Section titled “Use different fonts for display vs body”Common pattern — serif headings, sans body:
@import "@fontsource-variable/playfair-display";@import "@fontsource-variable/inter";
:root { --font-sans: "Inter Variable", system-ui, sans-serif; --font-display: "Playfair Display Variable", Georgia, serif;}Change the corner radius
Section titled “Change the corner radius”Some themes (like Forge) ship sharp border-radius: 0 corners; others (like Aurora) use 8px. There’s no --radius token by default — each component sets its own — but if you find yourself adjusting often, define one:
@theme { --radius-sm: 6px; --radius: 10px; --radius-lg: 16px; --radius-xl: 20px;}Then in components, swap style="border-radius: 8px" for the Tailwind utility rounded-[var(--radius)]. All your radii sync to one variable.
Change easing curves
Section titled “Change easing curves”Animations across the theme reference four easing variables:
--ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);--ease-out-quint: cubic-bezier(0.22, 1, 0.36, 1);--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);--ease-emphasized: cubic-bezier(0.2, 0, 0, 1);Most components use --ease-out-quint for hover and entrance animations. Change it once and every transition picks it up.
A whole-theme reskin in 60 seconds
Section titled “A whole-theme reskin in 60 seconds”For the most dramatic change, swap the brand hue and the body font at the same time:
:root { /* From blue + Geist to warm orange + Inter */ --color-brand: oklch(58% 0.234 50); --font-sans: "Inter Variable", system-ui, sans-serif; --font-display: "Inter Variable", system-ui, sans-serif;}…and update the four --color-brand-* variants + --color-bg/--color-surface/--color-line hue values to 50. Save, refresh — the entire theme reads as a different brand.
What’s next
Section titled “What’s next”- Section data — change every section’s copy, lists, and CTAs.
- Pages — add a new page using the same brand tokens.