You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Light and dark variants for every ad, picked automatically (#211)
* feat(ads): light and dark variants for every ad, picked automatically
Every creative carried one palette, and the generator's prompt pushed it
dark. On a black-on-white publisher page the unit rendered as a hole
punched in the page. Nothing errored, so it was invisible until somebody
ran the tag on a white site.
Creatives now carry two palettes and the tag works out which to ask for:
- ad.js walks up from the container for the first painted background,
converts it to relative luminance and sends theme=light|dark. With
nothing painted anywhere the answer is light, because that is what the
browser paints. prefers-color-scheme deliberately does not decide it:
a page with no CSS is white on a dark desktop too. data-theme on the
unit overrides everything.
- The generator asks the model for both trios and trusts neither: each
is checked for real contrast against the background it will sit on
(4.5:1 text, 3:1 CTA) and a failing trio is replaced by a derived one.
- paletteFor() derives a missing variant on the fly, so a creative that
predates this renders correctly without waiting for the backfill.
- Slots get a default polarity for surfaces that cannot measure: a MOTD
over curl, a feed spliced at build time, a page with JS blocked.
Colour maths lives in lib/ads/theme.ts and is the single source for the
renderer, the editor preview and the backfill, so a backfilled palette
and a freshly generated one cannot disagree.
Also: the editor's colour pickers gained an opacity slider (#rrggbbaa,
with a checkerboard swatch), and inks that punch out of a chip now strip
alpha so a translucent background cannot make a CTA label see-through.
The hard-coded rgba(255,255,255,.08) hairline on every unit is now
theme-aware. It was a white haze: invisible on a dark page, a grey smear
on a light one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Add a side-by-side theme preview script
Renders one creative in both polarities into a single page, so the pair
can be eyeballed the way a publisher sees them rather than inferred from
a hex in a diff.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
0 commit comments