A page that scrolls, in a collection of pages that don't. Some things are a document, and pretending otherwise is a format looking for a reason.
Everything on this site is a file in content/. A file says what it is in its own frontmatter
and then simply says it; nothing about a page is written twice, and nothing about it is written
in a route.
Made with
Next.js on the App Router, statically generated — every screen is HTML before anyone asks for it.
Tailwind CSS for everything that is a decision about spacing or type, and a short stylesheet for the handful of things that are a contract with the paginator.
pretext to measure prose without touching DOM layout, which is what lets a story break across pages the way pages break in print.
The View Transitions API, so a tile grows into the page it opens instead of two screens cross-fading.
The three kinds
| Kind | Reads as |
|---|---|
feed | A vertical reel of full-screen frames, flicked |
story | Prose measured and paginated, tapped a page at a time |
page | A document, scrolled — this one |
A file declares its kind and gets that screen. The markdown itself goes through one renderer whichever kind it is, so a heading is a heading and a list is a list in all three.
The interesting part is never the finished screen. It is the twenty decisions that made the screen inevitable.
Type and colour
Set in Geist with Playfair Display for display sizes, and Geist Mono for the small tracked lines. Each page carries its own four colours — two for the gradient it wears, two for the text on top of it — declared alongside everything else it says about itself:
palette:
from: '#bfdcd8'
to: '#a1cac4'
ink: '#1c4340'
muted: '#3a625d'The artwork is generated locally, so nothing on the page is fetched from anywhere else.
See also the Changelog, or go back and read Field Notes.