Skip to content

Adopt AXP Runde (Open Runde + a hooked l) as the UI face - #6

Open
maceip wants to merge 1 commit into
mainfrom
exp/type-open-runde
Open

Adopt AXP Runde (Open Runde + a hooked l) as the UI face#6
maceip wants to merge 1 commit into
mainfrom
exp/type-open-runde

Conversation

@maceip

@maceip maceip commented Sep 6, 2026

Copy link
Copy Markdown
Owner

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 l exposed as cv05/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 separates l/I/1 at the 10–12px sizes the UI uses.

  • Replaces DM Sans with four self-hosted weights (400/500/600/700); CSS weights 550/650 mapped to 600/700; tabular figures on counts and times
  • scripts/fonts/build-axp-runde.py (fontTools) rebuilds the fonts from upstream OTFs
  • Unmodified Open Runde files kept beside the build for comparison
  • Third-party notices and the served license directory carry the OFL text

Look at

  • docs/design/typography.md — why a signature glyph, the ten alternatives with verdicts, monospace and handwriting shortlists, my recommendation
  • docs/design/type-specimen.html — open locally in a browser: AXP Runde vs Open Runde, ten alternatives side by side
  • npm run build && npm run demo:ui for the workspace in the new face

Decisions 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 check and npm run test:ui pass.

Landing

Sibling design PRs touch THIRD_PARTY_NOTICES.md and scripts/ui-notices.mjs in adjacent lines (trivial conflicts). Suggested order: this → typesetting → mermaid → grove → liquid-leaf → review-tools → onboarding → poster.

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
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 6, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-06T22:16:51.232693Z 8b5d915 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +12 to +13
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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Pin the font build inputs

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(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Comment on lines +126 to +131
.plain {
font-feature-settings:
"kern" 1,
"liga" 1,
"calt" 1,
"cv05" 0;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant