validate served the composition over a loopback origin and let headless
Chrome fetch remote <img crossorigin>/@font-face assets cross-origin, while
the render pipeline downloads them to disk first. Buckets whose CORS
allowlist omits the loopback origin then failed the CORS-mode request with a
false net::ERR_FAILED that never occurs in the real render, pushing authors
(and agent pipelines) to delete crossorigin — which disables WebGL
color-grading/shaders for that asset.
Reuse producer's localizeRemote{Media,Image,FontFace}Sources in validate,
downloading into a temp dir served as an extra static-server asset root
(project dir untouched, cleaned up after). validate now matches render.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
The design-style extractor now captures a site's signature color grounds
and materials that a flat background-color misses:
- Capture gradient background-image + backdrop-filter on buttons/cards/nav.
- backgrounds[]: dominant gradient / mesh washes ranked by on-screen area
(includes ::before/::after glow orbs), chroma-weighted so a small vivid
brand wash outranks a large neutral scrim.
- glass[]: frosted-glass panels (backdrop-filter blur) with their raw
translucent fill, border, radius, shadow — ranked by area.
- nav CTA capture: keep filled buttons inside <nav> (a page's primary
"Sign up" / "Start for free" CTA that the old nav-drop lost), including
gradient-filled CTAs whose background-COLOR is transparent.
- Dedup keys for buttons/cards now include gradient + glass so a
gradient/frosted variant is not collapsed into its flat sibling.
- Fix: a fully-transparent fill rgba(...,0) now reports "transparent"
instead of #000000 — the old bug turned every transparent wrapper into a
phantom black button/card.
types: ComponentStyle gains backgroundImage/backdropFilter; DesignStyles
gains backgrounds[] and glass[].
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
designStyleExtractor now also extracts chip/pill/badge/tag, stat/metric cells, and
tab components — by class-substring selector plus a shape fallback (small + fully
rounded + short text) so hashed/utility class names (Tailwind, CSS-modules) are
still caught. It also emits a "transparent" sentinel for fully-transparent
(rgba(...,0)) grounds instead of collapsing them to #000000, so a transparent
chip/tab/stat on a light-ground site no longer reads as solid black.
fontMetadataExtractor now flags icon fonts (isIcon) by glyph coverage: a font is an
icon font only when it BOTH lacks a real Latin alphabet (<26 of A-Za-z) AND is
mostly (>50%) Private-Use-Area glyphs. The Latin gate matters — some text fonts pack
thousands of PUA glyphs yet are plainly text (Apple SF Pro is ~81% PUA but ships a
full alphabet; Descript's Booton ~50%); flagging by PUA ratio alone would strip a
brand's real typeface. Measured icon fonts: "hushly" 63% PUA / 7 letters, Font
Awesome 95% / 0 letters. Names alone can't identify icon fonts ("hushly",
"swiper-icons"), hence the glyph-based test.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>