Adopt AXP Runde (Open Runde + a hooked l) as the UI face - #6
Conversation
Open Runde is Laurids Kern's rounded cut of Inter (SIL OFL 1.1). It ships without Inter's alternate glyphs, so scripts/fonts/build-axp-runde.py adds one: a hooked lowercase l drawn from each weight's stem geometry, exposed as cv05/ss01. With the features off the outlines are Open Runde's. The app turns cv05 on globally, which also separates l, I and 1 at 10-12px. - Replace DM Sans with the four self-hosted AXP Runde weights - Map the CSS weights 550/650 to the static 600/700; tabular figures for counts - Keep the unmodified Open Runde files beside the build for comparison - Add docs/design/type-specimen.html (ten alternatives, mono and handwriting shortlists) and docs/design/typography.md with the recommendation - Third-party notices and the served license directory cover the OFL text
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8b5d915027
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| python3 -m venv .venv && .venv/bin/pip install fonttools brotli | ||
| .venv/bin/python scripts/fonts/build-axp-runde.py /path/to/open-runde/src/desktop ui/src/fonts/axp-runde |
There was a problem hiding this comment.
When these fonts need to be regenerated, this recipe installs the latest fonttools/brotli and accepts an arbitrary Open Runde checkout without a revision or checksum, so the documented “reproducible build” can silently produce different binary assets over time. Pin the Python tool versions and the exact upstream Open Runde revision (or validate source hashes) so future rebuilds use the inputs that produced the committed files.
Useful? React with 👍 / 👎.
| "licenseInfoURL": "https://scripts.sil.org/OFL", | ||
| } | ||
| ) | ||
| fb.setupOS2( |
There was a problem hiding this comment.
Preserve the source strikeout metrics
When user-authored Markdown contains GFM strikethrough, this partial setupOS2 call replaces Open Runde's yStrikeoutSize/yStrikeoutPosition values with zero in every generated font. Since Prose renders remark-gfm output without overriding <del> decoration geometry, browsers must fall back or may place the line incorrectly; pass the source OS/2 strikeout metrics into the rebuilt font.
Useful? React with 👍 / 👎.
| fsSelection=os2.fsSelection, | ||
| fsType=0, | ||
| ) | ||
| fb.setupPost() |
There was a problem hiding this comment.
Preserve the source underline metrics
For links and buttons that the UI underlines, calling setupPost() without the source values changes the committed fonts' underline position/thickness from -280/140 to 0/0. This discards the font's intended decoration geometry and makes underlines depend on browser fallback behavior, potentially rendering them at the baseline or with an incorrect thickness; copy underlinePosition and underlineThickness from the source post table.
Useful? React with 👍 / 👎.
| .plain { | ||
| font-feature-settings: | ||
| "kern" 1, | ||
| "liga" 1, | ||
| "calt" 1, | ||
| "cv05" 0; |
There was a problem hiding this comment.
Use Open Runde for the baseline card
When this specimen is used to verify that the custom build preserves the upstream face, .plain only disables cv05 while inheriting font-family: "AXP Runde" from body; the declared unmodified Open Runde face is never used. Consequently both hero cards render the rebuilt font and the comparison cannot expose unintended changes to ordinary glyphs or metrics, so set this card's family to Open Runde.
Useful? React with 👍 / 👎.
| <link rel="preconnect" href="https://fonts.googleapis.com" /> | ||
| <link | ||
| rel="stylesheet" | ||
| href="https://fonts.googleapis.com/css2?family=Nunito:wght@400..800&family=Zen+Maru+Gothic:wght@400;500;700&family=M+PLUS+Rounded+1c:wght@400;500;700&family=Quicksand:wght@400..700&family=Fredoka:wght@400..600&family=Figtree:wght@400..700&family=Plus+Jakarta+Sans:wght@400..700&family=Lexend:wght@400..700&family=Recursive:CASL,MONO,wght@0,0,400..700;1,0,400..700;0,1,400..700;1,1,400..700&family=Atkinson+Hyperlegible+Next:wght@400..700&family=Varela+Round&family=JetBrains+Mono:wght@400;600&family=Victor+Mono:wght@400;600&family=Caveat:wght@400;600&family=Patrick+Hand&display=swap" |
There was a problem hiding this comment.
Sort the Recursive axis tuples
When the specimen is opened with network access, the Google Fonts CSS2 request is invalid because the Recursive tuples are ordered 0,0;1,0;0,1;1,1 rather than monotonically by CASL and then MONO. Google Fonts rejects an invalid selector as a whole, so none of the remotely hosted comparison faces load and every candidate silently falls back; order the middle tuples as 0,1 then 1,0.
Useful? React with 👍 / 👎.
What
Open Runde (Laurids Kern's rounded Inter, SIL OFL 1.1) becomes the UI face, as AXP Runde: the same outlines plus one glyph of our own, a hooked lowercase
lexposed ascv05/ss01. Open Runde ships without Inter's alternate glyphs, so there was nothing to switch on; the hook is generated from each weight's stem geometry by a reproducible build script. The app turns it on globally, which also separatesl/I/1at the 10–12px sizes the UI uses.scripts/fonts/build-axp-runde.py(fontTools) rebuilds the fonts from upstream OTFsLook at
docs/design/typography.md— why a signature glyph, the ten alternatives with verdicts, monospace and handwriting shortlists, my recommendationdocs/design/type-specimen.html— open locally in a browser: AXP Runde vs Open Runde, ten alternatives side by sidenpm run build && npm run demo:uifor the workspace in the new faceDecisions for the reviewer
Keep AXP Runde (my recommendation) or prototype Recursive (one variable family for UI and code, real personality). Pick the monospace: my lean is Maple Mono so the hook echoes in code, with ligatures off in diffs.
Verification
npm run checkandnpm run test:uipass.Landing
Sibling design PRs touch
THIRD_PARTY_NOTICES.mdandscripts/ui-notices.mjsin adjacent lines (trivial conflicts). Suggested order: this → typesetting → mermaid → grove → liquid-leaf → review-tools → onboarding → poster.