Manifest ReferenceLayers

Layers

The Layer union — image, vector, video, audio, text, and plugin layers, shared LayerCommon properties, positioning, z-order, and opacity.

A panel's artwork is a stack of layers. Layer is a union of six kinds, discriminated by the required kind property: image, vector, video, audio, text, and plugin. All kinds share the LayerCommon base for identity, stacking, opacity, transforms, and conditional visibility.

{ "kind": "image", "id": "ly-bg", "assetId": "img-alley", "z": 0 }

A layer without a valid kind fails validation against every branch of the union, producing a wall of oneOf errors. Check kind first. See Validation.

Shared properties (LayerCommon)

PropertyTypeDefaultDescription
idIdentifier—Layer ID (used by variants to override matching layers)
znumber—Stacking order within the panel — higher renders on top
opacitynumber 0–11Layer opacity
parallaxDepthnumber0Parallax factor; 0 = static, higher values move more with viewport motion
dragRevealboolean | NormalizedRect—Layer is revealed by dragging; a rect constrains the reveal area
transformobject—x (number), y (number), scale (number ≥ 0.01, default 1), rotation (number, default 0)
visibleIfJsonLogic—Layer only renders when this evaluates truthy against variables
namestring—Human-friendly layer name (authoring aid)

There is no blend-mode property in the current schema — compositing is plain alpha stacking via z and opacity.

Editor fields

LayerCommon also admits fields written by the CMS editor: x, y, width, height, scaleX, scaleY, rotation (editor transform), locked, visible (editor state), and content, fontFamily, fontSize, fontWeight, color, align, verticalAlign (editor text styling). They are valid on any layer kind but are authoring metadata; runtime rendering is driven by transform, z, opacity, and the kind-specific fields.

Layer kinds

ImageLayer (kind: "image")

PropertyTypeRequiredDescription
assetIdIdentifierYesImage catalog asset
clipRectNormalizedRect—Crop the source image to this region
visibleRectNormalizedRect—Visible area of the layer; if omitted the full layer is visible. Hidden areas render at reduced opacity in the editor

VectorLayer (kind: "vector")

PropertyTypeRequiredDescription
assetIdIdentifierYesVector catalog asset (SVG/PDF)

VideoLayer (kind: "video")

PropertyTypeRequiredDefaultDescription
assetIdIdentifierYes—Video catalog asset
mutedboolean—falseMute playback (work default: settings.ui.videoMutedDefault)
startAtMsinteger ≥ 0——Start offset on the media timeline
playModestring—"once"once | loop | pingpong | loop-from (schema 1.1+)
loopFromMsinteger ≥ 0——Loop re-entry point for loop-from (semantic rule: startAtMs <= loopFromMs < durationMs)
startModestring—"on-view"on-view | on-hover | on-click (schema 1.1+)
controlsboolean—falseShow native video controls (schema 1.1+)
autoplayboolean—falseLegacy (1.0) — superseded by startMode; only interpreted when startMode is absent
loopboolean—falseLegacy (1.0) — superseded by playMode; only interpreted when playMode is absent

Full playback semantics, the legacy-field mapping, and reverse variants are covered in Video.

AudioLayer (kind: "audio")

PropertyTypeRequiredDefaultDescription
assetIdIdentifierYes—Audio catalog asset
loopboolean—falseLoop playback
gainnumber 0–2—1Volume multiplier
startAtMsinteger ≥ 0——Start offset

Panels more commonly use the Panel.audio array of AudioTracks (which adds role and visibleIf) — see Audio.

TextLayer (kind: "text")

Only kind is required.

PropertyTypeDescription
textLocalizedStringLocalized text content
contentstringPlain-string alternative to text (written by the CMS)
styleRefIdentifierSchema 1.3+. Name of a reusable preset in settings.typography.textStyles. Unknown names are ignored
styleTextStyleInline styling: font (string), sizePt (number 4–200), color (ColorHex), strokeColor (ColorHex), strokeWidth (number 0–20). When styleRef is also set, inline fields override the preset field-by-field

When many layers share the same look (e.g. every caption of an album), define it once in settings.typography.textStyles and reference it via styleRef instead of repeating identical style blocks. Resolution cascade: work typography defaults → preset → inline style.

PluginLayer (kind: "plugin")

PropertyTypeRequiredDescription
pluginPluginInstanceYesThe plugin instance to render in this layer

Positioning and z-order

  • Stacking: layers render in ascending z. Speech bubbles and hotspots render above the layer stack.
  • Coordinates: geometry fields that are NormalizedRect/NormalizedNumber (clipRect, visibleRect, dragReveal) are fractions of the panel box — resolution-independent. transform.x/y offset the layer; transform.scale/rotation apply around the layer.
  • Parallax: parallaxDepth shifts layers at different rates during viewport motion for a depth effect (e.g. background 0, midground 0.3, foreground 0.6).

AssetRef

The schema defines a general-purpose asset reference form:

{ "assetId": "img-alley", "variant": "alley-2048.avif", "locale": "de-DE" }

An AssetRef is one of: a plain Identifier (catalog ID), an absolute Uri, or an object with required assetId plus optional variant and locale to pin a specific variant or localization. Layer assetId fields themselves are plain Identifiers; automatic variant/locale selection is described in Assets.

Example

A layered panel with parallax, a conditional overlay, and a caption:

{
  "layers": [
    { "kind": "image", "id": "ly-bg", "assetId": "img-alley", "z": 0, "parallaxDepth": 0 },
    { "kind": "image", "id": "ly-mid", "assetId": "img-detective", "z": 10, "parallaxDepth": 0.3 },
    {
      "kind": "image",
      "id": "ly-overlay",
      "assetId": "img-overlay-left",
      "z": 20,
      "opacity": 0.4,
      "visibleIf": { "==": [ { "var": "path.choice" }, "left" ] }
    },
    {
      "kind": "text",
      "id": "ly-caption",
      "z": 30,
      "opacity": 0.95,
      "text": { "en-US": "Left path chosen.", "de-DE": "Linker Pfad gewählt." },
      "styleRef": "caption",
      "style": { "sizePt": 16 }
    }
  ]
}

The caption references the work's caption preset from settings.typography.textStyles and only overrides the size inline — see Settings.