Skip to main content
Glama

Add elements to clips

add_elements

Add many elements across one or more clips in a single tool call. Replaces the per-element tool — always batch.

SEND LESS. Most batches repeat themselves — the same clip_index, element_type, font_setting, alignment or gradientSetting on every item. Hoist those into defaults and send them once; each item then carries only what differs, and overrides any key it sets (type_data merges one level). On a 20-30 element batch this typically cuts the call by a quarter to a half. returning shapes the response the way select shapes a get_clip read.

defaults: { clip_index: 2, element_type: 'text', type_data: { font_setting: { font: 'Inter', weight: '600' }, alignment: 'center' } } elements: [ { name: 'headline', x: 960, y: 400, type_data: { text: 'Hello', fontSize: 120 } }, ... ]

Use after calling get_element_schema to confirm the type_data shape per element_type. Items within one call are applied in order; returns one result entry per input item so partial success is fine.

Reuse instead of rebuilding: an item may pass component_id INSTEAD of element_type/type_data to insert a saved component from this workspace exactly as stored — no generation, instant — returning every new element_id plus its parameter_schema; set its content afterwards with update_elements(type_data.parameter_values). Find them with find(type='element_components'). Use base_component_id (with element_type='animation' and a prompt) only when you want a NEW variant rather than that component.

Z-order: list position IS z-index — later renders on top — and a new element goes on top by default. Pass insert_at: 'back' to put it behind what's already there, or insert_at: {before: id} / {after: id} to land next to a specific element — that also puts the new element in THAT node's group, which is the only way to place inside one. reorder_elements rewrites the whole order in one call, grouped clips included.

group + insert_at: {before|after} together: what the reference is relative to decides what gets positioned. Point at a node INSIDE the group and the ELEMENT takes that slot among its new siblings. Point at one OUTSIDE it and the GROUP takes that slot, with the element inside — which is how you put a backdrop pattern of N elements at a chosen depth as one hideable unit: hoist both into defaults and the first item seats the group, the rest just join it. The one refusal left is naming a reference outside a group that already exists somewhere else, since moving an established group is not what adding one element to it should do; seat the group where you want it in the call that CREATES it, because there is no reposition afterwards. front/back with a group follow the same principle: they address the GROUP only while the element is alone in it — the call that creates it — and once the group has other members they address the ELEMENT within the group's interior, so they will not move an established group either.

Grouping: pass group: "<name>" to keep a unit together (a card and its label, a stat and its caption) so the user can move or hide it as one thing. Items in one call sharing a name land in the same group, and a later call with that name adds to it. Grouping never changes coordinates. It does affect z-order: a group's members render contiguously at the group's slot, and a NEW group takes the slot of its first member, so grouping already-adjacent elements keeps their z-position while grouping scattered ones pulls them together at the lowest member's slot.

Concurrency: within ONE call every element lands in a single save. Across calls the conflict domain is the CLIP's element list, not the individual element, so you can fan this tool out across parallel subagents targeting DIFFERENT clips. Two concurrent add_elements calls on the SAME clip are NOT safe: every add claims that clip's element list, so the later call is REJECTED ('changed since this edit was based on') and nothing it sent is written — batch all of a clip's elements into ONE call instead. A rejection is not last-write-wins: re-read and re-apply. Do NOT run it concurrently with a whole-clip or whole-project mutation on the same guide (update_clips on that clip, add_clips/remove_clip/split_clip/duplicate_clip, add_audio, update_project) — those rewrite a larger scope and would clobber the element.

Element-type quirks (handled per-item): • zoom → x/y/width/height are ignored; use centerX/centerY in type_data • image → provide x/y/width/height (the clip is located by clip_index; the clip_id input is accepted but unused) • animation → x/y/width/height default to the full canvas if omitted (the clip is located by clip_index) For everything else, x/y/width/height are required.

Animation: pass a top-level keyframes array (sibling of x/y/type_data, NOT inside type_data) — entries are { timestamp, positionX?, positionY?, width?, height?, interpolation? } in canvas pixels. positionX/Y use the SAME alignment-aware origin as the element's x/y. Text caveat: width/height are not keyframable on text — animate its size with fontSize (letterSpacing/lineHeight/padding* are also keyframable).

Position origin: for TEXT y is the vertical CENTRE when centre-aligned and the TOP otherwise; every other type uses the top; x is the left edge, except TEXT where alignment picks it: left→left, center→centre, right→right.

To centre a label in a row, pill, chip, card or beside an icon: pass the container's centre line as y with y_anchor:'center'. The server centres the measured text in it, so it is one number and it holds for wrapped text. Add type_data.fit{max_height} whenever the text could wrap, so the box stays inside the space you gave it. y_anchor is a directive for computing the stored y, not a property that sticks — repeat it on any later call that moves the same label.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
defaultsNoValues shared by every item, sent once rather than repeated. Items win per key; type_data merges one level. E.g. defaults:{clip_index:1, element_type:'text', type_data:{font_setting:{font:'Inter',weight:'600'}, alignment:'center'}} then items carry only what differs.
elementsYesElements to add — at least one entry.
returningNoDeclare what comes back, the way get_clip's `select` shapes a read. Omit it and you get ids, the measured layout, and the clip audit in compact form — which names every problem but drops the explanatory prose. Values: 'ids' (element_id per result), 'layout' (the measured text fit — font_size_px, text_width_px, natural_width_px, line_count, fits_width/fits_height/fits — `fits` is the WIDTH check (the widest rendered line inside the box), `fits_height` is the separate height one — plus an `adjusted` entry whenever the measured line box replaced the height you sent; widen a box to natural_width_px, NOT text_width_px, which is the widest RENDERED line and so a lower bound on text that is already wrapping; plus `placement` {y_anchor, top, center, bottom} — where the box landed and what your `y` meant, emitted only when the origin was implicit or resolves to 'center'. Compare placement.center with a container's centre line to verify centring: a mis-anchored label is the one layout error nothing else reports), 'qa.codes' (audit counts and summary plus severity/code/element_ids per finding), 'qa' (the same audit with the full message and suggested fix on every finding — ask for this when a code alone isn't enough to act on). A text element measured on a fallback face is listed in top-level `font_warnings` whichever you choose. ERROR-severity findings always come back with their full message whichever you choose — including `returning:[]` and `['ids']`, which suppress WARNINGS only. A failed item always returns complete. Pass [] for just {total, succeeded, failed} plus any errors, the leanest write.
project_idYesProject ID

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed3 schema fields changed
    • changedInput schema / properties / defaults / properties / keyframes / anyOf
      Previous value: -[
      -  {
      -    "items": {
      -      "additionalProperties": false,
      -      "properties": {
      -        "backgroundBlur": {
      -          "description": "Backdrop blur behind the element",
      -          "type": "number"
      -        },
      -        "bezier": {
      -          "description": "Cubic-bezier [x1,y1,x2,y2]; used when interpolation is 'custom'.",
      -          "items": {
      -            "type": "number"
      -          },
      -          "maxItems": 4,
      -          "minItems": 4,
      -          "type": "array"
      -        },
      -        "bezier_overrides": {
      -          "additionalProperties": {
      -            "items": {
      -              "type": "number"
      -            },
      -            "maxItems": 4,
      -            "minItems": 4,
      -            "type": "array"
      -          },
      -          "description": "Per-property cubic-bezier override, e.g. {\"opacity\":[.4,0,.6,1]}, when two `custom`-eased properties in this entry need DIFFERENT curves. Keys must be properties present in this entry.",
      -          "propertyNames": {
      -            "enum": [
      -              "positionX",
      -              "positionY",
      -              "width",
      -              "height",
      -              "rotation",
      -              "scaleX",
      -              "scaleY",
      -              "rotateX",
      -              "rotateY",
      -              "cropX",
      -              "cropY",
      -              "cropWidth",
      -              "cropHeight",
      -              "opacity",
      -              "blur",
      -              "backgroundBlur",
      -              "strokeWidth",
      -              "strokeDash",
      -              "strokeGap",
      -              "strokeTrimStart",
      -              "strokeTrimEnd",
      -              "strokeTrimOffset",
      -              "textStrokeWidth",
      -              "textStrokeDash",
      -              "textStrokeGap",
      -              "imageBorderWidth",
      -              "shadowOffsetX",
      -              "shadowOffsetY",
      -              "shadowBlur",
      -              "shadowSpread",
      -              "borderRadiusTopLeft",
      -              "borderRadiusTopRight",
      -              "borderRadiusBottomRight",
      -              "borderRadiusBottomLeft",
      -              "imageCornerRadiusTopLeft",
      -              "imageCornerRadiusTopRight",
      -              "imageCornerRadiusBottomRight",
      -              "imageCornerRadiusBottomLeft",
      -              "videoCornerRadiusTopLeft",
      -              "videoCornerRadiusTopRight",
      -              "videoCornerRadiusBottomRight",
      -              "videoCornerRadiusBottomLeft",
      -              "fontSize",
      -              "lineHeight",
      -              "letterSpacing",
      -              "paddingTop",
      -              "paddingRight",
      -              "paddingBottom",
      -              "paddingLeft",
      -              "textBgRadiusTopLeft",
      -              "textBgRadiusTopRight",
      -              "textBgRadiusBottomRight",
      -              "textBgRadiusBottomLeft",
      -              "fillColor",
      -              "strokeColor",
      -              "textStrokeColor",
      -              "imageBorderColor",
      -              "textColor",
      -              "textBackgroundColor",
      -              "shadowColor"
      -            ],
      -            "type": "string"
      -          },
      -          "required": [
      -            "positionX",
      -            "positionY",
      -            "width",
      -            "height",
      -            "rotation",
      -            "scaleX",
      -            "scaleY",
      -            "rotateX",
      -            "rotateY",
      -            "cropX",
      -            "cropY",
      -            "cropWidth",
      -            "cropHeight",
      -            "opacity",
      -            "blur",
      -            "backgroundBlur",
      -            "strokeWidth",
      -            "strokeDash",
      -            "strokeGap",
      -            "strokeTrimStart",
      -            "strokeTrimEnd",
      -            "strokeTrimOffset",
      -            "textStrokeWidth",
      -            "textStrokeDash",
      -            "textStrokeGap",
      -            "imageBorderWidth",
      -            "shadowOffsetX",
      -            "shadowOffsetY",
      -            "shadowBlur",
      -            "shadowSpread",
      -            "borderRadiusTopLeft",
      -            "borderRadiusTopRight",
      -            "borderRadiusBottomRight",
      -            "borderRadiusBottomLeft",
      -            "imageCornerRadiusTopLeft",
      -            "imageCornerRadiusTopRight",
      -            "imageCornerRadiusBottomRight",
      -            "imageCornerRadiusBottomLeft",
      -            "videoCornerRadiusTopLeft",
      -            "videoCornerRadiusTopRight",
      -            "videoCornerRadiusBottomRight",
      -            "videoCornerRadiusBottomLeft",
      -            "fontSize",
      -            "lineHeight",
      -            "letterSpacing",
      -            "paddingTop",
      -            "paddingRight",
      -            "paddingBottom",
      -            "paddingLeft",
      -            "textBgRadiusTopLeft",
      -            "textBgRadiusTopRight",
      -            "textBgRadiusBottomRight",
      -            "textBgRadiusBottomLeft",
      -            "fillColor",
      -            "strokeColor",
      -            "textStrokeColor",
      -            "imageBorderColor",
      -            "textColor",
      -            "textBackgroundColor",
      -            "shadowColor"
      -          ],
      -          "type": "object"
      -        },
      -        "blur": {
      -          "description": "Layer blur",
      -          "type": "number"
      -        },
      -        "borderRadiusBottomLeft": {
      -          "description": "borderRadiusBottomLeft in canvas pixels",
      -          "type": "number"
      -        },
      -        "borderRadiusBottomRight": {
      -          "description": "borderRadiusBottomRight in canvas pixels",
      -          "type": "number"
      -        },
      -        "borderRadiusTopLeft": {
      -          "description": "borderRadiusTopLeft in canvas pixels",
      -          "type": "number"
      -        },
      -        "borderRadiusTopRight": {
      -          "description": "borderRadiusTopRight in canvas pixels",
      -          "type": "number"
      -        },
      -        "cropHeight": {
      -          "description": "cropHeight (native unit)",
      -          "type": "number"
      -        },
      -        "cropWidth": {
      -          "description": "cropWidth (native unit)",
      -          "type": "number"
      -        },
      -        "cropX": {
      -          "description": "cropX (native unit)",
      -          "type": "number"
      -        },
      -        "cropY": {
      -          "description": "cropY (native unit)",
      -          "type": "number"
      -        },
      -        "fillColor": {
      -          "description": "fillColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      -          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      -          "type": "string"
      -        },
      -        "fontSize": {
      -          "description": "Font size in CANVAS PIXELS (same unit as the top-level fontSize — NOT a fraction).",
      -          "type": "number"
      -        },
      -        "height": {
      -          "description": "Height in canvas pixels (0 allowed)",
      -          "minimum": 0,
      -          "type": "number"
      -        },
      -        "imageBorderColor": {
      -          "description": "imageBorderColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      -          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      -          "type": "string"
      -        },
      -        "imageBorderWidth": {
      -          "description": "imageBorderWidth in canvas pixels",
      -          "type": "number"
      -        },
      -        "imageCornerRadiusBottomLeft": {
      -          "description": "imageCornerRadiusBottomLeft in canvas pixels",
      -          "type": "number"
      -        },
      -        "imageCornerRadiusBottomRight": {
      -          "description": "imageCornerRadiusBottomRight in canvas pixels",
      -          "type": "number"
      -        },
      -        "imageCornerRadiusTopLeft": {
      -          "description": "imageCornerRadiusTopLeft in canvas pixels",
      -          "type": "number"
      -        },
      -        "imageCornerRadiusTopRight": {
      -          "description": "imageCornerRadiusTopRight in canvas pixels",
      -          "type": "number"
      -        },
      -        "interpolation": {
      -          "description": "Easing for THIS entry, applied to every property in it (default easeInOut). NOT `easing`.",
      -          "enum": [
      -            "linear",
      -            "easeInOut",
      -            "easeIn",
      -            "easeOut",
      -            "sigmoid",
      -            "smootherstep",
      -            "smoothstep",
      -            "hold",
      -            "easeInBack",
      -            "easeOutBack",
      -            "easeInOutBack",
      -            "custom"
      -          ],
      -          "type": "string"
      -        },
      -        "interpolation_overrides": {
      -          "additionalProperties": {
      -            "enum": [
      -              "linear",
      -              "easeInOut",
      -              "easeIn",
      -              "easeOut",
      -              "sigmoid",
      -              "smootherstep",
      -              "smoothstep",
      -              "hold",
      -              "easeInBack",
      -              "easeOutBack",
      -              "easeInOutBack",
      -              "custom"
      -            ],
      -            "type": "string"
      -          },
      -          "description": "Per-property easing override, e.g. {\"opacity\":\"linear\"} while the rest use `interpolation`. Keys must be keyframable properties present in this entry.",
      -          "propertyNames": {
      -            "enum": [
      -              "positionX",
      -              "positionY",
      -              "width",
      -              "height",
      -              "rotation",
      -              "scaleX",
      -              "scaleY",
      -              "rotateX",
      -              "rotateY",
      -              "cropX",
      -              "cropY",
      -              "cropWidth",
      -              "cropHeight",
      -              "opacity",
      -              "blur",
      -              "backgroundBlur",
      -              "strokeWidth",
      -              "strokeDash",
      -              "strokeGap",
      -              "strokeTrimStart",
      -              "strokeTrimEnd",
      -              "strokeTrimOffset",
      -              "textStrokeWidth",
      -              "textStrokeDash",
      -              "textStrokeGap",
      -              "imageBorderWidth",
      -              "shadowOffsetX",
      -              "shadowOffsetY",
      -              "shadowBlur",
      -              "shadowSpread",
      -              "borderRadiusTopLeft",
      -              "borderRadiusTopRight",
      -              "borderRadiusBottomRight",
      -              "borderRadiusBottomLeft",
      -              "imageCornerRadiusTopLeft",
      -              "imageCornerRadiusTopRight",
      -              "imageCornerRadiusBottomRight",
      -              "imageCornerRadiusBottomLeft",
      -              "videoCornerRadiusTopLeft",
      -              "videoCornerRadiusTopRight",
      -              "videoCornerRadiusBottomRight",
      -              "videoCornerRadiusBottomLeft",
      -              "fontSize",
      -              "lineHeight",
      -              "letterSpacing",
      -              "paddingTop",
      -              "paddingRight",
      -              "paddingBottom",
      -              "paddingLeft",
      -              "textBgRadiusTopLeft",
      -              "textBgRadiusTopRight",
      -              "textBgRadiusBottomRight",
      -              "textBgRadiusBottomLeft",
      -              "fillColor",
      -              "strokeColor",
      -              "textStrokeColor",
      -              "imageBorderColor",
      -              "textColor",
      -              "textBackgroundColor",
      -              "shadowColor"
      -            ],
      -            "type": "string"
      -          },
      -          "required": [
      -            "positionX",
      -            "positionY",
      -            "width",
      -            "height",
      -            "rotation",
      -            "scaleX",
      -            "scaleY",
      -            "rotateX",
      -            "rotateY",
      -            "cropX",
      -            "cropY",
      -            "cropWidth",
      -            "cropHeight",
      -            "opacity",
      -            "blur",
      -            "backgroundBlur",
      -            "strokeWidth",
      -            "strokeDash",
      -            "strokeGap",
      -            "strokeTrimStart",
      -            "strokeTrimEnd",
      -            "strokeTrimOffset",
      -            "textStrokeWidth",
      -            "textStrokeDash",
      -            "textStrokeGap",
      -            "imageBorderWidth",
      -            "shadowOffsetX",
      -            "shadowOffsetY",
      -            "shadowBlur",
      -            "shadowSpread",
      -            "borderRadiusTopLeft",
      -            "borderRadiusTopRight",
      -            "borderRadiusBottomRight",
      -            "borderRadiusBottomLeft",
      -            "imageCornerRadiusTopLeft",
      -            "imageCornerRadiusTopRight",
      -            "imageCornerRadiusBottomRight",
      -            "imageCornerRadiusBottomLeft",
      -            "videoCornerRadiusTopLeft",
      -            "videoCornerRadiusTopRight",
      -            "videoCornerRadiusBottomRight",
      -            "videoCornerRadiusBottomLeft",
      -            "fontSize",
      -            "lineHeight",
      -            "letterSpacing",
      -            "paddingTop",
      -            "paddingRight",
      -            "paddingBottom",
      -            "paddingLeft",
      -            "textBgRadiusTopLeft",
      -            "textBgRadiusTopRight",
      -            "textBgRadiusBottomRight",
      -            "textBgRadiusBottomLeft",
      -            "fillColor",
      -            "strokeColor",
      -            "textStrokeColor",
      -            "imageBorderColor",
      -            "textColor",
      -            "textBackgroundColor",
      -            "shadowColor"
      -          ],
      -          "type": "object"
      -        },
      -        "letterSpacing": {
      -          "description": "Letter spacing in canvas pixels.",
      -          "type": "number"
      -        },
      -        "lineHeight": {
      -          "description": "lineHeight (native unit)",
      -          "type": "number"
      -        },
      -        "opacity": {
      -          "description": "Opacity 0-100",
      -          "maximum": 100,
      -          "minimum": 0,
      -          "type": "number"
      -        },
      -        "paddingBottom": {
      -          "description": "paddingBottom in canvas pixels",
      -          "type": "number"
      -        },
      -        "paddingLeft": {
      -          "description": "paddingLeft in canvas pixels",
      -          "type": "number"
      -        },
      -        "paddingRight": {
      -          "description": "paddingRight in canvas pixels",
      -          "type": "number"
      -        },
      -        "paddingTop": {
      -          "description": "paddingTop in canvas pixels",
      -          "type": "number"
      -        },
      -        "positionX": {
      -          "description": "X position in canvas pixels (NOT `x`). Same origin as the element's top-level x: `x` is the left edge, except TEXT where alignment picks it: left→left, center→centre, right→right.",
      -          "type": "number"
      -        },
      -        "positionY": {
      -          "description": "Y position in canvas pixels (NOT `y`). Same origin as the element's top-level y: for TEXT `y` is the vertical CENTRE when centre-aligned and the TOP otherwise; every other type uses the top. y_anchor applies to the element's own y, NOT to keyframe values, so read the element back and key off its stored y.",
      -          "type": "number"
      -        },
      -        "rotateX": {
      -          "description": "rotateX (native unit)",
      -          "type": "number"
      -        },
      -        "rotateY": {
      -          "description": "rotateY (native unit)",
      -          "type": "number"
      -        },
      -        "rotation": {
      -          "description": "Rotation in degrees",
      -          "type": "number"
      -        },
      -        "scaleX": {
      -          "description": "Horizontal scale multiplier (1 = 100%)",
      -          "type": "number"
      -        },
      -        "scaleY": {
      -          "description": "Vertical scale multiplier (1 = 100%)",
      -          "type": "number"
      -        },
      -        "shadowBlur": {
      -          "description": "shadowBlur in canvas pixels",
      -          "type": "number"
      -        },
      -        "shadowColor": {
      -          "description": "shadowColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      -          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      -          "type": "string"
      -        },
      -        "shadowOffsetX": {
      -          "description": "shadowOffsetX in canvas pixels",
      -          "type": "number"
      -        },
      -        "shadowOffsetY": {
      -          "description": "shadowOffsetY in canvas pixels",
      -          "type": "number"
      -        },
      -        "shadowSpread": {
      -          "description": "shadowSpread in canvas pixels",
      -          "type": "number"
      -        },
      -        "strokeColor": {
      -          "description": "strokeColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      -          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      -          "type": "string"
      -        },
      -        "strokeDash": {
      -          "description": "strokeDash in canvas pixels",
      -          "type": "number"
      -        },
      -        "strokeGap": {
      -          "description": "strokeGap in canvas pixels",
      -          "type": "number"
      -        },
      -        "strokeTrimEnd": {
      -          "description": "strokeTrimEnd (native unit)",
      -          "type": "number"
      -        },
      -        "strokeTrimOffset": {
      -          "description": "strokeTrimOffset (native unit)",
      -          "type": "number"
      -        },
      -        "strokeTrimStart": {
      -          "description": "strokeTrimStart (native unit)",
      -          "type": "number"
      -        },
      -        "strokeWidth": {
      -          "description": "strokeWidth in canvas pixels",
      -          "type": "number"
      -        },
      -        "textBackgroundColor": {
      -          "description": "textBackgroundColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      -          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      -          "type": "string"
      -        },
      -        "textBgRadiusBottomLeft": {
      -          "description": "textBgRadiusBottomLeft in canvas pixels",
      -          "type": "number"
      -        },
      -        "textBgRadiusBottomRight": {
      -          "description": "textBgRadiusBottomRight in canvas pixels",
      -          "type": "number"
      -        },
      -        "textBgRadiusTopLeft": {
      -          "description": "textBgRadiusTopLeft in canvas pixels",
      -          "type": "number"
      -        },
      -        "textBgRadiusTopRight": {
      -          "description": "textBgRadiusTopRight in canvas pixels",
      -          "type": "number"
      -        },
      -        "textColor": {
      -          "description": "textColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      -          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      -          "type": "string"
      -        },
      -        "textStrokeColor": {
      -          "description": "textStrokeColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      -          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      -          "type": "string"
      -        },
      -        "textStrokeDash": {
      -          "description": "textStrokeDash in canvas pixels",
      -          "type": "number"
      -        },
      -        "textStrokeGap": {
      -          "description": "textStrokeGap in canvas pixels",
      -          "type": "number"
      -        },
      -        "textStrokeWidth": {
      -          "description": "textStrokeWidth in canvas pixels",
      -          "type": "number"
      -        },
      -        "timestamp": {
      -          "description": "Clip-relative time in seconds",
      -          "minimum": 0,
      -          "type": "number"
      -        },
      -        "videoCornerRadiusBottomLeft": {
      -          "description": "videoCornerRadiusBottomLeft in canvas pixels",
      -          "type": "number"
      -        },
      -        "videoCornerRadiusBottomRight": {
      -          "description": "videoCornerRadiusBottomRight in canvas pixels",
      -          "type": "number"
      -        },
      -        "videoCornerRadiusTopLeft": {
      -          "description": "videoCornerRadiusTopLeft in canvas pixels",
      -          "type": "number"
      -        },
      -        "videoCornerRadiusTopRight": {
      -          "description": "videoCornerRadiusTopRight in canvas pixels",
      -          "type": "number"
      -        },
      -        "width": {
      -          "description": "Width in canvas pixels (0 allowed — e.g. a bar that draws in from 0)",
      -          "minimum": 0,
      -          "type": "number"
      -        }
      -      },
      -      "required": [
      -        "timestamp"
      -      ],
      -      "type": "object"
      -    },
      -    "type": "array"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "items": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "backgroundBlur": {
      +          "description": "Backdrop blur behind the element",
      +          "type": "number"
      +        },
      +        "bezier": {
      +          "description": "Cubic-bezier [x1,y1,x2,y2]; used when interpolation is 'custom'.",
      +          "items": {
      +            "type": "number"
      +          },
      +          "maxItems": 4,
      +          "minItems": 4,
      +          "type": "array"
      +        },
      +        "bezier_overrides": {
      +          "additionalProperties": {
      +            "items": {
      +              "type": "number"
      +            },
      +            "maxItems": 4,
      +            "minItems": 4,
      +            "type": "array"
      +          },
      +          "description": "Per-property cubic-bezier override, e.g. {\"opacity\":[.4,0,.6,1]}, when two `custom`-eased properties in this entry need DIFFERENT curves. Keys must be properties present in this entry.",
      +          "propertyNames": {
      +            "enum": [
      +              "positionX",
      +              "positionY",
      +              "width",
      +              "height",
      +              "rotation",
      +              "scaleX",
      +              "scaleY",
      +              "rotateX",
      +              "rotateY",
      +              "cropX",
      +              "cropY",
      +              "cropWidth",
      +              "cropHeight",
      +              "opacity",
      +              "blur",
      +              "backgroundBlur",
      +              "strokeWidth",
      +              "strokeDash",
      +              "strokeGap",
      +              "strokeTrimStart",
      +              "strokeTrimEnd",
      +              "strokeTrimOffset",
      +              "textStrokeWidth",
      +              "textStrokeDash",
      +              "textStrokeGap",
      +              "imageBorderWidth",
      +              "shadowOffsetX",
      +              "shadowOffsetY",
      +              "shadowBlur",
      +              "shadowSpread",
      +              "borderRadiusTopLeft",
      +              "borderRadiusTopRight",
      +              "borderRadiusBottomRight",
      +              "borderRadiusBottomLeft",
      +              "imageCornerRadiusTopLeft",
      +              "imageCornerRadiusTopRight",
      +              "imageCornerRadiusBottomRight",
      +              "imageCornerRadiusBottomLeft",
      +              "videoCornerRadiusTopLeft",
      +              "videoCornerRadiusTopRight",
      +              "videoCornerRadiusBottomRight",
      +              "videoCornerRadiusBottomLeft",
      +              "fontSize",
      +              "lineHeight",
      +              "letterSpacing",
      +              "paddingTop",
      +              "paddingRight",
      +              "paddingBottom",
      +              "paddingLeft",
      +              "textBgRadiusTopLeft",
      +              "textBgRadiusTopRight",
      +              "textBgRadiusBottomRight",
      +              "textBgRadiusBottomLeft",
      +              "fillColor",
      +              "strokeColor",
      +              "textStrokeColor",
      +              "imageBorderColor",
      +              "textColor",
      +              "textBackgroundColor",
      +              "shadowColor"
      +            ],
      +            "type": "string"
      +          },
      +          "type": "object"
      +        },
      +        "blur": {
      +          "description": "Layer blur",
      +          "type": "number"
      +        },
      +        "borderRadiusBottomLeft": {
      +          "description": "borderRadiusBottomLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "borderRadiusBottomRight": {
      +          "description": "borderRadiusBottomRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "borderRadiusTopLeft": {
      +          "description": "borderRadiusTopLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "borderRadiusTopRight": {
      +          "description": "borderRadiusTopRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "cropHeight": {
      +          "description": "cropHeight (native unit)",
      +          "type": "number"
      +        },
      +        "cropWidth": {
      +          "description": "cropWidth (native unit)",
      +          "type": "number"
      +        },
      +        "cropX": {
      +          "description": "cropX (native unit)",
      +          "type": "number"
      +        },
      +        "cropY": {
      +          "description": "cropY (native unit)",
      +          "type": "number"
      +        },
      +        "fillColor": {
      +          "description": "fillColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "fontSize": {
      +          "description": "Font size in CANVAS PIXELS (same unit as the top-level fontSize — NOT a fraction).",
      +          "type": "number"
      +        },
      +        "height": {
      +          "description": "Height in canvas pixels (0 allowed)",
      +          "minimum": 0,
      +          "type": "number"
      +        },
      +        "imageBorderColor": {
      +          "description": "imageBorderColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "imageBorderWidth": {
      +          "description": "imageBorderWidth in canvas pixels",
      +          "type": "number"
      +        },
      +        "imageCornerRadiusBottomLeft": {
      +          "description": "imageCornerRadiusBottomLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "imageCornerRadiusBottomRight": {
      +          "description": "imageCornerRadiusBottomRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "imageCornerRadiusTopLeft": {
      +          "description": "imageCornerRadiusTopLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "imageCornerRadiusTopRight": {
      +          "description": "imageCornerRadiusTopRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "interpolation": {
      +          "description": "Easing for THIS entry, applied to every property in it (default easeInOut). NOT `easing`.",
      +          "enum": [
      +            "linear",
      +            "easeInOut",
      +            "easeIn",
      +            "easeOut",
      +            "sigmoid",
      +            "smootherstep",
      +            "smoothstep",
      +            "hold",
      +            "easeInBack",
      +            "easeOutBack",
      +            "easeInOutBack",
      +            "custom"
      +          ],
      +          "type": "string"
      +        },
      +        "interpolation_overrides": {
      +          "additionalProperties": {
      +            "enum": [
      +              "linear",
      +              "easeInOut",
      +              "easeIn",
      +              "easeOut",
      +              "sigmoid",
      +              "smootherstep",
      +              "smoothstep",
      +              "hold",
      +              "easeInBack",
      +              "easeOutBack",
      +              "easeInOutBack",
      +              "custom"
      +            ],
      +            "type": "string"
      +          },
      +          "description": "Per-property easing override, e.g. {\"opacity\":\"linear\"} while the rest use `interpolation`. Keys must be keyframable properties present in this entry.",
      +          "propertyNames": {
      +            "enum": [
      +              "positionX",
      +              "positionY",
      +              "width",
      +              "height",
      +              "rotation",
      +              "scaleX",
      +              "scaleY",
      +              "rotateX",
      +              "rotateY",
      +              "cropX",
      +              "cropY",
      +              "cropWidth",
      +              "cropHeight",
      +              "opacity",
      +              "blur",
      +              "backgroundBlur",
      +              "strokeWidth",
      +              "strokeDash",
      +              "strokeGap",
      +              "strokeTrimStart",
      +              "strokeTrimEnd",
      +              "strokeTrimOffset",
      +              "textStrokeWidth",
      +              "textStrokeDash",
      +              "textStrokeGap",
      +              "imageBorderWidth",
      +              "shadowOffsetX",
      +              "shadowOffsetY",
      +              "shadowBlur",
      +              "shadowSpread",
      +              "borderRadiusTopLeft",
      +              "borderRadiusTopRight",
      +              "borderRadiusBottomRight",
      +              "borderRadiusBottomLeft",
      +              "imageCornerRadiusTopLeft",
      +              "imageCornerRadiusTopRight",
      +              "imageCornerRadiusBottomRight",
      +              "imageCornerRadiusBottomLeft",
      +              "videoCornerRadiusTopLeft",
      +              "videoCornerRadiusTopRight",
      +              "videoCornerRadiusBottomRight",
      +              "videoCornerRadiusBottomLeft",
      +              "fontSize",
      +              "lineHeight",
      +              "letterSpacing",
      +              "paddingTop",
      +              "paddingRight",
      +              "paddingBottom",
      +              "paddingLeft",
      +              "textBgRadiusTopLeft",
      +              "textBgRadiusTopRight",
      +              "textBgRadiusBottomRight",
      +              "textBgRadiusBottomLeft",
      +              "fillColor",
      +              "strokeColor",
      +              "textStrokeColor",
      +              "imageBorderColor",
      +              "textColor",
      +              "textBackgroundColor",
      +              "shadowColor"
      +            ],
      +            "type": "string"
      +          },
      +          "type": "object"
      +        },
      +        "letterSpacing": {
      +          "description": "Letter spacing in canvas pixels.",
      +          "type": "number"
      +        },
      +        "lineHeight": {
      +          "description": "lineHeight (native unit)",
      +          "type": "number"
      +        },
      +        "opacity": {
      +          "description": "Opacity 0-100",
      +          "maximum": 100,
      +          "minimum": 0,
      +          "type": "number"
      +        },
      +        "paddingBottom": {
      +          "description": "paddingBottom in canvas pixels",
      +          "type": "number"
      +        },
      +        "paddingLeft": {
      +          "description": "paddingLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "paddingRight": {
      +          "description": "paddingRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "paddingTop": {
      +          "description": "paddingTop in canvas pixels",
      +          "type": "number"
      +        },
      +        "positionX": {
      +          "description": "X position in canvas pixels (NOT `x`). Same origin as the element's top-level x: `x` is the left edge, except TEXT where alignment picks it: left→left, center→centre, right→right.",
      +          "type": "number"
      +        },
      +        "positionY": {
      +          "description": "Y position in canvas pixels (NOT `y`). Same origin as the element's top-level y: for TEXT `y` is the vertical CENTRE when centre-aligned and the TOP otherwise; every other type uses the top. y_anchor applies to the element's own y, NOT to keyframe values, so read the element back and key off its stored y.",
      +          "type": "number"
      +        },
      +        "rotateX": {
      +          "description": "rotateX (native unit)",
      +          "type": "number"
      +        },
      +        "rotateY": {
      +          "description": "rotateY (native unit)",
      +          "type": "number"
      +        },
      +        "rotation": {
      +          "description": "Rotation in degrees",
      +          "type": "number"
      +        },
      +        "scaleX": {
      +          "description": "Horizontal scale multiplier (1 = 100%)",
      +          "type": "number"
      +        },
      +        "scaleY": {
      +          "description": "Vertical scale multiplier (1 = 100%)",
      +          "type": "number"
      +        },
      +        "shadowBlur": {
      +          "description": "shadowBlur in canvas pixels",
      +          "type": "number"
      +        },
      +        "shadowColor": {
      +          "description": "shadowColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "shadowOffsetX": {
      +          "description": "shadowOffsetX in canvas pixels",
      +          "type": "number"
      +        },
      +        "shadowOffsetY": {
      +          "description": "shadowOffsetY in canvas pixels",
      +          "type": "number"
      +        },
      +        "shadowSpread": {
      +          "description": "shadowSpread in canvas pixels",
      +          "type": "number"
      +        },
      +        "strokeColor": {
      +          "description": "strokeColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "strokeDash": {
      +          "description": "strokeDash in canvas pixels",
      +          "type": "number"
      +        },
      +        "strokeGap": {
      +          "description": "strokeGap in canvas pixels",
      +          "type": "number"
      +        },
      +        "strokeTrimEnd": {
      +          "description": "strokeTrimEnd (native unit)",
      +          "type": "number"
      +        },
      +        "strokeTrimOffset": {
      +          "description": "strokeTrimOffset (native unit)",
      +          "type": "number"
      +        },
      +        "strokeTrimStart": {
      +          "description": "strokeTrimStart (native unit)",
      +          "type": "number"
      +        },
      +        "strokeWidth": {
      +          "description": "strokeWidth in canvas pixels",
      +          "type": "number"
      +        },
      +        "textBackgroundColor": {
      +          "description": "textBackgroundColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "textBgRadiusBottomLeft": {
      +          "description": "textBgRadiusBottomLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "textBgRadiusBottomRight": {
      +          "description": "textBgRadiusBottomRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "textBgRadiusTopLeft": {
      +          "description": "textBgRadiusTopLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "textBgRadiusTopRight": {
      +          "description": "textBgRadiusTopRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "textColor": {
      +          "description": "textColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "textStrokeColor": {
      +          "description": "textStrokeColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "textStrokeDash": {
      +          "description": "textStrokeDash in canvas pixels",
      +          "type": "number"
      +        },
      +        "textStrokeGap": {
      +          "description": "textStrokeGap in canvas pixels",
      +          "type": "number"
      +        },
      +        "textStrokeWidth": {
      +          "description": "textStrokeWidth in canvas pixels",
      +          "type": "number"
      +        },
      +        "timestamp": {
      +          "description": "Clip-relative time in seconds",
      +          "minimum": 0,
      +          "type": "number"
      +        },
      +        "videoCornerRadiusBottomLeft": {
      +          "description": "videoCornerRadiusBottomLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "videoCornerRadiusBottomRight": {
      +          "description": "videoCornerRadiusBottomRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "videoCornerRadiusTopLeft": {
      +          "description": "videoCornerRadiusTopLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "videoCornerRadiusTopRight": {
      +          "description": "videoCornerRadiusTopRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "width": {
      +          "description": "Width in canvas pixels (0 allowed — e.g. a bar that draws in from 0)",
      +          "minimum": 0,
      +          "type": "number"
      +        }
      +      },
      +      "required": [
      +        "timestamp"
      +      ],
      +      "type": "object"
      +    },
      +    "type": "array"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / elements / items / properties / keyframes / anyOf
      Previous value: -[
      -  {
      -    "items": {
      -      "additionalProperties": false,
      -      "properties": {
      -        "backgroundBlur": {
      -          "description": "Backdrop blur behind the element",
      -          "type": "number"
      -        },
      -        "bezier": {
      -          "description": "Cubic-bezier [x1,y1,x2,y2]; used when interpolation is 'custom'.",
      -          "items": {
      -            "type": "number"
      -          },
      -          "maxItems": 4,
      -          "minItems": 4,
      -          "type": "array"
      -        },
      -        "bezier_overrides": {
      -          "additionalProperties": {
      -            "items": {
      -              "type": "number"
      -            },
      -            "maxItems": 4,
      -            "minItems": 4,
      -            "type": "array"
      -          },
      -          "description": "Per-property cubic-bezier override, e.g. {\"opacity\":[.4,0,.6,1]}, when two `custom`-eased properties in this entry need DIFFERENT curves. Keys must be properties present in this entry.",
      -          "propertyNames": {
      -            "enum": [
      -              "positionX",
      -              "positionY",
      -              "width",
      -              "height",
      -              "rotation",
      -              "scaleX",
      -              "scaleY",
      -              "rotateX",
      -              "rotateY",
      -              "cropX",
      -              "cropY",
      -              "cropWidth",
      -              "cropHeight",
      -              "opacity",
      -              "blur",
      -              "backgroundBlur",
      -              "strokeWidth",
      -              "strokeDash",
      -              "strokeGap",
      -              "strokeTrimStart",
      -              "strokeTrimEnd",
      -              "strokeTrimOffset",
      -              "textStrokeWidth",
      -              "textStrokeDash",
      -              "textStrokeGap",
      -              "imageBorderWidth",
      -              "shadowOffsetX",
      -              "shadowOffsetY",
      -              "shadowBlur",
      -              "shadowSpread",
      -              "borderRadiusTopLeft",
      -              "borderRadiusTopRight",
      -              "borderRadiusBottomRight",
      -              "borderRadiusBottomLeft",
      -              "imageCornerRadiusTopLeft",
      -              "imageCornerRadiusTopRight",
      -              "imageCornerRadiusBottomRight",
      -              "imageCornerRadiusBottomLeft",
      -              "videoCornerRadiusTopLeft",
      -              "videoCornerRadiusTopRight",
      -              "videoCornerRadiusBottomRight",
      -              "videoCornerRadiusBottomLeft",
      -              "fontSize",
      -              "lineHeight",
      -              "letterSpacing",
      -              "paddingTop",
      -              "paddingRight",
      -              "paddingBottom",
      -              "paddingLeft",
      -              "textBgRadiusTopLeft",
      -              "textBgRadiusTopRight",
      -              "textBgRadiusBottomRight",
      -              "textBgRadiusBottomLeft",
      -              "fillColor",
      -              "strokeColor",
      -              "textStrokeColor",
      -              "imageBorderColor",
      -              "textColor",
      -              "textBackgroundColor",
      -              "shadowColor"
      -            ],
      -            "type": "string"
      -          },
      -          "required": [
      -            "positionX",
      -            "positionY",
      -            "width",
      -            "height",
      -            "rotation",
      -            "scaleX",
      -            "scaleY",
      -            "rotateX",
      -            "rotateY",
      -            "cropX",
      -            "cropY",
      -            "cropWidth",
      -            "cropHeight",
      -            "opacity",
      -            "blur",
      -            "backgroundBlur",
      -            "strokeWidth",
      -            "strokeDash",
      -            "strokeGap",
      -            "strokeTrimStart",
      -            "strokeTrimEnd",
      -            "strokeTrimOffset",
      -            "textStrokeWidth",
      -            "textStrokeDash",
      -            "textStrokeGap",
      -            "imageBorderWidth",
      -            "shadowOffsetX",
      -            "shadowOffsetY",
      -            "shadowBlur",
      -            "shadowSpread",
      -            "borderRadiusTopLeft",
      -            "borderRadiusTopRight",
      -            "borderRadiusBottomRight",
      -            "borderRadiusBottomLeft",
      -            "imageCornerRadiusTopLeft",
      -            "imageCornerRadiusTopRight",
      -            "imageCornerRadiusBottomRight",
      -            "imageCornerRadiusBottomLeft",
      -            "videoCornerRadiusTopLeft",
      -            "videoCornerRadiusTopRight",
      -            "videoCornerRadiusBottomRight",
      -            "videoCornerRadiusBottomLeft",
      -            "fontSize",
      -            "lineHeight",
      -            "letterSpacing",
      -            "paddingTop",
      -            "paddingRight",
      -            "paddingBottom",
      -            "paddingLeft",
      -            "textBgRadiusTopLeft",
      -            "textBgRadiusTopRight",
      -            "textBgRadiusBottomRight",
      -            "textBgRadiusBottomLeft",
      -            "fillColor",
      -            "strokeColor",
      -            "textStrokeColor",
      -            "imageBorderColor",
      -            "textColor",
      -            "textBackgroundColor",
      -            "shadowColor"
      -          ],
      -          "type": "object"
      -        },
      -        "blur": {
      -          "description": "Layer blur",
      -          "type": "number"
      -        },
      -        "borderRadiusBottomLeft": {
      -          "description": "borderRadiusBottomLeft in canvas pixels",
      -          "type": "number"
      -        },
      -        "borderRadiusBottomRight": {
      -          "description": "borderRadiusBottomRight in canvas pixels",
      -          "type": "number"
      -        },
      -        "borderRadiusTopLeft": {
      -          "description": "borderRadiusTopLeft in canvas pixels",
      -          "type": "number"
      -        },
      -        "borderRadiusTopRight": {
      -          "description": "borderRadiusTopRight in canvas pixels",
      -          "type": "number"
      -        },
      -        "cropHeight": {
      -          "description": "cropHeight (native unit)",
      -          "type": "number"
      -        },
      -        "cropWidth": {
      -          "description": "cropWidth (native unit)",
      -          "type": "number"
      -        },
      -        "cropX": {
      -          "description": "cropX (native unit)",
      -          "type": "number"
      -        },
      -        "cropY": {
      -          "description": "cropY (native unit)",
      -          "type": "number"
      -        },
      -        "fillColor": {
      -          "description": "fillColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      -          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      -          "type": "string"
      -        },
      -        "fontSize": {
      -          "description": "Font size in CANVAS PIXELS (same unit as the top-level fontSize — NOT a fraction).",
      -          "type": "number"
      -        },
      -        "height": {
      -          "description": "Height in canvas pixels (0 allowed)",
      -          "minimum": 0,
      -          "type": "number"
      -        },
      -        "imageBorderColor": {
      -          "description": "imageBorderColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      -          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      -          "type": "string"
      -        },
      -        "imageBorderWidth": {
      -          "description": "imageBorderWidth in canvas pixels",
      -          "type": "number"
      -        },
      -        "imageCornerRadiusBottomLeft": {
      -          "description": "imageCornerRadiusBottomLeft in canvas pixels",
      -          "type": "number"
      -        },
      -        "imageCornerRadiusBottomRight": {
      -          "description": "imageCornerRadiusBottomRight in canvas pixels",
      -          "type": "number"
      -        },
      -        "imageCornerRadiusTopLeft": {
      -          "description": "imageCornerRadiusTopLeft in canvas pixels",
      -          "type": "number"
      -        },
      -        "imageCornerRadiusTopRight": {
      -          "description": "imageCornerRadiusTopRight in canvas pixels",
      -          "type": "number"
      -        },
      -        "interpolation": {
      -          "description": "Easing for THIS entry, applied to every property in it (default easeInOut). NOT `easing`.",
      -          "enum": [
      -            "linear",
      -            "easeInOut",
      -            "easeIn",
      -            "easeOut",
      -            "sigmoid",
      -            "smootherstep",
      -            "smoothstep",
      -            "hold",
      -            "easeInBack",
      -            "easeOutBack",
      -            "easeInOutBack",
      -            "custom"
      -          ],
      -          "type": "string"
      -        },
      -        "interpolation_overrides": {
      -          "additionalProperties": {
      -            "enum": [
      -              "linear",
      -              "easeInOut",
      -              "easeIn",
      -              "easeOut",
      -              "sigmoid",
      -              "smootherstep",
      -              "smoothstep",
      -              "hold",
      -              "easeInBack",
      -              "easeOutBack",
      -              "easeInOutBack",
      -              "custom"
      -            ],
      -            "type": "string"
      -          },
      -          "description": "Per-property easing override, e.g. {\"opacity\":\"linear\"} while the rest use `interpolation`. Keys must be keyframable properties present in this entry.",
      -          "propertyNames": {
      -            "enum": [
      -              "positionX",
      -              "positionY",
      -              "width",
      -              "height",
      -              "rotation",
      -              "scaleX",
      -              "scaleY",
      -              "rotateX",
      -              "rotateY",
      -              "cropX",
      -              "cropY",
      -              "cropWidth",
      -              "cropHeight",
      -              "opacity",
      -              "blur",
      -              "backgroundBlur",
      -              "strokeWidth",
      -              "strokeDash",
      -              "strokeGap",
      -              "strokeTrimStart",
      -              "strokeTrimEnd",
      -              "strokeTrimOffset",
      -              "textStrokeWidth",
      -              "textStrokeDash",
      -              "textStrokeGap",
      -              "imageBorderWidth",
      -              "shadowOffsetX",
      -              "shadowOffsetY",
      -              "shadowBlur",
      -              "shadowSpread",
      -              "borderRadiusTopLeft",
      -              "borderRadiusTopRight",
      -              "borderRadiusBottomRight",
      -              "borderRadiusBottomLeft",
      -              "imageCornerRadiusTopLeft",
      -              "imageCornerRadiusTopRight",
      -              "imageCornerRadiusBottomRight",
      -              "imageCornerRadiusBottomLeft",
      -              "videoCornerRadiusTopLeft",
      -              "videoCornerRadiusTopRight",
      -              "videoCornerRadiusBottomRight",
      -              "videoCornerRadiusBottomLeft",
      -              "fontSize",
      -              "lineHeight",
      -              "letterSpacing",
      -              "paddingTop",
      -              "paddingRight",
      -              "paddingBottom",
      -              "paddingLeft",
      -              "textBgRadiusTopLeft",
      -              "textBgRadiusTopRight",
      -              "textBgRadiusBottomRight",
      -              "textBgRadiusBottomLeft",
      -              "fillColor",
      -              "strokeColor",
      -              "textStrokeColor",
      -              "imageBorderColor",
      -              "textColor",
      -              "textBackgroundColor",
      -              "shadowColor"
      -            ],
      -            "type": "string"
      -          },
      -          "required": [
      -            "positionX",
      -            "positionY",
      -            "width",
      -            "height",
      -            "rotation",
      -            "scaleX",
      -            "scaleY",
      -            "rotateX",
      -            "rotateY",
      -            "cropX",
      -            "cropY",
      -            "cropWidth",
      -            "cropHeight",
      -            "opacity",
      -            "blur",
      -            "backgroundBlur",
      -            "strokeWidth",
      -            "strokeDash",
      -            "strokeGap",
      -            "strokeTrimStart",
      -            "strokeTrimEnd",
      -            "strokeTrimOffset",
      -            "textStrokeWidth",
      -            "textStrokeDash",
      -            "textStrokeGap",
      -            "imageBorderWidth",
      -            "shadowOffsetX",
      -            "shadowOffsetY",
      -            "shadowBlur",
      -            "shadowSpread",
      -            "borderRadiusTopLeft",
      -            "borderRadiusTopRight",
      -            "borderRadiusBottomRight",
      -            "borderRadiusBottomLeft",
      -            "imageCornerRadiusTopLeft",
      -            "imageCornerRadiusTopRight",
      -            "imageCornerRadiusBottomRight",
      -            "imageCornerRadiusBottomLeft",
      -            "videoCornerRadiusTopLeft",
      -            "videoCornerRadiusTopRight",
      -            "videoCornerRadiusBottomRight",
      -            "videoCornerRadiusBottomLeft",
      -            "fontSize",
      -            "lineHeight",
      -            "letterSpacing",
      -            "paddingTop",
      -            "paddingRight",
      -            "paddingBottom",
      -            "paddingLeft",
      -            "textBgRadiusTopLeft",
      -            "textBgRadiusTopRight",
      -            "textBgRadiusBottomRight",
      -            "textBgRadiusBottomLeft",
      -            "fillColor",
      -            "strokeColor",
      -            "textStrokeColor",
      -            "imageBorderColor",
      -            "textColor",
      -            "textBackgroundColor",
      -            "shadowColor"
      -          ],
      -          "type": "object"
      -        },
      -        "letterSpacing": {
      -          "description": "Letter spacing in canvas pixels.",
      -          "type": "number"
      -        },
      -        "lineHeight": {
      -          "description": "lineHeight (native unit)",
      -          "type": "number"
      -        },
      -        "opacity": {
      -          "description": "Opacity 0-100",
      -          "maximum": 100,
      -          "minimum": 0,
      -          "type": "number"
      -        },
      -        "paddingBottom": {
      -          "description": "paddingBottom in canvas pixels",
      -          "type": "number"
      -        },
      -        "paddingLeft": {
      -          "description": "paddingLeft in canvas pixels",
      -          "type": "number"
      -        },
      -        "paddingRight": {
      -          "description": "paddingRight in canvas pixels",
      -          "type": "number"
      -        },
      -        "paddingTop": {
      -          "description": "paddingTop in canvas pixels",
      -          "type": "number"
      -        },
      -        "positionX": {
      -          "description": "X position in canvas pixels (NOT `x`). Same origin as the element's top-level x: `x` is the left edge, except TEXT where alignment picks it: left→left, center→centre, right→right.",
      -          "type": "number"
      -        },
      -        "positionY": {
      -          "description": "Y position in canvas pixels (NOT `y`). Same origin as the element's top-level y: for TEXT `y` is the vertical CENTRE when centre-aligned and the TOP otherwise; every other type uses the top. y_anchor applies to the element's own y, NOT to keyframe values, so read the element back and key off its stored y.",
      -          "type": "number"
      -        },
      -        "rotateX": {
      -          "description": "rotateX (native unit)",
      -          "type": "number"
      -        },
      -        "rotateY": {
      -          "description": "rotateY (native unit)",
      -          "type": "number"
      -        },
      -        "rotation": {
      -          "description": "Rotation in degrees",
      -          "type": "number"
      -        },
      -        "scaleX": {
      -          "description": "Horizontal scale multiplier (1 = 100%)",
      -          "type": "number"
      -        },
      -        "scaleY": {
      -          "description": "Vertical scale multiplier (1 = 100%)",
      -          "type": "number"
      -        },
      -        "shadowBlur": {
      -          "description": "shadowBlur in canvas pixels",
      -          "type": "number"
      -        },
      -        "shadowColor": {
      -          "description": "shadowColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      -          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      -          "type": "string"
      -        },
      -        "shadowOffsetX": {
      -          "description": "shadowOffsetX in canvas pixels",
      -          "type": "number"
      -        },
      -        "shadowOffsetY": {
      -          "description": "shadowOffsetY in canvas pixels",
      -          "type": "number"
      -        },
      -        "shadowSpread": {
      -          "description": "shadowSpread in canvas pixels",
      -          "type": "number"
      -        },
      -        "strokeColor": {
      -          "description": "strokeColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      -          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      -          "type": "string"
      -        },
      -        "strokeDash": {
      -          "description": "strokeDash in canvas pixels",
      -          "type": "number"
      -        },
      -        "strokeGap": {
      -          "description": "strokeGap in canvas pixels",
      -          "type": "number"
      -        },
      -        "strokeTrimEnd": {
      -          "description": "strokeTrimEnd (native unit)",
      -          "type": "number"
      -        },
      -        "strokeTrimOffset": {
      -          "description": "strokeTrimOffset (native unit)",
      -          "type": "number"
      -        },
      -        "strokeTrimStart": {
      -          "description": "strokeTrimStart (native unit)",
      -          "type": "number"
      -        },
      -        "strokeWidth": {
      -          "description": "strokeWidth in canvas pixels",
      -          "type": "number"
      -        },
      -        "textBackgroundColor": {
      -          "description": "textBackgroundColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      -          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      -          "type": "string"
      -        },
      -        "textBgRadiusBottomLeft": {
      -          "description": "textBgRadiusBottomLeft in canvas pixels",
      -          "type": "number"
      -        },
      -        "textBgRadiusBottomRight": {
      -          "description": "textBgRadiusBottomRight in canvas pixels",
      -          "type": "number"
      -        },
      -        "textBgRadiusTopLeft": {
      -          "description": "textBgRadiusTopLeft in canvas pixels",
      -          "type": "number"
      -        },
      -        "textBgRadiusTopRight": {
      -          "description": "textBgRadiusTopRight in canvas pixels",
      -          "type": "number"
      -        },
      -        "textColor": {
      -          "description": "textColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      -          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      -          "type": "string"
      -        },
      -        "textStrokeColor": {
      -          "description": "textStrokeColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      -          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      -          "type": "string"
      -        },
      -        "textStrokeDash": {
      -          "description": "textStrokeDash in canvas pixels",
      -          "type": "number"
      -        },
      -        "textStrokeGap": {
      -          "description": "textStrokeGap in canvas pixels",
      -          "type": "number"
      -        },
      -        "textStrokeWidth": {
      -          "description": "textStrokeWidth in canvas pixels",
      -          "type": "number"
      -        },
      -        "timestamp": {
      -          "description": "Clip-relative time in seconds",
      -          "minimum": 0,
      -          "type": "number"
      -        },
      -        "videoCornerRadiusBottomLeft": {
      -          "description": "videoCornerRadiusBottomLeft in canvas pixels",
      -          "type": "number"
      -        },
      -        "videoCornerRadiusBottomRight": {
      -          "description": "videoCornerRadiusBottomRight in canvas pixels",
      -          "type": "number"
      -        },
      -        "videoCornerRadiusTopLeft": {
      -          "description": "videoCornerRadiusTopLeft in canvas pixels",
      -          "type": "number"
      -        },
      -        "videoCornerRadiusTopRight": {
      -          "description": "videoCornerRadiusTopRight in canvas pixels",
      -          "type": "number"
      -        },
      -        "width": {
      -          "description": "Width in canvas pixels (0 allowed — e.g. a bar that draws in from 0)",
      -          "minimum": 0,
      -          "type": "number"
      -        }
      -      },
      -      "required": [
      -        "timestamp"
      -      ],
      -      "type": "object"
      -    },
      -    "type": "array"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "items": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "backgroundBlur": {
      +          "description": "Backdrop blur behind the element",
      +          "type": "number"
      +        },
      +        "bezier": {
      +          "description": "Cubic-bezier [x1,y1,x2,y2]; used when interpolation is 'custom'.",
      +          "items": {
      +            "type": "number"
      +          },
      +          "maxItems": 4,
      +          "minItems": 4,
      +          "type": "array"
      +        },
      +        "bezier_overrides": {
      +          "additionalProperties": {
      +            "items": {
      +              "type": "number"
      +            },
      +            "maxItems": 4,
      +            "minItems": 4,
      +            "type": "array"
      +          },
      +          "description": "Per-property cubic-bezier override, e.g. {\"opacity\":[.4,0,.6,1]}, when two `custom`-eased properties in this entry need DIFFERENT curves. Keys must be properties present in this entry.",
      +          "propertyNames": {
      +            "enum": [
      +              "positionX",
      +              "positionY",
      +              "width",
      +              "height",
      +              "rotation",
      +              "scaleX",
      +              "scaleY",
      +              "rotateX",
      +              "rotateY",
      +              "cropX",
      +              "cropY",
      +              "cropWidth",
      +              "cropHeight",
      +              "opacity",
      +              "blur",
      +              "backgroundBlur",
      +              "strokeWidth",
      +              "strokeDash",
      +              "strokeGap",
      +              "strokeTrimStart",
      +              "strokeTrimEnd",
      +              "strokeTrimOffset",
      +              "textStrokeWidth",
      +              "textStrokeDash",
      +              "textStrokeGap",
      +              "imageBorderWidth",
      +              "shadowOffsetX",
      +              "shadowOffsetY",
      +              "shadowBlur",
      +              "shadowSpread",
      +              "borderRadiusTopLeft",
      +              "borderRadiusTopRight",
      +              "borderRadiusBottomRight",
      +              "borderRadiusBottomLeft",
      +              "imageCornerRadiusTopLeft",
      +              "imageCornerRadiusTopRight",
      +              "imageCornerRadiusBottomRight",
      +              "imageCornerRadiusBottomLeft",
      +              "videoCornerRadiusTopLeft",
      +              "videoCornerRadiusTopRight",
      +              "videoCornerRadiusBottomRight",
      +              "videoCornerRadiusBottomLeft",
      +              "fontSize",
      +              "lineHeight",
      +              "letterSpacing",
      +              "paddingTop",
      +              "paddingRight",
      +              "paddingBottom",
      +              "paddingLeft",
      +              "textBgRadiusTopLeft",
      +              "textBgRadiusTopRight",
      +              "textBgRadiusBottomRight",
      +              "textBgRadiusBottomLeft",
      +              "fillColor",
      +              "strokeColor",
      +              "textStrokeColor",
      +              "imageBorderColor",
      +              "textColor",
      +              "textBackgroundColor",
      +              "shadowColor"
      +            ],
      +            "type": "string"
      +          },
      +          "type": "object"
      +        },
      +        "blur": {
      +          "description": "Layer blur",
      +          "type": "number"
      +        },
      +        "borderRadiusBottomLeft": {
      +          "description": "borderRadiusBottomLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "borderRadiusBottomRight": {
      +          "description": "borderRadiusBottomRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "borderRadiusTopLeft": {
      +          "description": "borderRadiusTopLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "borderRadiusTopRight": {
      +          "description": "borderRadiusTopRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "cropHeight": {
      +          "description": "cropHeight (native unit)",
      +          "type": "number"
      +        },
      +        "cropWidth": {
      +          "description": "cropWidth (native unit)",
      +          "type": "number"
      +        },
      +        "cropX": {
      +          "description": "cropX (native unit)",
      +          "type": "number"
      +        },
      +        "cropY": {
      +          "description": "cropY (native unit)",
      +          "type": "number"
      +        },
      +        "fillColor": {
      +          "description": "fillColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "fontSize": {
      +          "description": "Font size in CANVAS PIXELS (same unit as the top-level fontSize — NOT a fraction).",
      +          "type": "number"
      +        },
      +        "height": {
      +          "description": "Height in canvas pixels (0 allowed)",
      +          "minimum": 0,
      +          "type": "number"
      +        },
      +        "imageBorderColor": {
      +          "description": "imageBorderColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "imageBorderWidth": {
      +          "description": "imageBorderWidth in canvas pixels",
      +          "type": "number"
      +        },
      +        "imageCornerRadiusBottomLeft": {
      +          "description": "imageCornerRadiusBottomLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "imageCornerRadiusBottomRight": {
      +          "description": "imageCornerRadiusBottomRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "imageCornerRadiusTopLeft": {
      +          "description": "imageCornerRadiusTopLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "imageCornerRadiusTopRight": {
      +          "description": "imageCornerRadiusTopRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "interpolation": {
      +          "description": "Easing for THIS entry, applied to every property in it (default easeInOut). NOT `easing`.",
      +          "enum": [
      +            "linear",
      +            "easeInOut",
      +            "easeIn",
      +            "easeOut",
      +            "sigmoid",
      +            "smootherstep",
      +            "smoothstep",
      +            "hold",
      +            "easeInBack",
      +            "easeOutBack",
      +            "easeInOutBack",
      +            "custom"
      +          ],
      +          "type": "string"
      +        },
      +        "interpolation_overrides": {
      +          "additionalProperties": {
      +            "enum": [
      +              "linear",
      +              "easeInOut",
      +              "easeIn",
      +              "easeOut",
      +              "sigmoid",
      +              "smootherstep",
      +              "smoothstep",
      +              "hold",
      +              "easeInBack",
      +              "easeOutBack",
      +              "easeInOutBack",
      +              "custom"
      +            ],
      +            "type": "string"
      +          },
      +          "description": "Per-property easing override, e.g. {\"opacity\":\"linear\"} while the rest use `interpolation`. Keys must be keyframable properties present in this entry.",
      +          "propertyNames": {
      +            "enum": [
      +              "positionX",
      +              "positionY",
      +              "width",
      +              "height",
      +              "rotation",
      +              "scaleX",
      +              "scaleY",
      +              "rotateX",
      +              "rotateY",
      +              "cropX",
      +              "cropY",
      +              "cropWidth",
      +              "cropHeight",
      +              "opacity",
      +              "blur",
      +              "backgroundBlur",
      +              "strokeWidth",
      +              "strokeDash",
      +              "strokeGap",
      +              "strokeTrimStart",
      +              "strokeTrimEnd",
      +              "strokeTrimOffset",
      +              "textStrokeWidth",
      +              "textStrokeDash",
      +              "textStrokeGap",
      +              "imageBorderWidth",
      +              "shadowOffsetX",
      +              "shadowOffsetY",
      +              "shadowBlur",
      +              "shadowSpread",
      +              "borderRadiusTopLeft",
      +              "borderRadiusTopRight",
      +              "borderRadiusBottomRight",
      +              "borderRadiusBottomLeft",
      +              "imageCornerRadiusTopLeft",
      +              "imageCornerRadiusTopRight",
      +              "imageCornerRadiusBottomRight",
      +              "imageCornerRadiusBottomLeft",
      +              "videoCornerRadiusTopLeft",
      +              "videoCornerRadiusTopRight",
      +              "videoCornerRadiusBottomRight",
      +              "videoCornerRadiusBottomLeft",
      +              "fontSize",
      +              "lineHeight",
      +              "letterSpacing",
      +              "paddingTop",
      +              "paddingRight",
      +              "paddingBottom",
      +              "paddingLeft",
      +              "textBgRadiusTopLeft",
      +              "textBgRadiusTopRight",
      +              "textBgRadiusBottomRight",
      +              "textBgRadiusBottomLeft",
      +              "fillColor",
      +              "strokeColor",
      +              "textStrokeColor",
      +              "imageBorderColor",
      +              "textColor",
      +              "textBackgroundColor",
      +              "shadowColor"
      +            ],
      +            "type": "string"
      +          },
      +          "type": "object"
      +        },
      +        "letterSpacing": {
      +          "description": "Letter spacing in canvas pixels.",
      +          "type": "number"
      +        },
      +        "lineHeight": {
      +          "description": "lineHeight (native unit)",
      +          "type": "number"
      +        },
      +        "opacity": {
      +          "description": "Opacity 0-100",
      +          "maximum": 100,
      +          "minimum": 0,
      +          "type": "number"
      +        },
      +        "paddingBottom": {
      +          "description": "paddingBottom in canvas pixels",
      +          "type": "number"
      +        },
      +        "paddingLeft": {
      +          "description": "paddingLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "paddingRight": {
      +          "description": "paddingRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "paddingTop": {
      +          "description": "paddingTop in canvas pixels",
      +          "type": "number"
      +        },
      +        "positionX": {
      +          "description": "X position in canvas pixels (NOT `x`). Same origin as the element's top-level x: `x` is the left edge, except TEXT where alignment picks it: left→left, center→centre, right→right.",
      +          "type": "number"
      +        },
      +        "positionY": {
      +          "description": "Y position in canvas pixels (NOT `y`). Same origin as the element's top-level y: for TEXT `y` is the vertical CENTRE when centre-aligned and the TOP otherwise; every other type uses the top. y_anchor applies to the element's own y, NOT to keyframe values, so read the element back and key off its stored y.",
      +          "type": "number"
      +        },
      +        "rotateX": {
      +          "description": "rotateX (native unit)",
      +          "type": "number"
      +        },
      +        "rotateY": {
      +          "description": "rotateY (native unit)",
      +          "type": "number"
      +        },
      +        "rotation": {
      +          "description": "Rotation in degrees",
      +          "type": "number"
      +        },
      +        "scaleX": {
      +          "description": "Horizontal scale multiplier (1 = 100%)",
      +          "type": "number"
      +        },
      +        "scaleY": {
      +          "description": "Vertical scale multiplier (1 = 100%)",
      +          "type": "number"
      +        },
      +        "shadowBlur": {
      +          "description": "shadowBlur in canvas pixels",
      +          "type": "number"
      +        },
      +        "shadowColor": {
      +          "description": "shadowColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "shadowOffsetX": {
      +          "description": "shadowOffsetX in canvas pixels",
      +          "type": "number"
      +        },
      +        "shadowOffsetY": {
      +          "description": "shadowOffsetY in canvas pixels",
      +          "type": "number"
      +        },
      +        "shadowSpread": {
      +          "description": "shadowSpread in canvas pixels",
      +          "type": "number"
      +        },
      +        "strokeColor": {
      +          "description": "strokeColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "strokeDash": {
      +          "description": "strokeDash in canvas pixels",
      +          "type": "number"
      +        },
      +        "strokeGap": {
      +          "description": "strokeGap in canvas pixels",
      +          "type": "number"
      +        },
      +        "strokeTrimEnd": {
      +          "description": "strokeTrimEnd (native unit)",
      +          "type": "number"
      +        },
      +        "strokeTrimOffset": {
      +          "description": "strokeTrimOffset (native unit)",
      +          "type": "number"
      +        },
      +        "strokeTrimStart": {
      +          "description": "strokeTrimStart (native unit)",
      +          "type": "number"
      +        },
      +        "strokeWidth": {
      +          "description": "strokeWidth in canvas pixels",
      +          "type": "number"
      +        },
      +        "textBackgroundColor": {
      +          "description": "textBackgroundColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "textBgRadiusBottomLeft": {
      +          "description": "textBgRadiusBottomLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "textBgRadiusBottomRight": {
      +          "description": "textBgRadiusBottomRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "textBgRadiusTopLeft": {
      +          "description": "textBgRadiusTopLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "textBgRadiusTopRight": {
      +          "description": "textBgRadiusTopRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "textColor": {
      +          "description": "textColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "textStrokeColor": {
      +          "description": "textStrokeColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "textStrokeDash": {
      +          "description": "textStrokeDash in canvas pixels",
      +          "type": "number"
      +        },
      +        "textStrokeGap": {
      +          "description": "textStrokeGap in canvas pixels",
      +          "type": "number"
      +        },
      +        "textStrokeWidth": {
      +          "description": "textStrokeWidth in canvas pixels",
      +          "type": "number"
      +        },
      +        "timestamp": {
      +          "description": "Clip-relative time in seconds",
      +          "minimum": 0,
      +          "type": "number"
      +        },
      +        "videoCornerRadiusBottomLeft": {
      +          "description": "videoCornerRadiusBottomLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "videoCornerRadiusBottomRight": {
      +          "description": "videoCornerRadiusBottomRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "videoCornerRadiusTopLeft": {
      +          "description": "videoCornerRadiusTopLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "videoCornerRadiusTopRight": {
      +          "description": "videoCornerRadiusTopRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "width": {
      +          "description": "Width in canvas pixels (0 allowed — e.g. a bar that draws in from 0)",
      +          "minimum": 0,
      +          "type": "number"
      +        }
      +      },
      +      "required": [
      +        "timestamp"
      +      ],
      +      "type": "object"
      +    },
      +    "type": "array"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / returning / description
      Previous value: -"Declare what comes back, the way get_clip's `select` shapes a read. Omit it and you get ids, the measured layout, and the clip audit in compact form — which names every problem but drops the explanatory prose. Values: 'ids' (element_id per result), 'layout' (the measured text fit — font_size_px, text_width_px, natural_width_px, line_count, fits_width/fits_height/fits — `fits` is the WIDTH check (the widest rendered line inside the box), `fits_height` is the separate height one — plus an `adjusted` entry whenever the measured line box replaced the height you sent; widen a box to natural_width_px, NOT text_width_px, which is the widest RENDERED line and so a lower bound on text that is already wrapping; plus `placement` {y_anchor, top, center, bottom} — where the box landed and what your `y` meant, emitted only when the origin was implicit or resolves to 'center'. Compare placement.center with a container's centre line to verify centring: a mis-anchored label is the one layout error nothing else reports), 'qa.codes' (audit counts and summary plus severity/code/element_ids per finding), 'qa' (the same audit with the full message and suggested fix on every finding — ask for this when a code alone isn't enough to act on). ERROR-severity findings always come back with their full message whichever you choose — including `returning:[]` and `['ids']`, which suppress WARNINGS only. A failed item always returns complete. Pass [] for just {total, succeeded, failed} plus any errors, the leanest write."New value: +"Declare what comes back, the way get_clip's `select` shapes a read. Omit it and you get ids, the measured layout, and the clip audit in compact form — which names every problem but drops the explanatory prose. Values: 'ids' (element_id per result), 'layout' (the measured text fit — font_size_px, text_width_px, natural_width_px, line_count, fits_width/fits_height/fits — `fits` is the WIDTH check (the widest rendered line inside the box), `fits_height` is the separate height one — plus an `adjusted` entry whenever the measured line box replaced the height you sent; widen a box to natural_width_px, NOT text_width_px, which is the widest RENDERED line and so a lower bound on text that is already wrapping; plus `placement` {y_anchor, top, center, bottom} — where the box landed and what your `y` meant, emitted only when the origin was implicit or resolves to 'center'. Compare placement.center with a container's centre line to verify centring: a mis-anchored label is the one layout error nothing else reports), 'qa.codes' (audit counts and summary plus severity/code/element_ids per finding), 'qa' (the same audit with the full message and suggested fix on every finding — ask for this when a code alone isn't enough to act on). A text element measured on a fallback face is listed in top-level `font_warnings` whichever you choose. ERROR-severity findings always come back with their full message whichever you choose — including `returning:[]` and `['ids']`, which suppress WARNINGS only. A failed item always returns complete. Pass [] for just {total, succeeded, failed} plus any errors, the leanest write."
  2. Changed4 schema fields changed
    • removedInput schema / properties / context
      Removed value: -{
      -  "description": "Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as \"a user\", \"the customer\", or \"an account\". Example: \"Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution.\"",
      -  "type": "string"
      -}
    • removedInput schema / properties / conversation_id
      Removed value: -{
      -  "description": "Echo the conversation_id from the server's previous response. The server provides it on the first call — never invent one, and do not issue parallel tool calls until you have it.",
      -  "type": "string"
      -}
    • removedInput schema / properties / llm_model
      Removed value: -{
      -  "description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess.",
      -  "type": "string"
      -}
    • changedInput schema / required
      Previous value: -[
      -  "project_id",
      -  "elements",
      -  "context",
      -  "llm_model"
      -]New value: +[
      +  "project_id",
      +  "elements"
      +]
  3. Changed4 schema fields changed
    • addedInput schema / properties / context
      Added value: +{
      +  "description": "Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as \"a user\", \"the customer\", or \"an account\". Example: \"Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution.\"",
      +  "type": "string"
      +}
    • addedInput schema / properties / conversation_id
      Added value: +{
      +  "description": "Echo the conversation_id from the server's previous response. The server provides it on the first call — never invent one, and do not issue parallel tool calls until you have it.",
      +  "type": "string"
      +}
    • addedInput schema / properties / llm_model
      Added value: +{
      +  "description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess.",
      +  "type": "string"
      +}
    • changedInput schema / required
      Previous value: -[
      -  "project_id",
      -  "elements"
      -]New value: +[
      +  "project_id",
      +  "elements",
      +  "context",
      +  "llm_model"
      +]
  4. Changed14 schema fields changed
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • removedInput schema / additionalProperties
      Removed value: -false
    • addedInput schema / properties / defaults / properties / clip_index / maximum
      Added value: +9007199254740991
    • changedInput schema / properties / defaults / properties / keyframes / anyOf
      Previous value: -[
      -  {
      -    "items": {
      -      "$ref": "#/properties/elements/items/properties/keyframes/anyOf/0/items"
      -    },
      -    "type": "array"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "items": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "backgroundBlur": {
      +          "description": "Backdrop blur behind the element",
      +          "type": "number"
      +        },
      +        "bezier": {
      +          "description": "Cubic-bezier [x1,y1,x2,y2]; used when interpolation is 'custom'.",
      +          "items": {
      +            "type": "number"
      +          },
      +          "maxItems": 4,
      +          "minItems": 4,
      +          "type": "array"
      +        },
      +        "bezier_overrides": {
      +          "additionalProperties": {
      +            "items": {
      +              "type": "number"
      +            },
      +            "maxItems": 4,
      +            "minItems": 4,
      +            "type": "array"
      +          },
      +          "description": "Per-property cubic-bezier override, e.g. {\"opacity\":[.4,0,.6,1]}, when two `custom`-eased properties in this entry need DIFFERENT curves. Keys must be properties present in this entry.",
      +          "propertyNames": {
      +            "enum": [
      +              "positionX",
      +              "positionY",
      +              "width",
      +              "height",
      +              "rotation",
      +              "scaleX",
      +              "scaleY",
      +              "rotateX",
      +              "rotateY",
      +              "cropX",
      +              "cropY",
      +              "cropWidth",
      +              "cropHeight",
      +              "opacity",
      +              "blur",
      +              "backgroundBlur",
      +              "strokeWidth",
      +              "strokeDash",
      +              "strokeGap",
      +              "strokeTrimStart",
      +              "strokeTrimEnd",
      +              "strokeTrimOffset",
      +              "textStrokeWidth",
      +              "textStrokeDash",
      +              "textStrokeGap",
      +              "imageBorderWidth",
      +              "shadowOffsetX",
      +              "shadowOffsetY",
      +              "shadowBlur",
      +              "shadowSpread",
      +              "borderRadiusTopLeft",
      +              "borderRadiusTopRight",
      +              "borderRadiusBottomRight",
      +              "borderRadiusBottomLeft",
      +              "imageCornerRadiusTopLeft",
      +              "imageCornerRadiusTopRight",
      +              "imageCornerRadiusBottomRight",
      +              "imageCornerRadiusBottomLeft",
      +              "videoCornerRadiusTopLeft",
      +              "videoCornerRadiusTopRight",
      +              "videoCornerRadiusBottomRight",
      +              "videoCornerRadiusBottomLeft",
      +              "fontSize",
      +              "lineHeight",
      +              "letterSpacing",
      +              "paddingTop",
      +              "paddingRight",
      +              "paddingBottom",
      +              "paddingLeft",
      +              "textBgRadiusTopLeft",
      +              "textBgRadiusTopRight",
      +              "textBgRadiusBottomRight",
      +              "textBgRadiusBottomLeft",
      +              "fillColor",
      +              "strokeColor",
      +              "textStrokeColor",
      +              "imageBorderColor",
      +              "textColor",
      +              "textBackgroundColor",
      +              "shadowColor"
      +            ],
      +            "type": "string"
      +          },
      +          "required": [
      +            "positionX",
      +            "positionY",
      +            "width",
      +            "height",
      +            "rotation",
      +            "scaleX",
      +            "scaleY",
      +            "rotateX",
      +            "rotateY",
      +            "cropX",
      +            "cropY",
      +            "cropWidth",
      +            "cropHeight",
      +            "opacity",
      +            "blur",
      +            "backgroundBlur",
      +            "strokeWidth",
      +            "strokeDash",
      +            "strokeGap",
      +            "strokeTrimStart",
      +            "strokeTrimEnd",
      +            "strokeTrimOffset",
      +            "textStrokeWidth",
      +            "textStrokeDash",
      +            "textStrokeGap",
      +            "imageBorderWidth",
      +            "shadowOffsetX",
      +            "shadowOffsetY",
      +            "shadowBlur",
      +            "shadowSpread",
      +            "borderRadiusTopLeft",
      +            "borderRadiusTopRight",
      +            "borderRadiusBottomRight",
      +            "borderRadiusBottomLeft",
      +            "imageCornerRadiusTopLeft",
      +            "imageCornerRadiusTopRight",
      +            "imageCornerRadiusBottomRight",
      +            "imageCornerRadiusBottomLeft",
      +            "videoCornerRadiusTopLeft",
      +            "videoCornerRadiusTopRight",
      +            "videoCornerRadiusBottomRight",
      +            "videoCornerRadiusBottomLeft",
      +            "fontSize",
      +            "lineHeight",
      +            "letterSpacing",
      +            "paddingTop",
      +            "paddingRight",
      +            "paddingBottom",
      +            "paddingLeft",
      +            "textBgRadiusTopLeft",
      +            "textBgRadiusTopRight",
      +            "textBgRadiusBottomRight",
      +            "textBgRadiusBottomLeft",
      +            "fillColor",
      +            "strokeColor",
      +            "textStrokeColor",
      +            "imageBorderColor",
      +            "textColor",
      +            "textBackgroundColor",
      +            "shadowColor"
      +          ],
      +          "type": "object"
      +        },
      +        "blur": {
      +          "description": "Layer blur",
      +          "type": "number"
      +        },
      +        "borderRadiusBottomLeft": {
      +          "description": "borderRadiusBottomLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "borderRadiusBottomRight": {
      +          "description": "borderRadiusBottomRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "borderRadiusTopLeft": {
      +          "description": "borderRadiusTopLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "borderRadiusTopRight": {
      +          "description": "borderRadiusTopRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "cropHeight": {
      +          "description": "cropHeight (native unit)",
      +          "type": "number"
      +        },
      +        "cropWidth": {
      +          "description": "cropWidth (native unit)",
      +          "type": "number"
      +        },
      +        "cropX": {
      +          "description": "cropX (native unit)",
      +          "type": "number"
      +        },
      +        "cropY": {
      +          "description": "cropY (native unit)",
      +          "type": "number"
      +        },
      +        "fillColor": {
      +          "description": "fillColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "fontSize": {
      +          "description": "Font size in CANVAS PIXELS (same unit as the top-level fontSize — NOT a fraction).",
      +          "type": "number"
      +        },
      +        "height": {
      +          "description": "Height in canvas pixels (0 allowed)",
      +          "minimum": 0,
      +          "type": "number"
      +        },
      +        "imageBorderColor": {
      +          "description": "imageBorderColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "imageBorderWidth": {
      +          "description": "imageBorderWidth in canvas pixels",
      +          "type": "number"
      +        },
      +        "imageCornerRadiusBottomLeft": {
      +          "description": "imageCornerRadiusBottomLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "imageCornerRadiusBottomRight": {
      +          "description": "imageCornerRadiusBottomRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "imageCornerRadiusTopLeft": {
      +          "description": "imageCornerRadiusTopLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "imageCornerRadiusTopRight": {
      +          "description": "imageCornerRadiusTopRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "interpolation": {
      +          "description": "Easing for THIS entry, applied to every property in it (default easeInOut). NOT `easing`.",
      +          "enum": [
      +            "linear",
      +            "easeInOut",
      +            "easeIn",
      +            "easeOut",
      +            "sigmoid",
      +            "smootherstep",
      +            "smoothstep",
      +            "hold",
      +            "easeInBack",
      +            "easeOutBack",
      +            "easeInOutBack",
      +            "custom"
      +          ],
      +          "type": "string"
      +        },
      +        "interpolation_overrides": {
      +          "additionalProperties": {
      +            "enum": [
      +              "linear",
      +              "easeInOut",
      +              "easeIn",
      +              "easeOut",
      +              "sigmoid",
      +              "smootherstep",
      +              "smoothstep",
      +              "hold",
      +              "easeInBack",
      +              "easeOutBack",
      +              "easeInOutBack",
      +              "custom"
      +            ],
      +            "type": "string"
      +          },
      +          "description": "Per-property easing override, e.g. {\"opacity\":\"linear\"} while the rest use `interpolation`. Keys must be keyframable properties present in this entry.",
      +          "propertyNames": {
      +            "enum": [
      +              "positionX",
      +              "positionY",
      +              "width",
      +              "height",
      +              "rotation",
      +              "scaleX",
      +              "scaleY",
      +              "rotateX",
      +              "rotateY",
      +              "cropX",
      +              "cropY",
      +              "cropWidth",
      +              "cropHeight",
      +              "opacity",
      +              "blur",
      +              "backgroundBlur",
      +              "strokeWidth",
      +              "strokeDash",
      +              "strokeGap",
      +              "strokeTrimStart",
      +              "strokeTrimEnd",
      +              "strokeTrimOffset",
      +              "textStrokeWidth",
      +              "textStrokeDash",
      +              "textStrokeGap",
      +              "imageBorderWidth",
      +              "shadowOffsetX",
      +              "shadowOffsetY",
      +              "shadowBlur",
      +              "shadowSpread",
      +              "borderRadiusTopLeft",
      +              "borderRadiusTopRight",
      +              "borderRadiusBottomRight",
      +              "borderRadiusBottomLeft",
      +              "imageCornerRadiusTopLeft",
      +              "imageCornerRadiusTopRight",
      +              "imageCornerRadiusBottomRight",
      +              "imageCornerRadiusBottomLeft",
      +              "videoCornerRadiusTopLeft",
      +              "videoCornerRadiusTopRight",
      +              "videoCornerRadiusBottomRight",
      +              "videoCornerRadiusBottomLeft",
      +              "fontSize",
      +              "lineHeight",
      +              "letterSpacing",
      +              "paddingTop",
      +              "paddingRight",
      +              "paddingBottom",
      +              "paddingLeft",
      +              "textBgRadiusTopLeft",
      +              "textBgRadiusTopRight",
      +              "textBgRadiusBottomRight",
      +              "textBgRadiusBottomLeft",
      +              "fillColor",
      +              "strokeColor",
      +              "textStrokeColor",
      +              "imageBorderColor",
      +              "textColor",
      +              "textBackgroundColor",
      +              "shadowColor"
      +            ],
      +            "type": "string"
      +          },
      +          "required": [
      +            "positionX",
      +            "positionY",
      +            "width",
      +            "height",
      +            "rotation",
      +            "scaleX",
      +            "scaleY",
      +            "rotateX",
      +            "rotateY",
      +            "cropX",
      +            "cropY",
      +            "cropWidth",
      +            "cropHeight",
      +            "opacity",
      +            "blur",
      +            "backgroundBlur",
      +            "strokeWidth",
      +            "strokeDash",
      +            "strokeGap",
      +            "strokeTrimStart",
      +            "strokeTrimEnd",
      +            "strokeTrimOffset",
      +            "textStrokeWidth",
      +            "textStrokeDash",
      +            "textStrokeGap",
      +            "imageBorderWidth",
      +            "shadowOffsetX",
      +            "shadowOffsetY",
      +            "shadowBlur",
      +            "shadowSpread",
      +            "borderRadiusTopLeft",
      +            "borderRadiusTopRight",
      +            "borderRadiusBottomRight",
      +            "borderRadiusBottomLeft",
      +            "imageCornerRadiusTopLeft",
      +            "imageCornerRadiusTopRight",
      +            "imageCornerRadiusBottomRight",
      +            "imageCornerRadiusBottomLeft",
      +            "videoCornerRadiusTopLeft",
      +            "videoCornerRadiusTopRight",
      +            "videoCornerRadiusBottomRight",
      +            "videoCornerRadiusBottomLeft",
      +            "fontSize",
      +            "lineHeight",
      +            "letterSpacing",
      +            "paddingTop",
      +            "paddingRight",
      +            "paddingBottom",
      +            "paddingLeft",
      +            "textBgRadiusTopLeft",
      +            "textBgRadiusTopRight",
      +            "textBgRadiusBottomRight",
      +            "textBgRadiusBottomLeft",
      +            "fillColor",
      +            "strokeColor",
      +            "textStrokeColor",
      +            "imageBorderColor",
      +            "textColor",
      +            "textBackgroundColor",
      +            "shadowColor"
      +          ],
      +          "type": "object"
      +        },
      +        "letterSpacing": {
      +          "description": "Letter spacing in canvas pixels.",
      +          "type": "number"
      +        },
      +        "lineHeight": {
      +          "description": "lineHeight (native unit)",
      +          "type": "number"
      +        },
      +        "opacity": {
      +          "description": "Opacity 0-100",
      +          "maximum": 100,
      +          "minimum": 0,
      +          "type": "number"
      +        },
      +        "paddingBottom": {
      +          "description": "paddingBottom in canvas pixels",
      +          "type": "number"
      +        },
      +        "paddingLeft": {
      +          "description": "paddingLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "paddingRight": {
      +          "description": "paddingRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "paddingTop": {
      +          "description": "paddingTop in canvas pixels",
      +          "type": "number"
      +        },
      +        "positionX": {
      +          "description": "X position in canvas pixels (NOT `x`). Same origin as the element's top-level x: `x` is the left edge, except TEXT where alignment picks it: left→left, center→centre, right→right.",
      +          "type": "number"
      +        },
      +        "positionY": {
      +          "description": "Y position in canvas pixels (NOT `y`). Same origin as the element's top-level y: for TEXT `y` is the vertical CENTRE when centre-aligned and the TOP otherwise; every other type uses the top. y_anchor applies to the element's own y, NOT to keyframe values, so read the element back and key off its stored y.",
      +          "type": "number"
      +        },
      +        "rotateX": {
      +          "description": "rotateX (native unit)",
      +          "type": "number"
      +        },
      +        "rotateY": {
      +          "description": "rotateY (native unit)",
      +          "type": "number"
      +        },
      +        "rotation": {
      +          "description": "Rotation in degrees",
      +          "type": "number"
      +        },
      +        "scaleX": {
      +          "description": "Horizontal scale multiplier (1 = 100%)",
      +          "type": "number"
      +        },
      +        "scaleY": {
      +          "description": "Vertical scale multiplier (1 = 100%)",
      +          "type": "number"
      +        },
      +        "shadowBlur": {
      +          "description": "shadowBlur in canvas pixels",
      +          "type": "number"
      +        },
      +        "shadowColor": {
      +          "description": "shadowColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "shadowOffsetX": {
      +          "description": "shadowOffsetX in canvas pixels",
      +          "type": "number"
      +        },
      +        "shadowOffsetY": {
      +          "description": "shadowOffsetY in canvas pixels",
      +          "type": "number"
      +        },
      +        "shadowSpread": {
      +          "description": "shadowSpread in canvas pixels",
      +          "type": "number"
      +        },
      +        "strokeColor": {
      +          "description": "strokeColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "strokeDash": {
      +          "description": "strokeDash in canvas pixels",
      +          "type": "number"
      +        },
      +        "strokeGap": {
      +          "description": "strokeGap in canvas pixels",
      +          "type": "number"
      +        },
      +        "strokeTrimEnd": {
      +          "description": "strokeTrimEnd (native unit)",
      +          "type": "number"
      +        },
      +        "strokeTrimOffset": {
      +          "description": "strokeTrimOffset (native unit)",
      +          "type": "number"
      +        },
      +        "strokeTrimStart": {
      +          "description": "strokeTrimStart (native unit)",
      +          "type": "number"
      +        },
      +        "strokeWidth": {
      +          "description": "strokeWidth in canvas pixels",
      +          "type": "number"
      +        },
      +        "textBackgroundColor": {
      +          "description": "textBackgroundColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "textBgRadiusBottomLeft": {
      +          "description": "textBgRadiusBottomLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "textBgRadiusBottomRight": {
      +          "description": "textBgRadiusBottomRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "textBgRadiusTopLeft": {
      +          "description": "textBgRadiusTopLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "textBgRadiusTopRight": {
      +          "description": "textBgRadiusTopRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "textColor": {
      +          "description": "textColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "textStrokeColor": {
      +          "description": "textStrokeColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "textStrokeDash": {
      +          "description": "textStrokeDash in canvas pixels",
      +          "type": "number"
      +        },
      +        "textStrokeGap": {
      +          "description": "textStrokeGap in canvas pixels",
      +          "type": "number"
      +        },
      +        "textStrokeWidth": {
      +          "description": "textStrokeWidth in canvas pixels",
      +          "type": "number"
      +        },
      +        "timestamp": {
      +          "description": "Clip-relative time in seconds",
      +          "minimum": 0,
      +          "type": "number"
      +        },
      +        "videoCornerRadiusBottomLeft": {
      +          "description": "videoCornerRadiusBottomLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "videoCornerRadiusBottomRight": {
      +          "description": "videoCornerRadiusBottomRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "videoCornerRadiusTopLeft": {
      +          "description": "videoCornerRadiusTopLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "videoCornerRadiusTopRight": {
      +          "description": "videoCornerRadiusTopRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "width": {
      +          "description": "Width in canvas pixels (0 allowed — e.g. a bar that draws in from 0)",
      +          "minimum": 0,
      +          "type": "number"
      +        }
      +      },
      +      "required": [
      +        "timestamp"
      +      ],
      +      "type": "object"
      +    },
      +    "type": "array"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • addedInput schema / properties / defaults / properties / type_data / propertyNames
      Added value: +{
      +  "type": "string"
      +}
    • addedInput schema / properties / elements / items / properties / clip_index / maximum
      Added value: +9007199254740991
    • changedInput schema / properties / elements / items / properties / insert_at / description
      Previous value: -"Where the element lands in z-order, so you don't need a follow-up reorder_elements. `front` (default) puts it on top of what's already on the clip; `back` puts it behind everything — what a backdrop panel or a wash needs. `{before: element_id}` / `{after: element_id}` place it next to a specific element or group and put it in THAT node's group, which is the only way to position inside a group. Placement is relative to the clip AS IT STANDS when the item is applied, so several `back` items in one call end up in REVERSE input order: send one backdrop per call, or list them back-to-front."New value: +"Where the element lands in z-order, so you don't need a follow-up reorder_elements. `front` (default) puts it on top of what's already on the clip; `back` puts it behind everything — what a backdrop panel or a wash needs. `{before: element_id}` / `{after: element_id}` place it next to a specific element or group and put it in THAT node's group, which is the only way to position inside a group. Passing `group` as well changes what `front`/`back` address — see the Z-order notes in this tool's description. Placement is relative to the clip AS IT STANDS when the item is applied, so several `back` items in one call end up in REVERSE input order: send one backdrop per call, or list them back-to-front."
    • changedInput schema / properties / elements / items / properties / keyframes / anyOf
      Previous value: -[
      -  {
      -    "items": {
      -      "additionalProperties": false,
      -      "properties": {
      -        "backgroundBlur": {
      -          "description": "Backdrop blur behind the element",
      -          "type": "number"
      -        },
      -        "bezier": {
      -          "description": "Cubic-bezier [x1,y1,x2,y2]; used when interpolation is 'custom'.",
      -          "items": {
      -            "type": "number"
      -          },
      -          "maxItems": 4,
      -          "minItems": 4,
      -          "type": "array"
      -        },
      -        "bezier_overrides": {
      -          "additionalProperties": {
      -            "items": {
      -              "type": "number"
      -            },
      -            "maxItems": 4,
      -            "minItems": 4,
      -            "type": "array"
      -          },
      -          "description": "Per-property cubic-bezier override, e.g. {\"opacity\":[.4,0,.6,1]}, when two `custom`-eased properties in this entry need DIFFERENT curves. Keys must be properties present in this entry.",
      -          "propertyNames": {
      -            "enum": [
      -              "positionX",
      -              "positionY",
      -              "width",
      -              "height",
      -              "rotation",
      -              "scaleX",
      -              "scaleY",
      -              "rotateX",
      -              "rotateY",
      -              "cropX",
      -              "cropY",
      -              "cropWidth",
      -              "cropHeight",
      -              "opacity",
      -              "blur",
      -              "backgroundBlur",
      -              "strokeWidth",
      -              "strokeDash",
      -              "strokeGap",
      -              "strokeTrimStart",
      -              "strokeTrimEnd",
      -              "strokeTrimOffset",
      -              "textStrokeWidth",
      -              "textStrokeDash",
      -              "textStrokeGap",
      -              "imageBorderWidth",
      -              "shadowOffsetX",
      -              "shadowOffsetY",
      -              "shadowBlur",
      -              "shadowSpread",
      -              "borderRadiusTopLeft",
      -              "borderRadiusTopRight",
      -              "borderRadiusBottomRight",
      -              "borderRadiusBottomLeft",
      -              "imageCornerRadiusTopLeft",
      -              "imageCornerRadiusTopRight",
      -              "imageCornerRadiusBottomRight",
      -              "imageCornerRadiusBottomLeft",
      -              "videoCornerRadiusTopLeft",
      -              "videoCornerRadiusTopRight",
      -              "videoCornerRadiusBottomRight",
      -              "videoCornerRadiusBottomLeft",
      -              "fontSize",
      -              "lineHeight",
      -              "letterSpacing",
      -              "paddingTop",
      -              "paddingRight",
      -              "paddingBottom",
      -              "paddingLeft",
      -              "textBgRadiusTopLeft",
      -              "textBgRadiusTopRight",
      -              "textBgRadiusBottomRight",
      -              "textBgRadiusBottomLeft",
      -              "fillColor",
      -              "strokeColor",
      -              "textStrokeColor",
      -              "imageBorderColor",
      -              "textColor",
      -              "textBackgroundColor",
      -              "shadowColor"
      -            ]
      -          },
      -          "type": "object"
      -        },
      -        "blur": {
      -          "description": "Layer blur",
      -          "type": "number"
      -        },
      -        "borderRadiusBottomLeft": {
      -          "description": "borderRadiusBottomLeft in canvas pixels",
      -          "type": "number"
      -        },
      -        "borderRadiusBottomRight": {
      -          "description": "borderRadiusBottomRight in canvas pixels",
      -          "type": "number"
      -        },
      -        "borderRadiusTopLeft": {
      -          "description": "borderRadiusTopLeft in canvas pixels",
      -          "type": "number"
      -        },
      -        "borderRadiusTopRight": {
      -          "description": "borderRadiusTopRight in canvas pixels",
      -          "type": "number"
      -        },
      -        "cropHeight": {
      -          "description": "cropHeight (native unit)",
      -          "type": "number"
      -        },
      -        "cropWidth": {
      -          "description": "cropWidth (native unit)",
      -          "type": "number"
      -        },
      -        "cropX": {
      -          "description": "cropX (native unit)",
      -          "type": "number"
      -        },
      -        "cropY": {
      -          "description": "cropY (native unit)",
      -          "type": "number"
      -        },
      -        "fillColor": {
      -          "description": "fillColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      -          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      -          "type": "string"
      -        },
      -        "fontSize": {
      -          "description": "Font size in CANVAS PIXELS (same unit as the top-level fontSize — NOT a fraction).",
      -          "type": "number"
      -        },
      -        "height": {
      -          "description": "Height in canvas pixels (0 allowed)",
      -          "minimum": 0,
      -          "type": "number"
      -        },
      -        "imageBorderColor": {
      -          "$ref": "#/properties/elements/items/properties/keyframes/anyOf/0/items/properties/fillColor",
      -          "description": "imageBorderColor as #rrggbb or #rrggbbaa (alpha = opacity)"
      -        },
      -        "imageBorderWidth": {
      -          "description": "imageBorderWidth in canvas pixels",
      -          "type": "number"
      -        },
      -        "imageCornerRadiusBottomLeft": {
      -          "description": "imageCornerRadiusBottomLeft in canvas pixels",
      -          "type": "number"
      -        },
      -        "imageCornerRadiusBottomRight": {
      -          "description": "imageCornerRadiusBottomRight in canvas pixels",
      -          "type": "number"
      -        },
      -        "imageCornerRadiusTopLeft": {
      -          "description": "imageCornerRadiusTopLeft in canvas pixels",
      -          "type": "number"
      -        },
      -        "imageCornerRadiusTopRight": {
      -          "description": "imageCornerRadiusTopRight in canvas pixels",
      -          "type": "number"
      -        },
      -        "interpolation": {
      -          "description": "Easing for THIS entry, applied to every property in it (default easeInOut). NOT `easing`.",
      -          "enum": [
      -            "linear",
      -            "easeInOut",
      -            "easeIn",
      -            "easeOut",
      -            "sigmoid",
      -            "smootherstep",
      -            "smoothstep",
      -            "hold",
      -            "easeInBack",
      -            "easeOutBack",
      -            "easeInOutBack",
      -            "custom"
      -          ],
      -          "type": "string"
      -        },
      -        "interpolation_overrides": {
      -          "additionalProperties": {
      -            "$ref": "#/properties/elements/items/properties/keyframes/anyOf/0/items/properties/interpolation"
      -          },
      -          "description": "Per-property easing override, e.g. {\"opacity\":\"linear\"} while the rest use `interpolation`. Keys must be keyframable properties present in this entry.",
      -          "propertyNames": {
      -            "enum": [
      -              "positionX",
      -              "positionY",
      -              "width",
      -              "height",
      -              "rotation",
      -              "scaleX",
      -              "scaleY",
      -              "rotateX",
      -              "rotateY",
      -              "cropX",
      -              "cropY",
      -              "cropWidth",
      -              "cropHeight",
      -              "opacity",
      -              "blur",
      -              "backgroundBlur",
      -              "strokeWidth",
      -              "strokeDash",
      -              "strokeGap",
      -              "strokeTrimStart",
      -              "strokeTrimEnd",
      -              "strokeTrimOffset",
      -              "textStrokeWidth",
      -              "textStrokeDash",
      -              "textStrokeGap",
      -              "imageBorderWidth",
      -              "shadowOffsetX",
      -              "shadowOffsetY",
      -              "shadowBlur",
      -              "shadowSpread",
      -              "borderRadiusTopLeft",
      -              "borderRadiusTopRight",
      -              "borderRadiusBottomRight",
      -              "borderRadiusBottomLeft",
      -              "imageCornerRadiusTopLeft",
      -              "imageCornerRadiusTopRight",
      -              "imageCornerRadiusBottomRight",
      -              "imageCornerRadiusBottomLeft",
      -              "videoCornerRadiusTopLeft",
      -              "videoCornerRadiusTopRight",
      -              "videoCornerRadiusBottomRight",
      -              "videoCornerRadiusBottomLeft",
      -              "fontSize",
      -              "lineHeight",
      -              "letterSpacing",
      -              "paddingTop",
      -              "paddingRight",
      -              "paddingBottom",
      -              "paddingLeft",
      -              "textBgRadiusTopLeft",
      -              "textBgRadiusTopRight",
      -              "textBgRadiusBottomRight",
      -              "textBgRadiusBottomLeft",
      -              "fillColor",
      -              "strokeColor",
      -              "textStrokeColor",
      -              "imageBorderColor",
      -              "textColor",
      -              "textBackgroundColor",
      -              "shadowColor"
      -            ]
      -          },
      -          "type": "object"
      -        },
      -        "letterSpacing": {
      -          "description": "Letter spacing in canvas pixels.",
      -          "type": "number"
      -        },
      -        "lineHeight": {
      -          "description": "lineHeight (native unit)",
      -          "type": "number"
      -        },
      -        "opacity": {
      -          "description": "Opacity 0-100",
      -          "maximum": 100,
      -          "minimum": 0,
      -          "type": "number"
      -        },
      -        "paddingBottom": {
      -          "description": "paddingBottom in canvas pixels",
      -          "type": "number"
      -        },
      -        "paddingLeft": {
      -          "description": "paddingLeft in canvas pixels",
      -          "type": "number"
      -        },
      -        "paddingRight": {
      -          "description": "paddingRight in canvas pixels",
      -          "type": "number"
      -        },
      -        "paddingTop": {
      -          "description": "paddingTop in canvas pixels",
      -          "type": "number"
      -        },
      -        "positionX": {
      -          "description": "X position in canvas pixels (NOT `x`). Uses the SAME alignment-aware origin as the element's top-level x — left-aligned text uses top-left, center-aligned uses CENTER POINT, right-aligned uses top-right; all other types use top-left.",
      -          "type": "number"
      -        },
      -        "positionY": {
      -          "description": "Y position in canvas pixels (NOT `y`). Origin matches positionX — center-aligned text positions by vertical center. y_anchor applies to the element's own y, not to keyframe values — keyframes use the alignment origin, so read the element back and key off its stored y.",
      -          "type": "number"
      -        },
      -        "rotateX": {
      -          "description": "rotateX (native unit)",
      -          "type": "number"
      -        },
      -        "rotateY": {
      -          "description": "rotateY (native unit)",
      -          "type": "number"
      -        },
      -        "rotation": {
      -          "description": "Rotation in degrees",
      -          "type": "number"
      -        },
      -        "scaleX": {
      -          "description": "Horizontal scale multiplier (1 = 100%)",
      -          "type": "number"
      -        },
      -        "scaleY": {
      -          "description": "Vertical scale multiplier (1 = 100%)",
      -          "type": "number"
      -        },
      -        "shadowBlur": {
      -          "description": "shadowBlur in canvas pixels",
      -          "type": "number"
      -        },
      -        "shadowColor": {
      -          "$ref": "#/properties/elements/items/properties/keyframes/anyOf/0/items/properties/fillColor",
      -          "description": "shadowColor as #rrggbb or #rrggbbaa (alpha = opacity)"
      -        },
      -        "shadowOffsetX": {
      -          "description": "shadowOffsetX in canvas pixels",
      -          "type": "number"
      -        },
      -        "shadowOffsetY": {
      -          "description": "shadowOffsetY in canvas pixels",
      -          "type": "number"
      -        },
      -        "shadowSpread": {
      -          "description": "shadowSpread in canvas pixels",
      -          "type": "number"
      -        },
      -        "strokeColor": {
      -          "$ref": "#/properties/elements/items/properties/keyframes/anyOf/0/items/properties/fillColor",
      -          "description": "strokeColor as #rrggbb or #rrggbbaa (alpha = opacity)"
      -        },
      -        "strokeDash": {
      -          "description": "strokeDash in canvas pixels",
      -          "type": "number"
      -        },
      -        "strokeGap": {
      -          "description": "strokeGap in canvas pixels",
      -          "type": "number"
      -        },
      -        "strokeTrimEnd": {
      -          "description": "strokeTrimEnd (native unit)",
      -          "type": "number"
      -        },
      -        "strokeTrimOffset": {
      -          "description": "strokeTrimOffset (native unit)",
      -          "type": "number"
      -        },
      -        "strokeTrimStart": {
      -          "description": "strokeTrimStart (native unit)",
      -          "type": "number"
      -        },
      -        "strokeWidth": {
      -          "description": "strokeWidth in canvas pixels",
      -          "type": "number"
      -        },
      -        "textBackgroundColor": {
      -          "$ref": "#/properties/elements/items/properties/keyframes/anyOf/0/items/properties/fillColor",
      -          "description": "textBackgroundColor as #rrggbb or #rrggbbaa (alpha = opacity)"
      -        },
      -        "textBgRadiusBottomLeft": {
      -          "description": "textBgRadiusBottomLeft in canvas pixels",
      -          "type": "number"
      -        },
      -        "textBgRadiusBottomRight": {
      -          "description": "textBgRadiusBottomRight in canvas pixels",
      -          "type": "number"
      -        },
      -        "textBgRadiusTopLeft": {
      -          "description": "textBgRadiusTopLeft in canvas pixels",
      -          "type": "number"
      -        },
      -        "textBgRadiusTopRight": {
      -          "description": "textBgRadiusTopRight in canvas pixels",
      -          "type": "number"
      -        },
      -        "textColor": {
      -          "$ref": "#/properties/elements/items/properties/keyframes/anyOf/0/items/properties/fillColor",
      -          "description": "textColor as #rrggbb or #rrggbbaa (alpha = opacity)"
      -        },
      -        "textStrokeColor": {
      -          "$ref": "#/properties/elements/items/properties/keyframes/anyOf/0/items/properties/fillColor",
      -          "description": "textStrokeColor as #rrggbb or #rrggbbaa (alpha = opacity)"
      -        },
      -        "textStrokeDash": {
      -          "description": "textStrokeDash in canvas pixels",
      -          "type": "number"
      -        },
      -        "textStrokeGap": {
      -          "description": "textStrokeGap in canvas pixels",
      -          "type": "number"
      -        },
      -        "textStrokeWidth": {
      -          "description": "textStrokeWidth in canvas pixels",
      -          "type": "number"
      -        },
      -        "timestamp": {
      -          "description": "Clip-relative time in seconds",
      -          "minimum": 0,
      -          "type": "number"
      -        },
      -        "videoCornerRadiusBottomLeft": {
      -          "description": "videoCornerRadiusBottomLeft in canvas pixels",
      -          "type": "number"
      -        },
      -        "videoCornerRadiusBottomRight": {
      -          "description": "videoCornerRadiusBottomRight in canvas pixels",
      -          "type": "number"
      -        },
      -        "videoCornerRadiusTopLeft": {
      -          "description": "videoCornerRadiusTopLeft in canvas pixels",
      -          "type": "number"
      -        },
      -        "videoCornerRadiusTopRight": {
      -          "description": "videoCornerRadiusTopRight in canvas pixels",
      -          "type": "number"
      -        },
      -        "width": {
      -          "description": "Width in canvas pixels (0 allowed — e.g. a bar that draws in from 0)",
      -          "minimum": 0,
      -          "type": "number"
      -        }
      -      },
      -      "required": [
      -        "timestamp"
      -      ],
      -      "type": "object"
      -    },
      -    "type": "array"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "items": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "backgroundBlur": {
      +          "description": "Backdrop blur behind the element",
      +          "type": "number"
      +        },
      +        "bezier": {
      +          "description": "Cubic-bezier [x1,y1,x2,y2]; used when interpolation is 'custom'.",
      +          "items": {
      +            "type": "number"
      +          },
      +          "maxItems": 4,
      +          "minItems": 4,
      +          "type": "array"
      +        },
      +        "bezier_overrides": {
      +          "additionalProperties": {
      +            "items": {
      +              "type": "number"
      +            },
      +            "maxItems": 4,
      +            "minItems": 4,
      +            "type": "array"
      +          },
      +          "description": "Per-property cubic-bezier override, e.g. {\"opacity\":[.4,0,.6,1]}, when two `custom`-eased properties in this entry need DIFFERENT curves. Keys must be properties present in this entry.",
      +          "propertyNames": {
      +            "enum": [
      +              "positionX",
      +              "positionY",
      +              "width",
      +              "height",
      +              "rotation",
      +              "scaleX",
      +              "scaleY",
      +              "rotateX",
      +              "rotateY",
      +              "cropX",
      +              "cropY",
      +              "cropWidth",
      +              "cropHeight",
      +              "opacity",
      +              "blur",
      +              "backgroundBlur",
      +              "strokeWidth",
      +              "strokeDash",
      +              "strokeGap",
      +              "strokeTrimStart",
      +              "strokeTrimEnd",
      +              "strokeTrimOffset",
      +              "textStrokeWidth",
      +              "textStrokeDash",
      +              "textStrokeGap",
      +              "imageBorderWidth",
      +              "shadowOffsetX",
      +              "shadowOffsetY",
      +              "shadowBlur",
      +              "shadowSpread",
      +              "borderRadiusTopLeft",
      +              "borderRadiusTopRight",
      +              "borderRadiusBottomRight",
      +              "borderRadiusBottomLeft",
      +              "imageCornerRadiusTopLeft",
      +              "imageCornerRadiusTopRight",
      +              "imageCornerRadiusBottomRight",
      +              "imageCornerRadiusBottomLeft",
      +              "videoCornerRadiusTopLeft",
      +              "videoCornerRadiusTopRight",
      +              "videoCornerRadiusBottomRight",
      +              "videoCornerRadiusBottomLeft",
      +              "fontSize",
      +              "lineHeight",
      +              "letterSpacing",
      +              "paddingTop",
      +              "paddingRight",
      +              "paddingBottom",
      +              "paddingLeft",
      +              "textBgRadiusTopLeft",
      +              "textBgRadiusTopRight",
      +              "textBgRadiusBottomRight",
      +              "textBgRadiusBottomLeft",
      +              "fillColor",
      +              "strokeColor",
      +              "textStrokeColor",
      +              "imageBorderColor",
      +              "textColor",
      +              "textBackgroundColor",
      +              "shadowColor"
      +            ],
      +            "type": "string"
      +          },
      +          "required": [
      +            "positionX",
      +            "positionY",
      +            "width",
      +            "height",
      +            "rotation",
      +            "scaleX",
      +            "scaleY",
      +            "rotateX",
      +            "rotateY",
      +            "cropX",
      +            "cropY",
      +            "cropWidth",
      +            "cropHeight",
      +            "opacity",
      +            "blur",
      +            "backgroundBlur",
      +            "strokeWidth",
      +            "strokeDash",
      +            "strokeGap",
      +            "strokeTrimStart",
      +            "strokeTrimEnd",
      +            "strokeTrimOffset",
      +            "textStrokeWidth",
      +            "textStrokeDash",
      +            "textStrokeGap",
      +            "imageBorderWidth",
      +            "shadowOffsetX",
      +            "shadowOffsetY",
      +            "shadowBlur",
      +            "shadowSpread",
      +            "borderRadiusTopLeft",
      +            "borderRadiusTopRight",
      +            "borderRadiusBottomRight",
      +            "borderRadiusBottomLeft",
      +            "imageCornerRadiusTopLeft",
      +            "imageCornerRadiusTopRight",
      +            "imageCornerRadiusBottomRight",
      +            "imageCornerRadiusBottomLeft",
      +            "videoCornerRadiusTopLeft",
      +            "videoCornerRadiusTopRight",
      +            "videoCornerRadiusBottomRight",
      +            "videoCornerRadiusBottomLeft",
      +            "fontSize",
      +            "lineHeight",
      +            "letterSpacing",
      +            "paddingTop",
      +            "paddingRight",
      +            "paddingBottom",
      +            "paddingLeft",
      +            "textBgRadiusTopLeft",
      +            "textBgRadiusTopRight",
      +            "textBgRadiusBottomRight",
      +            "textBgRadiusBottomLeft",
      +            "fillColor",
      +            "strokeColor",
      +            "textStrokeColor",
      +            "imageBorderColor",
      +            "textColor",
      +            "textBackgroundColor",
      +            "shadowColor"
      +          ],
      +          "type": "object"
      +        },
      +        "blur": {
      +          "description": "Layer blur",
      +          "type": "number"
      +        },
      +        "borderRadiusBottomLeft": {
      +          "description": "borderRadiusBottomLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "borderRadiusBottomRight": {
      +          "description": "borderRadiusBottomRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "borderRadiusTopLeft": {
      +          "description": "borderRadiusTopLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "borderRadiusTopRight": {
      +          "description": "borderRadiusTopRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "cropHeight": {
      +          "description": "cropHeight (native unit)",
      +          "type": "number"
      +        },
      +        "cropWidth": {
      +          "description": "cropWidth (native unit)",
      +          "type": "number"
      +        },
      +        "cropX": {
      +          "description": "cropX (native unit)",
      +          "type": "number"
      +        },
      +        "cropY": {
      +          "description": "cropY (native unit)",
      +          "type": "number"
      +        },
      +        "fillColor": {
      +          "description": "fillColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "fontSize": {
      +          "description": "Font size in CANVAS PIXELS (same unit as the top-level fontSize — NOT a fraction).",
      +          "type": "number"
      +        },
      +        "height": {
      +          "description": "Height in canvas pixels (0 allowed)",
      +          "minimum": 0,
      +          "type": "number"
      +        },
      +        "imageBorderColor": {
      +          "description": "imageBorderColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "imageBorderWidth": {
      +          "description": "imageBorderWidth in canvas pixels",
      +          "type": "number"
      +        },
      +        "imageCornerRadiusBottomLeft": {
      +          "description": "imageCornerRadiusBottomLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "imageCornerRadiusBottomRight": {
      +          "description": "imageCornerRadiusBottomRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "imageCornerRadiusTopLeft": {
      +          "description": "imageCornerRadiusTopLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "imageCornerRadiusTopRight": {
      +          "description": "imageCornerRadiusTopRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "interpolation": {
      +          "description": "Easing for THIS entry, applied to every property in it (default easeInOut). NOT `easing`.",
      +          "enum": [
      +            "linear",
      +            "easeInOut",
      +            "easeIn",
      +            "easeOut",
      +            "sigmoid",
      +            "smootherstep",
      +            "smoothstep",
      +            "hold",
      +            "easeInBack",
      +            "easeOutBack",
      +            "easeInOutBack",
      +            "custom"
      +          ],
      +          "type": "string"
      +        },
      +        "interpolation_overrides": {
      +          "additionalProperties": {
      +            "enum": [
      +              "linear",
      +              "easeInOut",
      +              "easeIn",
      +              "easeOut",
      +              "sigmoid",
      +              "smootherstep",
      +              "smoothstep",
      +              "hold",
      +              "easeInBack",
      +              "easeOutBack",
      +              "easeInOutBack",
      +              "custom"
      +            ],
      +            "type": "string"
      +          },
      +          "description": "Per-property easing override, e.g. {\"opacity\":\"linear\"} while the rest use `interpolation`. Keys must be keyframable properties present in this entry.",
      +          "propertyNames": {
      +            "enum": [
      +              "positionX",
      +              "positionY",
      +              "width",
      +              "height",
      +              "rotation",
      +              "scaleX",
      +              "scaleY",
      +              "rotateX",
      +              "rotateY",
      +              "cropX",
      +              "cropY",
      +              "cropWidth",
      +              "cropHeight",
      +              "opacity",
      +              "blur",
      +              "backgroundBlur",
      +              "strokeWidth",
      +              "strokeDash",
      +              "strokeGap",
      +              "strokeTrimStart",
      +              "strokeTrimEnd",
      +              "strokeTrimOffset",
      +              "textStrokeWidth",
      +              "textStrokeDash",
      +              "textStrokeGap",
      +              "imageBorderWidth",
      +              "shadowOffsetX",
      +              "shadowOffsetY",
      +              "shadowBlur",
      +              "shadowSpread",
      +              "borderRadiusTopLeft",
      +              "borderRadiusTopRight",
      +              "borderRadiusBottomRight",
      +              "borderRadiusBottomLeft",
      +              "imageCornerRadiusTopLeft",
      +              "imageCornerRadiusTopRight",
      +              "imageCornerRadiusBottomRight",
      +              "imageCornerRadiusBottomLeft",
      +              "videoCornerRadiusTopLeft",
      +              "videoCornerRadiusTopRight",
      +              "videoCornerRadiusBottomRight",
      +              "videoCornerRadiusBottomLeft",
      +              "fontSize",
      +              "lineHeight",
      +              "letterSpacing",
      +              "paddingTop",
      +              "paddingRight",
      +              "paddingBottom",
      +              "paddingLeft",
      +              "textBgRadiusTopLeft",
      +              "textBgRadiusTopRight",
      +              "textBgRadiusBottomRight",
      +              "textBgRadiusBottomLeft",
      +              "fillColor",
      +              "strokeColor",
      +              "textStrokeColor",
      +              "imageBorderColor",
      +              "textColor",
      +              "textBackgroundColor",
      +              "shadowColor"
      +            ],
      +            "type": "string"
      +          },
      +          "required": [
      +            "positionX",
      +            "positionY",
      +            "width",
      +            "height",
      +            "rotation",
      +            "scaleX",
      +            "scaleY",
      +            "rotateX",
      +            "rotateY",
      +            "cropX",
      +            "cropY",
      +            "cropWidth",
      +            "cropHeight",
      +            "opacity",
      +            "blur",
      +            "backgroundBlur",
      +            "strokeWidth",
      +            "strokeDash",
      +            "strokeGap",
      +            "strokeTrimStart",
      +            "strokeTrimEnd",
      +            "strokeTrimOffset",
      +            "textStrokeWidth",
      +            "textStrokeDash",
      +            "textStrokeGap",
      +            "imageBorderWidth",
      +            "shadowOffsetX",
      +            "shadowOffsetY",
      +            "shadowBlur",
      +            "shadowSpread",
      +            "borderRadiusTopLeft",
      +            "borderRadiusTopRight",
      +            "borderRadiusBottomRight",
      +            "borderRadiusBottomLeft",
      +            "imageCornerRadiusTopLeft",
      +            "imageCornerRadiusTopRight",
      +            "imageCornerRadiusBottomRight",
      +            "imageCornerRadiusBottomLeft",
      +            "videoCornerRadiusTopLeft",
      +            "videoCornerRadiusTopRight",
      +            "videoCornerRadiusBottomRight",
      +            "videoCornerRadiusBottomLeft",
      +            "fontSize",
      +            "lineHeight",
      +            "letterSpacing",
      +            "paddingTop",
      +            "paddingRight",
      +            "paddingBottom",
      +            "paddingLeft",
      +            "textBgRadiusTopLeft",
      +            "textBgRadiusTopRight",
      +            "textBgRadiusBottomRight",
      +            "textBgRadiusBottomLeft",
      +            "fillColor",
      +            "strokeColor",
      +            "textStrokeColor",
      +            "imageBorderColor",
      +            "textColor",
      +            "textBackgroundColor",
      +            "shadowColor"
      +          ],
      +          "type": "object"
      +        },
      +        "letterSpacing": {
      +          "description": "Letter spacing in canvas pixels.",
      +          "type": "number"
      +        },
      +        "lineHeight": {
      +          "description": "lineHeight (native unit)",
      +          "type": "number"
      +        },
      +        "opacity": {
      +          "description": "Opacity 0-100",
      +          "maximum": 100,
      +          "minimum": 0,
      +          "type": "number"
      +        },
      +        "paddingBottom": {
      +          "description": "paddingBottom in canvas pixels",
      +          "type": "number"
      +        },
      +        "paddingLeft": {
      +          "description": "paddingLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "paddingRight": {
      +          "description": "paddingRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "paddingTop": {
      +          "description": "paddingTop in canvas pixels",
      +          "type": "number"
      +        },
      +        "positionX": {
      +          "description": "X position in canvas pixels (NOT `x`). Same origin as the element's top-level x: `x` is the left edge, except TEXT where alignment picks it: left→left, center→centre, right→right.",
      +          "type": "number"
      +        },
      +        "positionY": {
      +          "description": "Y position in canvas pixels (NOT `y`). Same origin as the element's top-level y: for TEXT `y` is the vertical CENTRE when centre-aligned and the TOP otherwise; every other type uses the top. y_anchor applies to the element's own y, NOT to keyframe values, so read the element back and key off its stored y.",
      +          "type": "number"
      +        },
      +        "rotateX": {
      +          "description": "rotateX (native unit)",
      +          "type": "number"
      +        },
      +        "rotateY": {
      +          "description": "rotateY (native unit)",
      +          "type": "number"
      +        },
      +        "rotation": {
      +          "description": "Rotation in degrees",
      +          "type": "number"
      +        },
      +        "scaleX": {
      +          "description": "Horizontal scale multiplier (1 = 100%)",
      +          "type": "number"
      +        },
      +        "scaleY": {
      +          "description": "Vertical scale multiplier (1 = 100%)",
      +          "type": "number"
      +        },
      +        "shadowBlur": {
      +          "description": "shadowBlur in canvas pixels",
      +          "type": "number"
      +        },
      +        "shadowColor": {
      +          "description": "shadowColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "shadowOffsetX": {
      +          "description": "shadowOffsetX in canvas pixels",
      +          "type": "number"
      +        },
      +        "shadowOffsetY": {
      +          "description": "shadowOffsetY in canvas pixels",
      +          "type": "number"
      +        },
      +        "shadowSpread": {
      +          "description": "shadowSpread in canvas pixels",
      +          "type": "number"
      +        },
      +        "strokeColor": {
      +          "description": "strokeColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "strokeDash": {
      +          "description": "strokeDash in canvas pixels",
      +          "type": "number"
      +        },
      +        "strokeGap": {
      +          "description": "strokeGap in canvas pixels",
      +          "type": "number"
      +        },
      +        "strokeTrimEnd": {
      +          "description": "strokeTrimEnd (native unit)",
      +          "type": "number"
      +        },
      +        "strokeTrimOffset": {
      +          "description": "strokeTrimOffset (native unit)",
      +          "type": "number"
      +        },
      +        "strokeTrimStart": {
      +          "description": "strokeTrimStart (native unit)",
      +          "type": "number"
      +        },
      +        "strokeWidth": {
      +          "description": "strokeWidth in canvas pixels",
      +          "type": "number"
      +        },
      +        "textBackgroundColor": {
      +          "description": "textBackgroundColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "textBgRadiusBottomLeft": {
      +          "description": "textBgRadiusBottomLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "textBgRadiusBottomRight": {
      +          "description": "textBgRadiusBottomRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "textBgRadiusTopLeft": {
      +          "description": "textBgRadiusTopLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "textBgRadiusTopRight": {
      +          "description": "textBgRadiusTopRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "textColor": {
      +          "description": "textColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "textStrokeColor": {
      +          "description": "textStrokeColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "textStrokeDash": {
      +          "description": "textStrokeDash in canvas pixels",
      +          "type": "number"
      +        },
      +        "textStrokeGap": {
      +          "description": "textStrokeGap in canvas pixels",
      +          "type": "number"
      +        },
      +        "textStrokeWidth": {
      +          "description": "textStrokeWidth in canvas pixels",
      +          "type": "number"
      +        },
      +        "timestamp": {
      +          "description": "Clip-relative time in seconds",
      +          "minimum": 0,
      +          "type": "number"
      +        },
      +        "videoCornerRadiusBottomLeft": {
      +          "description": "videoCornerRadiusBottomLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "videoCornerRadiusBottomRight": {
      +          "description": "videoCornerRadiusBottomRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "videoCornerRadiusTopLeft": {
      +          "description": "videoCornerRadiusTopLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "videoCornerRadiusTopRight": {
      +          "description": "videoCornerRadiusTopRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "width": {
      +          "description": "Width in canvas pixels (0 allowed — e.g. a bar that draws in from 0)",
      +          "minimum": 0,
      +          "type": "number"
      +        }
      +      },
      +      "required": [
      +        "timestamp"
      +      ],
      +      "type": "object"
      +    },
      +    "type": "array"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • addedInput schema / properties / elements / items / properties / keyframes_repeat / properties / count / maximum
      Added value: +9007199254740991
    • addedInput schema / properties / elements / items / properties / type_data / propertyNames
      Added value: +{
      +  "type": "string"
      +}
    • changedInput schema / properties / elements / items / properties / x / description
      Previous value: -"X position in canvas pixels. ORIGIN is alignment-dependent: TEXT only — left-aligned uses top-left, center-aligned uses CENTER POINT, right-aligned uses top-right. All other element types (callout, rectangle, arrow, blur, spotlight, image, animation) use top-left. For zoom, use type_data.centerX instead."New value: +"X position in canvas pixels. `x` is the left edge, except TEXT where alignment picks it: left→left, center→centre, right→right (callout, rectangle, arrow, blur, spotlight, image and animation all use the left edge). For zoom, use type_data.centerX instead."
    • changedInput schema / properties / elements / items / properties / y / description
      Previous value: -"Y position in canvas pixels. Which part of the element this refers to is set by type_data.y_anchor for text (top / center / bottom). To sit a label on a row, pill, chip, card or beside an icon, pass that container's centre line here with y_anchor:'center'."New value: +"Y position in canvas pixels — for TEXT `y` is the vertical CENTRE when centre-aligned and the TOP otherwise; every other type uses the top. Pair it with y_anchor (below), always."
    • addedInput schema / properties / elements / items / properties / y_anchor
      Added value: +{
      +  "description": "TEXT only. ALWAYS send `y_anchor` ('top'|'center'|'bottom') when you set `y` on text, so the position states what you meant instead of inheriting the alignment origin. To centre in a row, pill, chip, card or button: pass the container's centre line as `y` with y_anchor:'center'. The server centres the MEASURED box — you cannot compute that height, since wrapping and `fit` change it. A write-time DIRECTIVE: never stored, never returned by a read, so send it on every call whose `y` means the same thing. (Also accepted inside type_data — older spelling; this one wins.)",
      +  "enum": [
      +    "top",
      +    "center",
      +    "bottom"
      +  ],
      +  "type": "string"
      +}
    • changedInput schema / properties / returning / description
      Previous value: -"Declare what comes back, the way get_clip's `select` shapes a read. Omit it and you get ids, the measured layout, and the clip audit in compact form — which names every problem but drops the explanatory prose. Values: 'ids' (element_id per result), 'layout' (the measured text fit — font_size_px, text_width_px, natural_width_px, line_count, fits_width/fits_height/fits — `fits` is the WIDTH check (the widest rendered line inside the box), `fits_height` is the separate height one — plus an `adjusted` entry whenever the measured line box replaced the height you sent; widen a box to natural_width_px, NOT text_width_px, which is the widest RENDERED line and so a lower bound on text that is already wrapping), 'qa.codes' (audit counts and summary plus severity/code/element_ids per finding), 'qa' (the same audit with the full message and suggested fix on every finding — ask for this when a code alone isn't enough to act on). ERROR-severity findings always come back with their full message whichever you choose — including `returning:[]` and `['ids']`, which suppress WARNINGS only. A failed item always returns complete. Pass [] for just {total, succeeded, failed} plus any errors, the leanest write."New value: +"Declare what comes back, the way get_clip's `select` shapes a read. Omit it and you get ids, the measured layout, and the clip audit in compact form — which names every problem but drops the explanatory prose. Values: 'ids' (element_id per result), 'layout' (the measured text fit — font_size_px, text_width_px, natural_width_px, line_count, fits_width/fits_height/fits — `fits` is the WIDTH check (the widest rendered line inside the box), `fits_height` is the separate height one — plus an `adjusted` entry whenever the measured line box replaced the height you sent; widen a box to natural_width_px, NOT text_width_px, which is the widest RENDERED line and so a lower bound on text that is already wrapping; plus `placement` {y_anchor, top, center, bottom} — where the box landed and what your `y` meant, emitted only when the origin was implicit or resolves to 'center'. Compare placement.center with a container's centre line to verify centring: a mis-anchored label is the one layout error nothing else reports), 'qa.codes' (audit counts and summary plus severity/code/element_ids per finding), 'qa' (the same audit with the full message and suggested fix on every finding — ask for this when a code alone isn't enough to act on). ERROR-severity findings always come back with their full message whichever you choose — including `returning:[]` and `['ids']`, which suppress WARNINGS only. A failed item always returns complete. Pass [] for just {total, succeeded, failed} plus any errors, the leanest write."
  5. Changed14 schema fields changed
    • addedInput schema / properties / defaults
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Values shared by every item, sent once rather than repeated. Items win per key; type_data merges one level. E.g. defaults:{clip_index:1, element_type:'text', type_data:{font_setting:{font:'Inter',weight:'600'}, alignment:'center'}} then items carry only what differs.",
      +  "properties": {
      +    "clip_id": {
      +      "type": "string"
      +    },
      +    "clip_index": {
      +      "minimum": 0,
      +      "type": "integer"
      +    },
      +    "element_type": {
      +      "enum": [
      +        "text",
      +        "callout",
      +        "rectangle",
      +        "arrow",
      +        "blur",
      +        "spotlight",
      +        "zoom",
      +        "image",
      +        "video",
      +        "animation"
      +      ],
      +      "type": "string"
      +    },
      +    "end_time": {
      +      "minimum": 0,
      +      "type": "number"
      +    },
      +    "group": {
      +      "minLength": 1,
      +      "type": "string"
      +    },
      +    "height": {
      +      "minimum": 0,
      +      "type": "number"
      +    },
      +    "insert_at": {
      +      "enum": [
      +        "front",
      +        "back"
      +      ],
      +      "type": "string"
      +    },
      +    "keyframes": {
      +      "anyOf": [
      +        {
      +          "items": {
      +            "$ref": "#/properties/elements/items/properties/keyframes/anyOf/0/items"
      +          },
      +          "type": "array"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "rotation": {
      +      "type": "number"
      +    },
      +    "start_time": {
      +      "minimum": 0,
      +      "type": "number"
      +    },
      +    "type_data": {
      +      "additionalProperties": {},
      +      "type": "object"
      +    },
      +    "width": {
      +      "minimum": 0,
      +      "type": "number"
      +    },
      +    "x": {
      +      "type": "number"
      +    },
      +    "y": {
      +      "type": "number"
      +    }
      +  },
      +  "type": "object"
      +}
    • changedInput schema / properties / elements / items / properties / clip_index / description
      Previous value: -"Zero-based clip index"New value: +"Zero-based clip index. Required unless hoisted into `defaults`."
    • changedInput schema / properties / elements / items / properties / height / description
      Previous value: -"Height, pixels (0 allowed)"New value: +"Height, pixels (0 allowed). For text the box's height always follows the measured text, so this reads as the space you are giving it: the text is centred in that space and layout.fits_height says whether it fit. Use type_data.fit to shrink the font into it."
    • addedInput schema / properties / elements / items / properties / insert_at
      Added value: +{
      +  "anyOf": [
      +    {
      +      "enum": [
      +        "front",
      +        "back"
      +      ],
      +      "type": "string"
      +    },
      +    {
      +      "additionalProperties": false,
      +      "properties": {
      +        "before": {
      +          "minLength": 1,
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "before"
      +      ],
      +      "type": "object"
      +    },
      +    {
      +      "additionalProperties": false,
      +      "properties": {
      +        "after": {
      +          "minLength": 1,
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "after"
      +      ],
      +      "type": "object"
      +    }
      +  ],
      +  "description": "Where the element lands in z-order, so you don't need a follow-up reorder_elements. `front` (default) puts it on top of what's already on the clip; `back` puts it behind everything — what a backdrop panel or a wash needs. `{before: element_id}` / `{after: element_id}` place it next to a specific element or group and put it in THAT node's group, which is the only way to position inside a group. Placement is relative to the clip AS IT STANDS when the item is applied, so several `back` items in one call end up in REVERSE input order: send one backdrop per call, or list them back-to-front."
      +}
    • addedInput schema / properties / elements / items / properties / keyframes / anyOf
      Added value: +[
      +  {
      +    "items": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "backgroundBlur": {
      +          "description": "Backdrop blur behind the element",
      +          "type": "number"
      +        },
      +        "bezier": {
      +          "description": "Cubic-bezier [x1,y1,x2,y2]; used when interpolation is 'custom'.",
      +          "items": {
      +            "type": "number"
      +          },
      +          "maxItems": 4,
      +          "minItems": 4,
      +          "type": "array"
      +        },
      +        "bezier_overrides": {
      +          "additionalProperties": {
      +            "items": {
      +              "type": "number"
      +            },
      +            "maxItems": 4,
      +            "minItems": 4,
      +            "type": "array"
      +          },
      +          "description": "Per-property cubic-bezier override, e.g. {\"opacity\":[.4,0,.6,1]}, when two `custom`-eased properties in this entry need DIFFERENT curves. Keys must be properties present in this entry.",
      +          "propertyNames": {
      +            "enum": [
      +              "positionX",
      +              "positionY",
      +              "width",
      +              "height",
      +              "rotation",
      +              "scaleX",
      +              "scaleY",
      +              "rotateX",
      +              "rotateY",
      +              "cropX",
      +              "cropY",
      +              "cropWidth",
      +              "cropHeight",
      +              "opacity",
      +              "blur",
      +              "backgroundBlur",
      +              "strokeWidth",
      +              "strokeDash",
      +              "strokeGap",
      +              "strokeTrimStart",
      +              "strokeTrimEnd",
      +              "strokeTrimOffset",
      +              "textStrokeWidth",
      +              "textStrokeDash",
      +              "textStrokeGap",
      +              "imageBorderWidth",
      +              "shadowOffsetX",
      +              "shadowOffsetY",
      +              "shadowBlur",
      +              "shadowSpread",
      +              "borderRadiusTopLeft",
      +              "borderRadiusTopRight",
      +              "borderRadiusBottomRight",
      +              "borderRadiusBottomLeft",
      +              "imageCornerRadiusTopLeft",
      +              "imageCornerRadiusTopRight",
      +              "imageCornerRadiusBottomRight",
      +              "imageCornerRadiusBottomLeft",
      +              "videoCornerRadiusTopLeft",
      +              "videoCornerRadiusTopRight",
      +              "videoCornerRadiusBottomRight",
      +              "videoCornerRadiusBottomLeft",
      +              "fontSize",
      +              "lineHeight",
      +              "letterSpacing",
      +              "paddingTop",
      +              "paddingRight",
      +              "paddingBottom",
      +              "paddingLeft",
      +              "textBgRadiusTopLeft",
      +              "textBgRadiusTopRight",
      +              "textBgRadiusBottomRight",
      +              "textBgRadiusBottomLeft",
      +              "fillColor",
      +              "strokeColor",
      +              "textStrokeColor",
      +              "imageBorderColor",
      +              "textColor",
      +              "textBackgroundColor",
      +              "shadowColor"
      +            ]
      +          },
      +          "type": "object"
      +        },
      +        "blur": {
      +          "description": "Layer blur",
      +          "type": "number"
      +        },
      +        "borderRadiusBottomLeft": {
      +          "description": "borderRadiusBottomLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "borderRadiusBottomRight": {
      +          "description": "borderRadiusBottomRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "borderRadiusTopLeft": {
      +          "description": "borderRadiusTopLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "borderRadiusTopRight": {
      +          "description": "borderRadiusTopRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "cropHeight": {
      +          "description": "cropHeight (native unit)",
      +          "type": "number"
      +        },
      +        "cropWidth": {
      +          "description": "cropWidth (native unit)",
      +          "type": "number"
      +        },
      +        "cropX": {
      +          "description": "cropX (native unit)",
      +          "type": "number"
      +        },
      +        "cropY": {
      +          "description": "cropY (native unit)",
      +          "type": "number"
      +        },
      +        "fillColor": {
      +          "description": "fillColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      +          "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      +          "type": "string"
      +        },
      +        "fontSize": {
      +          "description": "Font size in CANVAS PIXELS (same unit as the top-level fontSize — NOT a fraction).",
      +          "type": "number"
      +        },
      +        "height": {
      +          "description": "Height in canvas pixels (0 allowed)",
      +          "minimum": 0,
      +          "type": "number"
      +        },
      +        "imageBorderColor": {
      +          "$ref": "#/properties/elements/items/properties/keyframes/anyOf/0/items/properties/fillColor",
      +          "description": "imageBorderColor as #rrggbb or #rrggbbaa (alpha = opacity)"
      +        },
      +        "imageBorderWidth": {
      +          "description": "imageBorderWidth in canvas pixels",
      +          "type": "number"
      +        },
      +        "imageCornerRadiusBottomLeft": {
      +          "description": "imageCornerRadiusBottomLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "imageCornerRadiusBottomRight": {
      +          "description": "imageCornerRadiusBottomRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "imageCornerRadiusTopLeft": {
      +          "description": "imageCornerRadiusTopLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "imageCornerRadiusTopRight": {
      +          "description": "imageCornerRadiusTopRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "interpolation": {
      +          "description": "Easing for THIS entry, applied to every property in it (default easeInOut). NOT `easing`.",
      +          "enum": [
      +            "linear",
      +            "easeInOut",
      +            "easeIn",
      +            "easeOut",
      +            "sigmoid",
      +            "smootherstep",
      +            "smoothstep",
      +            "hold",
      +            "easeInBack",
      +            "easeOutBack",
      +            "easeInOutBack",
      +            "custom"
      +          ],
      +          "type": "string"
      +        },
      +        "interpolation_overrides": {
      +          "additionalProperties": {
      +            "$ref": "#/properties/elements/items/properties/keyframes/anyOf/0/items/properties/interpolation"
      +          },
      +          "description": "Per-property easing override, e.g. {\"opacity\":\"linear\"} while the rest use `interpolation`. Keys must be keyframable properties present in this entry.",
      +          "propertyNames": {
      +            "enum": [
      +              "positionX",
      +              "positionY",
      +              "width",
      +              "height",
      +              "rotation",
      +              "scaleX",
      +              "scaleY",
      +              "rotateX",
      +              "rotateY",
      +              "cropX",
      +              "cropY",
      +              "cropWidth",
      +              "cropHeight",
      +              "opacity",
      +              "blur",
      +              "backgroundBlur",
      +              "strokeWidth",
      +              "strokeDash",
      +              "strokeGap",
      +              "strokeTrimStart",
      +              "strokeTrimEnd",
      +              "strokeTrimOffset",
      +              "textStrokeWidth",
      +              "textStrokeDash",
      +              "textStrokeGap",
      +              "imageBorderWidth",
      +              "shadowOffsetX",
      +              "shadowOffsetY",
      +              "shadowBlur",
      +              "shadowSpread",
      +              "borderRadiusTopLeft",
      +              "borderRadiusTopRight",
      +              "borderRadiusBottomRight",
      +              "borderRadiusBottomLeft",
      +              "imageCornerRadiusTopLeft",
      +              "imageCornerRadiusTopRight",
      +              "imageCornerRadiusBottomRight",
      +              "imageCornerRadiusBottomLeft",
      +              "videoCornerRadiusTopLeft",
      +              "videoCornerRadiusTopRight",
      +              "videoCornerRadiusBottomRight",
      +              "videoCornerRadiusBottomLeft",
      +              "fontSize",
      +              "lineHeight",
      +              "letterSpacing",
      +              "paddingTop",
      +              "paddingRight",
      +              "paddingBottom",
      +              "paddingLeft",
      +              "textBgRadiusTopLeft",
      +              "textBgRadiusTopRight",
      +              "textBgRadiusBottomRight",
      +              "textBgRadiusBottomLeft",
      +              "fillColor",
      +              "strokeColor",
      +              "textStrokeColor",
      +              "imageBorderColor",
      +              "textColor",
      +              "textBackgroundColor",
      +              "shadowColor"
      +            ]
      +          },
      +          "type": "object"
      +        },
      +        "letterSpacing": {
      +          "description": "Letter spacing in canvas pixels.",
      +          "type": "number"
      +        },
      +        "lineHeight": {
      +          "description": "lineHeight (native unit)",
      +          "type": "number"
      +        },
      +        "opacity": {
      +          "description": "Opacity 0-100",
      +          "maximum": 100,
      +          "minimum": 0,
      +          "type": "number"
      +        },
      +        "paddingBottom": {
      +          "description": "paddingBottom in canvas pixels",
      +          "type": "number"
      +        },
      +        "paddingLeft": {
      +          "description": "paddingLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "paddingRight": {
      +          "description": "paddingRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "paddingTop": {
      +          "description": "paddingTop in canvas pixels",
      +          "type": "number"
      +        },
      +        "positionX": {
      +          "description": "X position in canvas pixels (NOT `x`). Uses the SAME alignment-aware origin as the element's top-level x — left-aligned text uses top-left, center-aligned uses CENTER POINT, right-aligned uses top-right; all other types use top-left.",
      +          "type": "number"
      +        },
      +        "positionY": {
      +          "description": "Y position in canvas pixels (NOT `y`). Origin matches positionX — center-aligned text positions by vertical center. y_anchor applies to the element's own y, not to keyframe values — keyframes use the alignment origin, so read the element back and key off its stored y.",
      +          "type": "number"
      +        },
      +        "rotateX": {
      +          "description": "rotateX (native unit)",
      +          "type": "number"
      +        },
      +        "rotateY": {
      +          "description": "rotateY (native unit)",
      +          "type": "number"
      +        },
      +        "rotation": {
      +          "description": "Rotation in degrees",
      +          "type": "number"
      +        },
      +        "scaleX": {
      +          "description": "Horizontal scale multiplier (1 = 100%)",
      +          "type": "number"
      +        },
      +        "scaleY": {
      +          "description": "Vertical scale multiplier (1 = 100%)",
      +          "type": "number"
      +        },
      +        "shadowBlur": {
      +          "description": "shadowBlur in canvas pixels",
      +          "type": "number"
      +        },
      +        "shadowColor": {
      +          "$ref": "#/properties/elements/items/properties/keyframes/anyOf/0/items/properties/fillColor",
      +          "description": "shadowColor as #rrggbb or #rrggbbaa (alpha = opacity)"
      +        },
      +        "shadowOffsetX": {
      +          "description": "shadowOffsetX in canvas pixels",
      +          "type": "number"
      +        },
      +        "shadowOffsetY": {
      +          "description": "shadowOffsetY in canvas pixels",
      +          "type": "number"
      +        },
      +        "shadowSpread": {
      +          "description": "shadowSpread in canvas pixels",
      +          "type": "number"
      +        },
      +        "strokeColor": {
      +          "$ref": "#/properties/elements/items/properties/keyframes/anyOf/0/items/properties/fillColor",
      +          "description": "strokeColor as #rrggbb or #rrggbbaa (alpha = opacity)"
      +        },
      +        "strokeDash": {
      +          "description": "strokeDash in canvas pixels",
      +          "type": "number"
      +        },
      +        "strokeGap": {
      +          "description": "strokeGap in canvas pixels",
      +          "type": "number"
      +        },
      +        "strokeTrimEnd": {
      +          "description": "strokeTrimEnd (native unit)",
      +          "type": "number"
      +        },
      +        "strokeTrimOffset": {
      +          "description": "strokeTrimOffset (native unit)",
      +          "type": "number"
      +        },
      +        "strokeTrimStart": {
      +          "description": "strokeTrimStart (native unit)",
      +          "type": "number"
      +        },
      +        "strokeWidth": {
      +          "description": "strokeWidth in canvas pixels",
      +          "type": "number"
      +        },
      +        "textBackgroundColor": {
      +          "$ref": "#/properties/elements/items/properties/keyframes/anyOf/0/items/properties/fillColor",
      +          "description": "textBackgroundColor as #rrggbb or #rrggbbaa (alpha = opacity)"
      +        },
      +        "textBgRadiusBottomLeft": {
      +          "description": "textBgRadiusBottomLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "textBgRadiusBottomRight": {
      +          "description": "textBgRadiusBottomRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "textBgRadiusTopLeft": {
      +          "description": "textBgRadiusTopLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "textBgRadiusTopRight": {
      +          "description": "textBgRadiusTopRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "textColor": {
      +          "$ref": "#/properties/elements/items/properties/keyframes/anyOf/0/items/properties/fillColor",
      +          "description": "textColor as #rrggbb or #rrggbbaa (alpha = opacity)"
      +        },
      +        "textStrokeColor": {
      +          "$ref": "#/properties/elements/items/properties/keyframes/anyOf/0/items/properties/fillColor",
      +          "description": "textStrokeColor as #rrggbb or #rrggbbaa (alpha = opacity)"
      +        },
      +        "textStrokeDash": {
      +          "description": "textStrokeDash in canvas pixels",
      +          "type": "number"
      +        },
      +        "textStrokeGap": {
      +          "description": "textStrokeGap in canvas pixels",
      +          "type": "number"
      +        },
      +        "textStrokeWidth": {
      +          "description": "textStrokeWidth in canvas pixels",
      +          "type": "number"
      +        },
      +        "timestamp": {
      +          "description": "Clip-relative time in seconds",
      +          "minimum": 0,
      +          "type": "number"
      +        },
      +        "videoCornerRadiusBottomLeft": {
      +          "description": "videoCornerRadiusBottomLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "videoCornerRadiusBottomRight": {
      +          "description": "videoCornerRadiusBottomRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "videoCornerRadiusTopLeft": {
      +          "description": "videoCornerRadiusTopLeft in canvas pixels",
      +          "type": "number"
      +        },
      +        "videoCornerRadiusTopRight": {
      +          "description": "videoCornerRadiusTopRight in canvas pixels",
      +          "type": "number"
      +        },
      +        "width": {
      +          "description": "Width in canvas pixels (0 allowed — e.g. a bar that draws in from 0)",
      +          "minimum": 0,
      +          "type": "number"
      +        }
      +      },
      +      "required": [
      +        "timestamp"
      +      ],
      +      "type": "object"
      +    },
      +    "type": "array"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / elements / items / properties / keyframes / description
      Previous value: -"Animation keyframes (≥2 entries). Each entry has a timestamp plus one or more keyframable properties (position/size in canvas pixels; rotation°, opacity 0-100, scale, colors as #rrggbb[aa], etc. in native units). Easing: per-entry `interpolation` + optional per-property `interpolation_overrides`. Call get_element_schema to see which properties this element_type can keyframe."New value: +"Animation keyframes (≥2 entries). Each entry has a timestamp plus one or more keyframable properties (position/size in canvas pixels; rotation°, opacity 0-100, scale, colors as #rrggbb[aa], etc. in native units). Easing: per-entry `interpolation` + optional per-property `interpolation_overrides`. Call get_element_schema to see which properties this element_type can keyframe. null is accepted and means none."
    • removedInput schema / properties / elements / items / properties / keyframes / items
      Removed value: -{
      -  "additionalProperties": false,
      -  "properties": {
      -    "backgroundBlur": {
      -      "description": "Backdrop blur behind the element",
      -      "type": "number"
      -    },
      -    "bezier": {
      -      "description": "Cubic-bezier [x1,y1,x2,y2]; used when interpolation is 'custom'.",
      -      "items": {
      -        "type": "number"
      -      },
      -      "maxItems": 4,
      -      "minItems": 4,
      -      "type": "array"
      -    },
      -    "bezier_overrides": {
      -      "additionalProperties": {
      -        "items": {
      -          "type": "number"
      -        },
      -        "maxItems": 4,
      -        "minItems": 4,
      -        "type": "array"
      -      },
      -      "description": "Per-property cubic-bezier override, e.g. {\"opacity\":[.4,0,.6,1]}, when two `custom`-eased properties in this entry need DIFFERENT curves. Keys must be properties present in this entry.",
      -      "propertyNames": {
      -        "enum": [
      -          "positionX",
      -          "positionY",
      -          "width",
      -          "height",
      -          "rotation",
      -          "scaleX",
      -          "scaleY",
      -          "rotateX",
      -          "rotateY",
      -          "opacity",
      -          "blur",
      -          "backgroundBlur",
      -          "strokeWidth",
      -          "strokeDash",
      -          "strokeGap",
      -          "strokeTrimStart",
      -          "strokeTrimEnd",
      -          "strokeTrimOffset",
      -          "textStrokeWidth",
      -          "textStrokeDash",
      -          "textStrokeGap",
      -          "imageBorderWidth",
      -          "shadowOffsetX",
      -          "shadowOffsetY",
      -          "shadowBlur",
      -          "shadowSpread",
      -          "borderRadiusTopLeft",
      -          "borderRadiusTopRight",
      -          "borderRadiusBottomRight",
      -          "borderRadiusBottomLeft",
      -          "imageCornerRadiusTopLeft",
      -          "imageCornerRadiusTopRight",
      -          "imageCornerRadiusBottomRight",
      -          "imageCornerRadiusBottomLeft",
      -          "videoCornerRadiusTopLeft",
      -          "videoCornerRadiusTopRight",
      -          "videoCornerRadiusBottomRight",
      -          "videoCornerRadiusBottomLeft",
      -          "fontSize",
      -          "lineHeight",
      -          "letterSpacing",
      -          "paddingTop",
      -          "paddingRight",
      -          "paddingBottom",
      -          "paddingLeft",
      -          "textBgRadiusTopLeft",
      -          "textBgRadiusTopRight",
      -          "textBgRadiusBottomRight",
      -          "textBgRadiusBottomLeft",
      -          "strokeColor",
      -          "textStrokeColor",
      -          "imageBorderColor",
      -          "textColor",
      -          "textBackgroundColor",
      -          "shadowColor"
      -        ]
      -      },
      -      "type": "object"
      -    },
      -    "blur": {
      -      "description": "Layer blur",
      -      "type": "number"
      -    },
      -    "borderRadiusBottomLeft": {
      -      "description": "borderRadiusBottomLeft in canvas pixels",
      -      "type": "number"
      -    },
      -    "borderRadiusBottomRight": {
      -      "description": "borderRadiusBottomRight in canvas pixels",
      -      "type": "number"
      -    },
      -    "borderRadiusTopLeft": {
      -      "description": "borderRadiusTopLeft in canvas pixels",
      -      "type": "number"
      -    },
      -    "borderRadiusTopRight": {
      -      "description": "borderRadiusTopRight in canvas pixels",
      -      "type": "number"
      -    },
      -    "fontSize": {
      -      "description": "Font size in CANVAS PIXELS (same unit as the top-level fontSize — NOT a fraction).",
      -      "type": "number"
      -    },
      -    "height": {
      -      "description": "Height in canvas pixels (0 allowed)",
      -      "minimum": 0,
      -      "type": "number"
      -    },
      -    "imageBorderColor": {
      -      "$ref": "#/properties/elements/items/properties/keyframes/items/properties/strokeColor",
      -      "description": "imageBorderColor as #rrggbb or #rrggbbaa (alpha = opacity)"
      -    },
      -    "imageBorderWidth": {
      -      "description": "imageBorderWidth in canvas pixels",
      -      "type": "number"
      -    },
      -    "imageCornerRadiusBottomLeft": {
      -      "description": "imageCornerRadiusBottomLeft in canvas pixels",
      -      "type": "number"
      -    },
      -    "imageCornerRadiusBottomRight": {
      -      "description": "imageCornerRadiusBottomRight in canvas pixels",
      -      "type": "number"
      -    },
      -    "imageCornerRadiusTopLeft": {
      -      "description": "imageCornerRadiusTopLeft in canvas pixels",
      -      "type": "number"
      -    },
      -    "imageCornerRadiusTopRight": {
      -      "description": "imageCornerRadiusTopRight in canvas pixels",
      -      "type": "number"
      -    },
      -    "interpolation": {
      -      "description": "Easing for THIS entry, applied to every property in it (default easeInOut). NOT `easing`.",
      -      "enum": [
      -        "linear",
      -        "easeInOut",
      -        "easeIn",
      -        "easeOut",
      -        "sigmoid",
      -        "smootherstep",
      -        "smoothstep",
      -        "hold",
      -        "easeInBack",
      -        "easeOutBack",
      -        "easeInOutBack",
      -        "custom"
      -      ],
      -      "type": "string"
      -    },
      -    "interpolation_overrides": {
      -      "additionalProperties": {
      -        "$ref": "#/properties/elements/items/properties/keyframes/items/properties/interpolation"
      -      },
      -      "description": "Per-property easing override, e.g. {\"opacity\":\"linear\"} while the rest use `interpolation`. Keys must be keyframable properties present in this entry.",
      -      "propertyNames": {
      -        "enum": [
      -          "positionX",
      -          "positionY",
      -          "width",
      -          "height",
      -          "rotation",
      -          "scaleX",
      -          "scaleY",
      -          "rotateX",
      -          "rotateY",
      -          "opacity",
      -          "blur",
      -          "backgroundBlur",
      -          "strokeWidth",
      -          "strokeDash",
      -          "strokeGap",
      -          "strokeTrimStart",
      -          "strokeTrimEnd",
      -          "strokeTrimOffset",
      -          "textStrokeWidth",
      -          "textStrokeDash",
      -          "textStrokeGap",
      -          "imageBorderWidth",
      -          "shadowOffsetX",
      -          "shadowOffsetY",
      -          "shadowBlur",
      -          "shadowSpread",
      -          "borderRadiusTopLeft",
      -          "borderRadiusTopRight",
      -          "borderRadiusBottomRight",
      -          "borderRadiusBottomLeft",
      -          "imageCornerRadiusTopLeft",
      -          "imageCornerRadiusTopRight",
      -          "imageCornerRadiusBottomRight",
      -          "imageCornerRadiusBottomLeft",
      -          "videoCornerRadiusTopLeft",
      -          "videoCornerRadiusTopRight",
      -          "videoCornerRadiusBottomRight",
      -          "videoCornerRadiusBottomLeft",
      -          "fontSize",
      -          "lineHeight",
      -          "letterSpacing",
      -          "paddingTop",
      -          "paddingRight",
      -          "paddingBottom",
      -          "paddingLeft",
      -          "textBgRadiusTopLeft",
      -          "textBgRadiusTopRight",
      -          "textBgRadiusBottomRight",
      -          "textBgRadiusBottomLeft",
      -          "strokeColor",
      -          "textStrokeColor",
      -          "imageBorderColor",
      -          "textColor",
      -          "textBackgroundColor",
      -          "shadowColor"
      -        ]
      -      },
      -      "type": "object"
      -    },
      -    "letterSpacing": {
      -      "description": "Letter spacing in canvas pixels.",
      -      "type": "number"
      -    },
      -    "lineHeight": {
      -      "description": "lineHeight (native unit)",
      -      "type": "number"
      -    },
      -    "opacity": {
      -      "description": "Opacity 0-100",
      -      "maximum": 100,
      -      "minimum": 0,
      -      "type": "number"
      -    },
      -    "paddingBottom": {
      -      "description": "paddingBottom in canvas pixels",
      -      "type": "number"
      -    },
      -    "paddingLeft": {
      -      "description": "paddingLeft in canvas pixels",
      -      "type": "number"
      -    },
      -    "paddingRight": {
      -      "description": "paddingRight in canvas pixels",
      -      "type": "number"
      -    },
      -    "paddingTop": {
      -      "description": "paddingTop in canvas pixels",
      -      "type": "number"
      -    },
      -    "positionX": {
      -      "description": "X position in canvas pixels (NOT `x`). Uses the SAME alignment-aware origin as the element's top-level x — left-aligned text uses top-left, center-aligned uses CENTER POINT, right-aligned uses top-right; all other types use top-left.",
      -      "type": "number"
      -    },
      -    "positionY": {
      -      "description": "Y position in canvas pixels (NOT `y`). Origin matches positionX — center-aligned text positions by vertical center.",
      -      "type": "number"
      -    },
      -    "rotateX": {
      -      "description": "rotateX (native unit)",
      -      "type": "number"
      -    },
      -    "rotateY": {
      -      "description": "rotateY (native unit)",
      -      "type": "number"
      -    },
      -    "rotation": {
      -      "description": "Rotation in degrees",
      -      "type": "number"
      -    },
      -    "scaleX": {
      -      "description": "Horizontal scale multiplier (1 = 100%)",
      -      "type": "number"
      -    },
      -    "scaleY": {
      -      "description": "Vertical scale multiplier (1 = 100%)",
      -      "type": "number"
      -    },
      -    "shadowBlur": {
      -      "description": "shadowBlur in canvas pixels",
      -      "type": "number"
      -    },
      -    "shadowColor": {
      -      "$ref": "#/properties/elements/items/properties/keyframes/items/properties/strokeColor",
      -      "description": "shadowColor as #rrggbb or #rrggbbaa (alpha = opacity)"
      -    },
      -    "shadowOffsetX": {
      -      "description": "shadowOffsetX in canvas pixels",
      -      "type": "number"
      -    },
      -    "shadowOffsetY": {
      -      "description": "shadowOffsetY in canvas pixels",
      -      "type": "number"
      -    },
      -    "shadowSpread": {
      -      "description": "shadowSpread in canvas pixels",
      -      "type": "number"
      -    },
      -    "strokeColor": {
      -      "description": "strokeColor as #rrggbb or #rrggbbaa (alpha = opacity)",
      -      "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      -      "type": "string"
      -    },
      -    "strokeDash": {
      -      "description": "strokeDash in canvas pixels",
      -      "type": "number"
      -    },
      -    "strokeGap": {
      -      "description": "strokeGap in canvas pixels",
      -      "type": "number"
      -    },
      -    "strokeTrimEnd": {
      -      "description": "strokeTrimEnd (native unit)",
      -      "type": "number"
      -    },
      -    "strokeTrimOffset": {
      -      "description": "strokeTrimOffset (native unit)",
      -      "type": "number"
      -    },
      -    "strokeTrimStart": {
      -      "description": "strokeTrimStart (native unit)",
      -      "type": "number"
      -    },
      -    "strokeWidth": {
      -      "description": "strokeWidth in canvas pixels",
      -      "type": "number"
      -    },
      -    "textBackgroundColor": {
      -      "$ref": "#/properties/elements/items/properties/keyframes/items/properties/strokeColor",
      -      "description": "textBackgroundColor as #rrggbb or #rrggbbaa (alpha = opacity)"
      -    },
      -    "textBgRadiusBottomLeft": {
      -      "description": "textBgRadiusBottomLeft in canvas pixels",
      -      "type": "number"
      -    },
      -    "textBgRadiusBottomRight": {
      -      "description": "textBgRadiusBottomRight in canvas pixels",
      -      "type": "number"
      -    },
      -    "textBgRadiusTopLeft": {
      -      "description": "textBgRadiusTopLeft in canvas pixels",
      -      "type": "number"
      -    },
      -    "textBgRadiusTopRight": {
      -      "description": "textBgRadiusTopRight in canvas pixels",
      -      "type": "number"
      -    },
      -    "textColor": {
      -      "$ref": "#/properties/elements/items/properties/keyframes/items/properties/strokeColor",
      -      "description": "textColor as #rrggbb or #rrggbbaa (alpha = opacity)"
      -    },
      -    "textStrokeColor": {
      -      "$ref": "#/properties/elements/items/properties/keyframes/items/properties/strokeColor",
      -      "description": "textStrokeColor as #rrggbb or #rrggbbaa (alpha = opacity)"
      -    },
      -    "textStrokeDash": {
      -      "description": "textStrokeDash in canvas pixels",
      -      "type": "number"
      -    },
      -    "textStrokeGap": {
      -      "description": "textStrokeGap in canvas pixels",
      -      "type": "number"
      -    },
      -    "textStrokeWidth": {
      -      "description": "textStrokeWidth in canvas pixels",
      -      "type": "number"
      -    },
      -    "timestamp": {
      -      "description": "Clip-relative time in seconds",
      -      "minimum": 0,
      -      "type": "number"
      -    },
      -    "videoCornerRadiusBottomLeft": {
      -      "description": "videoCornerRadiusBottomLeft in canvas pixels",
      -      "type": "number"
      -    },
      -    "videoCornerRadiusBottomRight": {
      -      "description": "videoCornerRadiusBottomRight in canvas pixels",
      -      "type": "number"
      -    },
      -    "videoCornerRadiusTopLeft": {
      -      "description": "videoCornerRadiusTopLeft in canvas pixels",
      -      "type": "number"
      -    },
      -    "videoCornerRadiusTopRight": {
      -      "description": "videoCornerRadiusTopRight in canvas pixels",
      -      "type": "number"
      -    },
      -    "width": {
      -      "description": "Width in canvas pixels (0 allowed — e.g. a bar that draws in from 0)",
      -      "minimum": 0,
      -      "type": "number"
      -    }
      -  },
      -  "required": [
      -    "timestamp"
      -  ],
      -  "type": "object"
      -}
    • removedInput schema / properties / elements / items / properties / keyframes / type
      Removed value: -"array"
    • addedInput schema / properties / elements / items / properties / keyframes_repeat
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Repeat `keyframes` as a cycle — { count, mode?, every? }. Requires `keyframes` in the same call.",
      +  "properties": {
      +    "count": {
      +      "description": "TOTAL number of cycles, INCLUDING the one you wrote. 1 is a no-op. Expansion stops at the clip end rather than piling the overflow onto the last frame, and the generated total is capped at 600 keyframes (it errors rather than silently truncating).",
      +      "minimum": 1,
      +      "type": "integer"
      +    },
      +    "every": {
      +      "description": "Seconds between cycle STARTS. Defaults to the cycle's own span (back-to-back). A LARGER value holds the last value in the gap — that is how you get a pulse every 2s instead of a constant wobble. Shorter than the cycle is rejected, because the cycles would overlap and collide on the same frames.",
      +      "exclusiveMinimum": 0,
      +      "type": "number"
      +    },
      +    "mode": {
      +      "description": "'loop' (default) replays the cycle forwards every time — seamless only if your first and last values match. 'pingpong' alternates forwards/backwards, so the value always returns to where it started without a jump; use it for a breathe/pulse written as a one-way ramp.",
      +      "enum": [
      +        "loop",
      +        "pingpong"
      +      ],
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "count"
      +  ],
      +  "type": "object"
      +}
    • changedInput schema / properties / elements / items / properties / width / description
      Previous value: -"Width, pixels (0 allowed — e.g. a bar that draws in from 0)"New value: +"Width, pixels (0 allowed — e.g. a bar that draws in from 0). For text this is the WRAP width and it is kept as sent: the text wraps to it and the box stays this wide. (Height differs — the box's height follows the measured text.)"
    • changedInput schema / properties / elements / items / properties / x / description
      Previous value: -"X position in canvas pixels. ORIGIN is alignment-dependent: TEXT only — left-aligned uses top-left, center-aligned uses CENTER POINT, right-aligned uses top-right. All other element types (callout, rectangle, arrow, blur, spotlight, image, animation) use top-left. For zoom, use type_data.center_x instead."New value: +"X position in canvas pixels. ORIGIN is alignment-dependent: TEXT only — left-aligned uses top-left, center-aligned uses CENTER POINT, right-aligned uses top-right. All other element types (callout, rectangle, arrow, blur, spotlight, image, animation) use top-left. For zoom, use type_data.centerX instead."
    • changedInput schema / properties / elements / items / properties / y / description
      Previous value: -"Y position in canvas pixels. ORIGIN matches x: center-aligned text positions by its vertical center. All other types and alignments use the top edge."New value: +"Y position in canvas pixels. Which part of the element this refers to is set by type_data.y_anchor for text (top / center / bottom). To sit a label on a row, pill, chip, card or beside an icon, pass that container's centre line here with y_anchor:'center'."
    • removedInput schema / properties / elements / items / required
      Removed value: -[
      -  "clip_index"
      -]
    • addedInput schema / properties / returning
      Added value: +{
      +  "description": "Declare what comes back, the way get_clip's `select` shapes a read. Omit it and you get ids, the measured layout, and the clip audit in compact form — which names every problem but drops the explanatory prose. Values: 'ids' (element_id per result), 'layout' (the measured text fit — font_size_px, text_width_px, natural_width_px, line_count, fits_width/fits_height/fits — `fits` is the WIDTH check (the widest rendered line inside the box), `fits_height` is the separate height one — plus an `adjusted` entry whenever the measured line box replaced the height you sent; widen a box to natural_width_px, NOT text_width_px, which is the widest RENDERED line and so a lower bound on text that is already wrapping), 'qa.codes' (audit counts and summary plus severity/code/element_ids per finding), 'qa' (the same audit with the full message and suggested fix on every finding — ask for this when a code alone isn't enough to act on). ERROR-severity findings always come back with their full message whichever you choose — including `returning:[]` and `['ids']`, which suppress WARNINGS only. A failed item always returns complete. Pass [] for just {total, succeeded, failed} plus any errors, the leanest write.",
      +  "items": {
      +    "enum": [
      +      "ids",
      +      "layout",
      +      "qa",
      +      "qa.codes"
      +    ],
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
  6. First observed

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Despite annotations being minimal, the description thoroughly discloses behavioral traits: single-save semantics per call, sequential application of items, partial-success behavior, rejection semantics ('nothing it sent is written'), and the full concurrency conflict domain. It also clarifies non-obvious behaviors like z-order list position, grouping depth, and that a rejection is not last-write-wins.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but front-loaded with purpose and batched usage, and every paragraph addresses a distinct decision an agent must make: defaults, components, z-order, grouping, concurrency, quirks, animation, and y_anchor. It earns most of its length given the tool's complexity, though it is verbose enough that tighter editing would improve scannability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is complete for a complex mutation tool with no output schema. It covers return shaping via `returning`, per-item result behavior and partial success, failure/rejection modes, element-type-specific coordinate rules, keyframe placement, grouping semantics, and the y_anchor directive — leaving no major decision an agent needs to make undocumented.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, but the description adds crucial meaning beyond it: defaults merge one level, keyframes must be top-level and not inside type_data, zoom ignores x/y/width/height, clip_id is accepted but unused, and text width/height behave differently than other element types. These distinctions are essential for correct invocation and are not inferable from the schema alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence states exactly what the tool does: 'Add many elements across one or more clips in a single tool call.' It also differentiates from sibling and predecessor tools by saying 'Replaces the per-element tool — always batch,' making the batched scope explicit and preventing confusion with add_clips or add_audio.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit when-to-use guidance: 'Use after calling get_element_schema to confirm the type_data shape per element_type.' It also names alternatives for related operations (update_elements for content, reorder_elements for z-order, find for components) and states a clear exclusion: concurrent calls on the same clip are unsafe and whole-clip mutations should not run simultaneously.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.