Appearance
Font Families & Google Fonts Picker
Follow-up to font-optimization branch. Separate branch/PR.
Problem
Today, each block uploads its own font file independently. There is no concept of a font family -- uploading Regular, SemiBold, and Bold for the same typeface means three separate uploads with no grouping. HTML blocks have no way to discover which fonts are available. Google Fonts are limited to a hardcoded list of 10.
Design
Data Model
New top-level field creativeFonts in creative JSON (requires backend schema PR):
ts
type CreativeFonts = Record<string, FontFamily>
type FontFamily = {
name: string // "Ford F-1", "Poppins"
source: 'custom' | 'google'
variants: FontVariant[]
}
type FontVariant = {
label: string // "Regular", "SemiBold", "Bold Italic"
style: 'normal' | 'italic'
url?: string // CDN URL (custom uploads only)
fontName?: string // original filename (custom uploads only)
}Block reference (replaces current customFont: { url, fontName }):
ts
customFont: {
family: string // key in creativeFonts
variant: string // matches variant label
}Backward compatible: old customFont: { url, fontName } treated as a single-variant family.
Backend PR
One-liner in start/validators/creative_validation.ts:
ts
creativeFonts: schema.object.optional().anyMembers()No database migration needed (longtext JSON blob).
TypefaceSection (Upload UX)
Inline compact approach -- extends current dropdown:
- Drop zone accepts multiple files (.woff2, .woff, .ttf, .otf)
- Auto-groups by font family name from metadata (name table)
- Variant chips below drop zone show uploaded variants
- Can add individual variants to existing family
- Can remove individual variants from family
- Uploads go to
creativeFonts, shared across all blocks
FontWeight Section
- Custom fonts: variant chips (Regular, SemiBold, Bold) based on what is in the family
- Google Fonts: keeps weight slider as today (supports arbitrary weights)
- Removed variant: block falls back to nearest available variant
Google Fonts Picker
- Searchable picker with full Google Fonts catalog via API
- Shows font preview in search results
- Selecting a family auto-fetches all available variants
- Favorites stored in localStorage (personal preference)
- Selected Google Font added to
creativeFontswithsource: 'google'
HTML Block Font Hints
Info section in HTML block config showing available fonts:
Available fonts:
Ford F-1 -> font-family: 'Ford-F1'; (Regular, SemiBold, Bold)
Poppins -> font-family: 'Poppins'; (Google Font)Click to copy font-family name to clipboard. Upload button in HTML config adds to creativeFonts (shared with all blocks).
Creative Engine Changes
- FontHelper reads
creativeFontsand registers one@font-faceper variant - Each variant gets a unique font-family name (e.g.
Ford-F1-SemiBold) - Backward compatible with old
customFontformat parseCustomStylingresolves family+variant to correct font-family name
Creative Composer Changes
- Font optimizer reads
creativeFontsfor subsetting - Only variants actually referenced by blocks are included in build
- Subsetting works per-variant (each variant gets its own charset)
Out of Scope
- Asset library integration (future -- replaces localStorage favorites with server-side per brand/group)
- Font preview in builder block list
- Variable fonts (single file with continuous weight axis)
Dependencies
font-optimizationbranch merged first (subsetting, DevTools improvements)- Backend schema PR for
creativeFontsfield