Skip to main content

Brand and tokens

A BrandProfile is a small JSON document describing a palette, fonts and safe margins. Pass it with --brand and the renderer resolves tokens across the whole spec.

{
"palette": {
"bg": "#0B1210",
"ink": "#E7EFEB",
"muted": "#7C8C86",
"accent": "#2DD4BF",
"accent2": "#B8975A"
},
"fonts": [{ "family": "Didot", "role": "display", "src": "./didot.woff2" }],
"safeMargin": 64
}

Tokens

Anywhere a colour is accepted, $palette.bg, $palette.ink, $palette.accent and friends resolve from the brand. $brand.* reaches the rest of the profile. A scene written entirely in tokens is brand-portable: render it against a different profile and it re-skins completely.

Two behaviours worth knowing:

  • Fonts merge. Brand fonts are added to any the scene declares.
  • The brand's face speaks. If a scene declares no default font, the brand's display or body face becomes the stage default — otherwise "branding" degrades into a palette swap of someone else's layout.

Getting a profile

brand_extract turns a reference image into a starter BrandProfile, assigning roles deterministically over the colour engine: bg is the dominant ground, ink the highest contrast against it, accent the most chromatic, plus muted.

cleya brand_extract --input reference.png --output brand.json

It is explicitly a heuristic starting point — read it and edit it before trusting it.

Checking conformance

cleya brand_check --input frame.png --brand brand.json --scene promo.json

Scores the frame's dominant colours against the palette by ΔE and returns 0–100. Neutrals pass by design — greys and near-blacks are not brand violations. Pass --scene to also check that the fonts the scene declares are the brand's.

Data binding

--data binds $data.<dot.path> tokens over a spec, type-preserving — a counter's "to": "$data.days" becomes the number, not the string. --data-each takes an array and renders one output per row, which is how one spec becomes a personalised set.