dorfteich/docs/architecture/adr/0016-self-hosted-fonts.md
Claude Fable 5 0629411966 Add architecture documentation, ADRs, and operations concept
Initial deliverable of the architecture phase: 16 ADRs (stack, CRDT
collaboration, plugin sandbox, import/export, backups, CI/CD), data
model, permission model, real-time collaboration and plugin concepts,
deployment/operations/security documentation, and the milestone roadmap
that the implementation issues are derived from.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 14:36:16 +02:00

2.1 KiB
Raw Blame History

ADR 0016: Self-hosted Google Fonts, per-pond font configuration

  • Status: accepted
  • Date: 2026-07-04

Context

The vision: Pond Admins choose fonts for headings, body text, and monospace from a set of free Google Fonts; fonts must be served from the instance itself (never from Google's CDN) to avoid GDPR issues. Defaults: Roboto 400 (headings), Roboto 200 (body), Fira Code (monospace).

Decision

  • Curated font catalog: the repo contains a maintained list (~1525 families) of OFL/Apache-licensed families with the needed weights. A build step (deploy/fonts/) downloads the WOFF2 files at image build time from google-webfonts-helper/upstream sources and bakes them into the web image under /fonts/<family>/. No runtime download, no third-party requests from visitors' browsers — CSP allows font-src 'self' only.
  • Per-pond configuration: pond settings store three font slots (heading, body, mono), each referencing a catalog entry + weight. The app applies them as CSS custom properties (--font-heading, --font-body, --font-mono) on the pond's root element; @font-face rules for the catalog are generated once.
  • Defaults per vision: Roboto 400 / Roboto 200 / Fira Code. (Roboto 200 is provided via the variable font or the 200 static weight; fallback stack system-ui chain.)
  • Licensing: each catalog entry records its license (OFL/Apache); the catalog page in the app shows attribution.
  • Exports: the PDF renderer (ADR 0009) inlines the pond's fonts so PDFs match the on-screen look.

Consequences

  • Adding a font is a catalog PR + image rebuild — no runtime font management surface (deliberately small attack/complexity surface).
  • Image size grows by a few MiB per family (WOFF2, subset to latin/latin-ext by default) — negligible.

Alternatives considered

  • Runtime font download by the server on admin selection: flexible but adds an outbound dependency, cache invalidation, and licensing bookkeeping at runtime; rejected for v1.
  • Arbitrary font upload by Pond Admins: licensing risk and file-format attack surface; may become a Site-Admin-level feature later.