Goal: one shared typeface-resolution helper with graceful fallback; rendering never panics because a font is missing.
Evidence: caption.rs:46 .expect("No fallback font"), badge.rs:115, avatar_group.rs:172; the match_family_style(...).or_else(...) chain is duplicated in ~30 painters.
Invariants: missing font degrades to a default family + logged warning, never a panic; visual output unchanged when fonts resolve.
Acceptance: grep shows no .unwrap()/.expect() on typeface resolution in painters; a test resolves an unknown family without panicking.
Files: new helper in rustmotion-core renderer fonts module; all component painters currently duplicating the chain.
Verify: cargo test --workspace
Goal: one shared typeface-resolution helper with graceful fallback; rendering never panics because a font is missing.
Evidence:
caption.rs:46.expect("No fallback font"),badge.rs:115,avatar_group.rs:172; thematch_family_style(...).or_else(...)chain is duplicated in ~30 painters.Invariants: missing font degrades to a default family + logged warning, never a panic; visual output unchanged when fonts resolve.
Acceptance: grep shows no
.unwrap()/.expect()on typeface resolution in painters; a test resolves an unknown family without panicking.Files: new helper in
rustmotion-corerenderer fonts module; all component painters currently duplicating the chain.Verify:
cargo test --workspace