Theming

How theming works

All visual properties are CSS custom properties with the --ts-* prefix. The entire theme lives in one block: src/styles/global.css:root { ... }.

Change the values in that block and the whole site follows — buttons, links, focus rings, backgrounds, everything.

Color tokens

Token Purpose
--ts-color-primary-50 to 950 Brand color scale (11 steps)
--ts-color-accent-400/500/600 Accent color (CTAs, highlights)
--ts-surface Main background
--ts-surface-alt Alternating section background

Generating a color scale

Pick your brand color for the 500 step, then generate a full 50–950 scale. Recommended tools:

Paste the generated values into the :root block.

Contrast requirements

Accent colors on surface backgrounds must meet WCAG AA (4.5:1 for text, 3:1 for large text and UI). Test with the WebAIM Contrast Checker.

Typography tokens

Token Purpose
--ts-font-display Headings (hero, section titles)
--ts-font-sans Body text, navigation, UI elements

Changing fonts

  1. Install the font package:
    npm install @fontsource-variable/your-font
  2. Import it at the top of global.css:
    @import "@fontsource-variable/your-font";
  3. Update the token in :root:
    --ts-font-display: "Your Font Variable", Georgia, serif;

All templates use self-hosted fonts via @fontsource — no external requests, GDPR-friendly.

Spacing and radius

These tokens are defined in core/tokens.css and rarely need changing:

Token Default Purpose
--ts-space-4 1rem Base spacing unit (4px grid)
--ts-radius-sm 0.25rem Small radius (tags, badges)
--ts-radius-md 0.5rem Medium radius (cards, inputs)
--ts-radius-lg 0.75rem Large radius (sections)

Override in the same :root block if needed.

The golden rule

Do not edit component files to change colors or fonts. Everything flows from the :root block. If you find yourself editing a .astro component to change a color, something is wrong — check the token name and override it in global.css instead.