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
- Install the font package:
npm install @fontsource-variable/your-font - Import it at the top of
global.css:@import "@fontsource-variable/your-font"; - 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.