Channels, presets and Checks
The destinations a design can be made for, the exact pixel sizes and safe areas they publish, and every rule in the compliance gate.
A Channel is a delivery destination — an app store, a marketplace, a social platform — and it carries four things: a Spec (sizes, safe areas, formats), Checks (executable rules), an Idiom (written conventions), and a Connector (the publishing integration).
Two halves of that are worth separating carefully, because the difference is enforced rather than agreed:
- Checks gate. They are predicates with a pass/fail answer and a version
stamp, and a failure is a real failure. Two of them carry that weight — the
ones that say the rendered file is broken rather than that the design is
wrong. The rest report at
warning, which names the problem and blocks nothing; the table below says which is which. - Idiom advises. It is markdown loaded into a prompt, with no code path
through which a design could be rejected — the linter that reads it errors on
obligation language, so a convention cannot quietly harden into a
requirement. A critique is the same category: its severities are
problemandnote, nevererror.
Presets, and the safe area
A canvas that names a preset gets the destination's exact pixel size and its
safe area — the region the platform guarantees will not be cropped or covered by
its own chrome. That second half is the reason to prefer a preset over a
hand-written width/height: a canvas sized by hand has a zero safe area, and
nothing then remarks that the design is cropped where it ships.
The safe area is a guide, not a rule. It is in no Check on either pass, and
nothing that crosses it can fail a frame. Where a preset publishes a real figure
it is the platform's own; where none is published — every surface renders a link
card with its own crop — the inset is a margin wide enough to survive the worst
of them, which is a good default and a poor veto. So a Block reaching past it is
reported as an observation rather than a finding: vf_check returns those
beside its findings and outside its verdict, a critique carries them next to what
it thought of the design, and the editor draws the region as a dashed rectangle
on the canvas.
Two things follow from that. padding="safe" on the canvas insets flowing
children by the safe area, which is how most designs respect it without anybody
naming a number; and bleed on a Block declares that reaching past it is the
point, which silences the observation for that Block.
On a canvas sized by hand there is no preset and so no safe area — and
padding="safe" still gives it a margin, a proportional default drawn from the
side insets the presets above publish. The two are separate on purpose: nothing
reports a safe-area observation against that default, because it is a margin
this engine chose rather than a region any destination guaranteed. Write a
length to override it, and padding="0" to turn it off.
| Preset | Channel | Size | Safe area (t/r/b/l) | Format |
|---|---|---|---|---|
| AMAZON_MAIN | amazon | 2000 × 2000 | 150 / 150 / 150 / 150 | jpg, white ground required |
| APP_STORE_6_5 | app-store | 1242 × 2688 | 174 / 96 / 174 / 96 | png |
| APP_STORE_6_9 | app-store | 1290 × 2796 | 180 / 96 / 180 / 96 | png |
| GOOGLE_PLAY_PHONE | google-play | 1080 × 1920 | 144 / 84 / 144 / 84 | png |
| META_FEED_SQUARE | meta-ads | 1080 × 1080 | 108 / 108 / 108 / 108 | png |
| OG_IMAGE | web | 1200 × 630 | 48 / 60 / 48 / 60 | png |
| SOCIAL_CARD_16_9 | social | 1600 × 900 | 72 / 72 / 72 / 72 | png |
| SOCIAL_POST_SQUARE | social | 1080 × 1080 | 96 / 96 / 96 / 96 | png |
| SOCIAL_STORY_9_16 | social | 1080 × 1920 | 250 / 72 / 320 / 72 | png |
| Rule | Pass | Severity | What it holds |
|---|---|---|---|
| contrast | static, rendered | warning | Text meets WCAG's contrast ratio for the size it is set at — 4.5:1, or 3:1 where the run is large text by the standard's own definition. The static pass computes it from the declared colours; the rendered pass samples the pixels, so a photograph behind a headline is judged too. A warning, not a failure: no destination in the registry demands WCAG AA of a raster marketing image, and the tier that would apply to a display headline is the one the standard carves out. |
| clipped | rendered | warning | A node measured after layout is wholly or partly outside what the render shows — content that exists in the document and not in the picture. |
| overlap | rendered | warning | Two runs of text are drawn on top of one another. Only <vf-text> against <vf-text>: type over a photograph or a shape is the ordinary case, and glyphs over glyphs is the one nobody means. A warning rather than an error, because a layered effect is expressible even if it is rare. |
| glyph-coverage | static | error | Every character is one a bundled face can draw. An uncovered glyph is a failure rather than a fallback: the render network is blocked, so falling back would mean depending on the fonts of whichever machine rendered. Runs where the caller supplies the renderer's font coverage table. |
| synthesized-style | static | warning | A run is asked for a style no bundled face carries — a Chinese run set italic would be slanted by the browser rather than drawn. A warning, not a failure: the slant renders, and what it costs is reproducibility across Chromium builds rather than the picture the author is looking at. The hard half of the same hazard is in the schema, where `weight` admits 400 and 700 and nothing else. Runs where the caller supplies the renderer's font coverage table. |
| missing-asset | static | error | Every asset:// a Block points at is a file this Project actually holds. Runs where the caller supplies the Project's asset listing. |
| asset-font | static | warning | An SVG asset draws live <text>, which resolves against the rendering machine's own fonts — the one part of a render that the pinned environment does not make reproducible. Runs where the caller supplies the Project's asset listing. |
Two passes, one verdict
The static pass reads the document and its resolved layout. The rendered pass reads measured pixels: every node's box after layout, and the colour actually behind each run of text — so a headline over a photograph is judged on what is under it rather than on what was declared.
Every finding names the node and the parameter to change, and — where the rule can compute one — the value that would pass. A gate that names the rule and not the remedy is a gate that gets repaired badly; that was measured, not supposed.
A verdict is stamped with the rule-set version that produced it. Drift is that stamp against the current version, computed when somebody asks, rather than a boolean column that would be wrong for every stored row the instant a rule changed.