The body text here was hard to read, and I had the reason wrong twice before I got it right.

What Was Actually Wrong

The face was IM Fell English, a digitisation of the worn Fell types held at Oxford. It reproduces them faithfully, which means it also reproduces the ink spread, the uneven impression and the wandering baselines. Every letter comes out slightly different every time it appears. That’s the charm of it, and it’s also a tax that compounds: it wins a short side-by-side and loses the long read, which is exactly how it won the toggle test when I picked it.

The complaint I could actually name was that it read light, like a 200 or 300 where I wanted a 500. Two things were true at once.

The first is that IM Fell English has one weight. usWeightClass 400, no variable axis, and no medium exists anywhere to switch to. Asking for font-weight: 500 gets you a browser-synthesised smear, not a heavier cut.

The second is that light type on a dark ground optically thins. Halation eats stroke weight, so a real 400 on #131011 reads nearer 300. A dark site needs a step more weight than paper does, and this one had no step to give.

So it couldn’t be fixed by asking for more weight. The face had to go.

What Replaced It

Cantrip Mono, by Christopher Dollard (charredUtensil), released under the SIL Open Font License 1.1. It’s the font in my terminal, which is the strongest readability evidence I have for anything: I read it for hours a day, at the same size, on the same dark ground.

His stated aim is that “monospace fonts don’t have to be boring.”

The Thing I Had Wrong

I assumed calt meant programming ligatures, because that’s how Fira Code and JetBrains Mono ship them. It doesn’t. There are no -> or => ligatures in Cantrip, and that isn’t an oversight: the arrow codepoints aren’t in the font at all, and Dollard argues against syntax-specific ligatures on purpose. What he’s interested in is ligatures that serve the words themselves.

What calt actually does here is calligraphic. Doubled letters join, and letterforms change depending on what sits next to them. That’s a handwriting behaviour, not a programming one.

One File, Two Faces

The feature that turned out to matter is ss08, and I had that wrong too. It isn’t an alternate alphabet. It lets every width-adjustable character adjust, and it brings its own kerning table along, which makes the font proportional.

The whole point

One 16KB file is the proportional face for prose and the monospaced face for code. The switch is a single OpenType feature.

The advances are the proof. With ss08 on, punctuation narrows and capitals widen:

CharacterMonospacedProportional
. , : ;0.410em0.254em
'0.410em0.234em
A0.410em0.488em
H0.410em0.459em
monoReagent, tincture, elixir; a failed batch.
propReagent, tincture, elixir; a failed batch.

Prose runs proportional. Code runs monospaced, because in code the fixed advance is the whole point: columns line up, and a character takes the same space every time.

Bold and Italic, Without Either

Cantrip has one weight and no italic. Rather than let the browser fake both, the missing cuts get rebuilt out of features and some older habits.

Bold is letterspacing. Before a bold cut existed this is how emphasis got set: letterspaced roman, what German compositors called Sperrsatz, used because blackletter had no heavier weight to reach for. Same constraint here, same answer, plus a lift to the brightest ink.

Italic is cursive. ss01 gives a cursive s and t, and that is what italic actually is. The historical form is a chancery hand, not a sloped roman. So it lands closer to a real italic than shearing the roman would.

plainthe strangest essence settles
boldthe strangest essence settles
italthe strangest essence settles

Where Each Feature Is Allowed

Plain where the eye is reading, stylised where it’s scanning.

AreaSettingWhy
Prose, lists, tablesss08Proportional. Word shapes matter, and calt goes off so glyphs stay stable
Boldss08 plus trackingSperrsatz, plus the brightest ink
Italicss08 ss01Cursive, which is what italic means
CodenoneTrue monospace. Columns line up
Tagsss08They’re words
The closing lineall fourLooked at once, so the flourishes cost nothing

ss03 only shows up on that last line. Dollard’s own note says it can cost legibility, which is fine for one closing line and not for a paragraph.

ss16 is the one I haven’t used yet. It swaps in oldstyle a to f glyphs inside hexadecimal literals, and covers exactly 0-9, A-F, x and _ and nothing else. A feature built for one job:

off0xDEAD_BEEF 0xCAFE_F00D
ss160xDEAD_BEEF 0xCAFE_F00D

Using it means teaching the syntax highlighter to mark number tokens, which is the next thing to try.

What It Cost

Less than nothing, which I wasn’t expecting.

BeforeAfter
Files62
Weight195KB42KB

Three things came out. IBM Plex Mono, replaced by Cantrip, which is smaller. cinzel-400.woff2 and cinzel-700.woff2, which turned out to be byte-identical. One variable font shipped twice under two names, now one face declaring font-weight: 400 900. And IM Fell English, 117KB, once nothing referenced it any more.

The whole site is two faces now. Cinzel for the engraved labelling, and Cantrip doing everything else in four different guises.

The Whole Sheet

Every feature the font carries, off against on. Two of these are switched on somewhere in this site, four are switched off everywhere, and one is the reason prose and code can share a file.

caltstill mill letters summer arrow
onstill mill letters summer arrow
ss01the strangest essence settles
onthe strangest essence settles
ss02blissful mistress possesses
onblissful mistress possesses
ss03fifty flying fyrd
onfifty flying fyrd
lnum$1,234.56 €9,870 2026
on$1,234.56 €9,870 2026

ss02 is shown against ss01 alone rather than against the plain face, because it only fires on glyphs ss01 has already substituted. On its own it does nothing at all, which is why it reports zero affected characters if you go looking in the font binary.

Try It

Toggle anything. The sample is editable, so type your own words at it.

Reagent, tincture, elixir; a failed batch. 0xDEAD_BEEF

Ticking ss02 ticks ss01 with it, because its ligatures act on glyphs ss01 has already replaced.