Spec reference
Conditionals, overlays & motion
Visibility, tightly-whitelisted literal styles, out-of-flow overlays, and declared motion — each with its cross-surface fidelity stated, never implied.
visibleWhen — conditional partsGeneratedCurated#
The part renders only when the prop matches. Boolean props map to canvas visibility bindings; enum conditions resolve per variant. Omit equals for booleans (truthy).
The driving prop, by canonical name.
Required for enum props; omit for booleans.
Refusals: Each of these fails the build by name — the generator refuses, it never papers over (source: core/emit-react.ts validateContract, exercised by the C2 eval family).
- an unknown prop; an
equalsvalue outside the enum
{
"anatomy": {
"root": {
"parts": {
"endArea": {
"parts": {
"close": {
"description": "Close affordance — rendered only when isDismissable.",
"element": "button",
"visibleWhen": {
"prop": "isDismissable"
},
"icon": {
"asset": "close"
},
"attrs": {
"aria-label": "Dismiss",
"type": "button",
"data-action": "dismiss"
}
}
}
}
}
}
}
}stylesWhen — conditional literal stylesGeneratedCurated#
Literal CSS — never tokens — applied when a prop matches. Boolean conditions ride the per-boolean data attribute the generator already emits (.root[data-is-disabled] { … }); enum conditions ride the root’s enum class. The whitelist is deliberately tight: behavioral and positional properties with no token vocabulary. A color or a dimension belongs in tokens, and a brace-wrapped value here is refused by name.
Whitelist (from STYLES_WHEN_ALLOWED in the schema): position, top, right, bottom, left, z-index, overflow, text-overflow, white-space, display, opacity, pointer-events, transform, transition, flex-direction, justify-content, align-items, cursor, text-decoration, mask.
Boolean or enum prop.
Required for enum props; must be omitted for booleans.
CSS property → literal value; keys must be in the whitelist.
Refusals: Each of these fails the build by name — the generator refuses, it never papers over (source: core/emit-react.ts validateContract, exercised by the C2 eval family).
- a property outside the whitelist
- a value that looks like a token reference — token-driven styling belongs in
tokens equalsmissing on an enum condition, present on a boolean one, or outside the enum
Declared fidelity limit: v1 applies nothing on the canvas — boolean properties can bind visibility, not style. A code-side surface, like events.
{
"anatomy": {
"root": {
"stylesWhen": [
{
"prop": "isDisabled",
"styles": {
"opacity": "0.55",
"pointer-events": "none",
"cursor": "not-allowed"
}
}
]
}
}
}overlay — out-of-flow attachmentGeneratedCurated#
The part renders out of flow, attached to one edge of the root — tooltip bubbles, combobox popups. Code: position: absolute with placement-derived insets, and the root becomes position: relative. Canvas: layoutPositioning: ABSOLUTE with placement-derived constraints, preserved through the amend path. Four placements in v1; offset and alignment tuning is a later axis.
The root edge the part attaches to.
Refusals: Each of these fails the build by name — the generator refuses, it never papers over (source: core/emit-react.ts validateContract, exercised by the C2 eval family).
- the root cannot be an overlay — overlays attach to the root
- an overlay cannot also
grow(in-flow sizing) oroverlapchildren (in-flow semantics)
{
"overlay": {
"placement": "top"
},
"tokens": {
"background-color": "{color.surface.raised}"
}
}No shipping contract carries overlay yet — the field-case tooltip (CBDS) pins its pointer with per-variant stylesWhen insets instead, which the shape page shows replayed from the committed capture. The example above is schema-validated at build time.
animation — declared motionGeneratedCurated#
CSS-side motion: spin for spinners, pulse for skeletons. Not representable on the canvas — a documented fidelity scope, like events. Nothing richer belongs in a contract: animation timing is behavior whose truth can’t be verified on both surfaces.
{
"anatomy": {
"root": {
"parts": {
"arc": {
"icon": {
"asset": "spinner"
},
"animation": "spin"
}
}
}
}
}