Design System
The type, color, spacing and parts this site is built from. Swatches and scales on this page are read from the design tokens, so they always match the CSS.
01
Typography
Fonts
display
Source serif 700 with Georgia Bold as fallback
Font Families: Source Serif, Source Serif Fallback, serif
var(--font-display)base
Source Sans 3 VF with Arial as fallback
Font Families: Source Sans, Source Sans Fallback, sans-serif
var(--font-base)mono
Source Code Pro with Courier New as fallback
Font Families: Source Code Pro, Source Code Pro Fallback, Dank Mono, Fira Code, Fira Mono, Menlo, Consolas, Monaco, monospace
var(--font-mono)
Sizes
Fluid type and space scales were generated with Utopia.
| Token | Range | Sample |
|---|---|---|
step-min-2 | 13px to 16px var(--size-step-min-2) | step-min-2 |
step-min-1 | 16px to 22px var(--size-step-min-1) | step-min-1 |
step-0 | 19px to 28px var(--size-step-0) | step-0 |
step-1 | 23px to 35px var(--size-step-1) | step-1 |
step-2 | 27px to 44px var(--size-step-2) | step-2 |
step-3 | 33px to 55px var(--size-step-3) | step-3 |
step-4 | 40px to 68px var(--size-step-4) | step-4 |
step-5 | 47px to 86px var(--size-step-5) | step-5 |
step-6 | 56px to 107px var(--size-step-6) | step-6 |
Type features
Typographic defaults from Bringhurst's The Elements of Typographic Style and Butterick's Practical Typography. Each pair shows the plain setting, then the site's.
Old-style figures
Running text (.prose) sets old-style, proportional figures, which sit with lowercase letters. Tables, acronyms and code keep lining figures.
Plain
Founded in 1994, the W3C made CSS 2.1 a recommendation in 2011. Code keeps its own figures: --tracking-wide: 0.12ch.
Site
Founded in 1994, the W3C made CSS 2.1 a Recommendation in 2011. Code keeps its own figures: --tracking-wide: 0.12ch.
Small caps
The .small-caps class, by hand, for the opening words of an article or a name. Letterspaced, and never faked in italic, which has no small caps.
Plain
The opening words of an article, or a name such as Robert Bringhurst.
Site
The opening words of an article, or a name such as Robert Bringhurst.
Figure classes
Four classes for figures, used by hand. They combine with each other and with the running-text default, so class="lining-nums tabular-nums" keeps both. Samples are set in running text (.prose). Put .fraction on the fraction itself: in Source Sans it changes every digit, full stop, comma and parenthesis it covers. .slashed-zero brings lining figures with it, because the old-style zero has no slashed form.
Without, then with .fraction
Add 3/4 cup of water and 1/2 teaspoon of salt.
Add 3/4 cup of water and 1/2 teaspoon of salt.
Without, then with .slashed-zero
Serial number O0O-2020-0O.
Serial number O0O-2020-0O.
Without, then with .lining-nums
The 1990s, the 2020s, and 1,380 metres.
The 1990s, the 2020s, and 1,380 metres.
Without, then with .tabular-nums
1,111.11
8,888.88
1,111.11
8,888.88
Captions and quotes
Captions and quotes are balanced so their lines come out even, not ending on one word. Short captions are italic and centred; long wiki captions are upright and left-aligned.
Plain
Simple is almost always more effective than complex, and short.
Site
Simple is almost always more effective than complex, and short.
Capital labels
Strings of capitals are letterspaced 5–10% of the size: --tracking-wide is 0.12ch, about 5.7%.
Before (0.09ch)
Articles · Notes · Photos
Site
Articles · Notes · Photos
Footnote numbers
The font's own superscript figures, bare, rather than a shrunken, raised number in brackets. They don't push the lines apart.
Plain
A claim that needs a source.[1] The next line keeps its spacing, or doesn't.
Site
A claim that needs a source.1 The next line keeps its spacing, or doesn't.
List markers
List numbers take old-style figures, like the text around them; left alone, the browser sets them lining. They are tabular, so 9 and 10 line up. Numbers and hollow bullets share --color-accent-orange-text: orange-600 in light mode, so the numbers pass 4.5:1, and orange-500 in dark.
Plain
- Old-style figures in running text
- Lining figures with capitals
- Tabular figures in columns
- A bullet should be noticeable
- but not big
Site
- Old-style figures in running text
- Lining figures with capitals
- Tabular figures in columns
- A bullet should be noticeable
- but not big
Blockquotes
A quotation set off from the text: a rule on the start edge, a larger size, balanced lines, and no quote marks. The source goes inside the quote as its last paragraph, which the site sets two steps smaller.
With a source
Typography exists to honor content.
— Robert Bringhurst, The Elements of Typographic Style
Written in markdown
> Typography exists to honor content.
>
> — <span class="small-caps">Robert Bringhurst</span>, *The Elements of Typographic Style*Vertical rhythm
Prose, where every gap, and every line of text that is not body text, is a whole number of quarter lines of body text (global/blocks/prose-rhythm.css). The wiki page Vertical rhythm explains and measures it.
A page in prose
Running text sets the beat. Every line of it is one line-height tall, and whatever interrupts it should hand the beat back unchanged.
A second paragraph, so the gap between two of them is on the page.
A list
- Short items sit a small step apart.
- A longer item wraps onto a second line, and the step to the next item stays the same.
- The last one.
A paragraph after the list.

A paragraph after the figure.
| Element | Lines |
|---|---|
| Paragraph | 1 |
| Caption | ¾ |
| Table row | 1½ |
Space in typography is like time in music.
— Robert Bringhurst, The Elements of Typographic Style
.flow > * + * {
margin-block-start: var(--flow-space, 1em);
}A paragraph after the code.
- A numbered item.
- And another.
A disclosure
Its content, once opened.
A last paragraph with a note.1
Footnotes are set a step smaller, like captions.
02
Links and buttons
Buttons
03
Color
Roles
Every color has a job before it has a value. The page names the job; the theme picks the value. Values come from semanticColors.json.
| Role | Light | Dark | Used for |
|---|---|---|---|
Page--color-bg | #f4f4f2 | #141619 | The page itself. |
Raised surface--color-bg-accent | #ffffff | #383b3f | Cards, inline code, footnotes, popups and form fields. |
Divider--color-bg-accent-2 | #acaeb1 | #44484d | Heading lines, short rules and the rules in prose. |
Table rule--color-rule | #d5d6ce | #222423 | Hairlines between table rows, warmer than the gray ramp. |
Table head--color-bg-head | #e0e1e4 | #2d2f34 | The table head row, opaque so a sticky head hides the rows under it. |
Text--color-text | #495464 | #c8cacc | Body text. |
Headline--color-headline | #495464 | #e3e5e7 | Headings. |
Strong secondary text--color-text-accent | #383b3f | #e3e5e7 | Labels, metadata and captions that still need 4.5:1. |
Quiet text--color-text-subdued | #576374 | #acaeb1 | Table heads and caption icons. |
Accent--color-accent-orange | #d0621e | #d0621e | Link underlines, the logo mark, focus and form accents. The same in both themes. |
Logo mark--color-logo-icon | #d0621e | #d0621e | The mark in the header and breadcrumb. |
Page edge--color-border-top | #dddee8 | #320100 | The band along the top of every page. |
Palette
Foundational theme tones. Composed into the semantic theme variables in variables.css.
#495464
var(--color-base-darkest)#bbbfca
var(--color-base-dark)#dddee8
var(--color-base-light)#f4f4f2
var(--color-base-lightest)#d5d6ce
var(--color-base-rule)#222423
var(--color-base-rule-dark)#576374
var(--color-base-subdued)#ffffff
var(--color-base-white)#000000
var(--color-base-black)
Gray scale generated from a single base in OKLCH space. Includes the standalone gray-250.
#f7f8fb
var(--color-gray-100)#e3e5e7
var(--color-gray-200)#c8cacc
var(--color-gray-250)#acaeb1
var(--color-gray-300)#7d8085
var(--color-gray-400)#606368
var(--color-gray-500)#44484d
var(--color-gray-600)#383b3f
var(--color-gray-700)#2b2e32
var(--color-gray-800)#141619
var(--color-gray-900)
Orange scale generated from a single base in OKLCH space.
#ffece1
var(--color-orange-100)#ffdec3
var(--color-orange-200)#ffb78a
var(--color-orange-300)#f68f5a
var(--color-orange-400)#d0621e
var(--color-orange-500)#a73c00
var(--color-orange-600)#8c2100
var(--color-orange-700)#711a00
var(--color-orange-800)#320100
var(--color-orange-900)
Each has a chroma-reduced subdued variant used in dark theme.
#644b49
var(--color-red)#614d4b
var(--color-red-subdued)#d6403a
var(--color-red-vivid)#245375
var(--color-blue)#2f536e
var(--color-blue-subdued)#3d8ecc
var(--color-blue-vivid)#626449
var(--color-green)#62644e
var(--color-green-subdued)#2e9d4f
var(--color-green-vivid)
Custom colors
in variables.css. Some only change for dark theme.
--color-text--color-text-accent--color-bg--color-bg-accent--color-bg-accent-2--color-accent-orange--color-accent-blue--color-accent-green
Gradients
--gradient-slate--gradient-conic--gradient-stripes
04
Grid
Columns
Twelve columns of 6.25rem with 2rem gutters make the 97rem page; the middle eight make the 64rem column that prose sits in. As the window narrows, the outer columns go first, then the eight scale down with the text. ⌥ G lays the grid over any page while the site runs locally.
Breakouts
Anything on the page can step out of its column by a fixed amount: .popout by a gutter each side, .feature by a column and a gutter, .full to the window's edges. The bands below are drawn by those classes at their real widths, around the 64rem prose column, as in a post; widen the window to see each step.
05
Spacing
Scale
Fluid type and space scales were generated with Utopia.
| Token | Range | Sample |
|---|---|---|
3xs | 2px to 3px var(--space-3xs) | |
2xs | 3px to 5px var(--space-2xs) | |
xs | 5px to 7px var(--space-xs) | |
s | 10px to 14px var(--space-s) | |
m | 14px to 21px var(--space-m) | |
l | 19px to 31px var(--space-l) | |
xl | 38px to 56px var(--space-xl) | |
2xl | 57px to 84px var(--space-2xl) | |
3xl | 95px to 140px var(--space-3xl) | |
xs-s | 5px to 14px var(--space-xs-s) | |
s-m | 10px to 21px var(--space-s-m) | |
m-l | 14px to 31px var(--space-m-l) | |
l-xl | 19px to 56px var(--space-l-xl) | |
l-2xl | 19px to 84px var(--space-l-2xl) | |
xl-2xl | 38px to 84px var(--space-xl-2xl) | |
2xl-3xl | 57px to 140px var(--space-2xl-3xl) |
06
Patterns
Meta line
Under every post title: the post type linked to its archive, the activity type for activities, the date, and the last revision linked on GitHub. Each item is an icon and a label that never break apart.
Activity colors
Each activity type has one color, used for its map dots, its route lines and its icons. Orienteering changes shade so it is never as light as the hike green: the two are told apart by lightness alone under red–green color blindness. On a map it follows the map under it, so satellite takes the light orange and topographic the dark one.
- Orienteering
--color-activity-orienteering - Run
--color-activity-run - Hike
--color-activity-hike - Weight training
--color-activity-weight-training
Cards
Archive pages list posts as cards: one card per post type, each filling the same slots (image, date, headline, text, footer). These are the newest jam, book and note.

Nine
Nine by Russian Circles, released 28 August 2026.

Nils Holgerssons underbara resa genom Sverige
Wants to Read Nils Holgerssons underbara resa genom Sverige by Selma Lagerlöf
Hej från min telefon
Maps
Maps are drawn from the site's own map tiles in its own colors, and load only when scrolled to. A map shows places (the activities overview), a single pin (a photo's location) or a recorded route. The wiki page The place map covers how.
07
Tokens
Every value on this page starts in a design token file, in the W3C design tokens format. The build turns them into the CSS custom properties the site uses, a token file for Penpot, and DESIGN.md, a written summary for people and tools.
Color
colorsBase.json: The few source colors everything else is generated from.colors.json: The generated palettes: gray and orange scales, and the accent colors with their dark-mode variants.semanticColors.json: The color roles above, per theme.buttonColors.json: Button colors per variant and theme.megamenuColors.json: Menu colors per theme.
Type
fonts.json: The three font stacks.textSizes.json: The fluid type scale.textLeading.json: Line heights.textWeights.json: Font weights.typography.json: Type styles that combine family, size, weight and line height.
Space and shape
spacing.json: The fluid space scale.viewports.json: The smallest and largest window the fluid scales are tuned between.borderRadius.json: Corner radii.borderWidth.json: Border widths.shadows.json: Shadows.