{
"$type": "site.standard.document",
"canonicalUrl": "https://notes.juergen.social/blog/design-tokens-v2",
"coverImage": {
"$type": "blob",
"ref": {
"$link": "bafkreiekqi6x24poijwf4v4ej6ch7h6jjstkbkpcrciaexin2a6mwyfa2a"
},
"mimeType": "image/jpeg",
"size": 189376
},
"description": "Color, spacing, and type for the whole theme live in one tokens file. Edit it, refresh, done.",
"path": "/blog/design-tokens-v2",
"publishedAt": "2026-03-20T00:00:00.000Z",
"site": "at://did:plc:2n2ukq3osdu3k37ncpn6hwiy/site.standard.publication/3mn57dpj54425",
"tags": "Design",
"textContent": "If you want a different look for your site, start in one file:\n\nsrc/styles/tokens.css\n\nThe core colors, spacing steps, and type scale live there. Components and pages read those variables first, while specialized surfaces such as code highlighting keep a small local palette. Change the core variables and most of the site follows.\n\nChange the accent color\n\nFind --color-blue near the top. There are three copies:\n\n1. Light mode under :root\n2. Dark mode inside the prefers-color-scheme: dark media query\n3. Forced dark via [data-theme='dark']\n\nEdit all three. The starter uses the same variable name across modes so components do not need to know which mode they are in.\n\nScroll dark turns on here\n\nThis sample post has the optional scroll dark effect enabled. Keep scrolling through this color example and the page will switch to dark mode. Add or remove focusEffect: 'scroll-dark' in a post's frontmatter to turn it on or off for that post; the trigger point is theme-defined, not section-specific.\n\nRule of thumb: a darker shade for light mode (passes contrast on white) and a lighter shade for dark mode (passes contrast on near-black). The starter's pair is a good starting point; push the hue without changing that contrast relationship.\n\nChange spacing\n\nThe scale uses a 4-point grid:\n\nComponents reference var(--space-4), not raw 1rem. Doubling --space-4 would double every \"one unit\" gap across the site, which is rarely what you want. Instead, change one or two specific steps.\n\nCommon edits:\n\n- Tighter prose: lower --space-6 and --space-8.\n- Roomier headings: raise --space-10 and --space-12.\n\nChange the type scale\n\nAstro Tone follows a quiet type scale at 16px base:\n\nFor a more compact theme, scale every step down by ~10%:\n\nPost title sizes use clamp() directly in src/styles/layouts/blog-post.css. Edit there if you want a different scaling curve at wide widths.\n\nVerify in dark mode\n\nClick the theme toggle in the header. Every text and surface color should still pass contrast.\n\nThree places to check:\n\n1. Custom shadows. Light-mode shadows use rgba(0, 0, 0, …). Dark-mode shadows need to be stronger, or near-black, to be visible at all.\n2. Hard-coded colors. Grep the codebase for # and rgb( outside tokens.css, src/config/expressive-code.ts, and src/styles/code.css. The code block palette is intentionally separate; everything else should usually read from tokens.\n3. Images. Photos that read on white can disappear on near-black. Use a subtle separator or a tinted background for prose images if needed.\n\nReplace the font stack\n\nThe starter uses a system font stack by default. That keeps the first render fast and avoids bundling font license surface into the template.\n\nTo add a brand font:\n\n1. Drop your .woff2 file into src/assets/fonts/.\n2. Add an @font-face block near the top of tokens.css.\n3. Put the font family first in --font-sans.\n4. Add a preload in src/components/BaseHead.astro only if the font is critical to the first viewport.\n\nIf the new font is variable, keep font-weight: 100 900 or the range it supports. If it is static, list only the weights you actually use.\n\nWhen a token is not enough\n\nSometimes a single component needs a value the system does not have. Two options:\n\n- Local CSS variable. Define --feed-date-column inside the component's scoped style block. The PostFeed already does this for its layout columns.\n- New token. If more than one component would use it, add a new token to tokens.css and use it everywhere.\n\nPrefer local variables for one-off layout values. Prefer new tokens for anything that touches color, spacing, type, or motion.\n\nWhat does not belong in tokens\n\nThe token file is for visual primitives. It is not for:\n\n- Copy strings — those live in src/ui.ts and astro-theme-config.ts.\n- Route paths.\n- Feature flags.\n\nIf a value answers \"what does this look like?\", it is a token. If it answers \"what does this say?\" or \"where does it go?\", it is config.",
"title": "Change the Look in One File"
}