art50 · live demo

The label survives what breaks labels.

Every badge on this page is rendered live by a 9 KB script against the image's painted box — the official EU AI-transparency icons, unmodified. Resize the window: the labels stay on the picture.

01 · crop-proof

A hero image, aggressively cropped

Abstract generated artwork in blue and teal

The container forces object-fit: cover — the image is cropped after download, differently at every window width. A label burnt into these pixels server-side could land anywhere, including outside the visible area. This one is positioned against the rendered box, so it cannot.

02 · the three official marks

One attribute, the Commission's iconography

Fully AI-generated artwork data-ai="generated"
AI-modified artwork data-ai="edited"
Artwork with AI involvement data-ai="involved"

Wordmarks keep their real aspect ratio (3.16:1 and 3:1) — never squashed into a square, never redrawn. Each image also carries a screen-reader description in the page language; the badge itself is not announced twice.

03 · letterboxing handled

The badge sits on the picture, not beside it

Portrait-format AI artwork, letterboxed

A portrait image in a square container with object-fit: contain paints with empty gutters left and right. Naive overlays position against the element box and float in the gutter — this one computes the painted box and stays on the pixels.

04 · degrades, never disappears

Small images keep a legible mark

Tiny avatar, AI-generated
48 px
Small avatar, AI-generated
72 px
Avatar, AI-generated
128 px
Large avatar, AI-generated
240 px

Where the wordmark cannot fit legibly, the badge falls back to the square basic mark instead of shrinking below the 16 px floor — the disclosure stays visible. Screen readers always receive the full declared type, regardless of which mark is drawn.

05 · burned, for what leaves the page

OG images, e-mail, downloads: fixed dimensions, real pixels

OG image before burning
before
OG image with burned EU mark
after · art50-burn --type generated

A DOM overlay cannot follow an image into a share card or a download. The burn CLI composites the mark at known dimensions and re-embeds the machine-readable IPTC marker after the final re-encode. And it is honest about cost — verbatim output from burning a C2PA-signed source:

Burned generated mark into auto-burned.jpg (visible + XMP).
note: the source carried a C2PA manifest; re-encoding cannot preserve it
(measured 0/7 — see the explainer). EXIF was dropped.

06 · the scanner sees what you can't

Diagnostics for any page — including this one

The three images below are deliberately broken: an unresolved template variable (data-ai=""), a typo (data-ai="genrated"), and an image whose file itself claims AI provenance while the page fails to label it. The scanner report underneath is real output from scanning this very URL.

Broken example: empty data-ai
data-ai=""
Broken example: typo
data-ai="genrated"
Broken example: unlabelled AI provenance
unlabelled, file claims AI
$ art50-scan https://art50-demo.pages.dev/

14 image(s) found · 2 error(s), 1 warning(s), 0 note(s) · RED

✖ [empty-data-ai] data-ai is present but empty — a template variable that did not resolve. The overlay library labels nothing here; if this image is AI-generated, no disclosure is being made.
   https://art50-demo.pages.dev/img/square.jpg
✖ [unlabelled-ai-provenance] The image file itself claims AI provenance (http://cv.iptc.org/newscodes/digitalsourcetype/trainedAlgorithmicMedia) but the page does not label it.
   https://art50-demo.pages.dev/img/testbed-marked.jpg
▲ [unknown-data-ai] data-ai="genrated" is not a known value; the overlay falls back to the general disclosure mark. Check the spelling.
   https://art50-demo.pages.dev/img/portrait.jpg