Contents
PR Summary
What problems was I solving
Customers need brand-accurate typography using licensed/self-hosted fonts not available through Google Fonts. This PR adds end-to-end support for custom, non-Google brand fonts so tenants can upload their own font files, manage font families and faces with license attestation, assign brands to body/heading/mono roles, and have page-ui serve uploaded fonts via stable /fonts/{tenantId}/{brandId}/{faceId}.{ext} URLs.
What user-facing changes did I ship
Adds Brand Fonts panel to the Brand Details workspace in the management UI where users can: create uploaded font families with aliases/attestation, request and complete face uploads with WOFF/WOFF2 files, assign uploaded/google/system fonts to body/heading/mono roles, view font status and face count. Page rendering now loads uploaded fonts via browser preloaded links instead of Google Fonts API and uses Stable CSS variables (--font-sans, --font-heading, --font-mono) in addition to themeTokens.
How I implemented it
The implementation follows the existing modular architecture: brand-service owns the data model and RPC operations (families, faces, assignments, upload sessions) in brand_font_families/brand_font_faces/brand_font_assignments tables; admin-gateway serves 7 HTTP endpoints for font management; management-gateway GraphQL extends with brand-font queries/mutations; management-ui view-model builds typed queries and GraphQL client refactored to support generic requests; brand-rendering-model generates @font-face CSS and preload metadata; page-service fetches brand fonts into RenderingBrandFonts and injects them into page previews and SSR; page-gateway serves stable font assets via /fonts/{tenantId}/{brandId}/{faceId}.{ext} proxy with Cache-Control immutable headers.
Description for the changelog
Adds non-Google brand font support: brand_service gains font families, faces, aliases, assignments, and upload sessions tables with strict row-level constraints; brand-service-api exposes RPC-safe font management methods; admin-gateway adds /font-families, /font-assignments HTTP endpoints; management-gateway GraphQL includes brand-font queries/mutations; management-ui adds BrandFontsPanel workflow with license attestation and face upload; page-ui rendering now emits @font-face CSS and preload links for uploaded fonts; page-service projects brand.fonts into RenderingBrand rendering model; page-gateway adds stable font serving proxy. Backwards compatible: brand.fonts is optional, legacy Google-font detection continues to work, customCss-based font extraction is unaffected.