Colophon
How this is made
Recorded because design decisions that are not written down get re-litigated every six months.
Type2 families
Two typefaces, two jobs. The reading voice isNewsreader — a variable serif with a real optical-size axis, which is why display and body can be the same family without the headings looking like inflated text. Browser optical sizing is left on, so a 96px title automatically gets the high-contrast cut and a 17px paragraph gets the sturdy one. The field-label layer — navigation, metadata, counts, legends — isIBM Plex Mono, always uppercase and tracked out, which is what gives the whole thing its surveyor's-notebook register.
Both are self-hosted via Fontsource with unicode-range subsetting, so a Latin-only page downloads only the Latin files. No Inter, no system stack.
| Display | Reading terrain |
|---|---|
| Body | The compression ratio of a contour map is absurd, and it works anyway. |
| Label | Snow science · 14 notes |
| Mono | 1 234 567 890 · f/8 · 1/250s |
Colour3 chromatic slots
Warm paper, one accent, and hue used sparingly. Depth comes from paper tone and line weight — there are no shadows and no corner radii anywhere on the site.
The graph's domain colours were not chosen by eye. A force-directed graph is an all-pairs colour problem: any two nodes can end up adjacent, so every pair has to be separable, not just neighbouring ones in a legend. Under that constraint a validated categorical palette only clears the colour-vision-deficiency gates at three chromatic slots — so three domains carry hue and everything else is neutral. Both modes were stepped and checked separately against their own surface, because an inverted light palette is not a dark palette.
| Role | Light | Dark |
|---|---|---|
| Outdoor | #357f3a | #38833f |
| Technical | #2a5f9e | #5a94d8 |
| Business | #d08a0c | #c2871e |
| Everything else | #8a8275 | #7d7668 |
Measured results, light surface #faf8f3, all pairs: worst colour-deficient separation ΔE 10.1, worst normal-vision ΔE 20.5. The amber slot sits at 2.7:1 against paper, which is below the 3:1 bar — so it ships with relief rather than on its own: every topic node is permanently labelled, the legend is always visible, hovering gives a text readout, andthe graph page carries a full table of the same data. On the dark surface #15140f every slot clears 3:1, but green and amber land at ΔE 7.5 — inside the warn band, which the same labelling makes legitimate. The dark lightness band and an amber slot cannot both hold while clearing 8; that is a measurement, not an omission.
Buildstatic
- Astro, static output. No server, no database.
- Markdown via remark/rehype. Astro 7 ships Sätteri as its default processor; this site opts back into unified because the markdown pipeline is the product here and needs real plugins.
- Two wikilink passes. remark turns
[[slug]]into links; rehype resolves the display text to the target's title and marks dangling ones visibly. - d3-force on a 2D canvas for the graph, with the layout built from a single compile-time pass over the note bodies.
- Pagefind for full-text search, indexed after the build.
- Sharp, via Astro's image pipeline, for every photograph.
- Cloudflare Pages for hosting.
Behaviourthe boring guarantees
- Every interactive thing degrades. The graph's data exists as a table; search only appears if its index actually shipped; the note index filters a list that is fully rendered server-side.
prefers-reduced-motionis honoured literally, not cosmetically: the graph solves its layout silently and paints once, and the lab sketches render a single still frame instead of animating.- Canvas sketches pause when scrolled out of view.
- The theme toggle has three states — auto, light, dark — so following the system stays reachable after a manual override, and it beats the OS setting in both directions without a flash on load.
- The ornament is one deterministic contour generator, seeded, drawn as static SVG at build time. Zero JavaScript.