feat(layouts): offer six more page fonts, previewed in their own type - #66
Open
patriksimms wants to merge 1 commit into
Open
feat(layouts): offer six more page fonts, previewed in their own type#66patriksimms wants to merge 1 commit into
patriksimms wants to merge 1 commit into
Conversation
Summary: - Add Montserrat, Nunito, Lora, EB Garamond, Playfair Display and Caveat to the font picker, grouped by Sans, Serif and Handwriting, with every name rendered in the font it names. - Introduce src/domain/fonts.ts as the single registry behind the picker, the browser preview, the layout metrics and the embedded PDF cuts, so a family cannot render one way on screen and another in print. - Derive the print TTF and web woff2 cuts locally from the pinned OFL variable sources (scripts/build-print-fonts.py) and self-host them; nothing is fetched from Google at runtime. - Embed only the font cuts a book uses instead of all of them, which also shrinks existing exports. - Caveat ships no italic upstream: italic is disabled for it and resolves to the upright cuts rather than silently faking a slant. Rationale: - Quoting the family name through the registry also fixes Source Serif 4 text previewing in Inter, because an unquoted family name containing a digit is an invalid CSS identifier and was dropped. - Full advance-width metrics for 30 cuts grow the organizer-only layout chunk by about 62 kB gzip; exactness keeps preview and PDF line breaking identical, which is the point of the metrics. Tests: - bun run format:check, lint, typecheck: pass - bun run test: 233 pass (new src/domain/fonts.test.ts and a PDF embedding-scope test) - bun run test:e2e: 20 pass, 2 production smoke skipped - bun run build: pass - Verified new families render in the editor canvas and in a rasterised PDF export, umlauts and eszett included Closes #65 AI-Assisted-By: Codex AI-Assisted: true AI-Agent: claude-code AI-Model: anthropic/claude-opus-5
patriksimms
force-pushed
the
feat/more-fonts
branch
from
August 19, 2026 07:57
13dd08d to
349c04a
Compare
patriksimms
marked this pull request as ready for review
August 19, 2026 08:43
Owner
Author
|
CI note: The duplicate push-triggered run for the same commit (32230298722) is wedged on |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Layouts could only use Inter or Source Serif 4, so every book looked the same. The picker also listed both names in the app's own UI font, so you had to apply a font and look at the page to see what it actually was.
Solution
Six more families are available for every text element, grouped by category, and each name is rendered in the font it names. Everything is bundled with the app, so no font is ever fetched from Google at runtime.
Picking a family carries through the editor canvas, the book preview and the exported PDF:
How it works
src/domain/fonts.tsis now the single registry behind the picker, the browser preview, the layout metrics and the PDF cuts, so a family cannot render one way on screen and another in print.scripts/build-print-fonts.py(viabun run fonts:build) derives the static print TTFs and the web woff2 cuts from the pinned OFL variable sources on github.com/google/fonts. Only the derived files are served.Notable side effect
Routing families through the registry quotes the CSS family name.
font-family: Source Serif 4 Variableunquoted is an invalid identifier and was silently dropped, so Source Serif 4 text previewed in Inter while the PDF printed it correctly. Preview and print now agree.Trade-off
Advance-width metrics for 30 cuts grow the organizer-only layout editor chunk from about 159 kB to 221 kB gzip. Keeping them exact is what makes preview and PDF line breaking identical; trimming to a codepoint subset is possible later if that chunk becomes a problem.
Validation
bun run verifylocally: format, lint, typecheck, 233 unit tests, 20 e2e tests, build. New coverage: registry-to-asset-to-metrics integrity, the Caveat italic fallback, and that a PDF embeds only the cuts in use. A rasterised export was inspected for each new family, umlauts and eszett included.Closes #65
Changes authored by Claude Opus 5 in Claude Code.