Colophon
How this site is put together, and what every piece of markdown looks like once it lands here.
This is the first thing on the new dmerr.com, and it’s doing double duty: it explains how the site works, and it exercises every bit of formatting so I can see what a real post will look like before I write one.
The old site was four <hr> rules, a pixel portrait, a row of links separated by
slashes, and a small triangle at the bottom. I kept all four. The portrait sits at the
top of the front page, the slashes now do the work of the navigation, and the triangle
moved to the footer, where clicking it turns the lights off.
How a post gets here
A post is a markdown file in content/posts/. The filename becomes the URL, so
content/posts/colophon.md is served at /posts/colophon. The top of the file is
frontmatter:
---
title: Colophon
date: 2026-08-08
dek: A one-line summary. Optional.
draft: false
---
Only title and date are required. Set draft: true and the post stays visible in
local development and invisible everywhere else. Reading time is counted from the word
count, so there’s nothing to set by hand.
Then git push, and Vercel builds it.
What the formatting looks like
Body text runs in a single column about 34 rem wide, which lands somewhere between sixty and seventy-five characters a line — the range where reading stops being work.1
Quotes get a rule down the left in the accent colour, pulled off the portrait:
The best writing is rewriting. The second-best is deleting. There is no third-best.
Lists behave:
- Unordered items, with a muted marker
- A second item, so the spacing is visible
- A third, for good measure
- Ordered items are numbered
- And spaced the same way
Inline code gets a tinted background, and blocks of it scroll sideways rather than
wrapping:
export function readingMinutes(markdown: string): number {
const words = markdown.trim().split(/\s+/).filter(Boolean).length;
return Math.max(1, Math.round(words / 220));
}
Tables are plain — a rule under each row and nothing else:
| Piece | What it is |
|---|---|
| Framework | Next.js, App Router, fully static |
| Prose face | Newsreader |
| Utility | DM Mono, for anything that isn’t prose |
| Host | Vercel |
Smaller headings
Third-level headings are italic, which keeps them subordinate without shrinking them into illegibility. Fourth-level headings switch to the mono face and go quiet.
Footnotes collect at the bottom, behind a rule, with a link back up to where you left off.2
That’s the whole system. Nothing here needs a build step I have to remember, a login, or a database. It’s files.