Skip to content

slides: a deck names the shell's two fonts instead of embedding them - #468

Merged
nyblnet merged 2 commits into
mainfrom
slides-builtin-fonts
Sep 14, 2026
Merged

nyblnet merged 2 commits into
mainfrom
slides-builtin-fonts

Conversation

@nyblnet

@nyblnet nyblnet commented Sep 13, 2026

Copy link
Copy Markdown
Owner

Measured first, on three real decks' document blocks: a typical text deck was 80% two woff2 files — Fraunces 900 and Instrument Sans, 86 KB — which every shell already carries compiled in (fontdata.ts). The bytes existed twice in every saved file. The structure an AI actually edits was 17–21 KB.

Change. A doc.fonts[] entry may name a built-in face (asset: 'builtin:fraunces-900' / 'builtin:instrument-sans', fonts.ts BUILTIN_FONTS) with no bytes in assets. resolveFontSrc asks the deck's table first, then the shell; injectFonts goes through it. The starter deck names both. At save, adoptBuiltinFonts (slides' facade, beside the asset prune) rewrites any deck whose embedded bytes are identical to a built-in face — by bytes, never by family name, so a deck's own cut of Fraunces is kept — and the bytes leave the file. The live document is never touched.

The trade, stated: an older shell opening a new deck renders those two families in the system fallback until it updates itself — a degrade, not a break. Accepted for the saving; in the model comment and a DECISIONS entry.

Measured in Chrome against the built shell: both faces load from the shell (document.fonts.check true, status loaded); the starter deck saves with zero font bytes; a legacy deck carrying the old keys saves 85,269 bytes smaller with the live document untouched.

scripts/test-slides-fonts.ts (25 checks, registered): resolution, adoption by bytes and not by name, idempotence, other assets untouched, the facade wiring, and the measured saving. Also green: typecheck, build:single + splice gate, slides-assets 28, export-secrets 74, ci-registered 318, i18n, modelkeys. Changelog entry under [Unreleased] (tail; one-line rebase if it lands after #463/#465). No CLAUDE.md/AGENTS.md change.

Not in here, next lever: photos have no downscale or recompression at insert.

…— 86 KB off every file

Measured on three real decks: the document block of a typical text deck
was 80% two woff2 files, Fraunces 900 and Instrument Sans — 86 KB that
every shell already carries compiled in (fontdata.ts). The bytes existed
twice in every saved file; the structure an AI edits was 17–21 KB.

A doc.fonts entry may now name a built-in face (asset: 'builtin:…',
fonts.ts BUILTIN_FONTS) with no bytes in assets; resolveFontSrc asks the
deck's table first and the shell second, and injectFonts goes through it.
The starter deck names both faces. At save, adoptBuiltinFonts in slides'
own facade rewrites any deck whose embedded bytes are identical to a
built-in face — by bytes, never by family name, so a deck's own cut of
Fraunces is kept — and the bytes leave the file; the live document is
never touched. An older shell renders those two families in the system
fallback until it updates: a degrade, stated in the model and in
DECISIONS, accepted for the saving.

Measured in Chrome against the built shell: both faces load from the
shell (document.fonts), the starter deck saves with no font bytes, and a
legacy deck carrying the old keys saves 85,269 bytes smaller with the
live document untouched. scripts/test-slides-fonts.ts (25, registered)
pins resolution, adoption by bytes, idempotence, the facade wiring and
the measured saving. Changelog and DECISIONS entries ride along.
@github-actions

github-actions Bot commented Sep 13, 2026

Copy link
Copy Markdown

Build size

main (c09b417) → slides-builtin-fonts (5b4d136)

app base PR change
bento/slides 701.6 KiB 701.9 KiB +0.2 KiB (+0.03%)
bento/spaces 273.0 KiB 273.0 KiB 0.0 KiB (0.00%)
bento/dash 424.4 KiB 424.4 KiB 0.0 KiB (0.00%)

Updated: 2026-09-14T00:16:17Z

A fonts[].asset of the form builtin:… names a face the shell carries;
the validator reported it as a missing asset (2 errors on the starter
deck, caught by the validation rig in CI). A known built-in name is now
a satisfied reference; an unknown built-in name is the error, as is an
asset key with no bytes. Cases in test-validate (48).
@nyblnet
nyblnet merged commit dcb1ff5 into main Sep 14, 2026
2 checks passed
nyblnet added a commit that referenced this pull request Sep 14, 2026
nyblnet added a commit that referenced this pull request Sep 14, 2026
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