Backgrounds and images
The background presets tied to the brand palette, and how to bring real assets (captures, logos, photos, icons) into a scene.
Backgrounds
The backdrop is painted by the top-level bg array in windows of time. Each window names one backdrop, and every preset reads the brand palette, so the same preset looks different for every theme.
{ "bg": [{ "preset": "soft", "from": 0, "to": 6 }] }bg is required. The engine used to pick one for you (a light brand got dotmatrix, a dark one aurora), which left the largest area of the frame as the single design decision no author ever made. Choose a preset, or say [{ "preset": "plain" }] for a deliberately flat field.
There are 22 presets:
paper · paperShapes · paperDots · soft · accent · ink · dotmatrix · aurora · mesh · constellation · spotlight · brandglow · plain · accentPlain · shapes · deep · dark · metallic · metallicSheen · gradientWash · blobs · liquid
The newest four all read the brand accent:
metallic— a dramatic dark backdrop: a curtain of vertical light rods with a shimmer sweeping across (brushed metal / a lit equaliser).metallicSheen— the same rods, darker and grainier, with a diagonal light sweep raking across.gradientWash— a mesh gradient: one saturated pool bleeding off a corner into white (light, premium).blobs— smaller, well-separated gradient blobs over a technical grid (light, airy, open).liquid— slow folds of the accent against true black, the "liquid light" backdrop. It owns the frame: put quiet type on it and nothing else. Renders a low-res warped field and scales it up, so the softness is an honest interpolation rather than a blur pass.
A pattern is a seasoning, not the wallpaper
The backdrop should exist on the real site. A plain, flat brand gets a plain field (plain, paper, accentPlain), never invented dots or shapes. Even when a site is textured, use a patterned preset on at most a beat or two, never throughout. Content beats stay plain so the content reads.
Each preset varies by seed (defaulting to a hash of the theme and preset name), so the same preset differs across brands. A theme can also author its own backdrop and a video pulls it in with { "use": "theme" }. See Themes.
Hand-authoring one
The preset vocabulary is good and it is finite. When a backdrop falls outside it, most often when you are reflecting a real site whose hero background is hand-written CSS, write the CSS instead of adding a preset:
{ "bg": [{
"html": "<style>.fan i{transform:rotate(calc(var(--t) * 12deg))}</style><div class=\"fan\"><i></i></div>",
"tone": "light"
}] }tone says whether your backdrop is light or dark. It is required, because the engine cannot read lightness out of your CSS, and without it a layer that sets no color falls back to the theme's ink and can land white-on-white.
Animate it with two custom properties the engine writes onto the element every frame, both usable inside calc():
var(--t)— seconds into the video.var(--p)— 0 to 1 across this window's own span.
CSS animation and transition do not run
A frame here is seeked, not played, across eight parallel workers, so nothing may depend on elapsed wall-clock. core/tokens.css disables both engine-wide. A CSS animation would not error, it would render a dead still, so the validator rejects animation, @keyframes and transition by name and points you at var(--t). The same applies to the html layer.
Markup is sanitised the same way as the html layer (core/sanitize-html.js): scripts and embedding elements are stripped, and so is any URL that leaves the fragment. A worked example lives in formats/scene/example-html-bg.json.
Images, in order of preference
Always prefer a real image. The order that produces the best result:
- Captured real UI, via
make capture. A livecomponentfragment is the highest-taste source: real logos, gradients, and copy come for free. See Brand reflection. - Free and openly-licensed images. Brand logos from
cdn.simpleicons.org, flags fromflagcdn.com, and CC0 or CC-BY photos viamake photos(attribution is recorded automatically). - Drawn icons with
svgIcon(name). Sixteen are built in:file,check,shield,bolt,dollar,link,cube,agent,braces,globe,arrowRight,spark,plug,clock,layers. - Generated topic cards via
make assets. - Emoji, as a last resort.
Never embed copyrighted media
Movie posters, album covers, film stills, news photos, and paid stock trigger Content ID claims. Capture the real product UI instead.
Fetching assets
make assets D=formats/scene/my-video.json # dry run: list missing icons
make assets D=formats/scene/my-video.json WRITE=1 # fetch themmake assets fills gaps: a country becomes a flag, a brand becomes a logo, anything else becomes a generated topic card. For photos:
make photos Q="mountain sunrise" NAME=hero N=4Openverse CC0, public-domain, and CC-BY photos are downloaded with attribution written to credits.json. Use them in a clipped image layer with ken.
Image treatments
A still with no treatment reads as slop. Give every image one:
kenis a slow Ken Burns push, capped at 8% travel, that never reverses.edgeFadedissolves the left and right edges into the background. SetedgeFadeColorto your background on dark scenes.radiusrounds the corners into a card;reflectadds a floor reflection.canvasFxruns a per-pixel Canvas pass over the image. There are 8:halftone,dither,mosaic,stipple,ascii,edgeDetect,crosshatch, andpixelSort(sort bright spans by luminance for a glitch smear). Name it directly or pass{ fx, cell, ink, paper, seed }. It bakes once at build into a static image, so the frame stays pure. Stylized presets (blueprint,comic,risograph,sketch,matrix,newsprint) expand to a tuned pass.
{ "type": "image", "src": "hero.png", "canvasFx": { "fx": "halftone", "cell": 8 } }Video and generated media
Turn any mp4 into a deterministic frame sequence for a clip layer:
make gen-clip IN=source.mp4 NAME=demoThis extracts frames plus a manifest with no external service. AI image and video generation (make gen-image, make gen-video) is also available when a KIE_API_KEY is set.