Style guide
Everything on this page renders from the live stylesheet. If a token changes, this page changes with it — it cannot drift from the site the way a screenshot would.
Colour
Eight tokens, defined once in assets/css/tokens.css and redefined under
prefers-color-scheme: dark. No other file in the repo contains a colour literal.
Toggle your OS between light and dark to see both.
Every value below is asserted by test/tokens.test.mjs: ink tokens clear 4.5:1
against --bg, --ink clears 7:1, --accent clears 4.5:1, and --on-accent
clears 4.5:1 against --accent. A palette change that breaks legibility fails the
test rather than shipping.
--bgpage background--bg-sunkrecessed: code, pre--bg-liftraised: chips--inkbody text--ink-mutedmetadata, summaries--rulehairlines, borders--accentlinks, focus rings--on-accenttext on --accent
Type
Three roles. Body text uses no webfont, so reading never waits on a third party.
Eyebrow — JetBrains Mono, uppercase, tracked
Display — Newsreader
Second level
Third level
Body copy is the system sans stack. It should feel unremarkable, which is the point: the display face and the mono metadata do the work, and the reading column stays out of the way. The measure is capped at 34rem so a line never runs long enough to lose your place on the return sweep.
Elements
A link in running text, some inline code, and bold and italic.
A blockquote, for the times a quotation earns its own space.
// A fenced code block.
const tokens = readFileSync('assets/css/tokens.css', 'utf8');
| Column | Column |
|---|---|
| Table cell | Table cell |
| Table cell | Table cell |
Favicon
16 · 32 · 64
A keyhole, or a chess pawn. The ambiguity is deliberate — escape rooms read the first, games read the second, and neither needs explaining.
assets/favicon.svg is the only file besides tokens.css that contains colour
literals, because an external SVG referenced from <link rel="icon"> cannot see the
page’s custom properties. test/tokens.test.mjs asserts the duplicated values match
the palette in both schemes, so the icon cannot drift.
The glyph fills 78% of the tile height, and that number is load-bearing. An earlier version used 56%. At 16px — the only size most people ever see — that left a head barely 3px across, and the shape collapsed into an unreadable blob. Clearance that looks composed at 64px is wasted resolution at favicon size. A test fails if the scale drops below 1.1.
Some clearance still earns its place: past roughly 90% the glyph looks cramped inside the rounded corners at the large sizes used for bookmarks and PWA icons. 78% is the compromise.
Jelly components
Loaded from jelly-ui.com and enhancement only. Each is shown twice: as it upgrades,
and with the upgrade suppressed so you can inspect the fallback without taking the CDN
down.
Note that a default <jelly-chip> paints its body on a <canvas> from
--jelly-color-background-neutral. Any Jelly token left unbridged in tokens.css
silently keeps Jelly’s own blue-grey default, so the bridge list is asserted by test.
Upgraded
Fallback, as it renders if package.js never loads