Five candidate font sets against today’s, first on a specimen card, then on six real approval screens. Same screens, same pixels, only the fonts swapped: every picture is the real firmware in the emulator (the Pico’s 240×240 panel, shown here at 1.5×). Back to the v2 plan.
My pick: Inter, disambiguated, with Atkinson Mono kept for addresses. It needs some layout fixes, listed below. The safe pick is IBM Plex: it swaps in with no layout changes at all. Details and questions at the end.
| Set | Words | Addresses and hashes | Why try it |
|---|---|---|---|
| Today | Atkinson Hyperlegible Next | Atkinson Hyperlegible Mono | Made for telling look-alike letters apart |
| Inter | Inter | Atkinson Mono | The clean, neutral look of most modern apps |
| Inter, disambiguated | Inter with its ss02 alternates |
Atkinson Mono | Inter, but I, l and 1 are all different, and 0 is slashed |
| Space Grotesk | Space Grotesk | JetBrains Mono | More character, a bit “crypto” |
| IBM Plex | IBM Plex Sans | IBM Plex Mono | Engineered and calm; the same widths as today’s |
| Manrope | Manrope | Atkinson Mono | Round and friendly |
All six are SIL Open Font License, from Google Fonts. Every set keeps today’s seven sizes (12–28 px) and the 16-shade anti-aliasing.

Each card has a headline, body text, a title, an address, a row of look-alike characters
(Il1| O0o rn m 5S 8B 6b), the verify code and a button line. What the row shows:

Inter and Space Grotesk run wider, so row #3 is cut: “Refused · bad ha…”. Plex and Manrope fit.


The address uses the mono in every set. Only Space Grotesk (JetBrains Mono) and Plex (Plex Mono) change it.


The body text wraps differently by width. Every set fits here, but Inter and Space Grotesk carry more words onto the last line, and Plex breaks exactly like today.

Space Grotesk loses the end of the message: “entirely.” falls off the page. The layout has room for four lines here, and Space Grotesk needs five.
| Set | Fits today’s layouts? | Look-alikes | Work |
|---|---|---|---|
| Today | yes | all apart | none |
| Inter | no: longer rows get cut, and wrapped text runs longer | I = l | out, unless disambiguated |
| Inter, disambiguated | no, same as Inter | all apart | give the queue rows and the wrapped text more room (part of the v2 redo anyway) |
| Space Grotesk | no: text falls off a page | I = l | out |
| IBM Plex | yes | all apart | none: regenerate the fonts, done |
| Manrope | yes | I = l | out, and the tight spaces |
GF_DIR=/path/to/google/fonts uv run --with pillow python tools/fonts/gen.py --try # the candidates' glyphs
tools/quorum shots --fonts inter,interd,grotesk,plex,manrope # the screens in each set
uv run --with pillow python tools/fonts/compare.py # specimens and these grids
tools/emu run fontspec # the card live; A = next set
gen.py --try writes emu/sketches/qf_SET_NAME.bin. The emulator loads them, and
fonts.use("plex") swaps them in. They never go to the board, and today’s
firmware/qf_*.bin are untouched.GF_DIR is optional: without it, gen.py downloads each typeface. Both ways check it against a
pinned sha256.firmware/qf_*.bin, not a
re-render.