Skip to main content
Your portfolio’s entire visual identity — colors, fonts, spacing, and border radius — is controlled by a single file: src/data/config/theme.json. The token system inside this file maps directly to CSS custom properties that are generated at build time. You never need to touch a stylesheet directly; edit the tokens and let the build system handle the rest.

Where the Theme File Lives

Open theme.json and you’ll find a tokens object with five top-level sections: colors, typography, borderRadius, spacing, and modes (which holds light-mode overrides).

Color Tokens

The tokens.colors object defines the default (dark mode) palette. Each key becomes a CSS variable that components reference throughout the site.

Dark Mode and Light Mode

The default colors in tokens.colors serve as the dark mode palette. Light mode overrides live under tokens.modes.light.colors and replace only the tokens you specify — any token you omit inherits its dark-mode value.
The override is applied automatically when the user’s system reports prefers-color-scheme: light. You don’t need to add any logic — the build system emits both sets of CSS variables scoped to the correct media query.
You only need to override tokens that actually differ between modes. If your card, border, and muted colors work in both contexts, leave them out of modes.light.colors entirely.

Changing Your Primary Accent Color

The primary token is the most impactful single change you can make. It controls link colors, highlighted text, button backgrounds, and active states. Update it in both dark and light contexts for a consistent result.
1

Open theme.json

Navigate to src/data/config/theme.json in your editor.
2

Update the dark-mode accent

Change tokens.colors.primary to your chosen hex value. Adjust primary-light (lighter tint) and primary-dark (darker shade) to complement it.
3

Update the light-mode accent

Set a slightly darker value under tokens.modes.light.colors.primary so it stays readable on a light background.
4

Rebuild

Save the file and run your build command. The new CSS variables will be emitted automatically.
Theme changes require a rebuild to take effect. Editing theme.json while the dev server is running will hot-reload the page, but if you are generating a production build you must re-run npm run build.

Typography Tokens

Font families are declared under tokens.typography.fontFamily. Each value is a full CSS font-family string, including fallbacks.

Using Google Fonts

To swap in a Google Font, update the font-family string in theme.json and add the @import to your global stylesheet.
1

Choose your font on Google Fonts

Pick a font (for example, Inter for primary or Fraunces for display) and copy the import URL from the Google Fonts “Use on the web” panel.
2

Add the import to globals.css

Open app/globals.css and add the @import at the very top of the file.
3

Update the token in theme.json

Replace the fontFamily.primary value with the new font name and its fallbacks.
Always include a generic fallback (sans-serif, serif, or monospace) as the last entry in your font-family string. This ensures readable text renders immediately before the web font loads.

Border Radius Tokens

The tokens.borderRadius object controls the roundness of cards, buttons, inputs, and other UI elements.
To give your portfolio a sharper, more editorial look, reduce all values toward 0px. For a softer, more rounded aesthetic, increase lg and xl.

Spacing Tokens

The tokens.spacing object controls four layout-level dimensions that affect the overall density and rhythm of every page.
Changing header-h also affects scroll-offset calculations for anchor links. If you adjust this value, verify that in-page navigation (e.g., #contact) still scrolls to the correct position.

Complete theme.json Reference

Below is the full annotated structure for reference: