{"openapi":"3.1.0","info":{"title":"canvas","version":"1.0.0","description":"Granular page-document editing API for the Solidpixels stack. Read subtrees of a page document, or apply mutation ops one at a time with optimistic concurrency via a Valkey lock. Node ids in op payloads are regenerated server-side; see `LayoutNode` for the renderer-shape contract."},"tags":[{"name":"Documents","description":"Operations on a single page document. A page has separate `preview` and `published` documents; the data service exposes them under `pages/{id}/documents[]`."},{"name":"Design","description":"Website-scoped design operations. Create, update, or delete color, font, and typography tokens, and restyle prose/rich-text elements, in the website styleguide in one atomic batch; a token edit cascades to every node that references its class (`bg-<key>-*`, `font-<key>`). Separate from the document-scoped page-ops: design tokens are per-website, not per-document."},{"name":"Theme","description":"Website-scoped theme operations. Create, rename, reorder, duplicate, and hide/purge theme columns; add/rename/reorder/soft-delete/purge the global attribute rows; and set/clear a token value in a theme cell. One order-sensitive batch through the same per-website design lock as `/v2/design/apply`: the ops apply atomically in memory (all or none), then the resulting schemes / schemeMeta / schemeVariables rows are written sequentially, not in a single atomic persistence step."},{"name":"Code blocks","description":"Website-scoped CRUD for design code blocks — snippets of custom code injected into the rendered site head or footer. Stored as a single per-website row; ids are minted server-side."},{"name":"Admin migrations","description":"Trigger a blob migration run over this website — the same run the migration CLI drives from a shell, behind HTTP so datamanagement can start one without a container. Scope is the token: one call covers the website the JWT names and no other. Start with `dryRun: true`, which reports the same counts and writes nothing."},{"name":"Settings","description":"**Experimental — API subject to change.** Website-scoped configuration settings, persisted via the solidpixels website-settings API (the same rows the CMS settings UI manages). Currently covers the favicon."}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"Op":{"oneOf":[{"$ref":"#/components/schemas/UpdateNodeOp"},{"$ref":"#/components/schemas/AddNodesOp"},{"$ref":"#/components/schemas/RemoveNodeOp"},{"$ref":"#/components/schemas/MoveBeforeOp"},{"$ref":"#/components/schemas/WrapNodeOp"},{"$ref":"#/components/schemas/UnwrapNodeOp"},{"$ref":"#/components/schemas/AddSymbolOp"},{"$ref":"#/components/schemas/UpdateSymbolOp"},{"$ref":"#/components/schemas/SetSettingsOp"},{"$ref":"#/components/schemas/AssignThemeToSectionOp"},{"$ref":"#/components/schemas/ClearThemeFromSectionOp"}],"discriminator":{"propertyName":"type","mapping":{"updateNode":"#/components/schemas/UpdateNodeOp","addNodes":"#/components/schemas/AddNodesOp","removeNode":"#/components/schemas/RemoveNodeOp","moveBefore":"#/components/schemas/MoveBeforeOp","wrapNode":"#/components/schemas/WrapNodeOp","unwrapNode":"#/components/schemas/UnwrapNodeOp","addSymbol":"#/components/schemas/AddSymbolOp","updateSymbol":"#/components/schemas/UpdateSymbolOp","setSettings":"#/components/schemas/SetSettingsOp","assignThemeToSection":"#/components/schemas/AssignThemeToSectionOp","clearThemeFromSection":"#/components/schemas/ClearThemeFromSectionOp"}},"description":"Discriminated union of the mutation ops, keyed by `type`. Six primitive ops (updateNode, addNodes, removeNode, moveBefore, wrapNode, unwrapNode) plus two symbol ops (addSymbol, updateSymbol) plus one settings op (setSettings) plus two theme ops (assignThemeToSection, clearThemeFromSection) that compile to the primitives. See each variant for semantics and examples."},"UpdateNodeOp":{"type":"object","properties":{"type":{"type":"string","enum":["updateNode"]},"nodeId":{"type":"string"},"updates":{"type":"object","additionalProperties":{"nullable":true}}},"required":["type","nodeId","updates"],"description":"Merge `updates` into the node identified by `nodeId`. The keys `id`, `children` and `type` are reserved and rejected as INVALID_OP. Updated fields are validated against the target node's type: `tag` must stay within the type's allowlist (h1-h6/p for formattedInlineElement, span for text) and `content` must match the type (string for text, ProseMirror doc for formatted nodes).","example":{"type":"updateNode","nodeId":"h1","updates":{"tag":"h2"}}},"AddNodesOp":{"type":"object","properties":{"type":{"type":"string","enum":["addNodes"]},"parentId":{"type":"string"},"rootNodeId":{"type":"string"},"nodes":{"type":"object","additionalProperties":{"oneOf":[{"type":"object","properties":{"id":{"type":"string","description":"Unique id of this node within the document."},"tag":{"type":"string","description":"HTML tag of the rendered element, e.g. 'div', 'h1', 'section'. Omitted on symbol nodes."},"attrs":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"nullable":true}}],"description":"HTML attributes for element nodes (e.g. {\"href\":\"/about\"}); component props for non-element nodes such as symbols."},"classes":{"type":"array","items":{"type":"string"},"description":"Arbitrary utility classes written directly into the element's HTML class attribute. Use ONLY for one-off classes that have no token (e.g. Tailwind arbitrary values like 'gap-[2rem]', or 'prose'). All token styling — color, spacing, typography, radius, … — goes in styleOverrides (per node) or elementStyles (styleguide), NOT here."},"symbolId":{"type":"string","description":"Id of the linked symbol. Symbol nodes only."},"variantId":{"type":"string","description":"Id of the selected symbol variant. Symbol nodes only."},"binding":{"type":"object","additionalProperties":{"anyOf":[{"type":"array","items":{"anyOf":[{"type":"string","enum":["file"]},{"type":"string"},{"anyOf":[{"type":"string","enum":["id"]},{"type":"string","enum":["file_hash"]},{"type":"string","enum":["file_size"]},{"type":"string","enum":["mime_type"]},{"type":"string","enum":["storage_path"]},{"type":"string","enum":["cdn_path"]},{"type":"string","enum":["serve_path"]},{"type":"string","enum":["created_at"]},{"type":"string","enum":["updated_at"]},{"type":"string","enum":["alt_text"]},{"type":"string","enum":["value"]}]}]},"minItems":3,"maxItems":3,"description":"Value from a file: [\"file\", fileId, prop?]. prop selects a file field; \"value\" gives the primary URL (cdn_path, else serve_path)."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["symbol"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Value from a symbol prop: [\"symbol\", propKey, fieldKey]. propKey is the symbol prop; fieldKey selects a field of its value (e.g. \"value\", or a file field like \"cdn_path\")."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["collection"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current collection item: [\"collection\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["each"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current 'each' item: [\"each\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["source"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Item source for an 'each' node or a bound prop: 'static' (items provided on the node), 'collection' (a CMS collection query — id, sort, filters, pagination), 'navigation' (the site navigation tree), or 'locales' (the website's frontend-exposed locales for a language switcher)."}]},"minItems":2,"maxItems":2,"description":"Bind directly to an iterator source: [\"source\", IteratorSource]."}]},"description":"Binds live CMS data into this node instead of static values. Map from a target path on the node (e.g. \"content\", \"attrs.src\", \"classes\") to a value-handle tuple. Kinds: collection, file, symbol, link, each, source. Example: {\"attrs.src\": [\"file\",\"file_5d8e\",\"value\"]} fills src from a file."},"metadata":{"type":"object","properties":{"cmsType":{"type":"string","enum":["spacer"]},"formField":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"label":{"type":"string","description":"Human readable label authored for the field. Falls back to the field key when absent."},"required":{"type":"boolean"},"minLength":{"type":"number"},"maxLength":{"type":"number"},"pattern":{"type":"string","nullable":true},"min":{"type":"number"},"max":{"type":"number"},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]}},"multiple":{"type":"boolean"},"maxSize":{"type":"number"},"accept":{"type":"array","items":{"type":"string"}},"order":{"type":"number"}}},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["webhook"]},"url":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"to":{"type":"string"},"subject":{"type":"string"},"templateId":{"type":"string"}},"required":["type","to","subject"]}]}},"successBehavior":{"$ref":"#/components/schemas/SuccessBehavior"},"consentFieldKey":{"type":"string","description":"Key of the form field that carries the GDPR consent. Points at a field with type \"checkbox\" in the same form definition."},"consentBySubmit":{"type":"boolean","description":"Whether GDPR consent is given by submitting the form. Set instead of consentFieldKey on forms that show the consent text without a consent checkbox."},"visitorEmail":{"type":"object","properties":{"visitorEmailFieldKey":{"type":"string","description":"Key of the form field whose submitted value carries the visitor email address. Points at a field able to hold an email address in the same form definition."},"templateId":{"type":"string","description":"Id of the email template sent to the visitor."}},"required":["visitorEmailFieldKey"],"description":"Configuration of the email sent to the visitor after a successful submit. Absent when no visitor email is configured."}}}]},"custom":{"type":"object","additionalProperties":{"nullable":true},"description":"custom user metadata (for example, import description)"},"dataGuard":{"type":"object","properties":{"version":{"type":"number","enum":[1],"description":"Data guard schema version."},"enabled":{"type":"boolean","description":"Whether the guard is active. Owned outside the inspector section that edits the rest of this structure."},"type":{"type":"string","enum":["app"],"description":"Consumer kind. Placeholder — currently always \"app\"."},"data":{"type":"object","properties":{"collection":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string","description":"Target collection id this entry exposes to the frontend."},"columns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may project. Empty or missing means nothing is exposed — this is an allowlist, not a projection convenience."},"sortColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may sort by. Empty or missing means nothing is allowed."},"filterColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may filter by. Empty or missing means nothing is allowed."},"maxItems":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Upper bound on the number of items the frontend may request."},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]},"description":"Filters always applied on top of any frontend-supplied filter."}},"required":["type","collectionId"]},"description":"Collection entries keyed by a user-defined key."}},"required":["collection"]}},"required":["version","enabled","type","data"],"description":"Frontend data exposure allowlist for this node."}},"additionalProperties":{"nullable":true},"description":"Editor metadata for this node: cms element type, form-field definition, and custom notes (e.g. import description)."},"styleRole":{"type":"string","description":"Semantic style role, e.g. 'role_card'. Makes the node inherit the styleguide entry elementStyles[role], above its tag styles and below its own styleOverrides. Reuse one role's styling across many nodes."},"styleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for this node. Maps style slots ('color.bg', 'padding.top', 'font-size', …) to a StyleRef. Layers: default / breakpoints / containers; each has a base slot map and optional per-state (hover, focus) maps. A StyleRef is one of three variants: token (preferred) — {type:'token', scope:'project'|'primitive', key}, a design token by scope+key; pick from the design scale so the site stays consistent. keyword — {type:'keyword', value:'auto'}, a CSS keyword like 'auto' or 'inherit'. value — {type:'value', value:'25px'}, a raw CSS literal, last resort. Example: {\"default\":{\"base\":{\"color.bg\":{\"type\":\"token\",\"scope\":\"project\",\"key\":\"surface.primary\"}}}}."},"instanceStyleProps":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleOverrides"}}],"description":"Symbol-instance style overrides keyed by inner-node style role. Symbol nodes only. Only points exposed by the symbol design interface survive resolution."},"schemeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","description":"Color-scheme slug applied to this node and its subtree, emitted as data-scheme=\"<slug>\". Selects a named scheme that overrides project-scope color tokens for the subtree."},"type":{"type":"string","enum":["text"]},"content":{"type":"string","description":"Plain (unformatted) text content. Text and embed nodes only."},"children":{"type":"array","items":{"type":"string"},"description":"Ids of this node's child nodes, in render order."}},"required":["id","tag","attrs","classes","type","content","children"],"description":"Node with text content"},{"type":"object","properties":{"id":{"type":"string","description":"Unique id of this node within the document."},"tag":{"type":"string","description":"HTML tag of the rendered element, e.g. 'div', 'h1', 'section'. Omitted on symbol nodes."},"attrs":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"nullable":true}}],"description":"HTML attributes for element nodes (e.g. {\"href\":\"/about\"}); component props for non-element nodes such as symbols."},"classes":{"type":"array","items":{"type":"string"},"description":"Arbitrary utility classes written directly into the element's HTML class attribute. Use ONLY for one-off classes that have no token (e.g. Tailwind arbitrary values like 'gap-[2rem]', or 'prose'). All token styling — color, spacing, typography, radius, … — goes in styleOverrides (per node) or elementStyles (styleguide), NOT here."},"symbolId":{"type":"string","description":"Id of the linked symbol. Symbol nodes only."},"variantId":{"type":"string","description":"Id of the selected symbol variant. Symbol nodes only."},"binding":{"type":"object","additionalProperties":{"anyOf":[{"type":"array","items":{"anyOf":[{"type":"string","enum":["file"]},{"type":"string"},{"anyOf":[{"type":"string","enum":["id"]},{"type":"string","enum":["file_hash"]},{"type":"string","enum":["file_size"]},{"type":"string","enum":["mime_type"]},{"type":"string","enum":["storage_path"]},{"type":"string","enum":["cdn_path"]},{"type":"string","enum":["serve_path"]},{"type":"string","enum":["created_at"]},{"type":"string","enum":["updated_at"]},{"type":"string","enum":["alt_text"]},{"type":"string","enum":["value"]}]}]},"minItems":3,"maxItems":3,"description":"Value from a file: [\"file\", fileId, prop?]. prop selects a file field; \"value\" gives the primary URL (cdn_path, else serve_path)."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["symbol"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Value from a symbol prop: [\"symbol\", propKey, fieldKey]. propKey is the symbol prop; fieldKey selects a field of its value (e.g. \"value\", or a file field like \"cdn_path\")."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["collection"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current collection item: [\"collection\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["each"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current 'each' item: [\"each\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["source"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Item source for an 'each' node or a bound prop: 'static' (items provided on the node), 'collection' (a CMS collection query — id, sort, filters, pagination), 'navigation' (the site navigation tree), or 'locales' (the website's frontend-exposed locales for a language switcher)."}]},"minItems":2,"maxItems":2,"description":"Bind directly to an iterator source: [\"source\", IteratorSource]."}]},"description":"Binds live CMS data into this node instead of static values. Map from a target path on the node (e.g. \"content\", \"attrs.src\", \"classes\") to a value-handle tuple. Kinds: collection, file, symbol, link, each, source. Example: {\"attrs.src\": [\"file\",\"file_5d8e\",\"value\"]} fills src from a file."},"metadata":{"type":"object","properties":{"cmsType":{"type":"string","enum":["spacer"]},"formField":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"label":{"type":"string","description":"Human readable label authored for the field. Falls back to the field key when absent."},"required":{"type":"boolean"},"minLength":{"type":"number"},"maxLength":{"type":"number"},"pattern":{"type":"string","nullable":true},"min":{"type":"number"},"max":{"type":"number"},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]}},"multiple":{"type":"boolean"},"maxSize":{"type":"number"},"accept":{"type":"array","items":{"type":"string"}},"order":{"type":"number"}}},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["webhook"]},"url":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"to":{"type":"string"},"subject":{"type":"string"},"templateId":{"type":"string"}},"required":["type","to","subject"]}]}},"successBehavior":{"$ref":"#/components/schemas/SuccessBehavior"},"consentFieldKey":{"type":"string","description":"Key of the form field that carries the GDPR consent. Points at a field with type \"checkbox\" in the same form definition."},"consentBySubmit":{"type":"boolean","description":"Whether GDPR consent is given by submitting the form. Set instead of consentFieldKey on forms that show the consent text without a consent checkbox."},"visitorEmail":{"type":"object","properties":{"visitorEmailFieldKey":{"type":"string","description":"Key of the form field whose submitted value carries the visitor email address. Points at a field able to hold an email address in the same form definition."},"templateId":{"type":"string","description":"Id of the email template sent to the visitor."}},"required":["visitorEmailFieldKey"],"description":"Configuration of the email sent to the visitor after a successful submit. Absent when no visitor email is configured."}}}]},"custom":{"type":"object","additionalProperties":{"nullable":true},"description":"custom user metadata (for example, import description)"},"dataGuard":{"type":"object","properties":{"version":{"type":"number","enum":[1],"description":"Data guard schema version."},"enabled":{"type":"boolean","description":"Whether the guard is active. Owned outside the inspector section that edits the rest of this structure."},"type":{"type":"string","enum":["app"],"description":"Consumer kind. Placeholder — currently always \"app\"."},"data":{"type":"object","properties":{"collection":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string","description":"Target collection id this entry exposes to the frontend."},"columns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may project. Empty or missing means nothing is exposed — this is an allowlist, not a projection convenience."},"sortColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may sort by. Empty or missing means nothing is allowed."},"filterColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may filter by. Empty or missing means nothing is allowed."},"maxItems":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Upper bound on the number of items the frontend may request."},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]},"description":"Filters always applied on top of any frontend-supplied filter."}},"required":["type","collectionId"]},"description":"Collection entries keyed by a user-defined key."}},"required":["collection"]}},"required":["version","enabled","type","data"],"description":"Frontend data exposure allowlist for this node."}},"additionalProperties":{"nullable":true},"description":"Editor metadata for this node: cms element type, form-field definition, and custom notes (e.g. import description)."},"styleRole":{"type":"string","description":"Semantic style role, e.g. 'role_card'. Makes the node inherit the styleguide entry elementStyles[role], above its tag styles and below its own styleOverrides. Reuse one role's styling across many nodes."},"styleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for this node. Maps style slots ('color.bg', 'padding.top', 'font-size', …) to a StyleRef. Layers: default / breakpoints / containers; each has a base slot map and optional per-state (hover, focus) maps. A StyleRef is one of three variants: token (preferred) — {type:'token', scope:'project'|'primitive', key}, a design token by scope+key; pick from the design scale so the site stays consistent. keyword — {type:'keyword', value:'auto'}, a CSS keyword like 'auto' or 'inherit'. value — {type:'value', value:'25px'}, a raw CSS literal, last resort. Example: {\"default\":{\"base\":{\"color.bg\":{\"type\":\"token\",\"scope\":\"project\",\"key\":\"surface.primary\"}}}}."},"instanceStyleProps":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleOverrides"}}],"description":"Symbol-instance style overrides keyed by inner-node style role. Symbol nodes only. Only points exposed by the symbol design interface survive resolution."},"schemeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","description":"Color-scheme slug applied to this node and its subtree, emitted as data-scheme=\"<slug>\". Selects a named scheme that overrides project-scope color tokens for the subtree."},"type":{"type":"string","enum":["formattedInlineElement"]},"content":{"type":"object","properties":{"type":{"type":"string"},"attrs":{"type":"object","additionalProperties":{"nullable":true}},"content":{"type":"array","items":{"$ref":"#/components/schemas/JSONContent"}},"marks":{"type":"array","items":{"allOf":[{"type":"object","additionalProperties":{"nullable":true}},{"type":"object","properties":{"type":{"type":"string"},"attrs":{"type":"object","additionalProperties":{"nullable":true}}},"required":["type"]}]}},"text":{"type":"string"}},"description":"Rich-text content as a ProseMirror document. Formatted inline/block nodes only."},"children":{"type":"array","items":{"type":"string"},"description":"Ids of this node's child nodes, in render order."}},"required":["id","tag","attrs","classes","type","content","children"],"description":"Node with formatted content"},{"type":"object","properties":{"id":{"type":"string","description":"Unique id of this node within the document."},"tag":{"type":"string","description":"HTML tag of the rendered element, e.g. 'div', 'h1', 'section'. Omitted on symbol nodes."},"attrs":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"nullable":true}}],"description":"Static HTML attributes for element nodes (e.g. {\"href\":\"/about\"}); component props for non-element nodes such as symbols. Static literal values only — never value-handle tuples or any dynamic references. To bind dynamic data (CMS fields, files, links) to an attr or prop, use the binding field instead; binding targets the attr/prop by path, e.g. attrs.<name>."},"classes":{"type":"array","items":{"type":"string"},"description":"Arbitrary utility classes written directly into the element's HTML class attribute. Use ONLY for one-off classes that have no token (e.g. Tailwind arbitrary values like 'gap-[2rem]', or 'prose'). All token styling — color, spacing, typography, radius, … — goes in styleOverrides (per node) or elementStyles (styleguide), NOT here."},"symbolId":{"type":"string","description":"Id of the linked symbol. Symbol nodes only."},"variantId":{"type":"string","description":"Id of the selected symbol variant. Symbol nodes only."},"binding":{"type":"object","additionalProperties":{"anyOf":[{"type":"array","items":{"anyOf":[{"type":"string","enum":["file"]},{"type":"string"},{"anyOf":[{"type":"string","enum":["id"]},{"type":"string","enum":["file_hash"]},{"type":"string","enum":["file_size"]},{"type":"string","enum":["mime_type"]},{"type":"string","enum":["storage_path"]},{"type":"string","enum":["cdn_path"]},{"type":"string","enum":["serve_path"]},{"type":"string","enum":["created_at"]},{"type":"string","enum":["updated_at"]},{"type":"string","enum":["alt_text"]},{"type":"string","enum":["value"]}]}]},"minItems":3,"maxItems":3,"description":"Value from a file: [\"file\", fileId, prop?]. prop selects a file field; \"value\" gives the primary URL (cdn_path, else serve_path)."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["symbol"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Value from a symbol prop: [\"symbol\", propKey, fieldKey]. propKey is the symbol prop; fieldKey selects a field of its value (e.g. \"value\", or a file field like \"cdn_path\")."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["collection"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current collection item: [\"collection\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["each"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current 'each' item: [\"each\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["source"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Item source for an 'each' node or a bound prop: 'static' (items provided on the node), 'collection' (a CMS collection query — id, sort, filters, pagination), 'navigation' (the site navigation tree), or 'locales' (the website's frontend-exposed locales for a language switcher)."}]},"minItems":2,"maxItems":2,"description":"Bind directly to an iterator source: [\"source\", IteratorSource]."}]},"description":"Binds live CMS data into this node instead of static values. Map from a target path on the node (e.g. \"content\", \"attrs.src\", \"classes\") to a value-handle tuple. Kinds: collection, file, symbol, link, each, source. Example: {\"attrs.src\": [\"file\",\"file_5d8e\",\"value\"]} fills src from a file."},"metadata":{"type":"object","properties":{"cmsType":{"type":"string","enum":["spacer"]},"formField":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"label":{"type":"string","description":"Human readable label authored for the field. Falls back to the field key when absent."},"required":{"type":"boolean"},"minLength":{"type":"number"},"maxLength":{"type":"number"},"pattern":{"type":"string","nullable":true},"min":{"type":"number"},"max":{"type":"number"},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]}},"multiple":{"type":"boolean"},"maxSize":{"type":"number"},"accept":{"type":"array","items":{"type":"string"}},"order":{"type":"number"}}},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["webhook"]},"url":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"to":{"type":"string"},"subject":{"type":"string"},"templateId":{"type":"string"}},"required":["type","to","subject"]}]}},"successBehavior":{"$ref":"#/components/schemas/SuccessBehavior"},"consentFieldKey":{"type":"string","description":"Key of the form field that carries the GDPR consent. Points at a field with type \"checkbox\" in the same form definition."},"consentBySubmit":{"type":"boolean","description":"Whether GDPR consent is given by submitting the form. Set instead of consentFieldKey on forms that show the consent text without a consent checkbox."},"visitorEmail":{"type":"object","properties":{"visitorEmailFieldKey":{"type":"string","description":"Key of the form field whose submitted value carries the visitor email address. Points at a field able to hold an email address in the same form definition."},"templateId":{"type":"string","description":"Id of the email template sent to the visitor."}},"required":["visitorEmailFieldKey"],"description":"Configuration of the email sent to the visitor after a successful submit. Absent when no visitor email is configured."}}}]},"custom":{"type":"object","additionalProperties":{"nullable":true},"description":"custom user metadata (for example, import description)"},"dataGuard":{"type":"object","properties":{"version":{"type":"number","enum":[1],"description":"Data guard schema version."},"enabled":{"type":"boolean","description":"Whether the guard is active. Owned outside the inspector section that edits the rest of this structure."},"type":{"type":"string","enum":["app"],"description":"Consumer kind. Placeholder — currently always \"app\"."},"data":{"type":"object","properties":{"collection":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string","description":"Target collection id this entry exposes to the frontend."},"columns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may project. Empty or missing means nothing is exposed — this is an allowlist, not a projection convenience."},"sortColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may sort by. Empty or missing means nothing is allowed."},"filterColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may filter by. Empty or missing means nothing is allowed."},"maxItems":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Upper bound on the number of items the frontend may request."},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]},"description":"Filters always applied on top of any frontend-supplied filter."}},"required":["type","collectionId"]},"description":"Collection entries keyed by a user-defined key."}},"required":["collection"]}},"required":["version","enabled","type","data"],"description":"Frontend data exposure allowlist for this node."}},"additionalProperties":{"nullable":true},"description":"Editor metadata for this node: cms element type, form-field definition, and custom notes (e.g. import description)."},"styleRole":{"type":"string","description":"Semantic style role, e.g. 'role_card'. Makes the node inherit the styleguide entry elementStyles[role], above its tag styles and below its own styleOverrides. Reuse one role's styling across many nodes."},"styleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for this node. Maps style slots ('color.bg', 'padding.top', 'font-size', …) to a StyleRef. Layers: default / breakpoints / containers; each has a base slot map and optional per-state (hover, focus) maps. A StyleRef is one of three variants: token (preferred) — {type:'token', scope:'project'|'primitive', key}, a design token by scope+key; pick from the design scale so the site stays consistent. keyword — {type:'keyword', value:'auto'}, a CSS keyword like 'auto' or 'inherit'. value — {type:'value', value:'25px'}, a raw CSS literal, last resort. Example: {\"default\":{\"base\":{\"color.bg\":{\"type\":\"token\",\"scope\":\"project\",\"key\":\"surface.primary\"}}}}."},"instanceStyleProps":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleOverrides"}}],"description":"Symbol-instance style overrides keyed by inner-node style role. Symbol nodes only. Only points exposed by the symbol design interface survive resolution."},"schemeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","description":"Color-scheme slug applied to this node and its subtree, emitted as data-scheme=\"<slug>\". Selects a named scheme that overrides project-scope color tokens for the subtree."},"type":{"type":"string","enum":["each"]},"content":{"nullable":true},"source":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Where this 'each' node gets its items: static, a CMS collection query, or site navigation."},"items":{"type":"object","properties":{"items":{"type":"array","items":{"nullable":true}},"schema":{"nullable":true}},"required":["items"],"description":"Inline static items (with their schema) for a static 'each' source."},"preventEmpty":{"type":"boolean","description":"Hide the empty-state placeholder when the source yields no items."},"children":{"type":"array","items":{"type":"string"},"description":"Ids of this node's child nodes, in render order."}},"required":["id","tag","attrs","classes","type","children"],"description":"Node for iterating over a source"},{"type":"object","properties":{"id":{"type":"string","description":"Unique id of this node within the document."},"tag":{"type":"string","description":"HTML tag of the rendered element, e.g. 'div', 'h1', 'section'. Omitted on symbol nodes."},"attrs":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"nullable":true}}],"description":"Static HTML attributes for element nodes (e.g. {\"href\":\"/about\"}); component props for non-element nodes such as symbols. Static literal values only — never value-handle tuples or any dynamic references. To bind dynamic data (CMS fields, files, links) to an attr or prop, use the binding field instead; binding targets the attr/prop by path, e.g. attrs.<name>."},"classes":{"type":"array","items":{"type":"string"},"description":"Arbitrary utility classes written directly into the element's HTML class attribute. Use ONLY for one-off classes that have no token (e.g. Tailwind arbitrary values like 'gap-[2rem]', or 'prose'). All token styling — color, spacing, typography, radius, … — goes in styleOverrides (per node) or elementStyles (styleguide), NOT here."},"symbolId":{"type":"string","description":"Id of the linked symbol. Symbol nodes only."},"variantId":{"type":"string","description":"Id of the selected symbol variant. Symbol nodes only."},"binding":{"type":"object","additionalProperties":{"anyOf":[{"type":"array","items":{"anyOf":[{"type":"string","enum":["file"]},{"type":"string"},{"anyOf":[{"type":"string","enum":["id"]},{"type":"string","enum":["file_hash"]},{"type":"string","enum":["file_size"]},{"type":"string","enum":["mime_type"]},{"type":"string","enum":["storage_path"]},{"type":"string","enum":["cdn_path"]},{"type":"string","enum":["serve_path"]},{"type":"string","enum":["created_at"]},{"type":"string","enum":["updated_at"]},{"type":"string","enum":["alt_text"]},{"type":"string","enum":["value"]}]}]},"minItems":3,"maxItems":3,"description":"Value from a file: [\"file\", fileId, prop?]. prop selects a file field; \"value\" gives the primary URL (cdn_path, else serve_path)."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["symbol"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Value from a symbol prop: [\"symbol\", propKey, fieldKey]. propKey is the symbol prop; fieldKey selects a field of its value (e.g. \"value\", or a file field like \"cdn_path\")."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["collection"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current collection item: [\"collection\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["each"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current 'each' item: [\"each\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["source"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Item source for an 'each' node or a bound prop: 'static' (items provided on the node), 'collection' (a CMS collection query — id, sort, filters, pagination), 'navigation' (the site navigation tree), or 'locales' (the website's frontend-exposed locales for a language switcher)."}]},"minItems":2,"maxItems":2,"description":"Bind directly to an iterator source: [\"source\", IteratorSource]."}]},"description":"Binds live CMS data into this node instead of static values. Map from a target path on the node (e.g. \"content\", \"attrs.src\", \"classes\") to a value-handle tuple. Kinds: collection, file, symbol, link, each, source. Example: {\"attrs.src\": [\"file\",\"file_5d8e\",\"value\"]} fills src from a file."},"metadata":{"type":"object","properties":{"cmsType":{"type":"string","enum":["spacer"]},"formField":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"label":{"type":"string","description":"Human readable label authored for the field. Falls back to the field key when absent."},"required":{"type":"boolean"},"minLength":{"type":"number"},"maxLength":{"type":"number"},"pattern":{"type":"string","nullable":true},"min":{"type":"number"},"max":{"type":"number"},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]}},"multiple":{"type":"boolean"},"maxSize":{"type":"number"},"accept":{"type":"array","items":{"type":"string"}},"order":{"type":"number"}}},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["webhook"]},"url":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"to":{"type":"string"},"subject":{"type":"string"},"templateId":{"type":"string"}},"required":["type","to","subject"]}]}},"successBehavior":{"$ref":"#/components/schemas/SuccessBehavior"},"consentFieldKey":{"type":"string","description":"Key of the form field that carries the GDPR consent. Points at a field with type \"checkbox\" in the same form definition."},"consentBySubmit":{"type":"boolean","description":"Whether GDPR consent is given by submitting the form. Set instead of consentFieldKey on forms that show the consent text without a consent checkbox."},"visitorEmail":{"type":"object","properties":{"visitorEmailFieldKey":{"type":"string","description":"Key of the form field whose submitted value carries the visitor email address. Points at a field able to hold an email address in the same form definition."},"templateId":{"type":"string","description":"Id of the email template sent to the visitor."}},"required":["visitorEmailFieldKey"],"description":"Configuration of the email sent to the visitor after a successful submit. Absent when no visitor email is configured."}}}]},"custom":{"type":"object","additionalProperties":{"nullable":true},"description":"custom user metadata (for example, import description)"},"dataGuard":{"type":"object","properties":{"version":{"type":"number","enum":[1],"description":"Data guard schema version."},"enabled":{"type":"boolean","description":"Whether the guard is active. Owned outside the inspector section that edits the rest of this structure."},"type":{"type":"string","enum":["app"],"description":"Consumer kind. Placeholder — currently always \"app\"."},"data":{"type":"object","properties":{"collection":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string","description":"Target collection id this entry exposes to the frontend."},"columns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may project. Empty or missing means nothing is exposed — this is an allowlist, not a projection convenience."},"sortColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may sort by. Empty or missing means nothing is allowed."},"filterColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may filter by. Empty or missing means nothing is allowed."},"maxItems":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Upper bound on the number of items the frontend may request."},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]},"description":"Filters always applied on top of any frontend-supplied filter."}},"required":["type","collectionId"]},"description":"Collection entries keyed by a user-defined key."}},"required":["collection"]}},"required":["version","enabled","type","data"],"description":"Frontend data exposure allowlist for this node."}},"additionalProperties":{"nullable":true},"description":"Editor metadata for this node: cms element type, form-field definition, and custom notes (e.g. import description)."},"styleRole":{"type":"string","description":"Semantic style role, e.g. 'role_card'. Makes the node inherit the styleguide entry elementStyles[role], above its tag styles and below its own styleOverrides. Reuse one role's styling across many nodes."},"styleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for this node. Maps style slots ('color.bg', 'padding.top', 'font-size', …) to a StyleRef. Layers: default / breakpoints / containers; each has a base slot map and optional per-state (hover, focus) maps. A StyleRef is one of three variants: token (preferred) — {type:'token', scope:'project'|'primitive', key}, a design token by scope+key; pick from the design scale so the site stays consistent. keyword — {type:'keyword', value:'auto'}, a CSS keyword like 'auto' or 'inherit'. value — {type:'value', value:'25px'}, a raw CSS literal, last resort. Example: {\"default\":{\"base\":{\"color.bg\":{\"type\":\"token\",\"scope\":\"project\",\"key\":\"surface.primary\"}}}}."},"instanceStyleProps":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleOverrides"}}],"description":"Symbol-instance style overrides keyed by inner-node style role. Symbol nodes only. Only points exposed by the symbol design interface survive resolution."},"schemeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","description":"Color-scheme slug applied to this node and its subtree, emitted as data-scheme=\"<slug>\". Selects a named scheme that overrides project-scope color tokens for the subtree."},"type":{"type":"string","enum":["slot"]},"content":{"nullable":true},"name":{"type":"string","description":"Name of the slot this placeholder defines, inside a symbol variant layout."},"children":{"type":"array","items":{"type":"string"},"description":"Ids of this node's child nodes, in render order."}},"required":["id","tag","attrs","classes","type","name","children"],"description":"Slot placeholder inside a symbol variant layout"},{"type":"object","properties":{"id":{"type":"string","description":"Unique id of this node within the document."},"tag":{"type":"string","description":"HTML tag of the rendered element, e.g. 'div', 'h1', 'section'. Omitted on symbol nodes."},"attrs":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"nullable":true}}],"description":"Static HTML attributes for element nodes (e.g. {\"href\":\"/about\"}); component props for non-element nodes such as symbols. Static literal values only — never value-handle tuples or any dynamic references. To bind dynamic data (CMS fields, files, links) to an attr or prop, use the binding field instead; binding targets the attr/prop by path, e.g. attrs.<name>."},"classes":{"type":"array","items":{"type":"string"},"description":"Arbitrary utility classes written directly into the element's HTML class attribute. Use ONLY for one-off classes that have no token (e.g. Tailwind arbitrary values like 'gap-[2rem]', or 'prose'). All token styling — color, spacing, typography, radius, … — goes in styleOverrides (per node) or elementStyles (styleguide), NOT here."},"symbolId":{"type":"string","description":"Id of the linked symbol. Symbol nodes only."},"variantId":{"type":"string","description":"Id of the selected symbol variant. Symbol nodes only."},"binding":{"type":"object","additionalProperties":{"anyOf":[{"type":"array","items":{"anyOf":[{"type":"string","enum":["file"]},{"type":"string"},{"anyOf":[{"type":"string","enum":["id"]},{"type":"string","enum":["file_hash"]},{"type":"string","enum":["file_size"]},{"type":"string","enum":["mime_type"]},{"type":"string","enum":["storage_path"]},{"type":"string","enum":["cdn_path"]},{"type":"string","enum":["serve_path"]},{"type":"string","enum":["created_at"]},{"type":"string","enum":["updated_at"]},{"type":"string","enum":["alt_text"]},{"type":"string","enum":["value"]}]}]},"minItems":3,"maxItems":3,"description":"Value from a file: [\"file\", fileId, prop?]. prop selects a file field; \"value\" gives the primary URL (cdn_path, else serve_path)."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["symbol"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Value from a symbol prop: [\"symbol\", propKey, fieldKey]. propKey is the symbol prop; fieldKey selects a field of its value (e.g. \"value\", or a file field like \"cdn_path\")."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["collection"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current collection item: [\"collection\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["each"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current 'each' item: [\"each\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["source"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Item source for an 'each' node or a bound prop: 'static' (items provided on the node), 'collection' (a CMS collection query — id, sort, filters, pagination), 'navigation' (the site navigation tree), or 'locales' (the website's frontend-exposed locales for a language switcher)."}]},"minItems":2,"maxItems":2,"description":"Bind directly to an iterator source: [\"source\", IteratorSource]."}]},"description":"Binds live CMS data into this node instead of static values. Map from a target path on the node (e.g. \"content\", \"attrs.src\", \"classes\") to a value-handle tuple. Kinds: collection, file, symbol, link, each, source. Example: {\"attrs.src\": [\"file\",\"file_5d8e\",\"value\"]} fills src from a file."},"metadata":{"type":"object","properties":{"cmsType":{"type":"string","enum":["spacer"]},"formField":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"label":{"type":"string","description":"Human readable label authored for the field. Falls back to the field key when absent."},"required":{"type":"boolean"},"minLength":{"type":"number"},"maxLength":{"type":"number"},"pattern":{"type":"string","nullable":true},"min":{"type":"number"},"max":{"type":"number"},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]}},"multiple":{"type":"boolean"},"maxSize":{"type":"number"},"accept":{"type":"array","items":{"type":"string"}},"order":{"type":"number"}}},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["webhook"]},"url":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"to":{"type":"string"},"subject":{"type":"string"},"templateId":{"type":"string"}},"required":["type","to","subject"]}]}},"successBehavior":{"$ref":"#/components/schemas/SuccessBehavior"},"consentFieldKey":{"type":"string","description":"Key of the form field that carries the GDPR consent. Points at a field with type \"checkbox\" in the same form definition."},"consentBySubmit":{"type":"boolean","description":"Whether GDPR consent is given by submitting the form. Set instead of consentFieldKey on forms that show the consent text without a consent checkbox."},"visitorEmail":{"type":"object","properties":{"visitorEmailFieldKey":{"type":"string","description":"Key of the form field whose submitted value carries the visitor email address. Points at a field able to hold an email address in the same form definition."},"templateId":{"type":"string","description":"Id of the email template sent to the visitor."}},"required":["visitorEmailFieldKey"],"description":"Configuration of the email sent to the visitor after a successful submit. Absent when no visitor email is configured."}}}]},"custom":{"type":"object","additionalProperties":{"nullable":true},"description":"custom user metadata (for example, import description)"},"dataGuard":{"type":"object","properties":{"version":{"type":"number","enum":[1],"description":"Data guard schema version."},"enabled":{"type":"boolean","description":"Whether the guard is active. Owned outside the inspector section that edits the rest of this structure."},"type":{"type":"string","enum":["app"],"description":"Consumer kind. Placeholder — currently always \"app\"."},"data":{"type":"object","properties":{"collection":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string","description":"Target collection id this entry exposes to the frontend."},"columns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may project. Empty or missing means nothing is exposed — this is an allowlist, not a projection convenience."},"sortColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may sort by. Empty or missing means nothing is allowed."},"filterColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may filter by. Empty or missing means nothing is allowed."},"maxItems":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Upper bound on the number of items the frontend may request."},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]},"description":"Filters always applied on top of any frontend-supplied filter."}},"required":["type","collectionId"]},"description":"Collection entries keyed by a user-defined key."}},"required":["collection"]}},"required":["version","enabled","type","data"],"description":"Frontend data exposure allowlist for this node."}},"additionalProperties":{"nullable":true},"description":"Editor metadata for this node: cms element type, form-field definition, and custom notes (e.g. import description)."},"styleRole":{"type":"string","description":"Semantic style role, e.g. 'role_card'. Makes the node inherit the styleguide entry elementStyles[role], above its tag styles and below its own styleOverrides. Reuse one role's styling across many nodes."},"styleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for this node. Maps style slots ('color.bg', 'padding.top', 'font-size', …) to a StyleRef. Layers: default / breakpoints / containers; each has a base slot map and optional per-state (hover, focus) maps. A StyleRef is one of three variants: token (preferred) — {type:'token', scope:'project'|'primitive', key}, a design token by scope+key; pick from the design scale so the site stays consistent. keyword — {type:'keyword', value:'auto'}, a CSS keyword like 'auto' or 'inherit'. value — {type:'value', value:'25px'}, a raw CSS literal, last resort. Example: {\"default\":{\"base\":{\"color.bg\":{\"type\":\"token\",\"scope\":\"project\",\"key\":\"surface.primary\"}}}}."},"instanceStyleProps":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleOverrides"}}],"description":"Symbol-instance style overrides keyed by inner-node style role. Symbol nodes only. Only points exposed by the symbol design interface survive resolution."},"schemeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","description":"Color-scheme slug applied to this node and its subtree, emitted as data-scheme=\"<slug>\". Selects a named scheme that overrides project-scope color tokens for the subtree."},"type":{"type":"string","enum":["slotFill"]},"content":{"nullable":true},"name":{"type":"string","description":"Name of the slot this content fills, inside a symbol instance."},"itemId":{"type":"string","description":"Optional id of the item this slot fill belongs to."},"children":{"type":"array","items":{"type":"string"},"description":"Ids of this node's child nodes, in render order."}},"required":["id","tag","attrs","classes","type","name","children"],"description":"Named content container inside a symbol instance"},{"type":"object","properties":{"id":{"type":"string","description":"Unique id of this node within the document."},"tag":{"type":"string","description":"HTML tag of the rendered element, e.g. 'div', 'h1', 'section'. Omitted on symbol nodes."},"attrs":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"nullable":true}}],"description":"HTML attributes for element nodes (e.g. {\"href\":\"/about\"}); component props for non-element nodes such as symbols."},"classes":{"type":"array","items":{"type":"string"},"description":"Arbitrary utility classes written directly into the element's HTML class attribute. Use ONLY for one-off classes that have no token (e.g. Tailwind arbitrary values like 'gap-[2rem]', or 'prose'). All token styling — color, spacing, typography, radius, … — goes in styleOverrides (per node) or elementStyles (styleguide), NOT here."},"symbolId":{"type":"string","description":"Id of the linked symbol. Symbol nodes only."},"variantId":{"type":"string","description":"Id of the selected symbol variant. Symbol nodes only."},"binding":{"type":"object","additionalProperties":{"anyOf":[{"type":"array","items":{"anyOf":[{"type":"string","enum":["file"]},{"type":"string"},{"anyOf":[{"type":"string","enum":["id"]},{"type":"string","enum":["file_hash"]},{"type":"string","enum":["file_size"]},{"type":"string","enum":["mime_type"]},{"type":"string","enum":["storage_path"]},{"type":"string","enum":["cdn_path"]},{"type":"string","enum":["serve_path"]},{"type":"string","enum":["created_at"]},{"type":"string","enum":["updated_at"]},{"type":"string","enum":["alt_text"]},{"type":"string","enum":["value"]}]}]},"minItems":3,"maxItems":3,"description":"Value from a file: [\"file\", fileId, prop?]. prop selects a file field; \"value\" gives the primary URL (cdn_path, else serve_path)."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["symbol"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Value from a symbol prop: [\"symbol\", propKey, fieldKey]. propKey is the symbol prop; fieldKey selects a field of its value (e.g. \"value\", or a file field like \"cdn_path\")."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["collection"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current collection item: [\"collection\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["each"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current 'each' item: [\"each\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["source"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Item source for an 'each' node or a bound prop: 'static' (items provided on the node), 'collection' (a CMS collection query — id, sort, filters, pagination), 'navigation' (the site navigation tree), or 'locales' (the website's frontend-exposed locales for a language switcher)."}]},"minItems":2,"maxItems":2,"description":"Bind directly to an iterator source: [\"source\", IteratorSource]."}]},"description":"Binds live CMS data into this node instead of static values. Map from a target path on the node (e.g. \"content\", \"attrs.src\", \"classes\") to a value-handle tuple. Kinds: collection, file, symbol, link, each, source. Example: {\"attrs.src\": [\"file\",\"file_5d8e\",\"value\"]} fills src from a file."},"metadata":{"type":"object","properties":{"cmsType":{"type":"string","enum":["spacer"]},"formField":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"label":{"type":"string","description":"Human readable label authored for the field. Falls back to the field key when absent."},"required":{"type":"boolean"},"minLength":{"type":"number"},"maxLength":{"type":"number"},"pattern":{"type":"string","nullable":true},"min":{"type":"number"},"max":{"type":"number"},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]}},"multiple":{"type":"boolean"},"maxSize":{"type":"number"},"accept":{"type":"array","items":{"type":"string"}},"order":{"type":"number"}}},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["webhook"]},"url":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"to":{"type":"string"},"subject":{"type":"string"},"templateId":{"type":"string"}},"required":["type","to","subject"]}]}},"successBehavior":{"$ref":"#/components/schemas/SuccessBehavior"},"consentFieldKey":{"type":"string","description":"Key of the form field that carries the GDPR consent. Points at a field with type \"checkbox\" in the same form definition."},"consentBySubmit":{"type":"boolean","description":"Whether GDPR consent is given by submitting the form. Set instead of consentFieldKey on forms that show the consent text without a consent checkbox."},"visitorEmail":{"type":"object","properties":{"visitorEmailFieldKey":{"type":"string","description":"Key of the form field whose submitted value carries the visitor email address. Points at a field able to hold an email address in the same form definition."},"templateId":{"type":"string","description":"Id of the email template sent to the visitor."}},"required":["visitorEmailFieldKey"],"description":"Configuration of the email sent to the visitor after a successful submit. Absent when no visitor email is configured."}}}]},"custom":{"type":"object","additionalProperties":{"nullable":true},"description":"custom user metadata (for example, import description)"},"dataGuard":{"type":"object","properties":{"version":{"type":"number","enum":[1],"description":"Data guard schema version."},"enabled":{"type":"boolean","description":"Whether the guard is active. Owned outside the inspector section that edits the rest of this structure."},"type":{"type":"string","enum":["app"],"description":"Consumer kind. Placeholder — currently always \"app\"."},"data":{"type":"object","properties":{"collection":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string","description":"Target collection id this entry exposes to the frontend."},"columns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may project. Empty or missing means nothing is exposed — this is an allowlist, not a projection convenience."},"sortColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may sort by. Empty or missing means nothing is allowed."},"filterColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may filter by. Empty or missing means nothing is allowed."},"maxItems":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Upper bound on the number of items the frontend may request."},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]},"description":"Filters always applied on top of any frontend-supplied filter."}},"required":["type","collectionId"]},"description":"Collection entries keyed by a user-defined key."}},"required":["collection"]}},"required":["version","enabled","type","data"],"description":"Frontend data exposure allowlist for this node."}},"additionalProperties":{"nullable":true},"description":"Editor metadata for this node: cms element type, form-field definition, and custom notes (e.g. import description)."},"styleRole":{"type":"string","description":"Semantic style role, e.g. 'role_card'. Makes the node inherit the styleguide entry elementStyles[role], above its tag styles and below its own styleOverrides. Reuse one role's styling across many nodes."},"styleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for this node. Maps style slots ('color.bg', 'padding.top', 'font-size', …) to a StyleRef. Layers: default / breakpoints / containers; each has a base slot map and optional per-state (hover, focus) maps. A StyleRef is one of three variants: token (preferred) — {type:'token', scope:'project'|'primitive', key}, a design token by scope+key; pick from the design scale so the site stays consistent. keyword — {type:'keyword', value:'auto'}, a CSS keyword like 'auto' or 'inherit'. value — {type:'value', value:'25px'}, a raw CSS literal, last resort. Example: {\"default\":{\"base\":{\"color.bg\":{\"type\":\"token\",\"scope\":\"project\",\"key\":\"surface.primary\"}}}}."},"instanceStyleProps":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleOverrides"}}],"description":"Symbol-instance style overrides keyed by inner-node style role. Symbol nodes only. Only points exposed by the symbol design interface survive resolution."},"schemeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","description":"Color-scheme slug applied to this node and its subtree, emitted as data-scheme=\"<slug>\". Selects a named scheme that overrides project-scope color tokens for the subtree."},"type":{"type":"string","enum":["element"]},"content":{"nullable":true},"children":{"type":"array","items":{"type":"string"},"description":"Ids of this node's child nodes, in render order."}},"required":["id","tag","attrs","classes","type","children"],"description":"Regular node"},{"type":"object","properties":{"id":{"type":"string","description":"Unique id of this node within the document."},"tag":{"type":"string","description":"html element tag (omitted on symbol nodes; equals 'symbol')"},"attrs":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"nullable":true}}],"description":"Static HTML attributes for element nodes (e.g. {\"href\":\"/about\"}); component props for non-element nodes such as symbols. Static literal values only — never value-handle tuples or any dynamic references. To bind dynamic data (CMS fields, files, links) to an attr or prop, use the binding field instead; binding targets the attr/prop by path, e.g. attrs.<name>."},"classes":{"type":"array","items":{"type":"string"},"description":"Arbitrary utility classes written directly into the element's HTML class attribute. Use ONLY for one-off classes that have no token (e.g. Tailwind arbitrary values like 'gap-[2rem]', or 'prose'). All token styling — color, spacing, typography, radius, … — goes in styleOverrides (per node) or elementStyles (styleguide), NOT here."},"symbolId":{"type":"string","description":"Id of the linked symbol. Symbol nodes only."},"variantId":{"type":"string","description":"Id of the selected symbol variant. Symbol nodes only."},"binding":{"type":"object","additionalProperties":{"anyOf":[{"type":"array","items":{"anyOf":[{"type":"string","enum":["file"]},{"type":"string"},{"anyOf":[{"type":"string","enum":["id"]},{"type":"string","enum":["file_hash"]},{"type":"string","enum":["file_size"]},{"type":"string","enum":["mime_type"]},{"type":"string","enum":["storage_path"]},{"type":"string","enum":["cdn_path"]},{"type":"string","enum":["serve_path"]},{"type":"string","enum":["created_at"]},{"type":"string","enum":["updated_at"]},{"type":"string","enum":["alt_text"]},{"type":"string","enum":["value"]}]}]},"minItems":3,"maxItems":3,"description":"Value from a file: [\"file\", fileId, prop?]. prop selects a file field; \"value\" gives the primary URL (cdn_path, else serve_path)."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["symbol"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Value from a symbol prop: [\"symbol\", propKey, fieldKey]. propKey is the symbol prop; fieldKey selects a field of its value (e.g. \"value\", or a file field like \"cdn_path\")."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["collection"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current collection item: [\"collection\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["each"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current 'each' item: [\"each\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["source"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Item source for an 'each' node or a bound prop: 'static' (items provided on the node), 'collection' (a CMS collection query — id, sort, filters, pagination), 'navigation' (the site navigation tree), or 'locales' (the website's frontend-exposed locales for a language switcher)."}]},"minItems":2,"maxItems":2,"description":"Bind directly to an iterator source: [\"source\", IteratorSource]."}]},"description":"Binds live CMS data into this node instead of static values. Map from a target path on the node (e.g. \"content\", \"attrs.src\", \"classes\") to a value-handle tuple. Kinds: collection, file, symbol, link, each, source. Example: {\"attrs.src\": [\"file\",\"file_5d8e\",\"value\"]} fills src from a file."},"metadata":{"type":"object","properties":{"cmsType":{"type":"string","enum":["spacer"]},"formField":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"label":{"type":"string","description":"Human readable label authored for the field. Falls back to the field key when absent."},"required":{"type":"boolean"},"minLength":{"type":"number"},"maxLength":{"type":"number"},"pattern":{"type":"string","nullable":true},"min":{"type":"number"},"max":{"type":"number"},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]}},"multiple":{"type":"boolean"},"maxSize":{"type":"number"},"accept":{"type":"array","items":{"type":"string"}},"order":{"type":"number"}}},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["webhook"]},"url":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"to":{"type":"string"},"subject":{"type":"string"},"templateId":{"type":"string"}},"required":["type","to","subject"]}]}},"successBehavior":{"$ref":"#/components/schemas/SuccessBehavior"},"consentFieldKey":{"type":"string","description":"Key of the form field that carries the GDPR consent. Points at a field with type \"checkbox\" in the same form definition."},"consentBySubmit":{"type":"boolean","description":"Whether GDPR consent is given by submitting the form. Set instead of consentFieldKey on forms that show the consent text without a consent checkbox."},"visitorEmail":{"type":"object","properties":{"visitorEmailFieldKey":{"type":"string","description":"Key of the form field whose submitted value carries the visitor email address. Points at a field able to hold an email address in the same form definition."},"templateId":{"type":"string","description":"Id of the email template sent to the visitor."}},"required":["visitorEmailFieldKey"],"description":"Configuration of the email sent to the visitor after a successful submit. Absent when no visitor email is configured."}}}]},"custom":{"type":"object","additionalProperties":{"nullable":true},"description":"custom user metadata (for example, import description)"},"dataGuard":{"type":"object","properties":{"version":{"type":"number","enum":[1],"description":"Data guard schema version."},"enabled":{"type":"boolean","description":"Whether the guard is active. Owned outside the inspector section that edits the rest of this structure."},"type":{"type":"string","enum":["app"],"description":"Consumer kind. Placeholder — currently always \"app\"."},"data":{"type":"object","properties":{"collection":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string","description":"Target collection id this entry exposes to the frontend."},"columns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may project. Empty or missing means nothing is exposed — this is an allowlist, not a projection convenience."},"sortColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may sort by. Empty or missing means nothing is allowed."},"filterColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may filter by. Empty or missing means nothing is allowed."},"maxItems":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Upper bound on the number of items the frontend may request."},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]},"description":"Filters always applied on top of any frontend-supplied filter."}},"required":["type","collectionId"]},"description":"Collection entries keyed by a user-defined key."}},"required":["collection"]}},"required":["version","enabled","type","data"],"description":"Frontend data exposure allowlist for this node."}},"additionalProperties":{"nullable":true},"description":"Editor metadata for this node: cms element type, form-field definition, and custom notes (e.g. import description)."},"styleRole":{"type":"string","description":"Semantic style role, e.g. 'role_card'. Makes the node inherit the styleguide entry elementStyles[role], above its tag styles and below its own styleOverrides. Reuse one role's styling across many nodes."},"styleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for this node. Maps style slots ('color.bg', 'padding.top', 'font-size', …) to a StyleRef. Layers: default / breakpoints / containers; each has a base slot map and optional per-state (hover, focus) maps. A StyleRef is one of three variants: token (preferred) — {type:'token', scope:'project'|'primitive', key}, a design token by scope+key; pick from the design scale so the site stays consistent. keyword — {type:'keyword', value:'auto'}, a CSS keyword like 'auto' or 'inherit'. value — {type:'value', value:'25px'}, a raw CSS literal, last resort. Example: {\"default\":{\"base\":{\"color.bg\":{\"type\":\"token\",\"scope\":\"project\",\"key\":\"surface.primary\"}}}}."},"instanceStyleProps":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleOverrides"}}],"description":"Symbol-instance style overrides keyed by inner-node style role. Symbol nodes only. Only points exposed by the symbol design interface survive resolution."},"schemeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","description":"Color-scheme slug applied to this node and its subtree, emitted as data-scheme=\"<slug>\". Selects a named scheme that overrides project-scope color tokens for the subtree."},"type":{"type":"string","enum":["symbol"]},"content":{"nullable":true},"source":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"iterator source (symbol nodes only)"},"children":{"type":"array","items":{"type":"string"},"description":"Ids of this node's child nodes, in render order."}},"required":["id","attrs","classes","type","children"],"description":"Symbol instance node"},{"type":"object","properties":{"id":{"type":"string","description":"Unique id of this node within the document."},"tag":{"type":"string"},"attrs":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"nullable":true}}],"description":"HTML attributes for element nodes (e.g. {\"href\":\"/about\"}); component props for non-element nodes such as symbols."},"classes":{"type":"array","items":{"type":"string"}},"symbolId":{"type":"string","description":"Id of the linked symbol. Symbol nodes only."},"variantId":{"type":"string","description":"Id of the selected symbol variant. Symbol nodes only."},"binding":{"type":"object","additionalProperties":{"anyOf":[{"type":"array","items":{"anyOf":[{"type":"string","enum":["file"]},{"type":"string"},{"anyOf":[{"type":"string","enum":["id"]},{"type":"string","enum":["file_hash"]},{"type":"string","enum":["file_size"]},{"type":"string","enum":["mime_type"]},{"type":"string","enum":["storage_path"]},{"type":"string","enum":["cdn_path"]},{"type":"string","enum":["serve_path"]},{"type":"string","enum":["created_at"]},{"type":"string","enum":["updated_at"]},{"type":"string","enum":["alt_text"]},{"type":"string","enum":["value"]}]}]},"minItems":3,"maxItems":3,"description":"Value from a file: [\"file\", fileId, prop?]. prop selects a file field; \"value\" gives the primary URL (cdn_path, else serve_path)."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["symbol"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Value from a symbol prop: [\"symbol\", propKey, fieldKey]. propKey is the symbol prop; fieldKey selects a field of its value (e.g. \"value\", or a file field like \"cdn_path\")."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["collection"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current collection item: [\"collection\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["each"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current 'each' item: [\"each\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["source"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Item source for an 'each' node or a bound prop: 'static' (items provided on the node), 'collection' (a CMS collection query — id, sort, filters, pagination), 'navigation' (the site navigation tree), or 'locales' (the website's frontend-exposed locales for a language switcher)."}]},"minItems":2,"maxItems":2,"description":"Bind directly to an iterator source: [\"source\", IteratorSource]."}]},"description":"Binds live CMS data into this node instead of static values. Map from a target path on the node (e.g. \"content\", \"attrs.src\", \"classes\") to a value-handle tuple. Kinds: collection, file, symbol, link, each, source. Example: {\"attrs.src\": [\"file\",\"file_5d8e\",\"value\"]} fills src from a file."},"metadata":{"type":"object","properties":{"cmsType":{"type":"string","enum":["spacer"]},"formField":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"label":{"type":"string","description":"Human readable label authored for the field. Falls back to the field key when absent."},"required":{"type":"boolean"},"minLength":{"type":"number"},"maxLength":{"type":"number"},"pattern":{"type":"string","nullable":true},"min":{"type":"number"},"max":{"type":"number"},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]}},"multiple":{"type":"boolean"},"maxSize":{"type":"number"},"accept":{"type":"array","items":{"type":"string"}},"order":{"type":"number"}}},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["webhook"]},"url":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"to":{"type":"string"},"subject":{"type":"string"},"templateId":{"type":"string"}},"required":["type","to","subject"]}]}},"successBehavior":{"$ref":"#/components/schemas/SuccessBehavior"},"consentFieldKey":{"type":"string","description":"Key of the form field that carries the GDPR consent. Points at a field with type \"checkbox\" in the same form definition."},"consentBySubmit":{"type":"boolean","description":"Whether GDPR consent is given by submitting the form. Set instead of consentFieldKey on forms that show the consent text without a consent checkbox."},"visitorEmail":{"type":"object","properties":{"visitorEmailFieldKey":{"type":"string","description":"Key of the form field whose submitted value carries the visitor email address. Points at a field able to hold an email address in the same form definition."},"templateId":{"type":"string","description":"Id of the email template sent to the visitor."}},"required":["visitorEmailFieldKey"],"description":"Configuration of the email sent to the visitor after a successful submit. Absent when no visitor email is configured."}}}]},"custom":{"type":"object","additionalProperties":{"nullable":true},"description":"custom user metadata (for example, import description)"},"dataGuard":{"type":"object","properties":{"version":{"type":"number","enum":[1],"description":"Data guard schema version."},"enabled":{"type":"boolean","description":"Whether the guard is active. Owned outside the inspector section that edits the rest of this structure."},"type":{"type":"string","enum":["app"],"description":"Consumer kind. Placeholder — currently always \"app\"."},"data":{"type":"object","properties":{"collection":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string","description":"Target collection id this entry exposes to the frontend."},"columns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may project. Empty or missing means nothing is exposed — this is an allowlist, not a projection convenience."},"sortColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may sort by. Empty or missing means nothing is allowed."},"filterColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may filter by. Empty or missing means nothing is allowed."},"maxItems":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Upper bound on the number of items the frontend may request."},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]},"description":"Filters always applied on top of any frontend-supplied filter."}},"required":["type","collectionId"]},"description":"Collection entries keyed by a user-defined key."}},"required":["collection"]}},"required":["version","enabled","type","data"],"description":"Frontend data exposure allowlist for this node."}},"additionalProperties":{"nullable":true},"description":"Editor metadata for this node: cms element type, form-field definition, and custom notes (e.g. import description)."},"styleRole":{"type":"string","description":"Semantic style role, e.g. 'role_card'. Makes the node inherit the styleguide entry elementStyles[role], above its tag styles and below its own styleOverrides. Reuse one role's styling across many nodes."},"styleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for this node. Maps style slots ('color.bg', 'padding.top', 'font-size', …) to a StyleRef. Layers: default / breakpoints / containers; each has a base slot map and optional per-state (hover, focus) maps. A StyleRef is one of three variants: token (preferred) — {type:'token', scope:'project'|'primitive', key}, a design token by scope+key; pick from the design scale so the site stays consistent. keyword — {type:'keyword', value:'auto'}, a CSS keyword like 'auto' or 'inherit'. value — {type:'value', value:'25px'}, a raw CSS literal, last resort. Example: {\"default\":{\"base\":{\"color.bg\":{\"type\":\"token\",\"scope\":\"project\",\"key\":\"surface.primary\"}}}}."},"instanceStyleProps":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleOverrides"}}],"description":"Symbol-instance style overrides keyed by inner-node style role. Symbol nodes only. Only points exposed by the symbol design interface survive resolution."},"schemeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","description":"Color-scheme slug applied to this node and its subtree, emitted as data-scheme=\"<slug>\". Selects a named scheme that overrides project-scope color tokens for the subtree."},"type":{"nullable":true},"content":{"nullable":true},"children":{"type":"array","items":{"type":"string"},"description":"Ids of this node's child nodes, in render order."}},"required":["id","attrs","children"],"description":"Document root container (absent/null type)"},{"type":"object","properties":{"id":{"type":"string","description":"Unique id of this node within the document."},"tag":{"type":"string","description":"HTML tag of the rendered element, e.g. 'div', 'h1', 'section'. Omitted on symbol nodes."},"attrs":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"nullable":true}}],"description":"Static HTML attributes for element nodes (e.g. {\"href\":\"/about\"}); component props for non-element nodes such as symbols. Static literal values only — never value-handle tuples or any dynamic references. To bind dynamic data (CMS fields, files, links) to an attr or prop, use the binding field instead; binding targets the attr/prop by path, e.g. attrs.<name>."},"classes":{"type":"array","items":{"type":"string"},"description":"Arbitrary utility classes written directly into the element's HTML class attribute. Use ONLY for one-off classes that have no token (e.g. Tailwind arbitrary values like 'gap-[2rem]', or 'prose'). All token styling — color, spacing, typography, radius, … — goes in styleOverrides (per node) or elementStyles (styleguide), NOT here."},"symbolId":{"type":"string","description":"Id of the linked symbol. Symbol nodes only."},"variantId":{"type":"string","description":"Id of the selected symbol variant. Symbol nodes only."},"binding":{"type":"object","additionalProperties":{"anyOf":[{"type":"array","items":{"anyOf":[{"type":"string","enum":["file"]},{"type":"string"},{"anyOf":[{"type":"string","enum":["id"]},{"type":"string","enum":["file_hash"]},{"type":"string","enum":["file_size"]},{"type":"string","enum":["mime_type"]},{"type":"string","enum":["storage_path"]},{"type":"string","enum":["cdn_path"]},{"type":"string","enum":["serve_path"]},{"type":"string","enum":["created_at"]},{"type":"string","enum":["updated_at"]},{"type":"string","enum":["alt_text"]},{"type":"string","enum":["value"]}]}]},"minItems":3,"maxItems":3,"description":"Value from a file: [\"file\", fileId, prop?]. prop selects a file field; \"value\" gives the primary URL (cdn_path, else serve_path)."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["symbol"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Value from a symbol prop: [\"symbol\", propKey, fieldKey]. propKey is the symbol prop; fieldKey selects a field of its value (e.g. \"value\", or a file field like \"cdn_path\")."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["collection"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current collection item: [\"collection\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["each"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current 'each' item: [\"each\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["source"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Item source for an 'each' node or a bound prop: 'static' (items provided on the node), 'collection' (a CMS collection query — id, sort, filters, pagination), 'navigation' (the site navigation tree), or 'locales' (the website's frontend-exposed locales for a language switcher)."}]},"minItems":2,"maxItems":2,"description":"Bind directly to an iterator source: [\"source\", IteratorSource]."}]},"description":"Binds live CMS data into this node instead of static values. Map from a target path on the node (e.g. \"content\", \"attrs.src\", \"classes\") to a value-handle tuple. Kinds: collection, file, symbol, link, each, source. Example: {\"attrs.src\": [\"file\",\"file_5d8e\",\"value\"]} fills src from a file."},"metadata":{"type":"object","properties":{"cmsType":{"type":"string","enum":["spacer"]},"formField":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"label":{"type":"string","description":"Human readable label authored for the field. Falls back to the field key when absent."},"required":{"type":"boolean"},"minLength":{"type":"number"},"maxLength":{"type":"number"},"pattern":{"type":"string","nullable":true},"min":{"type":"number"},"max":{"type":"number"},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]}},"multiple":{"type":"boolean"},"maxSize":{"type":"number"},"accept":{"type":"array","items":{"type":"string"}},"order":{"type":"number"}}},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["webhook"]},"url":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"to":{"type":"string"},"subject":{"type":"string"},"templateId":{"type":"string"}},"required":["type","to","subject"]}]}},"successBehavior":{"$ref":"#/components/schemas/SuccessBehavior"},"consentFieldKey":{"type":"string","description":"Key of the form field that carries the GDPR consent. Points at a field with type \"checkbox\" in the same form definition."},"consentBySubmit":{"type":"boolean","description":"Whether GDPR consent is given by submitting the form. Set instead of consentFieldKey on forms that show the consent text without a consent checkbox."},"visitorEmail":{"type":"object","properties":{"visitorEmailFieldKey":{"type":"string","description":"Key of the form field whose submitted value carries the visitor email address. Points at a field able to hold an email address in the same form definition."},"templateId":{"type":"string","description":"Id of the email template sent to the visitor."}},"required":["visitorEmailFieldKey"],"description":"Configuration of the email sent to the visitor after a successful submit. Absent when no visitor email is configured."}}}]},"custom":{"type":"object","additionalProperties":{"nullable":true},"description":"custom user metadata (for example, import description)"},"dataGuard":{"type":"object","properties":{"version":{"type":"number","enum":[1],"description":"Data guard schema version."},"enabled":{"type":"boolean","description":"Whether the guard is active. Owned outside the inspector section that edits the rest of this structure."},"type":{"type":"string","enum":["app"],"description":"Consumer kind. Placeholder — currently always \"app\"."},"data":{"type":"object","properties":{"collection":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string","description":"Target collection id this entry exposes to the frontend."},"columns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may project. Empty or missing means nothing is exposed — this is an allowlist, not a projection convenience."},"sortColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may sort by. Empty or missing means nothing is allowed."},"filterColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may filter by. Empty or missing means nothing is allowed."},"maxItems":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Upper bound on the number of items the frontend may request."},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]},"description":"Filters always applied on top of any frontend-supplied filter."}},"required":["type","collectionId"]},"description":"Collection entries keyed by a user-defined key."}},"required":["collection"]}},"required":["version","enabled","type","data"],"description":"Frontend data exposure allowlist for this node."}},"additionalProperties":{"nullable":true},"description":"Editor metadata for this node: cms element type, form-field definition, and custom notes (e.g. import description)."},"styleRole":{"type":"string","description":"Semantic style role, e.g. 'role_card'. Makes the node inherit the styleguide entry elementStyles[role], above its tag styles and below its own styleOverrides. Reuse one role's styling across many nodes."},"styleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for this node. Maps style slots ('color.bg', 'padding.top', 'font-size', …) to a StyleRef. Layers: default / breakpoints / containers; each has a base slot map and optional per-state (hover, focus) maps. A StyleRef is one of three variants: token (preferred) — {type:'token', scope:'project'|'primitive', key}, a design token by scope+key; pick from the design scale so the site stays consistent. keyword — {type:'keyword', value:'auto'}, a CSS keyword like 'auto' or 'inherit'. value — {type:'value', value:'25px'}, a raw CSS literal, last resort. Example: {\"default\":{\"base\":{\"color.bg\":{\"type\":\"token\",\"scope\":\"project\",\"key\":\"surface.primary\"}}}}."},"instanceStyleProps":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleOverrides"}}],"description":"Symbol-instance style overrides keyed by inner-node style role. Symbol nodes only. Only points exposed by the symbol design interface survive resolution."},"schemeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","description":"Color-scheme slug applied to this node and its subtree, emitted as data-scheme=\"<slug>\". Selects a named scheme that overrides project-scope color tokens for the subtree."},"type":{"type":"string","enum":["outlet"]},"content":{"nullable":true},"documentName":{"type":"string","description":"Name of the CollectionDocument this outlet renders. Must match a CollectionDocument.name on the page's collection."},"children":{"type":"array","items":{"type":"string"},"description":"Ids of this node's child nodes, in render order."}},"required":["id","tag","attrs","classes","type","documentName","children"],"description":"Renders a CollectionItemDocument inline at this position"}]}}},"required":["type","parentId","rootNodeId","nodes"],"description":"Attach a subtree under parentId. nodes must contain rootNodeId as a key. On an empty document this is the only op that seeds the tree: canvas synthesizes a renderable root {id: parentId, type: \"element\", tag: \"div\", attrs: {}, classes: []} before attaching the payload. The node ids in `nodes` are regenerated server-side, so callers cannot predict the resulting ids; the server returns the new rootId in its ack.","example":{"type":"addNodes","parentId":"root","rootNodeId":"sec1","nodes":{"sec1":{"id":"sec1","type":"element","tag":"section","attrs":{},"classes":[],"children":["h1"],"content":null},"h1":{"id":"h1","type":"formattedInlineElement","tag":"h1","attrs":{},"classes":["prose"],"children":[],"content":{"type":"doc","content":[{"type":"text","text":"Hello"}]}}}}},"SuccessBehavior":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","enum":["message"]},"content":{"type":"object","properties":{"type":{"type":"string"},"attrs":{"type":"object","additionalProperties":{"nullable":true}},"content":{"type":"array","items":{"$ref":"#/components/schemas/JSONContent"}},"marks":{"type":"array","items":{"allOf":[{"type":"object","additionalProperties":{"nullable":true}},{"type":"object","properties":{"type":{"type":"string"},"attrs":{"type":"object","additionalProperties":{"nullable":true}}},"required":["type"]}]}},"text":{"type":"string"}},"description":"Rich text success message shown in place of the form after a successful submit (ProseMirror/Tiptap JSONContent document)."}},"required":["mode","content"]},{"type":"object","properties":{"mode":{"type":"string","enum":["redirect"]},"target":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["cms"]},"value":{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["url","email","phone","anchor"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"Redirect target after successful submit. Supports internal CMS page references and external URLs."}},"required":["mode"]}],"description":"Post-submit success behavior. Mutually exclusive: either show a rich text message (message mode) or redirect the visitor (redirect mode)."},"JSONContent":{"type":"object","properties":{"type":{"type":"string"},"attrs":{"type":"object","additionalProperties":{"nullable":true}},"content":{"type":"array","items":{"$ref":"#/components/schemas/JSONContent"}},"marks":{"type":"array","items":{"allOf":[{"type":"object","additionalProperties":{"nullable":true}},{"type":"object","properties":{"type":{"type":"string"},"attrs":{"type":"object","additionalProperties":{"nullable":true}}},"required":["type"]}]}},"text":{"type":"string"}},"description":"A ProseMirror rich-text document: a recursive node tree of type, attrs, content[], marks and text."},"StyleLayer":{"type":"object","properties":{"base":{"type":"object","properties":{"radius":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"color.bg":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"color.text":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"color.border":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"color.outline":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"color.placeholder":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"color.accent":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"color.ring":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"border.width":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"shadow":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"opacity":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"backdrop-blur":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"blur":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"ring.width":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"font-size":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"font-weight":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"font-family":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"line-height":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"letter-spacing":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"padding":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"padding.top":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"padding.right":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"padding.bottom":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"padding.left":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"padding.x":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"padding.y":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"margin":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"margin.top":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"margin.right":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"margin.bottom":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"margin.left":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"margin.x":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"margin.y":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"gap":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"gap.x":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"gap.y":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"width":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"height":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"min-width":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"max-width":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"min-height":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"max-height":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"size":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"inset":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"inset.top":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"inset.right":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"inset.bottom":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"inset.left":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"z-index":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"transition.duration":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."}},"description":"Map from a style slot ('color.bg', 'padding.top', 'font-size', …) to a StyleRef."},"states":{"type":"object","additionalProperties":{"type":"object","properties":{"radius":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"color.bg":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"color.text":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"color.border":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"color.outline":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"color.placeholder":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"color.accent":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"color.ring":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"border.width":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"shadow":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"opacity":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"backdrop-blur":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"blur":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"ring.width":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"font-size":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"font-weight":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"font-family":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"line-height":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"letter-spacing":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"padding":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"padding.top":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"padding.right":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"padding.bottom":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"padding.left":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"padding.x":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"padding.y":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"margin":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"margin.top":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"margin.right":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"margin.bottom":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"margin.left":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"margin.x":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"margin.y":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"gap":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"gap.x":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"gap.y":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"width":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"height":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"min-width":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"max-width":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"min-height":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"max-height":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"size":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"inset":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"inset.top":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"inset.right":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"inset.bottom":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"inset.left":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"z-index":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."},"transition.duration":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"],"description":"Token scope / cascade level: primitive (base scale) → platform (theme) → project (site). Token refs resolve project → platform → primitive."},"key":{"type":"string"},"default":{"type":"string","description":"CSS literal painted when the token key does not resolve, emitted as the var() fallback. Inert when the token resolves."}},"required":["type","scope","key","default"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}],"description":"How one style slot gets its value. 'token' (preferred): reference a design token by scope+key — prefer scope 'project' or 'primitive' to stay on the design scale and keep the site consistent. 'value': a raw CSS literal like '25px' — last resort, escapes the scale. 'keyword': a CSS keyword like 'auto' or 'inherit'."}},"description":"Map from a style slot ('color.bg', 'padding.top', 'font-size', …) to a StyleRef."}}},"required":["base","states"],"description":"One styling layer: a base slot→ref map plus exactOptional per-state slot maps (hover, focus, …)."},"StyleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for a node or styleguide selector. Layers: default plus exactOptional per-breakpoint and per-container overrides, each a StyleLayer. Slots map to StyleRefs; prefer token refs over raw values to stay on the design scale."},"RemoveNodeOp":{"type":"object","properties":{"type":{"type":"string","enum":["removeNode"]},"nodeId":{"type":"string"}},"required":["type","nodeId"],"description":"Remove the node identified by `nodeId` and all of its descendants. Removing the document root is allowed and collapses the document to the empty state `{ rootLayoutId: \"\", nodes: {} }`.","example":{"type":"removeNode","nodeId":"h1"}},"MoveBeforeOp":{"type":"object","properties":{"type":{"type":"string","enum":["moveBefore"]},"nodeId":{"type":"string"},"referenceId":{"type":"string","nullable":true}},"required":["type","nodeId","referenceId"],"description":"Move `nodeId` so it sits immediately before `referenceId` among its parent's children. Pass `referenceId: null` to move it to the end. Both ids must already exist; reparenting across parents is supported as long as `referenceId` resolves.","example":{"type":"moveBefore","nodeId":"p1","referenceId":"h1"}},"WrapNodeOp":{"type":"object","properties":{"type":{"type":"string","enum":["wrapNode"]},"nodeId":{"type":"string"},"wrapper":{"type":"object","properties":{"rootId":{"type":"string"},"leafNodeId":{"type":"string"},"nodes":{"type":"object","additionalProperties":{"oneOf":[{"type":"object","properties":{"id":{"type":"string","description":"Unique id of this node within the document."},"tag":{"type":"string","description":"HTML tag of the rendered element, e.g. 'div', 'h1', 'section'. Omitted on symbol nodes."},"attrs":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"nullable":true}}],"description":"HTML attributes for element nodes (e.g. {\"href\":\"/about\"}); component props for non-element nodes such as symbols."},"classes":{"type":"array","items":{"type":"string"},"description":"Arbitrary utility classes written directly into the element's HTML class attribute. Use ONLY for one-off classes that have no token (e.g. Tailwind arbitrary values like 'gap-[2rem]', or 'prose'). All token styling — color, spacing, typography, radius, … — goes in styleOverrides (per node) or elementStyles (styleguide), NOT here."},"symbolId":{"type":"string","description":"Id of the linked symbol. Symbol nodes only."},"variantId":{"type":"string","description":"Id of the selected symbol variant. Symbol nodes only."},"binding":{"type":"object","additionalProperties":{"anyOf":[{"type":"array","items":{"anyOf":[{"type":"string","enum":["file"]},{"type":"string"},{"anyOf":[{"type":"string","enum":["id"]},{"type":"string","enum":["file_hash"]},{"type":"string","enum":["file_size"]},{"type":"string","enum":["mime_type"]},{"type":"string","enum":["storage_path"]},{"type":"string","enum":["cdn_path"]},{"type":"string","enum":["serve_path"]},{"type":"string","enum":["created_at"]},{"type":"string","enum":["updated_at"]},{"type":"string","enum":["alt_text"]},{"type":"string","enum":["value"]}]}]},"minItems":3,"maxItems":3,"description":"Value from a file: [\"file\", fileId, prop?]. prop selects a file field; \"value\" gives the primary URL (cdn_path, else serve_path)."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["symbol"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Value from a symbol prop: [\"symbol\", propKey, fieldKey]. propKey is the symbol prop; fieldKey selects a field of its value (e.g. \"value\", or a file field like \"cdn_path\")."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["collection"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current collection item: [\"collection\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["each"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current 'each' item: [\"each\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["source"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Item source for an 'each' node or a bound prop: 'static' (items provided on the node), 'collection' (a CMS collection query — id, sort, filters, pagination), 'navigation' (the site navigation tree), or 'locales' (the website's frontend-exposed locales for a language switcher)."}]},"minItems":2,"maxItems":2,"description":"Bind directly to an iterator source: [\"source\", IteratorSource]."}]},"description":"Binds live CMS data into this node instead of static values. Map from a target path on the node (e.g. \"content\", \"attrs.src\", \"classes\") to a value-handle tuple. Kinds: collection, file, symbol, link, each, source. Example: {\"attrs.src\": [\"file\",\"file_5d8e\",\"value\"]} fills src from a file."},"metadata":{"type":"object","properties":{"cmsType":{"type":"string","enum":["spacer"]},"formField":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"label":{"type":"string","description":"Human readable label authored for the field. Falls back to the field key when absent."},"required":{"type":"boolean"},"minLength":{"type":"number"},"maxLength":{"type":"number"},"pattern":{"type":"string","nullable":true},"min":{"type":"number"},"max":{"type":"number"},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]}},"multiple":{"type":"boolean"},"maxSize":{"type":"number"},"accept":{"type":"array","items":{"type":"string"}},"order":{"type":"number"}}},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["webhook"]},"url":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"to":{"type":"string"},"subject":{"type":"string"},"templateId":{"type":"string"}},"required":["type","to","subject"]}]}},"successBehavior":{"$ref":"#/components/schemas/SuccessBehavior"},"consentFieldKey":{"type":"string","description":"Key of the form field that carries the GDPR consent. Points at a field with type \"checkbox\" in the same form definition."},"consentBySubmit":{"type":"boolean","description":"Whether GDPR consent is given by submitting the form. Set instead of consentFieldKey on forms that show the consent text without a consent checkbox."},"visitorEmail":{"type":"object","properties":{"visitorEmailFieldKey":{"type":"string","description":"Key of the form field whose submitted value carries the visitor email address. Points at a field able to hold an email address in the same form definition."},"templateId":{"type":"string","description":"Id of the email template sent to the visitor."}},"required":["visitorEmailFieldKey"],"description":"Configuration of the email sent to the visitor after a successful submit. Absent when no visitor email is configured."}}}]},"custom":{"type":"object","additionalProperties":{"nullable":true},"description":"custom user metadata (for example, import description)"},"dataGuard":{"type":"object","properties":{"version":{"type":"number","enum":[1],"description":"Data guard schema version."},"enabled":{"type":"boolean","description":"Whether the guard is active. Owned outside the inspector section that edits the rest of this structure."},"type":{"type":"string","enum":["app"],"description":"Consumer kind. Placeholder — currently always \"app\"."},"data":{"type":"object","properties":{"collection":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string","description":"Target collection id this entry exposes to the frontend."},"columns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may project. Empty or missing means nothing is exposed — this is an allowlist, not a projection convenience."},"sortColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may sort by. Empty or missing means nothing is allowed."},"filterColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may filter by. Empty or missing means nothing is allowed."},"maxItems":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Upper bound on the number of items the frontend may request."},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]},"description":"Filters always applied on top of any frontend-supplied filter."}},"required":["type","collectionId"]},"description":"Collection entries keyed by a user-defined key."}},"required":["collection"]}},"required":["version","enabled","type","data"],"description":"Frontend data exposure allowlist for this node."}},"additionalProperties":{"nullable":true},"description":"Editor metadata for this node: cms element type, form-field definition, and custom notes (e.g. import description)."},"styleRole":{"type":"string","description":"Semantic style role, e.g. 'role_card'. Makes the node inherit the styleguide entry elementStyles[role], above its tag styles and below its own styleOverrides. Reuse one role's styling across many nodes."},"styleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for this node. Maps style slots ('color.bg', 'padding.top', 'font-size', …) to a StyleRef. Layers: default / breakpoints / containers; each has a base slot map and optional per-state (hover, focus) maps. A StyleRef is one of three variants: token (preferred) — {type:'token', scope:'project'|'primitive', key}, a design token by scope+key; pick from the design scale so the site stays consistent. keyword — {type:'keyword', value:'auto'}, a CSS keyword like 'auto' or 'inherit'. value — {type:'value', value:'25px'}, a raw CSS literal, last resort. Example: {\"default\":{\"base\":{\"color.bg\":{\"type\":\"token\",\"scope\":\"project\",\"key\":\"surface.primary\"}}}}."},"instanceStyleProps":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleOverrides"}}],"description":"Symbol-instance style overrides keyed by inner-node style role. Symbol nodes only. Only points exposed by the symbol design interface survive resolution."},"schemeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","description":"Color-scheme slug applied to this node and its subtree, emitted as data-scheme=\"<slug>\". Selects a named scheme that overrides project-scope color tokens for the subtree."},"type":{"type":"string","enum":["text"]},"content":{"type":"string","description":"Plain (unformatted) text content. Text and embed nodes only."},"children":{"type":"array","items":{"type":"string"},"description":"Ids of this node's child nodes, in render order."}},"required":["id","tag","attrs","classes","type","content","children"],"description":"Node with text content"},{"type":"object","properties":{"id":{"type":"string","description":"Unique id of this node within the document."},"tag":{"type":"string","description":"HTML tag of the rendered element, e.g. 'div', 'h1', 'section'. Omitted on symbol nodes."},"attrs":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"nullable":true}}],"description":"HTML attributes for element nodes (e.g. {\"href\":\"/about\"}); component props for non-element nodes such as symbols."},"classes":{"type":"array","items":{"type":"string"},"description":"Arbitrary utility classes written directly into the element's HTML class attribute. Use ONLY for one-off classes that have no token (e.g. Tailwind arbitrary values like 'gap-[2rem]', or 'prose'). All token styling — color, spacing, typography, radius, … — goes in styleOverrides (per node) or elementStyles (styleguide), NOT here."},"symbolId":{"type":"string","description":"Id of the linked symbol. Symbol nodes only."},"variantId":{"type":"string","description":"Id of the selected symbol variant. Symbol nodes only."},"binding":{"type":"object","additionalProperties":{"anyOf":[{"type":"array","items":{"anyOf":[{"type":"string","enum":["file"]},{"type":"string"},{"anyOf":[{"type":"string","enum":["id"]},{"type":"string","enum":["file_hash"]},{"type":"string","enum":["file_size"]},{"type":"string","enum":["mime_type"]},{"type":"string","enum":["storage_path"]},{"type":"string","enum":["cdn_path"]},{"type":"string","enum":["serve_path"]},{"type":"string","enum":["created_at"]},{"type":"string","enum":["updated_at"]},{"type":"string","enum":["alt_text"]},{"type":"string","enum":["value"]}]}]},"minItems":3,"maxItems":3,"description":"Value from a file: [\"file\", fileId, prop?]. prop selects a file field; \"value\" gives the primary URL (cdn_path, else serve_path)."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["symbol"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Value from a symbol prop: [\"symbol\", propKey, fieldKey]. propKey is the symbol prop; fieldKey selects a field of its value (e.g. \"value\", or a file field like \"cdn_path\")."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["collection"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current collection item: [\"collection\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["each"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current 'each' item: [\"each\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["source"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Item source for an 'each' node or a bound prop: 'static' (items provided on the node), 'collection' (a CMS collection query — id, sort, filters, pagination), 'navigation' (the site navigation tree), or 'locales' (the website's frontend-exposed locales for a language switcher)."}]},"minItems":2,"maxItems":2,"description":"Bind directly to an iterator source: [\"source\", IteratorSource]."}]},"description":"Binds live CMS data into this node instead of static values. Map from a target path on the node (e.g. \"content\", \"attrs.src\", \"classes\") to a value-handle tuple. Kinds: collection, file, symbol, link, each, source. Example: {\"attrs.src\": [\"file\",\"file_5d8e\",\"value\"]} fills src from a file."},"metadata":{"type":"object","properties":{"cmsType":{"type":"string","enum":["spacer"]},"formField":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"label":{"type":"string","description":"Human readable label authored for the field. Falls back to the field key when absent."},"required":{"type":"boolean"},"minLength":{"type":"number"},"maxLength":{"type":"number"},"pattern":{"type":"string","nullable":true},"min":{"type":"number"},"max":{"type":"number"},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]}},"multiple":{"type":"boolean"},"maxSize":{"type":"number"},"accept":{"type":"array","items":{"type":"string"}},"order":{"type":"number"}}},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["webhook"]},"url":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"to":{"type":"string"},"subject":{"type":"string"},"templateId":{"type":"string"}},"required":["type","to","subject"]}]}},"successBehavior":{"$ref":"#/components/schemas/SuccessBehavior"},"consentFieldKey":{"type":"string","description":"Key of the form field that carries the GDPR consent. Points at a field with type \"checkbox\" in the same form definition."},"consentBySubmit":{"type":"boolean","description":"Whether GDPR consent is given by submitting the form. Set instead of consentFieldKey on forms that show the consent text without a consent checkbox."},"visitorEmail":{"type":"object","properties":{"visitorEmailFieldKey":{"type":"string","description":"Key of the form field whose submitted value carries the visitor email address. Points at a field able to hold an email address in the same form definition."},"templateId":{"type":"string","description":"Id of the email template sent to the visitor."}},"required":["visitorEmailFieldKey"],"description":"Configuration of the email sent to the visitor after a successful submit. Absent when no visitor email is configured."}}}]},"custom":{"type":"object","additionalProperties":{"nullable":true},"description":"custom user metadata (for example, import description)"},"dataGuard":{"type":"object","properties":{"version":{"type":"number","enum":[1],"description":"Data guard schema version."},"enabled":{"type":"boolean","description":"Whether the guard is active. Owned outside the inspector section that edits the rest of this structure."},"type":{"type":"string","enum":["app"],"description":"Consumer kind. Placeholder — currently always \"app\"."},"data":{"type":"object","properties":{"collection":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string","description":"Target collection id this entry exposes to the frontend."},"columns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may project. Empty or missing means nothing is exposed — this is an allowlist, not a projection convenience."},"sortColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may sort by. Empty or missing means nothing is allowed."},"filterColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may filter by. Empty or missing means nothing is allowed."},"maxItems":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Upper bound on the number of items the frontend may request."},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]},"description":"Filters always applied on top of any frontend-supplied filter."}},"required":["type","collectionId"]},"description":"Collection entries keyed by a user-defined key."}},"required":["collection"]}},"required":["version","enabled","type","data"],"description":"Frontend data exposure allowlist for this node."}},"additionalProperties":{"nullable":true},"description":"Editor metadata for this node: cms element type, form-field definition, and custom notes (e.g. import description)."},"styleRole":{"type":"string","description":"Semantic style role, e.g. 'role_card'. Makes the node inherit the styleguide entry elementStyles[role], above its tag styles and below its own styleOverrides. Reuse one role's styling across many nodes."},"styleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for this node. Maps style slots ('color.bg', 'padding.top', 'font-size', …) to a StyleRef. Layers: default / breakpoints / containers; each has a base slot map and optional per-state (hover, focus) maps. A StyleRef is one of three variants: token (preferred) — {type:'token', scope:'project'|'primitive', key}, a design token by scope+key; pick from the design scale so the site stays consistent. keyword — {type:'keyword', value:'auto'}, a CSS keyword like 'auto' or 'inherit'. value — {type:'value', value:'25px'}, a raw CSS literal, last resort. Example: {\"default\":{\"base\":{\"color.bg\":{\"type\":\"token\",\"scope\":\"project\",\"key\":\"surface.primary\"}}}}."},"instanceStyleProps":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleOverrides"}}],"description":"Symbol-instance style overrides keyed by inner-node style role. Symbol nodes only. Only points exposed by the symbol design interface survive resolution."},"schemeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","description":"Color-scheme slug applied to this node and its subtree, emitted as data-scheme=\"<slug>\". Selects a named scheme that overrides project-scope color tokens for the subtree."},"type":{"type":"string","enum":["formattedInlineElement"]},"content":{"type":"object","properties":{"type":{"type":"string"},"attrs":{"type":"object","additionalProperties":{"nullable":true}},"content":{"type":"array","items":{"$ref":"#/components/schemas/JSONContent"}},"marks":{"type":"array","items":{"allOf":[{"type":"object","additionalProperties":{"nullable":true}},{"type":"object","properties":{"type":{"type":"string"},"attrs":{"type":"object","additionalProperties":{"nullable":true}}},"required":["type"]}]}},"text":{"type":"string"}},"description":"Rich-text content as a ProseMirror document. Formatted inline/block nodes only."},"children":{"type":"array","items":{"type":"string"},"description":"Ids of this node's child nodes, in render order."}},"required":["id","tag","attrs","classes","type","content","children"],"description":"Node with formatted content"},{"type":"object","properties":{"id":{"type":"string","description":"Unique id of this node within the document."},"tag":{"type":"string","description":"HTML tag of the rendered element, e.g. 'div', 'h1', 'section'. Omitted on symbol nodes."},"attrs":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"nullable":true}}],"description":"Static HTML attributes for element nodes (e.g. {\"href\":\"/about\"}); component props for non-element nodes such as symbols. Static literal values only — never value-handle tuples or any dynamic references. To bind dynamic data (CMS fields, files, links) to an attr or prop, use the binding field instead; binding targets the attr/prop by path, e.g. attrs.<name>."},"classes":{"type":"array","items":{"type":"string"},"description":"Arbitrary utility classes written directly into the element's HTML class attribute. Use ONLY for one-off classes that have no token (e.g. Tailwind arbitrary values like 'gap-[2rem]', or 'prose'). All token styling — color, spacing, typography, radius, … — goes in styleOverrides (per node) or elementStyles (styleguide), NOT here."},"symbolId":{"type":"string","description":"Id of the linked symbol. Symbol nodes only."},"variantId":{"type":"string","description":"Id of the selected symbol variant. Symbol nodes only."},"binding":{"type":"object","additionalProperties":{"anyOf":[{"type":"array","items":{"anyOf":[{"type":"string","enum":["file"]},{"type":"string"},{"anyOf":[{"type":"string","enum":["id"]},{"type":"string","enum":["file_hash"]},{"type":"string","enum":["file_size"]},{"type":"string","enum":["mime_type"]},{"type":"string","enum":["storage_path"]},{"type":"string","enum":["cdn_path"]},{"type":"string","enum":["serve_path"]},{"type":"string","enum":["created_at"]},{"type":"string","enum":["updated_at"]},{"type":"string","enum":["alt_text"]},{"type":"string","enum":["value"]}]}]},"minItems":3,"maxItems":3,"description":"Value from a file: [\"file\", fileId, prop?]. prop selects a file field; \"value\" gives the primary URL (cdn_path, else serve_path)."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["symbol"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Value from a symbol prop: [\"symbol\", propKey, fieldKey]. propKey is the symbol prop; fieldKey selects a field of its value (e.g. \"value\", or a file field like \"cdn_path\")."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["collection"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current collection item: [\"collection\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["each"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current 'each' item: [\"each\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["source"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Item source for an 'each' node or a bound prop: 'static' (items provided on the node), 'collection' (a CMS collection query — id, sort, filters, pagination), 'navigation' (the site navigation tree), or 'locales' (the website's frontend-exposed locales for a language switcher)."}]},"minItems":2,"maxItems":2,"description":"Bind directly to an iterator source: [\"source\", IteratorSource]."}]},"description":"Binds live CMS data into this node instead of static values. Map from a target path on the node (e.g. \"content\", \"attrs.src\", \"classes\") to a value-handle tuple. Kinds: collection, file, symbol, link, each, source. Example: {\"attrs.src\": [\"file\",\"file_5d8e\",\"value\"]} fills src from a file."},"metadata":{"type":"object","properties":{"cmsType":{"type":"string","enum":["spacer"]},"formField":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"label":{"type":"string","description":"Human readable label authored for the field. Falls back to the field key when absent."},"required":{"type":"boolean"},"minLength":{"type":"number"},"maxLength":{"type":"number"},"pattern":{"type":"string","nullable":true},"min":{"type":"number"},"max":{"type":"number"},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]}},"multiple":{"type":"boolean"},"maxSize":{"type":"number"},"accept":{"type":"array","items":{"type":"string"}},"order":{"type":"number"}}},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["webhook"]},"url":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"to":{"type":"string"},"subject":{"type":"string"},"templateId":{"type":"string"}},"required":["type","to","subject"]}]}},"successBehavior":{"$ref":"#/components/schemas/SuccessBehavior"},"consentFieldKey":{"type":"string","description":"Key of the form field that carries the GDPR consent. Points at a field with type \"checkbox\" in the same form definition."},"consentBySubmit":{"type":"boolean","description":"Whether GDPR consent is given by submitting the form. Set instead of consentFieldKey on forms that show the consent text without a consent checkbox."},"visitorEmail":{"type":"object","properties":{"visitorEmailFieldKey":{"type":"string","description":"Key of the form field whose submitted value carries the visitor email address. Points at a field able to hold an email address in the same form definition."},"templateId":{"type":"string","description":"Id of the email template sent to the visitor."}},"required":["visitorEmailFieldKey"],"description":"Configuration of the email sent to the visitor after a successful submit. Absent when no visitor email is configured."}}}]},"custom":{"type":"object","additionalProperties":{"nullable":true},"description":"custom user metadata (for example, import description)"},"dataGuard":{"type":"object","properties":{"version":{"type":"number","enum":[1],"description":"Data guard schema version."},"enabled":{"type":"boolean","description":"Whether the guard is active. Owned outside the inspector section that edits the rest of this structure."},"type":{"type":"string","enum":["app"],"description":"Consumer kind. Placeholder — currently always \"app\"."},"data":{"type":"object","properties":{"collection":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string","description":"Target collection id this entry exposes to the frontend."},"columns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may project. Empty or missing means nothing is exposed — this is an allowlist, not a projection convenience."},"sortColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may sort by. Empty or missing means nothing is allowed."},"filterColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may filter by. Empty or missing means nothing is allowed."},"maxItems":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Upper bound on the number of items the frontend may request."},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]},"description":"Filters always applied on top of any frontend-supplied filter."}},"required":["type","collectionId"]},"description":"Collection entries keyed by a user-defined key."}},"required":["collection"]}},"required":["version","enabled","type","data"],"description":"Frontend data exposure allowlist for this node."}},"additionalProperties":{"nullable":true},"description":"Editor metadata for this node: cms element type, form-field definition, and custom notes (e.g. import description)."},"styleRole":{"type":"string","description":"Semantic style role, e.g. 'role_card'. Makes the node inherit the styleguide entry elementStyles[role], above its tag styles and below its own styleOverrides. Reuse one role's styling across many nodes."},"styleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for this node. Maps style slots ('color.bg', 'padding.top', 'font-size', …) to a StyleRef. Layers: default / breakpoints / containers; each has a base slot map and optional per-state (hover, focus) maps. A StyleRef is one of three variants: token (preferred) — {type:'token', scope:'project'|'primitive', key}, a design token by scope+key; pick from the design scale so the site stays consistent. keyword — {type:'keyword', value:'auto'}, a CSS keyword like 'auto' or 'inherit'. value — {type:'value', value:'25px'}, a raw CSS literal, last resort. Example: {\"default\":{\"base\":{\"color.bg\":{\"type\":\"token\",\"scope\":\"project\",\"key\":\"surface.primary\"}}}}."},"instanceStyleProps":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleOverrides"}}],"description":"Symbol-instance style overrides keyed by inner-node style role. Symbol nodes only. Only points exposed by the symbol design interface survive resolution."},"schemeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","description":"Color-scheme slug applied to this node and its subtree, emitted as data-scheme=\"<slug>\". Selects a named scheme that overrides project-scope color tokens for the subtree."},"type":{"type":"string","enum":["each"]},"content":{"nullable":true},"source":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Where this 'each' node gets its items: static, a CMS collection query, or site navigation."},"items":{"type":"object","properties":{"items":{"type":"array","items":{"nullable":true}},"schema":{"nullable":true}},"required":["items"],"description":"Inline static items (with their schema) for a static 'each' source."},"preventEmpty":{"type":"boolean","description":"Hide the empty-state placeholder when the source yields no items."},"children":{"type":"array","items":{"type":"string"},"description":"Ids of this node's child nodes, in render order."}},"required":["id","tag","attrs","classes","type","children"],"description":"Node for iterating over a source"},{"type":"object","properties":{"id":{"type":"string","description":"Unique id of this node within the document."},"tag":{"type":"string","description":"HTML tag of the rendered element, e.g. 'div', 'h1', 'section'. Omitted on symbol nodes."},"attrs":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"nullable":true}}],"description":"Static HTML attributes for element nodes (e.g. {\"href\":\"/about\"}); component props for non-element nodes such as symbols. Static literal values only — never value-handle tuples or any dynamic references. To bind dynamic data (CMS fields, files, links) to an attr or prop, use the binding field instead; binding targets the attr/prop by path, e.g. attrs.<name>."},"classes":{"type":"array","items":{"type":"string"},"description":"Arbitrary utility classes written directly into the element's HTML class attribute. Use ONLY for one-off classes that have no token (e.g. Tailwind arbitrary values like 'gap-[2rem]', or 'prose'). All token styling — color, spacing, typography, radius, … — goes in styleOverrides (per node) or elementStyles (styleguide), NOT here."},"symbolId":{"type":"string","description":"Id of the linked symbol. Symbol nodes only."},"variantId":{"type":"string","description":"Id of the selected symbol variant. Symbol nodes only."},"binding":{"type":"object","additionalProperties":{"anyOf":[{"type":"array","items":{"anyOf":[{"type":"string","enum":["file"]},{"type":"string"},{"anyOf":[{"type":"string","enum":["id"]},{"type":"string","enum":["file_hash"]},{"type":"string","enum":["file_size"]},{"type":"string","enum":["mime_type"]},{"type":"string","enum":["storage_path"]},{"type":"string","enum":["cdn_path"]},{"type":"string","enum":["serve_path"]},{"type":"string","enum":["created_at"]},{"type":"string","enum":["updated_at"]},{"type":"string","enum":["alt_text"]},{"type":"string","enum":["value"]}]}]},"minItems":3,"maxItems":3,"description":"Value from a file: [\"file\", fileId, prop?]. prop selects a file field; \"value\" gives the primary URL (cdn_path, else serve_path)."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["symbol"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Value from a symbol prop: [\"symbol\", propKey, fieldKey]. propKey is the symbol prop; fieldKey selects a field of its value (e.g. \"value\", or a file field like \"cdn_path\")."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["collection"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current collection item: [\"collection\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["each"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current 'each' item: [\"each\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["source"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Item source for an 'each' node or a bound prop: 'static' (items provided on the node), 'collection' (a CMS collection query — id, sort, filters, pagination), 'navigation' (the site navigation tree), or 'locales' (the website's frontend-exposed locales for a language switcher)."}]},"minItems":2,"maxItems":2,"description":"Bind directly to an iterator source: [\"source\", IteratorSource]."}]},"description":"Binds live CMS data into this node instead of static values. Map from a target path on the node (e.g. \"content\", \"attrs.src\", \"classes\") to a value-handle tuple. Kinds: collection, file, symbol, link, each, source. Example: {\"attrs.src\": [\"file\",\"file_5d8e\",\"value\"]} fills src from a file."},"metadata":{"type":"object","properties":{"cmsType":{"type":"string","enum":["spacer"]},"formField":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"label":{"type":"string","description":"Human readable label authored for the field. Falls back to the field key when absent."},"required":{"type":"boolean"},"minLength":{"type":"number"},"maxLength":{"type":"number"},"pattern":{"type":"string","nullable":true},"min":{"type":"number"},"max":{"type":"number"},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]}},"multiple":{"type":"boolean"},"maxSize":{"type":"number"},"accept":{"type":"array","items":{"type":"string"}},"order":{"type":"number"}}},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["webhook"]},"url":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"to":{"type":"string"},"subject":{"type":"string"},"templateId":{"type":"string"}},"required":["type","to","subject"]}]}},"successBehavior":{"$ref":"#/components/schemas/SuccessBehavior"},"consentFieldKey":{"type":"string","description":"Key of the form field that carries the GDPR consent. Points at a field with type \"checkbox\" in the same form definition."},"consentBySubmit":{"type":"boolean","description":"Whether GDPR consent is given by submitting the form. Set instead of consentFieldKey on forms that show the consent text without a consent checkbox."},"visitorEmail":{"type":"object","properties":{"visitorEmailFieldKey":{"type":"string","description":"Key of the form field whose submitted value carries the visitor email address. Points at a field able to hold an email address in the same form definition."},"templateId":{"type":"string","description":"Id of the email template sent to the visitor."}},"required":["visitorEmailFieldKey"],"description":"Configuration of the email sent to the visitor after a successful submit. Absent when no visitor email is configured."}}}]},"custom":{"type":"object","additionalProperties":{"nullable":true},"description":"custom user metadata (for example, import description)"},"dataGuard":{"type":"object","properties":{"version":{"type":"number","enum":[1],"description":"Data guard schema version."},"enabled":{"type":"boolean","description":"Whether the guard is active. Owned outside the inspector section that edits the rest of this structure."},"type":{"type":"string","enum":["app"],"description":"Consumer kind. Placeholder — currently always \"app\"."},"data":{"type":"object","properties":{"collection":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string","description":"Target collection id this entry exposes to the frontend."},"columns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may project. Empty or missing means nothing is exposed — this is an allowlist, not a projection convenience."},"sortColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may sort by. Empty or missing means nothing is allowed."},"filterColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may filter by. Empty or missing means nothing is allowed."},"maxItems":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Upper bound on the number of items the frontend may request."},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]},"description":"Filters always applied on top of any frontend-supplied filter."}},"required":["type","collectionId"]},"description":"Collection entries keyed by a user-defined key."}},"required":["collection"]}},"required":["version","enabled","type","data"],"description":"Frontend data exposure allowlist for this node."}},"additionalProperties":{"nullable":true},"description":"Editor metadata for this node: cms element type, form-field definition, and custom notes (e.g. import description)."},"styleRole":{"type":"string","description":"Semantic style role, e.g. 'role_card'. Makes the node inherit the styleguide entry elementStyles[role], above its tag styles and below its own styleOverrides. Reuse one role's styling across many nodes."},"styleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for this node. Maps style slots ('color.bg', 'padding.top', 'font-size', …) to a StyleRef. Layers: default / breakpoints / containers; each has a base slot map and optional per-state (hover, focus) maps. A StyleRef is one of three variants: token (preferred) — {type:'token', scope:'project'|'primitive', key}, a design token by scope+key; pick from the design scale so the site stays consistent. keyword — {type:'keyword', value:'auto'}, a CSS keyword like 'auto' or 'inherit'. value — {type:'value', value:'25px'}, a raw CSS literal, last resort. Example: {\"default\":{\"base\":{\"color.bg\":{\"type\":\"token\",\"scope\":\"project\",\"key\":\"surface.primary\"}}}}."},"instanceStyleProps":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleOverrides"}}],"description":"Symbol-instance style overrides keyed by inner-node style role. Symbol nodes only. Only points exposed by the symbol design interface survive resolution."},"schemeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","description":"Color-scheme slug applied to this node and its subtree, emitted as data-scheme=\"<slug>\". Selects a named scheme that overrides project-scope color tokens for the subtree."},"type":{"type":"string","enum":["slot"]},"content":{"nullable":true},"name":{"type":"string","description":"Name of the slot this placeholder defines, inside a symbol variant layout."},"children":{"type":"array","items":{"type":"string"},"description":"Ids of this node's child nodes, in render order."}},"required":["id","tag","attrs","classes","type","name","children"],"description":"Slot placeholder inside a symbol variant layout"},{"type":"object","properties":{"id":{"type":"string","description":"Unique id of this node within the document."},"tag":{"type":"string","description":"HTML tag of the rendered element, e.g. 'div', 'h1', 'section'. Omitted on symbol nodes."},"attrs":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"nullable":true}}],"description":"Static HTML attributes for element nodes (e.g. {\"href\":\"/about\"}); component props for non-element nodes such as symbols. Static literal values only — never value-handle tuples or any dynamic references. To bind dynamic data (CMS fields, files, links) to an attr or prop, use the binding field instead; binding targets the attr/prop by path, e.g. attrs.<name>."},"classes":{"type":"array","items":{"type":"string"},"description":"Arbitrary utility classes written directly into the element's HTML class attribute. Use ONLY for one-off classes that have no token (e.g. Tailwind arbitrary values like 'gap-[2rem]', or 'prose'). All token styling — color, spacing, typography, radius, … — goes in styleOverrides (per node) or elementStyles (styleguide), NOT here."},"symbolId":{"type":"string","description":"Id of the linked symbol. Symbol nodes only."},"variantId":{"type":"string","description":"Id of the selected symbol variant. Symbol nodes only."},"binding":{"type":"object","additionalProperties":{"anyOf":[{"type":"array","items":{"anyOf":[{"type":"string","enum":["file"]},{"type":"string"},{"anyOf":[{"type":"string","enum":["id"]},{"type":"string","enum":["file_hash"]},{"type":"string","enum":["file_size"]},{"type":"string","enum":["mime_type"]},{"type":"string","enum":["storage_path"]},{"type":"string","enum":["cdn_path"]},{"type":"string","enum":["serve_path"]},{"type":"string","enum":["created_at"]},{"type":"string","enum":["updated_at"]},{"type":"string","enum":["alt_text"]},{"type":"string","enum":["value"]}]}]},"minItems":3,"maxItems":3,"description":"Value from a file: [\"file\", fileId, prop?]. prop selects a file field; \"value\" gives the primary URL (cdn_path, else serve_path)."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["symbol"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Value from a symbol prop: [\"symbol\", propKey, fieldKey]. propKey is the symbol prop; fieldKey selects a field of its value (e.g. \"value\", or a file field like \"cdn_path\")."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["collection"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current collection item: [\"collection\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["each"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current 'each' item: [\"each\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["source"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Item source for an 'each' node or a bound prop: 'static' (items provided on the node), 'collection' (a CMS collection query — id, sort, filters, pagination), 'navigation' (the site navigation tree), or 'locales' (the website's frontend-exposed locales for a language switcher)."}]},"minItems":2,"maxItems":2,"description":"Bind directly to an iterator source: [\"source\", IteratorSource]."}]},"description":"Binds live CMS data into this node instead of static values. Map from a target path on the node (e.g. \"content\", \"attrs.src\", \"classes\") to a value-handle tuple. Kinds: collection, file, symbol, link, each, source. Example: {\"attrs.src\": [\"file\",\"file_5d8e\",\"value\"]} fills src from a file."},"metadata":{"type":"object","properties":{"cmsType":{"type":"string","enum":["spacer"]},"formField":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"label":{"type":"string","description":"Human readable label authored for the field. Falls back to the field key when absent."},"required":{"type":"boolean"},"minLength":{"type":"number"},"maxLength":{"type":"number"},"pattern":{"type":"string","nullable":true},"min":{"type":"number"},"max":{"type":"number"},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]}},"multiple":{"type":"boolean"},"maxSize":{"type":"number"},"accept":{"type":"array","items":{"type":"string"}},"order":{"type":"number"}}},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["webhook"]},"url":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"to":{"type":"string"},"subject":{"type":"string"},"templateId":{"type":"string"}},"required":["type","to","subject"]}]}},"successBehavior":{"$ref":"#/components/schemas/SuccessBehavior"},"consentFieldKey":{"type":"string","description":"Key of the form field that carries the GDPR consent. Points at a field with type \"checkbox\" in the same form definition."},"consentBySubmit":{"type":"boolean","description":"Whether GDPR consent is given by submitting the form. Set instead of consentFieldKey on forms that show the consent text without a consent checkbox."},"visitorEmail":{"type":"object","properties":{"visitorEmailFieldKey":{"type":"string","description":"Key of the form field whose submitted value carries the visitor email address. Points at a field able to hold an email address in the same form definition."},"templateId":{"type":"string","description":"Id of the email template sent to the visitor."}},"required":["visitorEmailFieldKey"],"description":"Configuration of the email sent to the visitor after a successful submit. Absent when no visitor email is configured."}}}]},"custom":{"type":"object","additionalProperties":{"nullable":true},"description":"custom user metadata (for example, import description)"},"dataGuard":{"type":"object","properties":{"version":{"type":"number","enum":[1],"description":"Data guard schema version."},"enabled":{"type":"boolean","description":"Whether the guard is active. Owned outside the inspector section that edits the rest of this structure."},"type":{"type":"string","enum":["app"],"description":"Consumer kind. Placeholder — currently always \"app\"."},"data":{"type":"object","properties":{"collection":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string","description":"Target collection id this entry exposes to the frontend."},"columns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may project. Empty or missing means nothing is exposed — this is an allowlist, not a projection convenience."},"sortColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may sort by. Empty or missing means nothing is allowed."},"filterColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may filter by. Empty or missing means nothing is allowed."},"maxItems":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Upper bound on the number of items the frontend may request."},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]},"description":"Filters always applied on top of any frontend-supplied filter."}},"required":["type","collectionId"]},"description":"Collection entries keyed by a user-defined key."}},"required":["collection"]}},"required":["version","enabled","type","data"],"description":"Frontend data exposure allowlist for this node."}},"additionalProperties":{"nullable":true},"description":"Editor metadata for this node: cms element type, form-field definition, and custom notes (e.g. import description)."},"styleRole":{"type":"string","description":"Semantic style role, e.g. 'role_card'. Makes the node inherit the styleguide entry elementStyles[role], above its tag styles and below its own styleOverrides. Reuse one role's styling across many nodes."},"styleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for this node. Maps style slots ('color.bg', 'padding.top', 'font-size', …) to a StyleRef. Layers: default / breakpoints / containers; each has a base slot map and optional per-state (hover, focus) maps. A StyleRef is one of three variants: token (preferred) — {type:'token', scope:'project'|'primitive', key}, a design token by scope+key; pick from the design scale so the site stays consistent. keyword — {type:'keyword', value:'auto'}, a CSS keyword like 'auto' or 'inherit'. value — {type:'value', value:'25px'}, a raw CSS literal, last resort. Example: {\"default\":{\"base\":{\"color.bg\":{\"type\":\"token\",\"scope\":\"project\",\"key\":\"surface.primary\"}}}}."},"instanceStyleProps":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleOverrides"}}],"description":"Symbol-instance style overrides keyed by inner-node style role. Symbol nodes only. Only points exposed by the symbol design interface survive resolution."},"schemeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","description":"Color-scheme slug applied to this node and its subtree, emitted as data-scheme=\"<slug>\". Selects a named scheme that overrides project-scope color tokens for the subtree."},"type":{"type":"string","enum":["slotFill"]},"content":{"nullable":true},"name":{"type":"string","description":"Name of the slot this content fills, inside a symbol instance."},"itemId":{"type":"string","description":"Optional id of the item this slot fill belongs to."},"children":{"type":"array","items":{"type":"string"},"description":"Ids of this node's child nodes, in render order."}},"required":["id","tag","attrs","classes","type","name","children"],"description":"Named content container inside a symbol instance"},{"type":"object","properties":{"id":{"type":"string","description":"Unique id of this node within the document."},"tag":{"type":"string","description":"HTML tag of the rendered element, e.g. 'div', 'h1', 'section'. Omitted on symbol nodes."},"attrs":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"nullable":true}}],"description":"HTML attributes for element nodes (e.g. {\"href\":\"/about\"}); component props for non-element nodes such as symbols."},"classes":{"type":"array","items":{"type":"string"},"description":"Arbitrary utility classes written directly into the element's HTML class attribute. Use ONLY for one-off classes that have no token (e.g. Tailwind arbitrary values like 'gap-[2rem]', or 'prose'). All token styling — color, spacing, typography, radius, … — goes in styleOverrides (per node) or elementStyles (styleguide), NOT here."},"symbolId":{"type":"string","description":"Id of the linked symbol. Symbol nodes only."},"variantId":{"type":"string","description":"Id of the selected symbol variant. Symbol nodes only."},"binding":{"type":"object","additionalProperties":{"anyOf":[{"type":"array","items":{"anyOf":[{"type":"string","enum":["file"]},{"type":"string"},{"anyOf":[{"type":"string","enum":["id"]},{"type":"string","enum":["file_hash"]},{"type":"string","enum":["file_size"]},{"type":"string","enum":["mime_type"]},{"type":"string","enum":["storage_path"]},{"type":"string","enum":["cdn_path"]},{"type":"string","enum":["serve_path"]},{"type":"string","enum":["created_at"]},{"type":"string","enum":["updated_at"]},{"type":"string","enum":["alt_text"]},{"type":"string","enum":["value"]}]}]},"minItems":3,"maxItems":3,"description":"Value from a file: [\"file\", fileId, prop?]. prop selects a file field; \"value\" gives the primary URL (cdn_path, else serve_path)."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["symbol"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Value from a symbol prop: [\"symbol\", propKey, fieldKey]. propKey is the symbol prop; fieldKey selects a field of its value (e.g. \"value\", or a file field like \"cdn_path\")."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["collection"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current collection item: [\"collection\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["each"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current 'each' item: [\"each\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["source"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Item source for an 'each' node or a bound prop: 'static' (items provided on the node), 'collection' (a CMS collection query — id, sort, filters, pagination), 'navigation' (the site navigation tree), or 'locales' (the website's frontend-exposed locales for a language switcher)."}]},"minItems":2,"maxItems":2,"description":"Bind directly to an iterator source: [\"source\", IteratorSource]."}]},"description":"Binds live CMS data into this node instead of static values. Map from a target path on the node (e.g. \"content\", \"attrs.src\", \"classes\") to a value-handle tuple. Kinds: collection, file, symbol, link, each, source. Example: {\"attrs.src\": [\"file\",\"file_5d8e\",\"value\"]} fills src from a file."},"metadata":{"type":"object","properties":{"cmsType":{"type":"string","enum":["spacer"]},"formField":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"label":{"type":"string","description":"Human readable label authored for the field. Falls back to the field key when absent."},"required":{"type":"boolean"},"minLength":{"type":"number"},"maxLength":{"type":"number"},"pattern":{"type":"string","nullable":true},"min":{"type":"number"},"max":{"type":"number"},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]}},"multiple":{"type":"boolean"},"maxSize":{"type":"number"},"accept":{"type":"array","items":{"type":"string"}},"order":{"type":"number"}}},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["webhook"]},"url":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"to":{"type":"string"},"subject":{"type":"string"},"templateId":{"type":"string"}},"required":["type","to","subject"]}]}},"successBehavior":{"$ref":"#/components/schemas/SuccessBehavior"},"consentFieldKey":{"type":"string","description":"Key of the form field that carries the GDPR consent. Points at a field with type \"checkbox\" in the same form definition."},"consentBySubmit":{"type":"boolean","description":"Whether GDPR consent is given by submitting the form. Set instead of consentFieldKey on forms that show the consent text without a consent checkbox."},"visitorEmail":{"type":"object","properties":{"visitorEmailFieldKey":{"type":"string","description":"Key of the form field whose submitted value carries the visitor email address. Points at a field able to hold an email address in the same form definition."},"templateId":{"type":"string","description":"Id of the email template sent to the visitor."}},"required":["visitorEmailFieldKey"],"description":"Configuration of the email sent to the visitor after a successful submit. Absent when no visitor email is configured."}}}]},"custom":{"type":"object","additionalProperties":{"nullable":true},"description":"custom user metadata (for example, import description)"},"dataGuard":{"type":"object","properties":{"version":{"type":"number","enum":[1],"description":"Data guard schema version."},"enabled":{"type":"boolean","description":"Whether the guard is active. Owned outside the inspector section that edits the rest of this structure."},"type":{"type":"string","enum":["app"],"description":"Consumer kind. Placeholder — currently always \"app\"."},"data":{"type":"object","properties":{"collection":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string","description":"Target collection id this entry exposes to the frontend."},"columns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may project. Empty or missing means nothing is exposed — this is an allowlist, not a projection convenience."},"sortColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may sort by. Empty or missing means nothing is allowed."},"filterColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may filter by. Empty or missing means nothing is allowed."},"maxItems":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Upper bound on the number of items the frontend may request."},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]},"description":"Filters always applied on top of any frontend-supplied filter."}},"required":["type","collectionId"]},"description":"Collection entries keyed by a user-defined key."}},"required":["collection"]}},"required":["version","enabled","type","data"],"description":"Frontend data exposure allowlist for this node."}},"additionalProperties":{"nullable":true},"description":"Editor metadata for this node: cms element type, form-field definition, and custom notes (e.g. import description)."},"styleRole":{"type":"string","description":"Semantic style role, e.g. 'role_card'. Makes the node inherit the styleguide entry elementStyles[role], above its tag styles and below its own styleOverrides. Reuse one role's styling across many nodes."},"styleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for this node. Maps style slots ('color.bg', 'padding.top', 'font-size', …) to a StyleRef. Layers: default / breakpoints / containers; each has a base slot map and optional per-state (hover, focus) maps. A StyleRef is one of three variants: token (preferred) — {type:'token', scope:'project'|'primitive', key}, a design token by scope+key; pick from the design scale so the site stays consistent. keyword — {type:'keyword', value:'auto'}, a CSS keyword like 'auto' or 'inherit'. value — {type:'value', value:'25px'}, a raw CSS literal, last resort. Example: {\"default\":{\"base\":{\"color.bg\":{\"type\":\"token\",\"scope\":\"project\",\"key\":\"surface.primary\"}}}}."},"instanceStyleProps":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleOverrides"}}],"description":"Symbol-instance style overrides keyed by inner-node style role. Symbol nodes only. Only points exposed by the symbol design interface survive resolution."},"schemeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","description":"Color-scheme slug applied to this node and its subtree, emitted as data-scheme=\"<slug>\". Selects a named scheme that overrides project-scope color tokens for the subtree."},"type":{"type":"string","enum":["element"]},"content":{"nullable":true},"children":{"type":"array","items":{"type":"string"},"description":"Ids of this node's child nodes, in render order."}},"required":["id","tag","attrs","classes","type","children"],"description":"Regular node"},{"type":"object","properties":{"id":{"type":"string","description":"Unique id of this node within the document."},"tag":{"type":"string","description":"html element tag (omitted on symbol nodes; equals 'symbol')"},"attrs":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"nullable":true}}],"description":"Static HTML attributes for element nodes (e.g. {\"href\":\"/about\"}); component props for non-element nodes such as symbols. Static literal values only — never value-handle tuples or any dynamic references. To bind dynamic data (CMS fields, files, links) to an attr or prop, use the binding field instead; binding targets the attr/prop by path, e.g. attrs.<name>."},"classes":{"type":"array","items":{"type":"string"},"description":"Arbitrary utility classes written directly into the element's HTML class attribute. Use ONLY for one-off classes that have no token (e.g. Tailwind arbitrary values like 'gap-[2rem]', or 'prose'). All token styling — color, spacing, typography, radius, … — goes in styleOverrides (per node) or elementStyles (styleguide), NOT here."},"symbolId":{"type":"string","description":"Id of the linked symbol. Symbol nodes only."},"variantId":{"type":"string","description":"Id of the selected symbol variant. Symbol nodes only."},"binding":{"type":"object","additionalProperties":{"anyOf":[{"type":"array","items":{"anyOf":[{"type":"string","enum":["file"]},{"type":"string"},{"anyOf":[{"type":"string","enum":["id"]},{"type":"string","enum":["file_hash"]},{"type":"string","enum":["file_size"]},{"type":"string","enum":["mime_type"]},{"type":"string","enum":["storage_path"]},{"type":"string","enum":["cdn_path"]},{"type":"string","enum":["serve_path"]},{"type":"string","enum":["created_at"]},{"type":"string","enum":["updated_at"]},{"type":"string","enum":["alt_text"]},{"type":"string","enum":["value"]}]}]},"minItems":3,"maxItems":3,"description":"Value from a file: [\"file\", fileId, prop?]. prop selects a file field; \"value\" gives the primary URL (cdn_path, else serve_path)."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["symbol"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Value from a symbol prop: [\"symbol\", propKey, fieldKey]. propKey is the symbol prop; fieldKey selects a field of its value (e.g. \"value\", or a file field like \"cdn_path\")."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["collection"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current collection item: [\"collection\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["each"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current 'each' item: [\"each\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["source"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Item source for an 'each' node or a bound prop: 'static' (items provided on the node), 'collection' (a CMS collection query — id, sort, filters, pagination), 'navigation' (the site navigation tree), or 'locales' (the website's frontend-exposed locales for a language switcher)."}]},"minItems":2,"maxItems":2,"description":"Bind directly to an iterator source: [\"source\", IteratorSource]."}]},"description":"Binds live CMS data into this node instead of static values. Map from a target path on the node (e.g. \"content\", \"attrs.src\", \"classes\") to a value-handle tuple. Kinds: collection, file, symbol, link, each, source. Example: {\"attrs.src\": [\"file\",\"file_5d8e\",\"value\"]} fills src from a file."},"metadata":{"type":"object","properties":{"cmsType":{"type":"string","enum":["spacer"]},"formField":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"label":{"type":"string","description":"Human readable label authored for the field. Falls back to the field key when absent."},"required":{"type":"boolean"},"minLength":{"type":"number"},"maxLength":{"type":"number"},"pattern":{"type":"string","nullable":true},"min":{"type":"number"},"max":{"type":"number"},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]}},"multiple":{"type":"boolean"},"maxSize":{"type":"number"},"accept":{"type":"array","items":{"type":"string"}},"order":{"type":"number"}}},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["webhook"]},"url":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"to":{"type":"string"},"subject":{"type":"string"},"templateId":{"type":"string"}},"required":["type","to","subject"]}]}},"successBehavior":{"$ref":"#/components/schemas/SuccessBehavior"},"consentFieldKey":{"type":"string","description":"Key of the form field that carries the GDPR consent. Points at a field with type \"checkbox\" in the same form definition."},"consentBySubmit":{"type":"boolean","description":"Whether GDPR consent is given by submitting the form. Set instead of consentFieldKey on forms that show the consent text without a consent checkbox."},"visitorEmail":{"type":"object","properties":{"visitorEmailFieldKey":{"type":"string","description":"Key of the form field whose submitted value carries the visitor email address. Points at a field able to hold an email address in the same form definition."},"templateId":{"type":"string","description":"Id of the email template sent to the visitor."}},"required":["visitorEmailFieldKey"],"description":"Configuration of the email sent to the visitor after a successful submit. Absent when no visitor email is configured."}}}]},"custom":{"type":"object","additionalProperties":{"nullable":true},"description":"custom user metadata (for example, import description)"},"dataGuard":{"type":"object","properties":{"version":{"type":"number","enum":[1],"description":"Data guard schema version."},"enabled":{"type":"boolean","description":"Whether the guard is active. Owned outside the inspector section that edits the rest of this structure."},"type":{"type":"string","enum":["app"],"description":"Consumer kind. Placeholder — currently always \"app\"."},"data":{"type":"object","properties":{"collection":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string","description":"Target collection id this entry exposes to the frontend."},"columns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may project. Empty or missing means nothing is exposed — this is an allowlist, not a projection convenience."},"sortColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may sort by. Empty or missing means nothing is allowed."},"filterColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may filter by. Empty or missing means nothing is allowed."},"maxItems":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Upper bound on the number of items the frontend may request."},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]},"description":"Filters always applied on top of any frontend-supplied filter."}},"required":["type","collectionId"]},"description":"Collection entries keyed by a user-defined key."}},"required":["collection"]}},"required":["version","enabled","type","data"],"description":"Frontend data exposure allowlist for this node."}},"additionalProperties":{"nullable":true},"description":"Editor metadata for this node: cms element type, form-field definition, and custom notes (e.g. import description)."},"styleRole":{"type":"string","description":"Semantic style role, e.g. 'role_card'. Makes the node inherit the styleguide entry elementStyles[role], above its tag styles and below its own styleOverrides. Reuse one role's styling across many nodes."},"styleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for this node. Maps style slots ('color.bg', 'padding.top', 'font-size', …) to a StyleRef. Layers: default / breakpoints / containers; each has a base slot map and optional per-state (hover, focus) maps. A StyleRef is one of three variants: token (preferred) — {type:'token', scope:'project'|'primitive', key}, a design token by scope+key; pick from the design scale so the site stays consistent. keyword — {type:'keyword', value:'auto'}, a CSS keyword like 'auto' or 'inherit'. value — {type:'value', value:'25px'}, a raw CSS literal, last resort. Example: {\"default\":{\"base\":{\"color.bg\":{\"type\":\"token\",\"scope\":\"project\",\"key\":\"surface.primary\"}}}}."},"instanceStyleProps":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleOverrides"}}],"description":"Symbol-instance style overrides keyed by inner-node style role. Symbol nodes only. Only points exposed by the symbol design interface survive resolution."},"schemeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","description":"Color-scheme slug applied to this node and its subtree, emitted as data-scheme=\"<slug>\". Selects a named scheme that overrides project-scope color tokens for the subtree."},"type":{"type":"string","enum":["symbol"]},"content":{"nullable":true},"source":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"iterator source (symbol nodes only)"},"children":{"type":"array","items":{"type":"string"},"description":"Ids of this node's child nodes, in render order."}},"required":["id","attrs","classes","type","children"],"description":"Symbol instance node"},{"type":"object","properties":{"id":{"type":"string","description":"Unique id of this node within the document."},"tag":{"type":"string"},"attrs":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"nullable":true}}],"description":"HTML attributes for element nodes (e.g. {\"href\":\"/about\"}); component props for non-element nodes such as symbols."},"classes":{"type":"array","items":{"type":"string"}},"symbolId":{"type":"string","description":"Id of the linked symbol. Symbol nodes only."},"variantId":{"type":"string","description":"Id of the selected symbol variant. Symbol nodes only."},"binding":{"type":"object","additionalProperties":{"anyOf":[{"type":"array","items":{"anyOf":[{"type":"string","enum":["file"]},{"type":"string"},{"anyOf":[{"type":"string","enum":["id"]},{"type":"string","enum":["file_hash"]},{"type":"string","enum":["file_size"]},{"type":"string","enum":["mime_type"]},{"type":"string","enum":["storage_path"]},{"type":"string","enum":["cdn_path"]},{"type":"string","enum":["serve_path"]},{"type":"string","enum":["created_at"]},{"type":"string","enum":["updated_at"]},{"type":"string","enum":["alt_text"]},{"type":"string","enum":["value"]}]}]},"minItems":3,"maxItems":3,"description":"Value from a file: [\"file\", fileId, prop?]. prop selects a file field; \"value\" gives the primary URL (cdn_path, else serve_path)."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["symbol"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Value from a symbol prop: [\"symbol\", propKey, fieldKey]. propKey is the symbol prop; fieldKey selects a field of its value (e.g. \"value\", or a file field like \"cdn_path\")."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["collection"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current collection item: [\"collection\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["each"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current 'each' item: [\"each\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["source"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Item source for an 'each' node or a bound prop: 'static' (items provided on the node), 'collection' (a CMS collection query — id, sort, filters, pagination), 'navigation' (the site navigation tree), or 'locales' (the website's frontend-exposed locales for a language switcher)."}]},"minItems":2,"maxItems":2,"description":"Bind directly to an iterator source: [\"source\", IteratorSource]."}]},"description":"Binds live CMS data into this node instead of static values. Map from a target path on the node (e.g. \"content\", \"attrs.src\", \"classes\") to a value-handle tuple. Kinds: collection, file, symbol, link, each, source. Example: {\"attrs.src\": [\"file\",\"file_5d8e\",\"value\"]} fills src from a file."},"metadata":{"type":"object","properties":{"cmsType":{"type":"string","enum":["spacer"]},"formField":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"label":{"type":"string","description":"Human readable label authored for the field. Falls back to the field key when absent."},"required":{"type":"boolean"},"minLength":{"type":"number"},"maxLength":{"type":"number"},"pattern":{"type":"string","nullable":true},"min":{"type":"number"},"max":{"type":"number"},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]}},"multiple":{"type":"boolean"},"maxSize":{"type":"number"},"accept":{"type":"array","items":{"type":"string"}},"order":{"type":"number"}}},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["webhook"]},"url":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"to":{"type":"string"},"subject":{"type":"string"},"templateId":{"type":"string"}},"required":["type","to","subject"]}]}},"successBehavior":{"$ref":"#/components/schemas/SuccessBehavior"},"consentFieldKey":{"type":"string","description":"Key of the form field that carries the GDPR consent. Points at a field with type \"checkbox\" in the same form definition."},"consentBySubmit":{"type":"boolean","description":"Whether GDPR consent is given by submitting the form. Set instead of consentFieldKey on forms that show the consent text without a consent checkbox."},"visitorEmail":{"type":"object","properties":{"visitorEmailFieldKey":{"type":"string","description":"Key of the form field whose submitted value carries the visitor email address. Points at a field able to hold an email address in the same form definition."},"templateId":{"type":"string","description":"Id of the email template sent to the visitor."}},"required":["visitorEmailFieldKey"],"description":"Configuration of the email sent to the visitor after a successful submit. Absent when no visitor email is configured."}}}]},"custom":{"type":"object","additionalProperties":{"nullable":true},"description":"custom user metadata (for example, import description)"},"dataGuard":{"type":"object","properties":{"version":{"type":"number","enum":[1],"description":"Data guard schema version."},"enabled":{"type":"boolean","description":"Whether the guard is active. Owned outside the inspector section that edits the rest of this structure."},"type":{"type":"string","enum":["app"],"description":"Consumer kind. Placeholder — currently always \"app\"."},"data":{"type":"object","properties":{"collection":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string","description":"Target collection id this entry exposes to the frontend."},"columns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may project. Empty or missing means nothing is exposed — this is an allowlist, not a projection convenience."},"sortColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may sort by. Empty or missing means nothing is allowed."},"filterColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may filter by. Empty or missing means nothing is allowed."},"maxItems":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Upper bound on the number of items the frontend may request."},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]},"description":"Filters always applied on top of any frontend-supplied filter."}},"required":["type","collectionId"]},"description":"Collection entries keyed by a user-defined key."}},"required":["collection"]}},"required":["version","enabled","type","data"],"description":"Frontend data exposure allowlist for this node."}},"additionalProperties":{"nullable":true},"description":"Editor metadata for this node: cms element type, form-field definition, and custom notes (e.g. import description)."},"styleRole":{"type":"string","description":"Semantic style role, e.g. 'role_card'. Makes the node inherit the styleguide entry elementStyles[role], above its tag styles and below its own styleOverrides. Reuse one role's styling across many nodes."},"styleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for this node. Maps style slots ('color.bg', 'padding.top', 'font-size', …) to a StyleRef. Layers: default / breakpoints / containers; each has a base slot map and optional per-state (hover, focus) maps. A StyleRef is one of three variants: token (preferred) — {type:'token', scope:'project'|'primitive', key}, a design token by scope+key; pick from the design scale so the site stays consistent. keyword — {type:'keyword', value:'auto'}, a CSS keyword like 'auto' or 'inherit'. value — {type:'value', value:'25px'}, a raw CSS literal, last resort. Example: {\"default\":{\"base\":{\"color.bg\":{\"type\":\"token\",\"scope\":\"project\",\"key\":\"surface.primary\"}}}}."},"instanceStyleProps":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleOverrides"}}],"description":"Symbol-instance style overrides keyed by inner-node style role. Symbol nodes only. Only points exposed by the symbol design interface survive resolution."},"schemeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","description":"Color-scheme slug applied to this node and its subtree, emitted as data-scheme=\"<slug>\". Selects a named scheme that overrides project-scope color tokens for the subtree."},"type":{"nullable":true},"content":{"nullable":true},"children":{"type":"array","items":{"type":"string"},"description":"Ids of this node's child nodes, in render order."}},"required":["id","attrs","children"],"description":"Document root container (absent/null type)"},{"type":"object","properties":{"id":{"type":"string","description":"Unique id of this node within the document."},"tag":{"type":"string","description":"HTML tag of the rendered element, e.g. 'div', 'h1', 'section'. Omitted on symbol nodes."},"attrs":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"nullable":true}}],"description":"Static HTML attributes for element nodes (e.g. {\"href\":\"/about\"}); component props for non-element nodes such as symbols. Static literal values only — never value-handle tuples or any dynamic references. To bind dynamic data (CMS fields, files, links) to an attr or prop, use the binding field instead; binding targets the attr/prop by path, e.g. attrs.<name>."},"classes":{"type":"array","items":{"type":"string"},"description":"Arbitrary utility classes written directly into the element's HTML class attribute. Use ONLY for one-off classes that have no token (e.g. Tailwind arbitrary values like 'gap-[2rem]', or 'prose'). All token styling — color, spacing, typography, radius, … — goes in styleOverrides (per node) or elementStyles (styleguide), NOT here."},"symbolId":{"type":"string","description":"Id of the linked symbol. Symbol nodes only."},"variantId":{"type":"string","description":"Id of the selected symbol variant. Symbol nodes only."},"binding":{"type":"object","additionalProperties":{"anyOf":[{"type":"array","items":{"anyOf":[{"type":"string","enum":["file"]},{"type":"string"},{"anyOf":[{"type":"string","enum":["id"]},{"type":"string","enum":["file_hash"]},{"type":"string","enum":["file_size"]},{"type":"string","enum":["mime_type"]},{"type":"string","enum":["storage_path"]},{"type":"string","enum":["cdn_path"]},{"type":"string","enum":["serve_path"]},{"type":"string","enum":["created_at"]},{"type":"string","enum":["updated_at"]},{"type":"string","enum":["alt_text"]},{"type":"string","enum":["value"]}]}]},"minItems":3,"maxItems":3,"description":"Value from a file: [\"file\", fileId, prop?]. prop selects a file field; \"value\" gives the primary URL (cdn_path, else serve_path)."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["symbol"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Value from a symbol prop: [\"symbol\", propKey, fieldKey]. propKey is the symbol prop; fieldKey selects a field of its value (e.g. \"value\", or a file field like \"cdn_path\")."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["collection"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current collection item: [\"collection\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["each"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current 'each' item: [\"each\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["source"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Item source for an 'each' node or a bound prop: 'static' (items provided on the node), 'collection' (a CMS collection query — id, sort, filters, pagination), 'navigation' (the site navigation tree), or 'locales' (the website's frontend-exposed locales for a language switcher)."}]},"minItems":2,"maxItems":2,"description":"Bind directly to an iterator source: [\"source\", IteratorSource]."}]},"description":"Binds live CMS data into this node instead of static values. Map from a target path on the node (e.g. \"content\", \"attrs.src\", \"classes\") to a value-handle tuple. Kinds: collection, file, symbol, link, each, source. Example: {\"attrs.src\": [\"file\",\"file_5d8e\",\"value\"]} fills src from a file."},"metadata":{"type":"object","properties":{"cmsType":{"type":"string","enum":["spacer"]},"formField":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"label":{"type":"string","description":"Human readable label authored for the field. Falls back to the field key when absent."},"required":{"type":"boolean"},"minLength":{"type":"number"},"maxLength":{"type":"number"},"pattern":{"type":"string","nullable":true},"min":{"type":"number"},"max":{"type":"number"},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]}},"multiple":{"type":"boolean"},"maxSize":{"type":"number"},"accept":{"type":"array","items":{"type":"string"}},"order":{"type":"number"}}},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["webhook"]},"url":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"to":{"type":"string"},"subject":{"type":"string"},"templateId":{"type":"string"}},"required":["type","to","subject"]}]}},"successBehavior":{"$ref":"#/components/schemas/SuccessBehavior"},"consentFieldKey":{"type":"string","description":"Key of the form field that carries the GDPR consent. Points at a field with type \"checkbox\" in the same form definition."},"consentBySubmit":{"type":"boolean","description":"Whether GDPR consent is given by submitting the form. Set instead of consentFieldKey on forms that show the consent text without a consent checkbox."},"visitorEmail":{"type":"object","properties":{"visitorEmailFieldKey":{"type":"string","description":"Key of the form field whose submitted value carries the visitor email address. Points at a field able to hold an email address in the same form definition."},"templateId":{"type":"string","description":"Id of the email template sent to the visitor."}},"required":["visitorEmailFieldKey"],"description":"Configuration of the email sent to the visitor after a successful submit. Absent when no visitor email is configured."}}}]},"custom":{"type":"object","additionalProperties":{"nullable":true},"description":"custom user metadata (for example, import description)"},"dataGuard":{"type":"object","properties":{"version":{"type":"number","enum":[1],"description":"Data guard schema version."},"enabled":{"type":"boolean","description":"Whether the guard is active. Owned outside the inspector section that edits the rest of this structure."},"type":{"type":"string","enum":["app"],"description":"Consumer kind. Placeholder — currently always \"app\"."},"data":{"type":"object","properties":{"collection":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string","description":"Target collection id this entry exposes to the frontend."},"columns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may project. Empty or missing means nothing is exposed — this is an allowlist, not a projection convenience."},"sortColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may sort by. Empty or missing means nothing is allowed."},"filterColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may filter by. Empty or missing means nothing is allowed."},"maxItems":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Upper bound on the number of items the frontend may request."},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]},"description":"Filters always applied on top of any frontend-supplied filter."}},"required":["type","collectionId"]},"description":"Collection entries keyed by a user-defined key."}},"required":["collection"]}},"required":["version","enabled","type","data"],"description":"Frontend data exposure allowlist for this node."}},"additionalProperties":{"nullable":true},"description":"Editor metadata for this node: cms element type, form-field definition, and custom notes (e.g. import description)."},"styleRole":{"type":"string","description":"Semantic style role, e.g. 'role_card'. Makes the node inherit the styleguide entry elementStyles[role], above its tag styles and below its own styleOverrides. Reuse one role's styling across many nodes."},"styleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for this node. Maps style slots ('color.bg', 'padding.top', 'font-size', …) to a StyleRef. Layers: default / breakpoints / containers; each has a base slot map and optional per-state (hover, focus) maps. A StyleRef is one of three variants: token (preferred) — {type:'token', scope:'project'|'primitive', key}, a design token by scope+key; pick from the design scale so the site stays consistent. keyword — {type:'keyword', value:'auto'}, a CSS keyword like 'auto' or 'inherit'. value — {type:'value', value:'25px'}, a raw CSS literal, last resort. Example: {\"default\":{\"base\":{\"color.bg\":{\"type\":\"token\",\"scope\":\"project\",\"key\":\"surface.primary\"}}}}."},"instanceStyleProps":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleOverrides"}}],"description":"Symbol-instance style overrides keyed by inner-node style role. Symbol nodes only. Only points exposed by the symbol design interface survive resolution."},"schemeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","description":"Color-scheme slug applied to this node and its subtree, emitted as data-scheme=\"<slug>\". Selects a named scheme that overrides project-scope color tokens for the subtree."},"type":{"type":"string","enum":["outlet"]},"content":{"nullable":true},"documentName":{"type":"string","description":"Name of the CollectionDocument this outlet renders. Must match a CollectionDocument.name on the page's collection."},"children":{"type":"array","items":{"type":"string"},"description":"Ids of this node's child nodes, in render order."}},"required":["id","tag","attrs","classes","type","documentName","children"],"description":"Renders a CollectionItemDocument inline at this position"}]}}},"required":["rootId","leafNodeId","nodes"]}},"required":["type","nodeId","wrapper"],"description":"Wrap `nodeId` in a new subtree. `wrapper.nodes` carries the new nodes; `wrapper.rootId` is the new outer node that replaces `nodeId` in its parent; `wrapper.leafNodeId` is the descendant of the wrapper that adopts the original `nodeId` as a child. `rootId` and `leafNodeId` must both be keys in `wrapper.nodes`, and the leaf must be a node type that allows children (not a formatted or text node).","example":{"type":"wrapNode","nodeId":"h1","wrapper":{"rootId":"box","leafNodeId":"box","nodes":{"box":{"id":"box","type":"element","tag":"div","attrs":{},"classes":["wrapper"],"children":[],"content":null}}}}},"UnwrapNodeOp":{"type":"object","properties":{"type":{"type":"string","enum":["unwrapNode"]},"nodeId":{"type":"string"}},"required":["type","nodeId"],"description":"Replace `nodeId` with its children in its parent — i.e. remove one level of nesting. The root node cannot be unwrapped.","example":{"type":"unwrapNode","nodeId":"box"}},"AddSymbolOp":{"type":"object","properties":{"type":{"type":"string","enum":["addSymbol"]},"parentId":{"type":"string"},"referenceId":{"type":"string","nullable":true},"symbolId":{"type":"string"},"variantId":{"type":"string"},"rootNodeId":{"type":"string"},"props":{"type":"object","additionalProperties":{"nullable":true}},"slotFills":{"type":"object","additionalProperties":{"type":"string"}}},"required":["type","parentId","symbolId","rootNodeId"],"description":"Place a linked symbol instance. Sugar that compiles to a single `addNodes`: the server resolves the symbol interface (via GET /v1/symbols/{symbolId}), validates `variantId`, every key in `props` against the symbol's prop types, and every key in `slotFills` against the symbol's slot names, then assembles a `type:\"symbol\"` node `{id: rootNodeId, symbolId, variantId, attrs: <props>, classes: [], children: [<slotFill ids>]}` plus one empty `slotFill` node per `slotFills` entry. `variantId` may be omitted to use the symbol's default variant. Caller supplies all node ids. Slot *content* is added afterward with an ordinary `addNodes` targeting the scaffolded slotFill id. Prop value formats are strict (no coercion): text→string, number→number, boolean→boolean, list→array, richTextInline→ProseMirror doc with text/inline nodes directly under `doc` (no paragraph), richTextBlock→doc with paragraph blocks, file→file id string, link→`[\"link\", page|collection_item|file, id]` tuple.","example":{"type":"addSymbol","parentId":"root","referenceId":null,"symbolId":"sym_hero","variantId":"v_centered","rootNodeId":"hero_1","props":{"heading":"Ship faster","ctaLink":["link","page","pag_home"],"background":"fi_5d8e"},"slotFills":{"actions":"sf_actions"}}},"UpdateSymbolOp":{"type":"object","properties":{"type":{"type":"string","enum":["updateSymbol"]},"nodeId":{"type":"string"},"variantId":{"type":"string"},"props":{"type":"object","additionalProperties":{"nullable":true}}},"required":["type","nodeId"],"description":"Change the variant and/or prop values of an existing symbol instance. Sugar that compiles to a single `updateNode`: the server resolves the symbol interface from the existing node's `symbolId`, validates the new `variantId` and every supplied prop against the symbol's interface, then merges `variantId` and the given props into the node (only supplied props change; others and slot children are untouched). Prop value formats are the same strict shapes as `addSymbol`.","example":{"type":"updateSymbol","nodeId":"hero_1","variantId":"v_left","props":{"heading":"Ship even faster"}}},"SetSettingsOp":{"type":"object","properties":{"type":{"type":"string","enum":["setSettings"]},"nodeId":{"type":"string"},"settings":{"$ref":"#/components/schemas/SettingsSchema"},"symbolContext":{"type":"object","properties":{"symbolId":{"type":"string"},"variantId":{"type":"string"}},"required":["symbolId","variantId"]},"variant":{"type":"string"}},"required":["type","nodeId","settings"],"description":"Apply Tailwind settings updates to a node. Sugar that compiles to a single `updateNode`: the server calls `updateTailwindClasses` with the node's current classes and the supplied `settings` (a SettingsUpdates map), then writes back the resulting `classes` and `attrs.style`. `variant` selects the responsive/state variant to target (defaults to `\"default\"`). `symbolContext` pins edits inside a symbol variant when the node lives inside a symbol.","example":{"type":"setSettings","nodeId":"hero_1","settings":{"backgroundColor":{"kind":"named","value":"blue-600"},"padding":{"kind":"named","value":"4"}},"variant":"default"}},"SettingsSchema":{"type":"object","properties":{"position":{"type":"string","enum":["static"]},"display":{"type":"string","enum":["block"]},"flexDirection":{"type":"string","enum":["flex-row"]},"flexWrap":{"type":"string","enum":["flex-nowrap"]},"justifyContent":{"type":"string","enum":["justify-normal"]},"justifyItems":{"type":"string","enum":["justify-items-start"]},"alignContent":{"type":"string","enum":["content-normal"]},"alignItems":{"type":"string","enum":["items-normal"]},"gap":{"$ref":"#/components/schemas/VariableValue"},"rowGap":{"$ref":"#/components/schemas/VariableValue"},"columnGap":{"$ref":"#/components/schemas/VariableValue"},"gridTemplateColumns":{"$ref":"#/components/schemas/VariableValue"},"gridTemplateRows":{"$ref":"#/components/schemas/VariableValue"},"gridColumnStart":{"$ref":"#/components/schemas/VariableValue"},"gridColumnSpan":{"$ref":"#/components/schemas/VariableValue"},"gridRowStart":{"$ref":"#/components/schemas/VariableValue"},"gridRowSpan":{"$ref":"#/components/schemas/VariableValue"},"backgroundColor":{"$ref":"#/components/schemas/VariableValue"},"textColor":{"$ref":"#/components/schemas/VariableValue"},"borderColor":{"$ref":"#/components/schemas/VariableValue"},"borderInlineColor":{"$ref":"#/components/schemas/VariableValue"},"borderBlockColor":{"$ref":"#/components/schemas/VariableValue"},"borderInlineStartColor":{"$ref":"#/components/schemas/VariableValue"},"borderInlineEndColor":{"$ref":"#/components/schemas/VariableValue"},"borderTopColor":{"$ref":"#/components/schemas/VariableValue"},"borderRightColor":{"$ref":"#/components/schemas/VariableValue"},"borderBottomColor":{"$ref":"#/components/schemas/VariableValue"},"borderLeftColor":{"$ref":"#/components/schemas/VariableValue"},"borderRadius":{"$ref":"#/components/schemas/VariableValue"},"borderTopLeftRadius":{"$ref":"#/components/schemas/VariableValue"},"borderTopRightRadius":{"$ref":"#/components/schemas/VariableValue"},"borderBottomRightRadius":{"$ref":"#/components/schemas/VariableValue"},"borderBottomLeftRadius":{"$ref":"#/components/schemas/VariableValue"},"boxShadow":{"$ref":"#/components/schemas/VariableValue"},"boxShadowColor":{"$ref":"#/components/schemas/VariableValue"},"boxShadowOffsetX":{"$ref":"#/components/schemas/VariableValue"},"boxShadowOffsetY":{"$ref":"#/components/schemas/VariableValue"},"boxShadowBlurRadius":{"$ref":"#/components/schemas/VariableValue"},"boxShadowSpread":{"$ref":"#/components/schemas/VariableValue"},"boxShadowInset":{"$ref":"#/components/schemas/VariableValue"},"blur":{"$ref":"#/components/schemas/VariableValue"},"mixBlendMode":{"$ref":"#/components/schemas/VariableValue"},"borderWidth":{"$ref":"#/components/schemas/VariableValue"},"borderInlineWidth":{"$ref":"#/components/schemas/VariableValue"},"borderBlockWidth":{"$ref":"#/components/schemas/VariableValue"},"borderTopWidth":{"$ref":"#/components/schemas/VariableValue"},"borderRightWidth":{"$ref":"#/components/schemas/VariableValue"},"borderBottomWidth":{"$ref":"#/components/schemas/VariableValue"},"borderLeftWidth":{"$ref":"#/components/schemas/VariableValue"},"borderStyle":{"type":"string","enum":["border-solid"]},"fontSize":{"$ref":"#/components/schemas/VariableValue"},"fontFamily":{"$ref":"#/components/schemas/VariableValue"},"fontWeight":{"$ref":"#/components/schemas/VariableValue"},"fontStretch":{"anyOf":[{"type":"string","enum":["ultra-condensed"]},{"type":"string","pattern":"^\\d+%$"}]},"fontStyle":{"type":"string","enum":["italic"]},"letterSpacing":{"$ref":"#/components/schemas/VariableValue"},"lineHeight":{"$ref":"#/components/schemas/VariableValue"},"textAlign":{"type":"string","enum":["text-left"]},"textTransform":{"type":"string","enum":["uppercase"]},"textDecorationLine":{"type":"string","enum":["underline"]},"textWrap":{"type":"string","enum":["text-wrap"]},"textOverflow":{"type":"string","enum":["text-ellipsis"]},"backgroundImage":{"$ref":"#/components/schemas/VariableValue"},"backgroundSize":{"$ref":"#/components/schemas/VariableValue"},"backgroundRepeat":{"$ref":"#/components/schemas/VariableValue"},"backgroundPosition":{"$ref":"#/components/schemas/VariableValue"},"backgroundClip":{"type":"string","enum":["bg-clip-border"]},"opacity":{"$ref":"#/components/schemas/VariableValue"},"overflow":{"type":"string","enum":["overflow-auto"]},"visibility":{"type":"string","enum":["visible"]},"hidden":{"type":"string","enum":["hidden"]},"padding":{"$ref":"#/components/schemas/VariableValue"},"paddingInline":{"$ref":"#/components/schemas/VariableValue"},"paddingBlock":{"$ref":"#/components/schemas/VariableValue"},"paddingTop":{"$ref":"#/components/schemas/VariableValue"},"paddingRight":{"$ref":"#/components/schemas/VariableValue"},"paddingBottom":{"$ref":"#/components/schemas/VariableValue"},"paddingLeft":{"$ref":"#/components/schemas/VariableValue"},"margin":{"$ref":"#/components/schemas/VariableValue"},"marginInline":{"$ref":"#/components/schemas/VariableValue"},"marginBlock":{"$ref":"#/components/schemas/VariableValue"},"marginTop":{"$ref":"#/components/schemas/VariableValue"},"marginRight":{"$ref":"#/components/schemas/VariableValue"},"marginBottom":{"$ref":"#/components/schemas/VariableValue"},"marginLeft":{"$ref":"#/components/schemas/VariableValue"},"width":{"$ref":"#/components/schemas/VariableValue"},"minWidth":{"$ref":"#/components/schemas/VariableValue"},"maxWidth":{"$ref":"#/components/schemas/VariableValue"},"height":{"$ref":"#/components/schemas/VariableValue"},"minHeight":{"$ref":"#/components/schemas/VariableValue"},"maxHeight":{"$ref":"#/components/schemas/VariableValue"},"top":{"$ref":"#/components/schemas/VariableValue"},"left":{"$ref":"#/components/schemas/VariableValue"},"bottom":{"$ref":"#/components/schemas/VariableValue"},"right":{"$ref":"#/components/schemas/VariableValue"},"inset":{"$ref":"#/components/schemas/VariableValue"}},"description":"Design settings updates to apply."},"VariableValue":{"anyOf":[{"$ref":"#/components/schemas/ArbitraryValue"},{"$ref":"#/components/schemas/NamedValue"},{"$ref":"#/components/schemas/StaticValue"},{"$ref":"#/components/schemas/TokenValue"}],"description":"Represents a value that can be either arbitrary or named"},"ArbitraryValue":{"type":"object","properties":{"kind":{"type":"string","enum":["arbitrary"]},"value":{"type":"string"},"negative":{"type":"boolean"}},"required":["kind","value"],"description":"Represents an arbitrary value like `bg-[#ff0000]`"},"NamedValue":{"type":"object","properties":{"kind":{"type":"string","enum":["named"]},"value":{"type":"string"},"negative":{"type":"boolean"},"fraction":{"type":"string"}},"required":["kind","value"],"description":"Represents a named value like `bg-red-500`"},"StaticValue":{"type":"object","properties":{"kind":{"type":"string","enum":["static"]},"value":{"type":"string"},"negative":{"type":"boolean"}},"required":["kind","value"],"description":"Represents a static value like `absolute`"},"TokenValue":{"type":"object","properties":{"kind":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"]},"key":{"type":"string"}},"required":["kind","scope","key"],"description":"A reference to a design token by scope and key"},"AssignThemeToSectionOp":{"type":"object","properties":{"type":{"type":"string","enum":["assignThemeToSection"]},"nodeId":{"type":"string"},"themeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$"}},"required":["type","nodeId","themeId"],"description":"Assign a color theme (scheme) to a section node. Sugar that compiles to `updateNode{ schemeId: themeId }`. `themeId` must be a slug (letters, digits, `_`, `-`); a malformed value is rejected as INVALID_OP. No theme-existence check is performed — a well-formed id that matches no theme is accepted.","example":{"type":"assignThemeToSection","nodeId":"sec1","themeId":"dark"}},"ClearThemeFromSectionOp":{"type":"object","properties":{"type":{"type":"string","enum":["clearThemeFromSection"]},"nodeId":{"type":"string"}},"required":["type","nodeId"],"description":"Clear the assigned theme from a section node. Sugar that compiles to `updateNode{ schemeId: null }`, which deletes the field.","example":{"type":"clearThemeFromSection","nodeId":"sec1"}},"LayoutNode":{"oneOf":[{"type":"object","properties":{"id":{"type":"string","description":"Unique id of this node within the document."},"tag":{"type":"string","description":"HTML tag of the rendered element, e.g. 'div', 'h1', 'section'. Omitted on symbol nodes."},"attrs":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"nullable":true}}],"description":"HTML attributes for element nodes (e.g. {\"href\":\"/about\"}); component props for non-element nodes such as symbols."},"classes":{"type":"array","items":{"type":"string"},"description":"Arbitrary utility classes written directly into the element's HTML class attribute. Use ONLY for one-off classes that have no token (e.g. Tailwind arbitrary values like 'gap-[2rem]', or 'prose'). All token styling — color, spacing, typography, radius, … — goes in styleOverrides (per node) or elementStyles (styleguide), NOT here."},"symbolId":{"type":"string","description":"Id of the linked symbol. Symbol nodes only."},"variantId":{"type":"string","description":"Id of the selected symbol variant. Symbol nodes only."},"binding":{"type":"object","additionalProperties":{"anyOf":[{"type":"array","items":{"anyOf":[{"type":"string","enum":["file"]},{"type":"string"},{"anyOf":[{"type":"string","enum":["id"]},{"type":"string","enum":["file_hash"]},{"type":"string","enum":["file_size"]},{"type":"string","enum":["mime_type"]},{"type":"string","enum":["storage_path"]},{"type":"string","enum":["cdn_path"]},{"type":"string","enum":["serve_path"]},{"type":"string","enum":["created_at"]},{"type":"string","enum":["updated_at"]},{"type":"string","enum":["alt_text"]},{"type":"string","enum":["value"]}]}]},"minItems":3,"maxItems":3,"description":"Value from a file: [\"file\", fileId, prop?]. prop selects a file field; \"value\" gives the primary URL (cdn_path, else serve_path)."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["symbol"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Value from a symbol prop: [\"symbol\", propKey, fieldKey]. propKey is the symbol prop; fieldKey selects a field of its value (e.g. \"value\", or a file field like \"cdn_path\")."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["collection"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current collection item: [\"collection\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["each"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current 'each' item: [\"each\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["source"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Item source for an 'each' node or a bound prop: 'static' (items provided on the node), 'collection' (a CMS collection query — id, sort, filters, pagination), 'navigation' (the site navigation tree), or 'locales' (the website's frontend-exposed locales for a language switcher)."}]},"minItems":2,"maxItems":2,"description":"Bind directly to an iterator source: [\"source\", IteratorSource]."}]},"description":"Binds live CMS data into this node instead of static values. Map from a target path on the node (e.g. \"content\", \"attrs.src\", \"classes\") to a value-handle tuple. Kinds: collection, file, symbol, link, each, source. Example: {\"attrs.src\": [\"file\",\"file_5d8e\",\"value\"]} fills src from a file."},"metadata":{"type":"object","properties":{"cmsType":{"type":"string","enum":["spacer"]},"formField":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"label":{"type":"string","description":"Human readable label authored for the field. Falls back to the field key when absent."},"required":{"type":"boolean"},"minLength":{"type":"number"},"maxLength":{"type":"number"},"pattern":{"type":"string","nullable":true},"min":{"type":"number"},"max":{"type":"number"},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]}},"multiple":{"type":"boolean"},"maxSize":{"type":"number"},"accept":{"type":"array","items":{"type":"string"}},"order":{"type":"number"}}},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["webhook"]},"url":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"to":{"type":"string"},"subject":{"type":"string"},"templateId":{"type":"string"}},"required":["type","to","subject"]}]}},"successBehavior":{"$ref":"#/components/schemas/SuccessBehavior"},"consentFieldKey":{"type":"string","description":"Key of the form field that carries the GDPR consent. Points at a field with type \"checkbox\" in the same form definition."},"consentBySubmit":{"type":"boolean","description":"Whether GDPR consent is given by submitting the form. Set instead of consentFieldKey on forms that show the consent text without a consent checkbox."},"visitorEmail":{"type":"object","properties":{"visitorEmailFieldKey":{"type":"string","description":"Key of the form field whose submitted value carries the visitor email address. Points at a field able to hold an email address in the same form definition."},"templateId":{"type":"string","description":"Id of the email template sent to the visitor."}},"required":["visitorEmailFieldKey"],"description":"Configuration of the email sent to the visitor after a successful submit. Absent when no visitor email is configured."}}}]},"custom":{"type":"object","additionalProperties":{"nullable":true},"description":"custom user metadata (for example, import description)"},"dataGuard":{"type":"object","properties":{"version":{"type":"number","enum":[1],"description":"Data guard schema version."},"enabled":{"type":"boolean","description":"Whether the guard is active. Owned outside the inspector section that edits the rest of this structure."},"type":{"type":"string","enum":["app"],"description":"Consumer kind. Placeholder — currently always \"app\"."},"data":{"type":"object","properties":{"collection":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string","description":"Target collection id this entry exposes to the frontend."},"columns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may project. Empty or missing means nothing is exposed — this is an allowlist, not a projection convenience."},"sortColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may sort by. Empty or missing means nothing is allowed."},"filterColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may filter by. Empty or missing means nothing is allowed."},"maxItems":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Upper bound on the number of items the frontend may request."},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]},"description":"Filters always applied on top of any frontend-supplied filter."}},"required":["type","collectionId"]},"description":"Collection entries keyed by a user-defined key."}},"required":["collection"]}},"required":["version","enabled","type","data"],"description":"Frontend data exposure allowlist for this node."}},"additionalProperties":{"nullable":true},"description":"Editor metadata for this node: cms element type, form-field definition, and custom notes (e.g. import description)."},"styleRole":{"type":"string","description":"Semantic style role, e.g. 'role_card'. Makes the node inherit the styleguide entry elementStyles[role], above its tag styles and below its own styleOverrides. Reuse one role's styling across many nodes."},"styleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for this node. Maps style slots ('color.bg', 'padding.top', 'font-size', …) to a StyleRef. Layers: default / breakpoints / containers; each has a base slot map and optional per-state (hover, focus) maps. A StyleRef is one of three variants: token (preferred) — {type:'token', scope:'project'|'primitive', key}, a design token by scope+key; pick from the design scale so the site stays consistent. keyword — {type:'keyword', value:'auto'}, a CSS keyword like 'auto' or 'inherit'. value — {type:'value', value:'25px'}, a raw CSS literal, last resort. Example: {\"default\":{\"base\":{\"color.bg\":{\"type\":\"token\",\"scope\":\"project\",\"key\":\"surface.primary\"}}}}."},"instanceStyleProps":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleOverrides"}}],"description":"Symbol-instance style overrides keyed by inner-node style role. Symbol nodes only. Only points exposed by the symbol design interface survive resolution."},"schemeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","description":"Color-scheme slug applied to this node and its subtree, emitted as data-scheme=\"<slug>\". Selects a named scheme that overrides project-scope color tokens for the subtree."},"type":{"type":"string","enum":["text"]},"content":{"type":"string","description":"Plain (unformatted) text content. Text and embed nodes only."},"children":{"type":"array","items":{"type":"string"},"description":"Ids of this node's child nodes, in render order."}},"required":["id","tag","attrs","classes","type","content","children"],"description":"Node with text content"},{"type":"object","properties":{"id":{"type":"string","description":"Unique id of this node within the document."},"tag":{"type":"string","description":"HTML tag of the rendered element, e.g. 'div', 'h1', 'section'. Omitted on symbol nodes."},"attrs":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"nullable":true}}],"description":"HTML attributes for element nodes (e.g. {\"href\":\"/about\"}); component props for non-element nodes such as symbols."},"classes":{"type":"array","items":{"type":"string"},"description":"Arbitrary utility classes written directly into the element's HTML class attribute. Use ONLY for one-off classes that have no token (e.g. Tailwind arbitrary values like 'gap-[2rem]', or 'prose'). All token styling — color, spacing, typography, radius, … — goes in styleOverrides (per node) or elementStyles (styleguide), NOT here."},"symbolId":{"type":"string","description":"Id of the linked symbol. Symbol nodes only."},"variantId":{"type":"string","description":"Id of the selected symbol variant. Symbol nodes only."},"binding":{"type":"object","additionalProperties":{"anyOf":[{"type":"array","items":{"anyOf":[{"type":"string","enum":["file"]},{"type":"string"},{"anyOf":[{"type":"string","enum":["id"]},{"type":"string","enum":["file_hash"]},{"type":"string","enum":["file_size"]},{"type":"string","enum":["mime_type"]},{"type":"string","enum":["storage_path"]},{"type":"string","enum":["cdn_path"]},{"type":"string","enum":["serve_path"]},{"type":"string","enum":["created_at"]},{"type":"string","enum":["updated_at"]},{"type":"string","enum":["alt_text"]},{"type":"string","enum":["value"]}]}]},"minItems":3,"maxItems":3,"description":"Value from a file: [\"file\", fileId, prop?]. prop selects a file field; \"value\" gives the primary URL (cdn_path, else serve_path)."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["symbol"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Value from a symbol prop: [\"symbol\", propKey, fieldKey]. propKey is the symbol prop; fieldKey selects a field of its value (e.g. \"value\", or a file field like \"cdn_path\")."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["collection"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current collection item: [\"collection\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["each"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current 'each' item: [\"each\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["source"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Item source for an 'each' node or a bound prop: 'static' (items provided on the node), 'collection' (a CMS collection query — id, sort, filters, pagination), 'navigation' (the site navigation tree), or 'locales' (the website's frontend-exposed locales for a language switcher)."}]},"minItems":2,"maxItems":2,"description":"Bind directly to an iterator source: [\"source\", IteratorSource]."}]},"description":"Binds live CMS data into this node instead of static values. Map from a target path on the node (e.g. \"content\", \"attrs.src\", \"classes\") to a value-handle tuple. Kinds: collection, file, symbol, link, each, source. Example: {\"attrs.src\": [\"file\",\"file_5d8e\",\"value\"]} fills src from a file."},"metadata":{"type":"object","properties":{"cmsType":{"type":"string","enum":["spacer"]},"formField":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"label":{"type":"string","description":"Human readable label authored for the field. Falls back to the field key when absent."},"required":{"type":"boolean"},"minLength":{"type":"number"},"maxLength":{"type":"number"},"pattern":{"type":"string","nullable":true},"min":{"type":"number"},"max":{"type":"number"},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]}},"multiple":{"type":"boolean"},"maxSize":{"type":"number"},"accept":{"type":"array","items":{"type":"string"}},"order":{"type":"number"}}},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["webhook"]},"url":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"to":{"type":"string"},"subject":{"type":"string"},"templateId":{"type":"string"}},"required":["type","to","subject"]}]}},"successBehavior":{"$ref":"#/components/schemas/SuccessBehavior"},"consentFieldKey":{"type":"string","description":"Key of the form field that carries the GDPR consent. Points at a field with type \"checkbox\" in the same form definition."},"consentBySubmit":{"type":"boolean","description":"Whether GDPR consent is given by submitting the form. Set instead of consentFieldKey on forms that show the consent text without a consent checkbox."},"visitorEmail":{"type":"object","properties":{"visitorEmailFieldKey":{"type":"string","description":"Key of the form field whose submitted value carries the visitor email address. Points at a field able to hold an email address in the same form definition."},"templateId":{"type":"string","description":"Id of the email template sent to the visitor."}},"required":["visitorEmailFieldKey"],"description":"Configuration of the email sent to the visitor after a successful submit. Absent when no visitor email is configured."}}}]},"custom":{"type":"object","additionalProperties":{"nullable":true},"description":"custom user metadata (for example, import description)"},"dataGuard":{"type":"object","properties":{"version":{"type":"number","enum":[1],"description":"Data guard schema version."},"enabled":{"type":"boolean","description":"Whether the guard is active. Owned outside the inspector section that edits the rest of this structure."},"type":{"type":"string","enum":["app"],"description":"Consumer kind. Placeholder — currently always \"app\"."},"data":{"type":"object","properties":{"collection":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string","description":"Target collection id this entry exposes to the frontend."},"columns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may project. Empty or missing means nothing is exposed — this is an allowlist, not a projection convenience."},"sortColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may sort by. Empty or missing means nothing is allowed."},"filterColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may filter by. Empty or missing means nothing is allowed."},"maxItems":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Upper bound on the number of items the frontend may request."},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]},"description":"Filters always applied on top of any frontend-supplied filter."}},"required":["type","collectionId"]},"description":"Collection entries keyed by a user-defined key."}},"required":["collection"]}},"required":["version","enabled","type","data"],"description":"Frontend data exposure allowlist for this node."}},"additionalProperties":{"nullable":true},"description":"Editor metadata for this node: cms element type, form-field definition, and custom notes (e.g. import description)."},"styleRole":{"type":"string","description":"Semantic style role, e.g. 'role_card'. Makes the node inherit the styleguide entry elementStyles[role], above its tag styles and below its own styleOverrides. Reuse one role's styling across many nodes."},"styleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for this node. Maps style slots ('color.bg', 'padding.top', 'font-size', …) to a StyleRef. Layers: default / breakpoints / containers; each has a base slot map and optional per-state (hover, focus) maps. A StyleRef is one of three variants: token (preferred) — {type:'token', scope:'project'|'primitive', key}, a design token by scope+key; pick from the design scale so the site stays consistent. keyword — {type:'keyword', value:'auto'}, a CSS keyword like 'auto' or 'inherit'. value — {type:'value', value:'25px'}, a raw CSS literal, last resort. Example: {\"default\":{\"base\":{\"color.bg\":{\"type\":\"token\",\"scope\":\"project\",\"key\":\"surface.primary\"}}}}."},"instanceStyleProps":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleOverrides"}}],"description":"Symbol-instance style overrides keyed by inner-node style role. Symbol nodes only. Only points exposed by the symbol design interface survive resolution."},"schemeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","description":"Color-scheme slug applied to this node and its subtree, emitted as data-scheme=\"<slug>\". Selects a named scheme that overrides project-scope color tokens for the subtree."},"type":{"type":"string","enum":["formattedInlineElement"]},"content":{"type":"object","properties":{"type":{"type":"string"},"attrs":{"type":"object","additionalProperties":{"nullable":true}},"content":{"type":"array","items":{"$ref":"#/components/schemas/JSONContent"}},"marks":{"type":"array","items":{"allOf":[{"type":"object","additionalProperties":{"nullable":true}},{"type":"object","properties":{"type":{"type":"string"},"attrs":{"type":"object","additionalProperties":{"nullable":true}}},"required":["type"]}]}},"text":{"type":"string"}},"description":"Rich-text content as a ProseMirror document. Formatted inline/block nodes only."},"children":{"type":"array","items":{"type":"string"},"description":"Ids of this node's child nodes, in render order."}},"required":["id","tag","attrs","classes","type","content","children"],"description":"Node with formatted content"},{"type":"object","properties":{"id":{"type":"string","description":"Unique id of this node within the document."},"tag":{"type":"string","description":"HTML tag of the rendered element, e.g. 'div', 'h1', 'section'. Omitted on symbol nodes."},"attrs":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"nullable":true}}],"description":"Static HTML attributes for element nodes (e.g. {\"href\":\"/about\"}); component props for non-element nodes such as symbols. Static literal values only — never value-handle tuples or any dynamic references. To bind dynamic data (CMS fields, files, links) to an attr or prop, use the binding field instead; binding targets the attr/prop by path, e.g. attrs.<name>."},"classes":{"type":"array","items":{"type":"string"},"description":"Arbitrary utility classes written directly into the element's HTML class attribute. Use ONLY for one-off classes that have no token (e.g. Tailwind arbitrary values like 'gap-[2rem]', or 'prose'). All token styling — color, spacing, typography, radius, … — goes in styleOverrides (per node) or elementStyles (styleguide), NOT here."},"symbolId":{"type":"string","description":"Id of the linked symbol. Symbol nodes only."},"variantId":{"type":"string","description":"Id of the selected symbol variant. Symbol nodes only."},"binding":{"type":"object","additionalProperties":{"anyOf":[{"type":"array","items":{"anyOf":[{"type":"string","enum":["file"]},{"type":"string"},{"anyOf":[{"type":"string","enum":["id"]},{"type":"string","enum":["file_hash"]},{"type":"string","enum":["file_size"]},{"type":"string","enum":["mime_type"]},{"type":"string","enum":["storage_path"]},{"type":"string","enum":["cdn_path"]},{"type":"string","enum":["serve_path"]},{"type":"string","enum":["created_at"]},{"type":"string","enum":["updated_at"]},{"type":"string","enum":["alt_text"]},{"type":"string","enum":["value"]}]}]},"minItems":3,"maxItems":3,"description":"Value from a file: [\"file\", fileId, prop?]. prop selects a file field; \"value\" gives the primary URL (cdn_path, else serve_path)."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["symbol"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Value from a symbol prop: [\"symbol\", propKey, fieldKey]. propKey is the symbol prop; fieldKey selects a field of its value (e.g. \"value\", or a file field like \"cdn_path\")."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["collection"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current collection item: [\"collection\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["each"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current 'each' item: [\"each\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["source"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Item source for an 'each' node or a bound prop: 'static' (items provided on the node), 'collection' (a CMS collection query — id, sort, filters, pagination), 'navigation' (the site navigation tree), or 'locales' (the website's frontend-exposed locales for a language switcher)."}]},"minItems":2,"maxItems":2,"description":"Bind directly to an iterator source: [\"source\", IteratorSource]."}]},"description":"Binds live CMS data into this node instead of static values. Map from a target path on the node (e.g. \"content\", \"attrs.src\", \"classes\") to a value-handle tuple. Kinds: collection, file, symbol, link, each, source. Example: {\"attrs.src\": [\"file\",\"file_5d8e\",\"value\"]} fills src from a file."},"metadata":{"type":"object","properties":{"cmsType":{"type":"string","enum":["spacer"]},"formField":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"label":{"type":"string","description":"Human readable label authored for the field. Falls back to the field key when absent."},"required":{"type":"boolean"},"minLength":{"type":"number"},"maxLength":{"type":"number"},"pattern":{"type":"string","nullable":true},"min":{"type":"number"},"max":{"type":"number"},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]}},"multiple":{"type":"boolean"},"maxSize":{"type":"number"},"accept":{"type":"array","items":{"type":"string"}},"order":{"type":"number"}}},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["webhook"]},"url":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"to":{"type":"string"},"subject":{"type":"string"},"templateId":{"type":"string"}},"required":["type","to","subject"]}]}},"successBehavior":{"$ref":"#/components/schemas/SuccessBehavior"},"consentFieldKey":{"type":"string","description":"Key of the form field that carries the GDPR consent. Points at a field with type \"checkbox\" in the same form definition."},"consentBySubmit":{"type":"boolean","description":"Whether GDPR consent is given by submitting the form. Set instead of consentFieldKey on forms that show the consent text without a consent checkbox."},"visitorEmail":{"type":"object","properties":{"visitorEmailFieldKey":{"type":"string","description":"Key of the form field whose submitted value carries the visitor email address. Points at a field able to hold an email address in the same form definition."},"templateId":{"type":"string","description":"Id of the email template sent to the visitor."}},"required":["visitorEmailFieldKey"],"description":"Configuration of the email sent to the visitor after a successful submit. Absent when no visitor email is configured."}}}]},"custom":{"type":"object","additionalProperties":{"nullable":true},"description":"custom user metadata (for example, import description)"},"dataGuard":{"type":"object","properties":{"version":{"type":"number","enum":[1],"description":"Data guard schema version."},"enabled":{"type":"boolean","description":"Whether the guard is active. Owned outside the inspector section that edits the rest of this structure."},"type":{"type":"string","enum":["app"],"description":"Consumer kind. Placeholder — currently always \"app\"."},"data":{"type":"object","properties":{"collection":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string","description":"Target collection id this entry exposes to the frontend."},"columns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may project. Empty or missing means nothing is exposed — this is an allowlist, not a projection convenience."},"sortColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may sort by. Empty or missing means nothing is allowed."},"filterColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may filter by. Empty or missing means nothing is allowed."},"maxItems":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Upper bound on the number of items the frontend may request."},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]},"description":"Filters always applied on top of any frontend-supplied filter."}},"required":["type","collectionId"]},"description":"Collection entries keyed by a user-defined key."}},"required":["collection"]}},"required":["version","enabled","type","data"],"description":"Frontend data exposure allowlist for this node."}},"additionalProperties":{"nullable":true},"description":"Editor metadata for this node: cms element type, form-field definition, and custom notes (e.g. import description)."},"styleRole":{"type":"string","description":"Semantic style role, e.g. 'role_card'. Makes the node inherit the styleguide entry elementStyles[role], above its tag styles and below its own styleOverrides. Reuse one role's styling across many nodes."},"styleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for this node. Maps style slots ('color.bg', 'padding.top', 'font-size', …) to a StyleRef. Layers: default / breakpoints / containers; each has a base slot map and optional per-state (hover, focus) maps. A StyleRef is one of three variants: token (preferred) — {type:'token', scope:'project'|'primitive', key}, a design token by scope+key; pick from the design scale so the site stays consistent. keyword — {type:'keyword', value:'auto'}, a CSS keyword like 'auto' or 'inherit'. value — {type:'value', value:'25px'}, a raw CSS literal, last resort. Example: {\"default\":{\"base\":{\"color.bg\":{\"type\":\"token\",\"scope\":\"project\",\"key\":\"surface.primary\"}}}}."},"instanceStyleProps":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleOverrides"}}],"description":"Symbol-instance style overrides keyed by inner-node style role. Symbol nodes only. Only points exposed by the symbol design interface survive resolution."},"schemeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","description":"Color-scheme slug applied to this node and its subtree, emitted as data-scheme=\"<slug>\". Selects a named scheme that overrides project-scope color tokens for the subtree."},"type":{"type":"string","enum":["each"]},"content":{"nullable":true},"source":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Where this 'each' node gets its items: static, a CMS collection query, or site navigation."},"items":{"type":"object","properties":{"items":{"type":"array","items":{"nullable":true}},"schema":{"nullable":true}},"required":["items"],"description":"Inline static items (with their schema) for a static 'each' source."},"preventEmpty":{"type":"boolean","description":"Hide the empty-state placeholder when the source yields no items."},"children":{"type":"array","items":{"type":"string"},"description":"Ids of this node's child nodes, in render order."}},"required":["id","tag","attrs","classes","type","children"],"description":"Node for iterating over a source"},{"type":"object","properties":{"id":{"type":"string","description":"Unique id of this node within the document."},"tag":{"type":"string","description":"HTML tag of the rendered element, e.g. 'div', 'h1', 'section'. Omitted on symbol nodes."},"attrs":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"nullable":true}}],"description":"Static HTML attributes for element nodes (e.g. {\"href\":\"/about\"}); component props for non-element nodes such as symbols. Static literal values only — never value-handle tuples or any dynamic references. To bind dynamic data (CMS fields, files, links) to an attr or prop, use the binding field instead; binding targets the attr/prop by path, e.g. attrs.<name>."},"classes":{"type":"array","items":{"type":"string"},"description":"Arbitrary utility classes written directly into the element's HTML class attribute. Use ONLY for one-off classes that have no token (e.g. Tailwind arbitrary values like 'gap-[2rem]', or 'prose'). All token styling — color, spacing, typography, radius, … — goes in styleOverrides (per node) or elementStyles (styleguide), NOT here."},"symbolId":{"type":"string","description":"Id of the linked symbol. Symbol nodes only."},"variantId":{"type":"string","description":"Id of the selected symbol variant. Symbol nodes only."},"binding":{"type":"object","additionalProperties":{"anyOf":[{"type":"array","items":{"anyOf":[{"type":"string","enum":["file"]},{"type":"string"},{"anyOf":[{"type":"string","enum":["id"]},{"type":"string","enum":["file_hash"]},{"type":"string","enum":["file_size"]},{"type":"string","enum":["mime_type"]},{"type":"string","enum":["storage_path"]},{"type":"string","enum":["cdn_path"]},{"type":"string","enum":["serve_path"]},{"type":"string","enum":["created_at"]},{"type":"string","enum":["updated_at"]},{"type":"string","enum":["alt_text"]},{"type":"string","enum":["value"]}]}]},"minItems":3,"maxItems":3,"description":"Value from a file: [\"file\", fileId, prop?]. prop selects a file field; \"value\" gives the primary URL (cdn_path, else serve_path)."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["symbol"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Value from a symbol prop: [\"symbol\", propKey, fieldKey]. propKey is the symbol prop; fieldKey selects a field of its value (e.g. \"value\", or a file field like \"cdn_path\")."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["collection"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current collection item: [\"collection\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["each"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current 'each' item: [\"each\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["source"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Item source for an 'each' node or a bound prop: 'static' (items provided on the node), 'collection' (a CMS collection query — id, sort, filters, pagination), 'navigation' (the site navigation tree), or 'locales' (the website's frontend-exposed locales for a language switcher)."}]},"minItems":2,"maxItems":2,"description":"Bind directly to an iterator source: [\"source\", IteratorSource]."}]},"description":"Binds live CMS data into this node instead of static values. Map from a target path on the node (e.g. \"content\", \"attrs.src\", \"classes\") to a value-handle tuple. Kinds: collection, file, symbol, link, each, source. Example: {\"attrs.src\": [\"file\",\"file_5d8e\",\"value\"]} fills src from a file."},"metadata":{"type":"object","properties":{"cmsType":{"type":"string","enum":["spacer"]},"formField":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"label":{"type":"string","description":"Human readable label authored for the field. Falls back to the field key when absent."},"required":{"type":"boolean"},"minLength":{"type":"number"},"maxLength":{"type":"number"},"pattern":{"type":"string","nullable":true},"min":{"type":"number"},"max":{"type":"number"},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]}},"multiple":{"type":"boolean"},"maxSize":{"type":"number"},"accept":{"type":"array","items":{"type":"string"}},"order":{"type":"number"}}},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["webhook"]},"url":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"to":{"type":"string"},"subject":{"type":"string"},"templateId":{"type":"string"}},"required":["type","to","subject"]}]}},"successBehavior":{"$ref":"#/components/schemas/SuccessBehavior"},"consentFieldKey":{"type":"string","description":"Key of the form field that carries the GDPR consent. Points at a field with type \"checkbox\" in the same form definition."},"consentBySubmit":{"type":"boolean","description":"Whether GDPR consent is given by submitting the form. Set instead of consentFieldKey on forms that show the consent text without a consent checkbox."},"visitorEmail":{"type":"object","properties":{"visitorEmailFieldKey":{"type":"string","description":"Key of the form field whose submitted value carries the visitor email address. Points at a field able to hold an email address in the same form definition."},"templateId":{"type":"string","description":"Id of the email template sent to the visitor."}},"required":["visitorEmailFieldKey"],"description":"Configuration of the email sent to the visitor after a successful submit. Absent when no visitor email is configured."}}}]},"custom":{"type":"object","additionalProperties":{"nullable":true},"description":"custom user metadata (for example, import description)"},"dataGuard":{"type":"object","properties":{"version":{"type":"number","enum":[1],"description":"Data guard schema version."},"enabled":{"type":"boolean","description":"Whether the guard is active. Owned outside the inspector section that edits the rest of this structure."},"type":{"type":"string","enum":["app"],"description":"Consumer kind. Placeholder — currently always \"app\"."},"data":{"type":"object","properties":{"collection":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string","description":"Target collection id this entry exposes to the frontend."},"columns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may project. Empty or missing means nothing is exposed — this is an allowlist, not a projection convenience."},"sortColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may sort by. Empty or missing means nothing is allowed."},"filterColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may filter by. Empty or missing means nothing is allowed."},"maxItems":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Upper bound on the number of items the frontend may request."},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]},"description":"Filters always applied on top of any frontend-supplied filter."}},"required":["type","collectionId"]},"description":"Collection entries keyed by a user-defined key."}},"required":["collection"]}},"required":["version","enabled","type","data"],"description":"Frontend data exposure allowlist for this node."}},"additionalProperties":{"nullable":true},"description":"Editor metadata for this node: cms element type, form-field definition, and custom notes (e.g. import description)."},"styleRole":{"type":"string","description":"Semantic style role, e.g. 'role_card'. Makes the node inherit the styleguide entry elementStyles[role], above its tag styles and below its own styleOverrides. Reuse one role's styling across many nodes."},"styleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for this node. Maps style slots ('color.bg', 'padding.top', 'font-size', …) to a StyleRef. Layers: default / breakpoints / containers; each has a base slot map and optional per-state (hover, focus) maps. A StyleRef is one of three variants: token (preferred) — {type:'token', scope:'project'|'primitive', key}, a design token by scope+key; pick from the design scale so the site stays consistent. keyword — {type:'keyword', value:'auto'}, a CSS keyword like 'auto' or 'inherit'. value — {type:'value', value:'25px'}, a raw CSS literal, last resort. Example: {\"default\":{\"base\":{\"color.bg\":{\"type\":\"token\",\"scope\":\"project\",\"key\":\"surface.primary\"}}}}."},"instanceStyleProps":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleOverrides"}}],"description":"Symbol-instance style overrides keyed by inner-node style role. Symbol nodes only. Only points exposed by the symbol design interface survive resolution."},"schemeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","description":"Color-scheme slug applied to this node and its subtree, emitted as data-scheme=\"<slug>\". Selects a named scheme that overrides project-scope color tokens for the subtree."},"type":{"type":"string","enum":["slot"]},"content":{"nullable":true},"name":{"type":"string","description":"Name of the slot this placeholder defines, inside a symbol variant layout."},"children":{"type":"array","items":{"type":"string"},"description":"Ids of this node's child nodes, in render order."}},"required":["id","tag","attrs","classes","type","name","children"],"description":"Slot placeholder inside a symbol variant layout"},{"type":"object","properties":{"id":{"type":"string","description":"Unique id of this node within the document."},"tag":{"type":"string","description":"HTML tag of the rendered element, e.g. 'div', 'h1', 'section'. Omitted on symbol nodes."},"attrs":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"nullable":true}}],"description":"Static HTML attributes for element nodes (e.g. {\"href\":\"/about\"}); component props for non-element nodes such as symbols. Static literal values only — never value-handle tuples or any dynamic references. To bind dynamic data (CMS fields, files, links) to an attr or prop, use the binding field instead; binding targets the attr/prop by path, e.g. attrs.<name>."},"classes":{"type":"array","items":{"type":"string"},"description":"Arbitrary utility classes written directly into the element's HTML class attribute. Use ONLY for one-off classes that have no token (e.g. Tailwind arbitrary values like 'gap-[2rem]', or 'prose'). All token styling — color, spacing, typography, radius, … — goes in styleOverrides (per node) or elementStyles (styleguide), NOT here."},"symbolId":{"type":"string","description":"Id of the linked symbol. Symbol nodes only."},"variantId":{"type":"string","description":"Id of the selected symbol variant. Symbol nodes only."},"binding":{"type":"object","additionalProperties":{"anyOf":[{"type":"array","items":{"anyOf":[{"type":"string","enum":["file"]},{"type":"string"},{"anyOf":[{"type":"string","enum":["id"]},{"type":"string","enum":["file_hash"]},{"type":"string","enum":["file_size"]},{"type":"string","enum":["mime_type"]},{"type":"string","enum":["storage_path"]},{"type":"string","enum":["cdn_path"]},{"type":"string","enum":["serve_path"]},{"type":"string","enum":["created_at"]},{"type":"string","enum":["updated_at"]},{"type":"string","enum":["alt_text"]},{"type":"string","enum":["value"]}]}]},"minItems":3,"maxItems":3,"description":"Value from a file: [\"file\", fileId, prop?]. prop selects a file field; \"value\" gives the primary URL (cdn_path, else serve_path)."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["symbol"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Value from a symbol prop: [\"symbol\", propKey, fieldKey]. propKey is the symbol prop; fieldKey selects a field of its value (e.g. \"value\", or a file field like \"cdn_path\")."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["collection"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current collection item: [\"collection\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["each"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current 'each' item: [\"each\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["source"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Item source for an 'each' node or a bound prop: 'static' (items provided on the node), 'collection' (a CMS collection query — id, sort, filters, pagination), 'navigation' (the site navigation tree), or 'locales' (the website's frontend-exposed locales for a language switcher)."}]},"minItems":2,"maxItems":2,"description":"Bind directly to an iterator source: [\"source\", IteratorSource]."}]},"description":"Binds live CMS data into this node instead of static values. Map from a target path on the node (e.g. \"content\", \"attrs.src\", \"classes\") to a value-handle tuple. Kinds: collection, file, symbol, link, each, source. Example: {\"attrs.src\": [\"file\",\"file_5d8e\",\"value\"]} fills src from a file."},"metadata":{"type":"object","properties":{"cmsType":{"type":"string","enum":["spacer"]},"formField":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"label":{"type":"string","description":"Human readable label authored for the field. Falls back to the field key when absent."},"required":{"type":"boolean"},"minLength":{"type":"number"},"maxLength":{"type":"number"},"pattern":{"type":"string","nullable":true},"min":{"type":"number"},"max":{"type":"number"},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]}},"multiple":{"type":"boolean"},"maxSize":{"type":"number"},"accept":{"type":"array","items":{"type":"string"}},"order":{"type":"number"}}},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["webhook"]},"url":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"to":{"type":"string"},"subject":{"type":"string"},"templateId":{"type":"string"}},"required":["type","to","subject"]}]}},"successBehavior":{"$ref":"#/components/schemas/SuccessBehavior"},"consentFieldKey":{"type":"string","description":"Key of the form field that carries the GDPR consent. Points at a field with type \"checkbox\" in the same form definition."},"consentBySubmit":{"type":"boolean","description":"Whether GDPR consent is given by submitting the form. Set instead of consentFieldKey on forms that show the consent text without a consent checkbox."},"visitorEmail":{"type":"object","properties":{"visitorEmailFieldKey":{"type":"string","description":"Key of the form field whose submitted value carries the visitor email address. Points at a field able to hold an email address in the same form definition."},"templateId":{"type":"string","description":"Id of the email template sent to the visitor."}},"required":["visitorEmailFieldKey"],"description":"Configuration of the email sent to the visitor after a successful submit. Absent when no visitor email is configured."}}}]},"custom":{"type":"object","additionalProperties":{"nullable":true},"description":"custom user metadata (for example, import description)"},"dataGuard":{"type":"object","properties":{"version":{"type":"number","enum":[1],"description":"Data guard schema version."},"enabled":{"type":"boolean","description":"Whether the guard is active. Owned outside the inspector section that edits the rest of this structure."},"type":{"type":"string","enum":["app"],"description":"Consumer kind. Placeholder — currently always \"app\"."},"data":{"type":"object","properties":{"collection":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string","description":"Target collection id this entry exposes to the frontend."},"columns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may project. Empty or missing means nothing is exposed — this is an allowlist, not a projection convenience."},"sortColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may sort by. Empty or missing means nothing is allowed."},"filterColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may filter by. Empty or missing means nothing is allowed."},"maxItems":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Upper bound on the number of items the frontend may request."},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]},"description":"Filters always applied on top of any frontend-supplied filter."}},"required":["type","collectionId"]},"description":"Collection entries keyed by a user-defined key."}},"required":["collection"]}},"required":["version","enabled","type","data"],"description":"Frontend data exposure allowlist for this node."}},"additionalProperties":{"nullable":true},"description":"Editor metadata for this node: cms element type, form-field definition, and custom notes (e.g. import description)."},"styleRole":{"type":"string","description":"Semantic style role, e.g. 'role_card'. Makes the node inherit the styleguide entry elementStyles[role], above its tag styles and below its own styleOverrides. Reuse one role's styling across many nodes."},"styleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for this node. Maps style slots ('color.bg', 'padding.top', 'font-size', …) to a StyleRef. Layers: default / breakpoints / containers; each has a base slot map and optional per-state (hover, focus) maps. A StyleRef is one of three variants: token (preferred) — {type:'token', scope:'project'|'primitive', key}, a design token by scope+key; pick from the design scale so the site stays consistent. keyword — {type:'keyword', value:'auto'}, a CSS keyword like 'auto' or 'inherit'. value — {type:'value', value:'25px'}, a raw CSS literal, last resort. Example: {\"default\":{\"base\":{\"color.bg\":{\"type\":\"token\",\"scope\":\"project\",\"key\":\"surface.primary\"}}}}."},"instanceStyleProps":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleOverrides"}}],"description":"Symbol-instance style overrides keyed by inner-node style role. Symbol nodes only. Only points exposed by the symbol design interface survive resolution."},"schemeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","description":"Color-scheme slug applied to this node and its subtree, emitted as data-scheme=\"<slug>\". Selects a named scheme that overrides project-scope color tokens for the subtree."},"type":{"type":"string","enum":["slotFill"]},"content":{"nullable":true},"name":{"type":"string","description":"Name of the slot this content fills, inside a symbol instance."},"itemId":{"type":"string","description":"Optional id of the item this slot fill belongs to."},"children":{"type":"array","items":{"type":"string"},"description":"Ids of this node's child nodes, in render order."}},"required":["id","tag","attrs","classes","type","name","children"],"description":"Named content container inside a symbol instance"},{"type":"object","properties":{"id":{"type":"string","description":"Unique id of this node within the document."},"tag":{"type":"string","description":"HTML tag of the rendered element, e.g. 'div', 'h1', 'section'. Omitted on symbol nodes."},"attrs":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"nullable":true}}],"description":"HTML attributes for element nodes (e.g. {\"href\":\"/about\"}); component props for non-element nodes such as symbols."},"classes":{"type":"array","items":{"type":"string"},"description":"Arbitrary utility classes written directly into the element's HTML class attribute. Use ONLY for one-off classes that have no token (e.g. Tailwind arbitrary values like 'gap-[2rem]', or 'prose'). All token styling — color, spacing, typography, radius, … — goes in styleOverrides (per node) or elementStyles (styleguide), NOT here."},"symbolId":{"type":"string","description":"Id of the linked symbol. Symbol nodes only."},"variantId":{"type":"string","description":"Id of the selected symbol variant. Symbol nodes only."},"binding":{"type":"object","additionalProperties":{"anyOf":[{"type":"array","items":{"anyOf":[{"type":"string","enum":["file"]},{"type":"string"},{"anyOf":[{"type":"string","enum":["id"]},{"type":"string","enum":["file_hash"]},{"type":"string","enum":["file_size"]},{"type":"string","enum":["mime_type"]},{"type":"string","enum":["storage_path"]},{"type":"string","enum":["cdn_path"]},{"type":"string","enum":["serve_path"]},{"type":"string","enum":["created_at"]},{"type":"string","enum":["updated_at"]},{"type":"string","enum":["alt_text"]},{"type":"string","enum":["value"]}]}]},"minItems":3,"maxItems":3,"description":"Value from a file: [\"file\", fileId, prop?]. prop selects a file field; \"value\" gives the primary URL (cdn_path, else serve_path)."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["symbol"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Value from a symbol prop: [\"symbol\", propKey, fieldKey]. propKey is the symbol prop; fieldKey selects a field of its value (e.g. \"value\", or a file field like \"cdn_path\")."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["collection"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current collection item: [\"collection\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["each"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current 'each' item: [\"each\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["source"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Item source for an 'each' node or a bound prop: 'static' (items provided on the node), 'collection' (a CMS collection query — id, sort, filters, pagination), 'navigation' (the site navigation tree), or 'locales' (the website's frontend-exposed locales for a language switcher)."}]},"minItems":2,"maxItems":2,"description":"Bind directly to an iterator source: [\"source\", IteratorSource]."}]},"description":"Binds live CMS data into this node instead of static values. Map from a target path on the node (e.g. \"content\", \"attrs.src\", \"classes\") to a value-handle tuple. Kinds: collection, file, symbol, link, each, source. Example: {\"attrs.src\": [\"file\",\"file_5d8e\",\"value\"]} fills src from a file."},"metadata":{"type":"object","properties":{"cmsType":{"type":"string","enum":["spacer"]},"formField":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"label":{"type":"string","description":"Human readable label authored for the field. Falls back to the field key when absent."},"required":{"type":"boolean"},"minLength":{"type":"number"},"maxLength":{"type":"number"},"pattern":{"type":"string","nullable":true},"min":{"type":"number"},"max":{"type":"number"},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]}},"multiple":{"type":"boolean"},"maxSize":{"type":"number"},"accept":{"type":"array","items":{"type":"string"}},"order":{"type":"number"}}},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["webhook"]},"url":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"to":{"type":"string"},"subject":{"type":"string"},"templateId":{"type":"string"}},"required":["type","to","subject"]}]}},"successBehavior":{"$ref":"#/components/schemas/SuccessBehavior"},"consentFieldKey":{"type":"string","description":"Key of the form field that carries the GDPR consent. Points at a field with type \"checkbox\" in the same form definition."},"consentBySubmit":{"type":"boolean","description":"Whether GDPR consent is given by submitting the form. Set instead of consentFieldKey on forms that show the consent text without a consent checkbox."},"visitorEmail":{"type":"object","properties":{"visitorEmailFieldKey":{"type":"string","description":"Key of the form field whose submitted value carries the visitor email address. Points at a field able to hold an email address in the same form definition."},"templateId":{"type":"string","description":"Id of the email template sent to the visitor."}},"required":["visitorEmailFieldKey"],"description":"Configuration of the email sent to the visitor after a successful submit. Absent when no visitor email is configured."}}}]},"custom":{"type":"object","additionalProperties":{"nullable":true},"description":"custom user metadata (for example, import description)"},"dataGuard":{"type":"object","properties":{"version":{"type":"number","enum":[1],"description":"Data guard schema version."},"enabled":{"type":"boolean","description":"Whether the guard is active. Owned outside the inspector section that edits the rest of this structure."},"type":{"type":"string","enum":["app"],"description":"Consumer kind. Placeholder — currently always \"app\"."},"data":{"type":"object","properties":{"collection":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string","description":"Target collection id this entry exposes to the frontend."},"columns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may project. Empty or missing means nothing is exposed — this is an allowlist, not a projection convenience."},"sortColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may sort by. Empty or missing means nothing is allowed."},"filterColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may filter by. Empty or missing means nothing is allowed."},"maxItems":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Upper bound on the number of items the frontend may request."},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]},"description":"Filters always applied on top of any frontend-supplied filter."}},"required":["type","collectionId"]},"description":"Collection entries keyed by a user-defined key."}},"required":["collection"]}},"required":["version","enabled","type","data"],"description":"Frontend data exposure allowlist for this node."}},"additionalProperties":{"nullable":true},"description":"Editor metadata for this node: cms element type, form-field definition, and custom notes (e.g. import description)."},"styleRole":{"type":"string","description":"Semantic style role, e.g. 'role_card'. Makes the node inherit the styleguide entry elementStyles[role], above its tag styles and below its own styleOverrides. Reuse one role's styling across many nodes."},"styleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for this node. Maps style slots ('color.bg', 'padding.top', 'font-size', …) to a StyleRef. Layers: default / breakpoints / containers; each has a base slot map and optional per-state (hover, focus) maps. A StyleRef is one of three variants: token (preferred) — {type:'token', scope:'project'|'primitive', key}, a design token by scope+key; pick from the design scale so the site stays consistent. keyword — {type:'keyword', value:'auto'}, a CSS keyword like 'auto' or 'inherit'. value — {type:'value', value:'25px'}, a raw CSS literal, last resort. Example: {\"default\":{\"base\":{\"color.bg\":{\"type\":\"token\",\"scope\":\"project\",\"key\":\"surface.primary\"}}}}."},"instanceStyleProps":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleOverrides"}}],"description":"Symbol-instance style overrides keyed by inner-node style role. Symbol nodes only. Only points exposed by the symbol design interface survive resolution."},"schemeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","description":"Color-scheme slug applied to this node and its subtree, emitted as data-scheme=\"<slug>\". Selects a named scheme that overrides project-scope color tokens for the subtree."},"type":{"type":"string","enum":["element"]},"content":{"nullable":true},"children":{"type":"array","items":{"type":"string"},"description":"Ids of this node's child nodes, in render order."}},"required":["id","tag","attrs","classes","type","children"],"description":"Regular node"},{"type":"object","properties":{"id":{"type":"string","description":"Unique id of this node within the document."},"tag":{"type":"string","description":"html element tag (omitted on symbol nodes; equals 'symbol')"},"attrs":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"nullable":true}}],"description":"Static HTML attributes for element nodes (e.g. {\"href\":\"/about\"}); component props for non-element nodes such as symbols. Static literal values only — never value-handle tuples or any dynamic references. To bind dynamic data (CMS fields, files, links) to an attr or prop, use the binding field instead; binding targets the attr/prop by path, e.g. attrs.<name>."},"classes":{"type":"array","items":{"type":"string"},"description":"Arbitrary utility classes written directly into the element's HTML class attribute. Use ONLY for one-off classes that have no token (e.g. Tailwind arbitrary values like 'gap-[2rem]', or 'prose'). All token styling — color, spacing, typography, radius, … — goes in styleOverrides (per node) or elementStyles (styleguide), NOT here."},"symbolId":{"type":"string","description":"Id of the linked symbol. Symbol nodes only."},"variantId":{"type":"string","description":"Id of the selected symbol variant. Symbol nodes only."},"binding":{"type":"object","additionalProperties":{"anyOf":[{"type":"array","items":{"anyOf":[{"type":"string","enum":["file"]},{"type":"string"},{"anyOf":[{"type":"string","enum":["id"]},{"type":"string","enum":["file_hash"]},{"type":"string","enum":["file_size"]},{"type":"string","enum":["mime_type"]},{"type":"string","enum":["storage_path"]},{"type":"string","enum":["cdn_path"]},{"type":"string","enum":["serve_path"]},{"type":"string","enum":["created_at"]},{"type":"string","enum":["updated_at"]},{"type":"string","enum":["alt_text"]},{"type":"string","enum":["value"]}]}]},"minItems":3,"maxItems":3,"description":"Value from a file: [\"file\", fileId, prop?]. prop selects a file field; \"value\" gives the primary URL (cdn_path, else serve_path)."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["symbol"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Value from a symbol prop: [\"symbol\", propKey, fieldKey]. propKey is the symbol prop; fieldKey selects a field of its value (e.g. \"value\", or a file field like \"cdn_path\")."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["collection"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current collection item: [\"collection\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["each"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current 'each' item: [\"each\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["source"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Item source for an 'each' node or a bound prop: 'static' (items provided on the node), 'collection' (a CMS collection query — id, sort, filters, pagination), 'navigation' (the site navigation tree), or 'locales' (the website's frontend-exposed locales for a language switcher)."}]},"minItems":2,"maxItems":2,"description":"Bind directly to an iterator source: [\"source\", IteratorSource]."}]},"description":"Binds live CMS data into this node instead of static values. Map from a target path on the node (e.g. \"content\", \"attrs.src\", \"classes\") to a value-handle tuple. Kinds: collection, file, symbol, link, each, source. Example: {\"attrs.src\": [\"file\",\"file_5d8e\",\"value\"]} fills src from a file."},"metadata":{"type":"object","properties":{"cmsType":{"type":"string","enum":["spacer"]},"formField":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"label":{"type":"string","description":"Human readable label authored for the field. Falls back to the field key when absent."},"required":{"type":"boolean"},"minLength":{"type":"number"},"maxLength":{"type":"number"},"pattern":{"type":"string","nullable":true},"min":{"type":"number"},"max":{"type":"number"},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]}},"multiple":{"type":"boolean"},"maxSize":{"type":"number"},"accept":{"type":"array","items":{"type":"string"}},"order":{"type":"number"}}},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["webhook"]},"url":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"to":{"type":"string"},"subject":{"type":"string"},"templateId":{"type":"string"}},"required":["type","to","subject"]}]}},"successBehavior":{"$ref":"#/components/schemas/SuccessBehavior"},"consentFieldKey":{"type":"string","description":"Key of the form field that carries the GDPR consent. Points at a field with type \"checkbox\" in the same form definition."},"consentBySubmit":{"type":"boolean","description":"Whether GDPR consent is given by submitting the form. Set instead of consentFieldKey on forms that show the consent text without a consent checkbox."},"visitorEmail":{"type":"object","properties":{"visitorEmailFieldKey":{"type":"string","description":"Key of the form field whose submitted value carries the visitor email address. Points at a field able to hold an email address in the same form definition."},"templateId":{"type":"string","description":"Id of the email template sent to the visitor."}},"required":["visitorEmailFieldKey"],"description":"Configuration of the email sent to the visitor after a successful submit. Absent when no visitor email is configured."}}}]},"custom":{"type":"object","additionalProperties":{"nullable":true},"description":"custom user metadata (for example, import description)"},"dataGuard":{"type":"object","properties":{"version":{"type":"number","enum":[1],"description":"Data guard schema version."},"enabled":{"type":"boolean","description":"Whether the guard is active. Owned outside the inspector section that edits the rest of this structure."},"type":{"type":"string","enum":["app"],"description":"Consumer kind. Placeholder — currently always \"app\"."},"data":{"type":"object","properties":{"collection":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string","description":"Target collection id this entry exposes to the frontend."},"columns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may project. Empty or missing means nothing is exposed — this is an allowlist, not a projection convenience."},"sortColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may sort by. Empty or missing means nothing is allowed."},"filterColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may filter by. Empty or missing means nothing is allowed."},"maxItems":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Upper bound on the number of items the frontend may request."},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]},"description":"Filters always applied on top of any frontend-supplied filter."}},"required":["type","collectionId"]},"description":"Collection entries keyed by a user-defined key."}},"required":["collection"]}},"required":["version","enabled","type","data"],"description":"Frontend data exposure allowlist for this node."}},"additionalProperties":{"nullable":true},"description":"Editor metadata for this node: cms element type, form-field definition, and custom notes (e.g. import description)."},"styleRole":{"type":"string","description":"Semantic style role, e.g. 'role_card'. Makes the node inherit the styleguide entry elementStyles[role], above its tag styles and below its own styleOverrides. Reuse one role's styling across many nodes."},"styleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for this node. Maps style slots ('color.bg', 'padding.top', 'font-size', …) to a StyleRef. Layers: default / breakpoints / containers; each has a base slot map and optional per-state (hover, focus) maps. A StyleRef is one of three variants: token (preferred) — {type:'token', scope:'project'|'primitive', key}, a design token by scope+key; pick from the design scale so the site stays consistent. keyword — {type:'keyword', value:'auto'}, a CSS keyword like 'auto' or 'inherit'. value — {type:'value', value:'25px'}, a raw CSS literal, last resort. Example: {\"default\":{\"base\":{\"color.bg\":{\"type\":\"token\",\"scope\":\"project\",\"key\":\"surface.primary\"}}}}."},"instanceStyleProps":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleOverrides"}}],"description":"Symbol-instance style overrides keyed by inner-node style role. Symbol nodes only. Only points exposed by the symbol design interface survive resolution."},"schemeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","description":"Color-scheme slug applied to this node and its subtree, emitted as data-scheme=\"<slug>\". Selects a named scheme that overrides project-scope color tokens for the subtree."},"type":{"type":"string","enum":["symbol"]},"content":{"nullable":true},"source":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"iterator source (symbol nodes only)"},"children":{"type":"array","items":{"type":"string"},"description":"Ids of this node's child nodes, in render order."}},"required":["id","attrs","classes","type","children"],"description":"Symbol instance node"},{"type":"object","properties":{"id":{"type":"string","description":"Unique id of this node within the document."},"tag":{"type":"string"},"attrs":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"nullable":true}}],"description":"HTML attributes for element nodes (e.g. {\"href\":\"/about\"}); component props for non-element nodes such as symbols."},"classes":{"type":"array","items":{"type":"string"}},"symbolId":{"type":"string","description":"Id of the linked symbol. Symbol nodes only."},"variantId":{"type":"string","description":"Id of the selected symbol variant. Symbol nodes only."},"binding":{"type":"object","additionalProperties":{"anyOf":[{"type":"array","items":{"anyOf":[{"type":"string","enum":["file"]},{"type":"string"},{"anyOf":[{"type":"string","enum":["id"]},{"type":"string","enum":["file_hash"]},{"type":"string","enum":["file_size"]},{"type":"string","enum":["mime_type"]},{"type":"string","enum":["storage_path"]},{"type":"string","enum":["cdn_path"]},{"type":"string","enum":["serve_path"]},{"type":"string","enum":["created_at"]},{"type":"string","enum":["updated_at"]},{"type":"string","enum":["alt_text"]},{"type":"string","enum":["value"]}]}]},"minItems":3,"maxItems":3,"description":"Value from a file: [\"file\", fileId, prop?]. prop selects a file field; \"value\" gives the primary URL (cdn_path, else serve_path)."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["symbol"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Value from a symbol prop: [\"symbol\", propKey, fieldKey]. propKey is the symbol prop; fieldKey selects a field of its value (e.g. \"value\", or a file field like \"cdn_path\")."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["collection"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current collection item: [\"collection\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["each"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current 'each' item: [\"each\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["source"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Item source for an 'each' node or a bound prop: 'static' (items provided on the node), 'collection' (a CMS collection query — id, sort, filters, pagination), 'navigation' (the site navigation tree), or 'locales' (the website's frontend-exposed locales for a language switcher)."}]},"minItems":2,"maxItems":2,"description":"Bind directly to an iterator source: [\"source\", IteratorSource]."}]},"description":"Binds live CMS data into this node instead of static values. Map from a target path on the node (e.g. \"content\", \"attrs.src\", \"classes\") to a value-handle tuple. Kinds: collection, file, symbol, link, each, source. Example: {\"attrs.src\": [\"file\",\"file_5d8e\",\"value\"]} fills src from a file."},"metadata":{"type":"object","properties":{"cmsType":{"type":"string","enum":["spacer"]},"formField":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"label":{"type":"string","description":"Human readable label authored for the field. Falls back to the field key when absent."},"required":{"type":"boolean"},"minLength":{"type":"number"},"maxLength":{"type":"number"},"pattern":{"type":"string","nullable":true},"min":{"type":"number"},"max":{"type":"number"},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]}},"multiple":{"type":"boolean"},"maxSize":{"type":"number"},"accept":{"type":"array","items":{"type":"string"}},"order":{"type":"number"}}},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["webhook"]},"url":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"to":{"type":"string"},"subject":{"type":"string"},"templateId":{"type":"string"}},"required":["type","to","subject"]}]}},"successBehavior":{"$ref":"#/components/schemas/SuccessBehavior"},"consentFieldKey":{"type":"string","description":"Key of the form field that carries the GDPR consent. Points at a field with type \"checkbox\" in the same form definition."},"consentBySubmit":{"type":"boolean","description":"Whether GDPR consent is given by submitting the form. Set instead of consentFieldKey on forms that show the consent text without a consent checkbox."},"visitorEmail":{"type":"object","properties":{"visitorEmailFieldKey":{"type":"string","description":"Key of the form field whose submitted value carries the visitor email address. Points at a field able to hold an email address in the same form definition."},"templateId":{"type":"string","description":"Id of the email template sent to the visitor."}},"required":["visitorEmailFieldKey"],"description":"Configuration of the email sent to the visitor after a successful submit. Absent when no visitor email is configured."}}}]},"custom":{"type":"object","additionalProperties":{"nullable":true},"description":"custom user metadata (for example, import description)"},"dataGuard":{"type":"object","properties":{"version":{"type":"number","enum":[1],"description":"Data guard schema version."},"enabled":{"type":"boolean","description":"Whether the guard is active. Owned outside the inspector section that edits the rest of this structure."},"type":{"type":"string","enum":["app"],"description":"Consumer kind. Placeholder — currently always \"app\"."},"data":{"type":"object","properties":{"collection":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string","description":"Target collection id this entry exposes to the frontend."},"columns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may project. Empty or missing means nothing is exposed — this is an allowlist, not a projection convenience."},"sortColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may sort by. Empty or missing means nothing is allowed."},"filterColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may filter by. Empty or missing means nothing is allowed."},"maxItems":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Upper bound on the number of items the frontend may request."},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]},"description":"Filters always applied on top of any frontend-supplied filter."}},"required":["type","collectionId"]},"description":"Collection entries keyed by a user-defined key."}},"required":["collection"]}},"required":["version","enabled","type","data"],"description":"Frontend data exposure allowlist for this node."}},"additionalProperties":{"nullable":true},"description":"Editor metadata for this node: cms element type, form-field definition, and custom notes (e.g. import description)."},"styleRole":{"type":"string","description":"Semantic style role, e.g. 'role_card'. Makes the node inherit the styleguide entry elementStyles[role], above its tag styles and below its own styleOverrides. Reuse one role's styling across many nodes."},"styleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for this node. Maps style slots ('color.bg', 'padding.top', 'font-size', …) to a StyleRef. Layers: default / breakpoints / containers; each has a base slot map and optional per-state (hover, focus) maps. A StyleRef is one of three variants: token (preferred) — {type:'token', scope:'project'|'primitive', key}, a design token by scope+key; pick from the design scale so the site stays consistent. keyword — {type:'keyword', value:'auto'}, a CSS keyword like 'auto' or 'inherit'. value — {type:'value', value:'25px'}, a raw CSS literal, last resort. Example: {\"default\":{\"base\":{\"color.bg\":{\"type\":\"token\",\"scope\":\"project\",\"key\":\"surface.primary\"}}}}."},"instanceStyleProps":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleOverrides"}}],"description":"Symbol-instance style overrides keyed by inner-node style role. Symbol nodes only. Only points exposed by the symbol design interface survive resolution."},"schemeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","description":"Color-scheme slug applied to this node and its subtree, emitted as data-scheme=\"<slug>\". Selects a named scheme that overrides project-scope color tokens for the subtree."},"type":{"nullable":true},"content":{"nullable":true},"children":{"type":"array","items":{"type":"string"},"description":"Ids of this node's child nodes, in render order."}},"required":["id","attrs","children"],"description":"Document root container (absent/null type)"},{"type":"object","properties":{"id":{"type":"string","description":"Unique id of this node within the document."},"tag":{"type":"string","description":"HTML tag of the rendered element, e.g. 'div', 'h1', 'section'. Omitted on symbol nodes."},"attrs":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"nullable":true}}],"description":"Static HTML attributes for element nodes (e.g. {\"href\":\"/about\"}); component props for non-element nodes such as symbols. Static literal values only — never value-handle tuples or any dynamic references. To bind dynamic data (CMS fields, files, links) to an attr or prop, use the binding field instead; binding targets the attr/prop by path, e.g. attrs.<name>."},"classes":{"type":"array","items":{"type":"string"},"description":"Arbitrary utility classes written directly into the element's HTML class attribute. Use ONLY for one-off classes that have no token (e.g. Tailwind arbitrary values like 'gap-[2rem]', or 'prose'). All token styling — color, spacing, typography, radius, … — goes in styleOverrides (per node) or elementStyles (styleguide), NOT here."},"symbolId":{"type":"string","description":"Id of the linked symbol. Symbol nodes only."},"variantId":{"type":"string","description":"Id of the selected symbol variant. Symbol nodes only."},"binding":{"type":"object","additionalProperties":{"anyOf":[{"type":"array","items":{"anyOf":[{"type":"string","enum":["file"]},{"type":"string"},{"anyOf":[{"type":"string","enum":["id"]},{"type":"string","enum":["file_hash"]},{"type":"string","enum":["file_size"]},{"type":"string","enum":["mime_type"]},{"type":"string","enum":["storage_path"]},{"type":"string","enum":["cdn_path"]},{"type":"string","enum":["serve_path"]},{"type":"string","enum":["created_at"]},{"type":"string","enum":["updated_at"]},{"type":"string","enum":["alt_text"]},{"type":"string","enum":["value"]}]}]},"minItems":3,"maxItems":3,"description":"Value from a file: [\"file\", fileId, prop?]. prop selects a file field; \"value\" gives the primary URL (cdn_path, else serve_path)."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["symbol"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Value from a symbol prop: [\"symbol\", propKey, fieldKey]. propKey is the symbol prop; fieldKey selects a field of its value (e.g. \"value\", or a file field like \"cdn_path\")."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["collection"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current collection item: [\"collection\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["link"]},{"type":"string","enum":["page"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"A CMS link: [\"link\", type, id]. type is page | collection_item | file; id is the target id."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["each"]},{"type":"string"}]},"minItems":3,"maxItems":3,"description":"Field of the current 'each' item: [\"each\", field, subField?]. subField reads a nested field when the value is an object."},{"type":"array","items":{"anyOf":[{"type":"string","enum":["source"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["static"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string"},"name":{"type":"string"},"params":{"type":"object","properties":{"_beFix":{"nullable":true},"limit":{"type":"number"},"paginationType":{"type":"string","enum":["numbered"]},"page":{"type":"number"},"itemsPerPage":{"type":"number"},"sort":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"direction":{"type":"string","enum":["asc","desc"]}},"required":["field","direction"]}},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]}},"itemId":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["navigation"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["locales"]},"variant":{"type":"boolean","description":"When bound directly to a node, `variant: true` resolves to a symbol variant id ('none' | 'toggle' | 'dropdown') chosen by the number of exposed locales, instead of the locale array, driving the language switcher's layout. Ignored by 'each' iteration."}},"required":["type"]}],"description":"Item source for an 'each' node or a bound prop: 'static' (items provided on the node), 'collection' (a CMS collection query — id, sort, filters, pagination), 'navigation' (the site navigation tree), or 'locales' (the website's frontend-exposed locales for a language switcher)."}]},"minItems":2,"maxItems":2,"description":"Bind directly to an iterator source: [\"source\", IteratorSource]."}]},"description":"Binds live CMS data into this node instead of static values. Map from a target path on the node (e.g. \"content\", \"attrs.src\", \"classes\") to a value-handle tuple. Kinds: collection, file, symbol, link, each, source. Example: {\"attrs.src\": [\"file\",\"file_5d8e\",\"value\"]} fills src from a file."},"metadata":{"type":"object","properties":{"cmsType":{"type":"string","enum":["spacer"]},"formField":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"label":{"type":"string","description":"Human readable label authored for the field. Falls back to the field key when absent."},"required":{"type":"boolean"},"minLength":{"type":"number"},"maxLength":{"type":"number"},"pattern":{"type":"string","nullable":true},"min":{"type":"number"},"max":{"type":"number"},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]}},"multiple":{"type":"boolean"},"maxSize":{"type":"number"},"accept":{"type":"array","items":{"type":"string"}},"order":{"type":"number"}}},{"type":"object","properties":{"actions":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["webhook"]},"url":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"to":{"type":"string"},"subject":{"type":"string"},"templateId":{"type":"string"}},"required":["type","to","subject"]}]}},"successBehavior":{"$ref":"#/components/schemas/SuccessBehavior"},"consentFieldKey":{"type":"string","description":"Key of the form field that carries the GDPR consent. Points at a field with type \"checkbox\" in the same form definition."},"consentBySubmit":{"type":"boolean","description":"Whether GDPR consent is given by submitting the form. Set instead of consentFieldKey on forms that show the consent text without a consent checkbox."},"visitorEmail":{"type":"object","properties":{"visitorEmailFieldKey":{"type":"string","description":"Key of the form field whose submitted value carries the visitor email address. Points at a field able to hold an email address in the same form definition."},"templateId":{"type":"string","description":"Id of the email template sent to the visitor."}},"required":["visitorEmailFieldKey"],"description":"Configuration of the email sent to the visitor after a successful submit. Absent when no visitor email is configured."}}}]},"custom":{"type":"object","additionalProperties":{"nullable":true},"description":"custom user metadata (for example, import description)"},"dataGuard":{"type":"object","properties":{"version":{"type":"number","enum":[1],"description":"Data guard schema version."},"enabled":{"type":"boolean","description":"Whether the guard is active. Owned outside the inspector section that edits the rest of this structure."},"type":{"type":"string","enum":["app"],"description":"Consumer kind. Placeholder — currently always \"app\"."},"data":{"type":"object","properties":{"collection":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["collection"]},"collectionId":{"type":"string","description":"Target collection id this entry exposes to the frontend."},"columns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may project. Empty or missing means nothing is exposed — this is an allowlist, not a projection convenience."},"sortColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may sort by. Empty or missing means nothing is allowed."},"filterColumns":{"type":"array","items":{"type":"string"},"description":"Columns the frontend may filter by. Empty or missing means nothing is allowed."},"maxItems":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Upper bound on the number of items the frontend may request."},"filters":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","like","gt","lt","in"]},"value":{"nullable":true}},"required":["field","op"]},"description":"Filters always applied on top of any frontend-supplied filter."}},"required":["type","collectionId"]},"description":"Collection entries keyed by a user-defined key."}},"required":["collection"]}},"required":["version","enabled","type","data"],"description":"Frontend data exposure allowlist for this node."}},"additionalProperties":{"nullable":true},"description":"Editor metadata for this node: cms element type, form-field definition, and custom notes (e.g. import description)."},"styleRole":{"type":"string","description":"Semantic style role, e.g. 'role_card'. Makes the node inherit the styleguide entry elementStyles[role], above its tag styles and below its own styleOverrides. Reuse one role's styling across many nodes."},"styleOverrides":{"type":"object","properties":{"default":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"$ref":"#/components/schemas/StyleLayer"}]},"breakpoints":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}},"containers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleLayer"}}},"required":["default","breakpoints","containers"],"description":"Token styling for this node. Maps style slots ('color.bg', 'padding.top', 'font-size', …) to a StyleRef. Layers: default / breakpoints / containers; each has a base slot map and optional per-state (hover, focus) maps. A StyleRef is one of three variants: token (preferred) — {type:'token', scope:'project'|'primitive', key}, a design token by scope+key; pick from the design scale so the site stays consistent. keyword — {type:'keyword', value:'auto'}, a CSS keyword like 'auto' or 'inherit'. value — {type:'value', value:'25px'}, a raw CSS literal, last resort. Example: {\"default\":{\"base\":{\"color.bg\":{\"type\":\"token\",\"scope\":\"project\",\"key\":\"surface.primary\"}}}}."},"instanceStyleProps":{"anyOf":[{"type":"array","items":{"anyOf":[]},"minItems":0,"maxItems":0},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/StyleOverrides"}}],"description":"Symbol-instance style overrides keyed by inner-node style role. Symbol nodes only. Only points exposed by the symbol design interface survive resolution."},"schemeId":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","description":"Color-scheme slug applied to this node and its subtree, emitted as data-scheme=\"<slug>\". Selects a named scheme that overrides project-scope color tokens for the subtree."},"type":{"type":"string","enum":["outlet"]},"content":{"nullable":true},"documentName":{"type":"string","description":"Name of the CollectionDocument this outlet renders. Must match a CollectionDocument.name on the page's collection."},"children":{"type":"array","items":{"type":"string"},"description":"Ids of this node's child nodes, in render order."}},"required":["id","tag","attrs","classes","type","documentName","children"],"description":"Renders a CollectionItemDocument inline at this position"}]},"SetColorOp":{"type":"object","properties":{"type":{"type":"string","enum":["setColor"]},"key":{"type":"string","minLength":1},"name":{"type":"string","minLength":1},"baseColor":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","key","name","baseColor"],"description":"Create-or-update (upsert) a color token by its caller-supplied `key`. On first use it creates a palette; sent again with the same key it updates the base color and regenerates shades — so the same op both creates a token and recolors it site-wide.","example":{"type":"setColor","key":"brand","name":"Brand","baseColor":"#0066cc"}},"SetFontOp":{"type":"object","properties":{"type":{"type":"string","enum":["setFont"]},"key":{"type":"string","minLength":1},"family":{"type":"string","minLength":1},"name":{"type":"string","minLength":1},"source":{"type":"string","enum":["google","custom","system"]},"category":{"type":"string","minLength":1},"fontWeights":{"type":"array","items":{"type":"string"}},"fallback":{"type":"string"}},"required":["type","key","family","name","source"],"description":"Create-or-update (upsert) a font by its caller-supplied `key` (becomes the font id). A font on its own is not usable on a node — pair it with a setTypography op that references this key. On an update, omitted optional fields keep their stored value. Stored font files (weightFiles) are kept for the weights still listed in `fontWeights` — narrowing `fontWeights` drops the removed weights' files — and can only be set through the v2 design apply API.","example":{"type":"setFont","key":"inter","family":"Inter","name":"Inter","source":"google"}},"SetTypographyOp":{"type":"object","properties":{"type":{"type":"string","enum":["setTypography"]},"key":{"type":"string","minLength":1},"name":{"type":"string","minLength":1},"fontKey":{"type":"string","minLength":1},"role":{"type":"string","enum":["heading","body","button","caption"]}},"required":["type","key","name","fontKey"],"description":"Create-or-update (upsert) a typography token by its caller-supplied `key`. `fontKey` must reference a font that already exists or is created earlier in the same batch. Returns the ready-to-use node class `font-<key>`.","example":{"type":"setTypography","key":"heading","name":"Heading","fontKey":"inter"}},"DeleteColorOp":{"type":"object","properties":{"type":{"type":"string","enum":["deleteColor"]},"key":{"type":"string","minLength":1}},"required":["type","key"],"description":"Remove a color token by its `key`. Idempotent — deleting an absent key succeeds as a no-op. The dead shade utilities are marked for removal on the next CSS rebuild.","example":{"type":"deleteColor","key":"brand"}},"DeleteFontOp":{"type":"object","properties":{"type":{"type":"string","enum":["deleteFont"]},"key":{"type":"string","minLength":1}},"required":["type","key"],"description":"Remove a font token by its `key`. Idempotent. Rejected with 400 if a typography token still references the font — delete or repoint that typography first (an earlier op in the same batch counts).","example":{"type":"deleteFont","key":"lobster"}},"DeleteTypographyOp":{"type":"object","properties":{"type":{"type":"string","enum":["deleteTypography"]},"key":{"type":"string","minLength":1}},"required":["type","key"],"description":"Remove a typography token by its `key`. Idempotent. The font it referenced is left in place — delete it separately with deleteFont.","example":{"type":"deleteTypography","key":"heading"}},"SetProseStyleOp":{"type":"object","properties":{"type":{"type":"string","enum":["setProseStyle"]},"selector":{"type":"string","minLength":1},"classes":{"type":"array","items":{"type":"string","pattern":"^\\S+$"}}},"required":["type","selector","classes"],"description":"Replace the full class list of a prose/rich-text element, keyed by `selector` (upsert). `selector` is restricted to a fixed allowlist of prose elements (root, h1-h6, p, a, ul, ol, li, blockquote, strong, em, s, u, code, pre, hr, img); anything else → 400. `classes: []` clears all styling for the selector. Classes are opaque, whitespace-free strings and are NOT checked against existing tokens (a deleted token leaves a dead class here).","example":{"type":"setProseStyle","selector":"h1","classes":["font-heading","text-6xl"]}},"SetColorOpV2":{"type":"object","properties":{"type":{"type":"string","enum":["setColor"]},"key":{"type":"string","pattern":"^[a-z0-9-]+$"},"name":{"type":"string","minLength":1},"baseColor":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","key","name","baseColor"],"description":"Create-or-update a color the same way the CMS color picker does: upserts the palette (name + baseColor + generated shade scale) in designVariables AND derives the `color.<key>-<shade>` tokens (plus `color.<key>-base`) into the project layer. Returns ready-to-use `bg-`/`text-` node classes. This is the supported way to create color tokens.","example":{"type":"setColor","key":"brand","name":"Brand","baseColor":"#0066cc"}},"SetVariableOp":{"type":"object","properties":{"type":{"type":"string","enum":["setVariable"]},"variableType":{"type":"string","enum":["spacing","radius","shadow","font-family","font-size"]},"key":{"type":"string","pattern":"^[a-z0-9-]+(\\.[a-z0-9-]+)*$"},"name":{"type":"string","minLength":1},"value":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"object","properties":{"$ref":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"]},"key":{"type":"string","minLength":1}},"required":["type","scope","key"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}]}},"required":["$ref"]}]}},"required":["type","variableType","key","name","value"],"description":"Create-or-update a design variable the same way the CMS Variables tab does: registers it in the variable group of `variableType` (creating the group if needed) AND sets its token value in the project layer. Registered variables survive the CMS design-model cleanup. Valid variableTypes and primitive token keys: GET /v2/design/capabilities.","example":{"type":"setVariable","variableType":"spacing","key":"spacing.card-pad","name":"Card padding","value":"1.5rem"}},"SetFontOpV2":{"type":"object","properties":{"type":{"type":"string","enum":["setFont"]},"key":{"type":"string","minLength":1},"family":{"type":"string","minLength":1},"name":{"type":"string","minLength":1},"source":{"type":"string","enum":["google","custom","system"]},"category":{"type":"string","minLength":1},"fontWeights":{"type":"array","items":{"type":"string"}},"fallback":{"type":"string"},"weightFiles":{"type":"object","additionalProperties":{"type":"string","minLength":1},"description":"Maps a weight key to the files-service `fi_…` id of a woff2 upload. Key = a 3-digit weight, optionally followed by \"italic\" (e.g. \"400\", \"700italic\"); each key must also appear in `fontWeights` verbatim — italic variants are listed as-is, e.g. \"700italic\" needs \"700italic\" in `fontWeights`, not just \"700\". Replaces the whole map when present; `{}` clears it; omit to keep the existing value."}},"required":["type","key","family","name","source"],"description":"Create-or-update (upsert) a font by its caller-supplied `key` (becomes the font id). A font on its own is not usable on a node — pair it with a setTypography op that references this key.","example":{"type":"setFont","key":"brand-sans","family":"Brand Sans","name":"Brand Sans","source":"custom","fontWeights":["400","700","700italic"],"weightFiles":{"400":"fi_abc123","700italic":"fi_def456"}}},"SetTypographyOpV2":{"type":"object","properties":{"type":{"type":"string","enum":["setTypography"]},"key":{"type":"string","minLength":1},"name":{"type":"string","minLength":1},"fontKey":{"type":"string","minLength":1},"role":{"type":"string","enum":["heading","body","button","caption"]}},"required":["type","key","name","fontKey"],"description":"Create-or-update (upsert) a typography token by its caller-supplied `key`. `fontKey` must reference a font that already exists or is created earlier in the same batch. Returns the ready-to-use node class `font-<key>`.","example":{"type":"setTypography","key":"heading","name":"Heading","fontKey":"brand-sans"}},"SetElementStyleOp":{"type":"object","properties":{"type":{"type":"string","enum":["setElementStyle"]},"selector":{"type":"string","minLength":1},"overrides":{"type":"object","properties":{"default":{"type":"object","properties":{"base":{"type":"object","additionalProperties":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"]},"key":{"type":"string","minLength":1}},"required":["type","scope","key"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}]}},"states":{"type":"object","additionalProperties":{"type":"object","additionalProperties":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"]},"key":{"type":"string","minLength":1}},"required":["type","scope","key"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}]}}}}},"breakpoints":{"type":"object","additionalProperties":{"type":"object","properties":{"base":{"type":"object","additionalProperties":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"]},"key":{"type":"string","minLength":1}},"required":["type","scope","key"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}]}},"states":{"type":"object","additionalProperties":{"type":"object","additionalProperties":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"]},"key":{"type":"string","minLength":1}},"required":["type","scope","key"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}]}}}}}},"containers":{"type":"object","additionalProperties":{"type":"object","properties":{"base":{"type":"object","additionalProperties":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"]},"key":{"type":"string","minLength":1}},"required":["type","scope","key"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}]}},"states":{"type":"object","additionalProperties":{"type":"object","additionalProperties":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"]},"key":{"type":"string","minLength":1}},"required":["type","scope","key"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}]}}}}}}},"required":["default"]}},"required":["type","selector","overrides"],"description":"Replace the global styleguide entry for one HTML element selector (upsert). The whole entry for `selector` is replaced; all other selectors are untouched. Slots hold StyleRefs — token refs resolve through the project → platform → primitive cascade (late binding). Valid slots, states, and primitive token keys: GET /v2/design/capabilities.","example":{"type":"setElementStyle","selector":"h2","overrides":{"default":{"base":{"color.text":{"type":"token","scope":"project","key":"color.primary"}}}}}},"DeleteElementStyleOp":{"type":"object","properties":{"type":{"type":"string","enum":["deleteElementStyle"]},"selector":{"type":"string","minLength":1}},"required":["type","selector"],"description":"Remove the global styleguide entry for one selector. Idempotent — deleting an absent selector succeeds as a no-op.","example":{"type":"deleteElementStyle","selector":"blockquote"}},"CreateThemeOp":{"type":"object","properties":{"type":{"type":"string","enum":["createTheme"]},"name":{"type":"string","minLength":1}},"required":["type"],"description":"Append a new theme (scheme column) the same way the CMS \"add theme\" action does: writes a schemeMeta entry (name + order) and an empty cell map. Returns the new scheme id.","example":{"type":"createTheme","name":"Brand"}},"SetThemeValueOp":{"type":"object","properties":{"type":{"type":"string","enum":["setThemeValue"]},"themeId":{"type":"string","minLength":1},"attribute":{"type":"string","minLength":1},"ref":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"]},"key":{"type":"string","minLength":1}},"required":["type","scope","key"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}]}},"required":["type","themeId","attribute","ref"],"description":"Sets one scheme cell (the .light variant only) for a theme attribute. themeId must already exist (createTheme) and attribute must be a registered theme attribute row, else 400. The ref late-binds: a token ref to a not-yet-defined project key is stored and warned, not rejected.","example":{"type":"setThemeValue","themeId":"scheme-1","attribute":"color.text","ref":{"type":"token","scope":"project","key":"color.primary"}}},"ClearThemeValueOp":{"type":"object","properties":{"type":{"type":"string","enum":["clearThemeValue"]},"themeId":{"type":"string","minLength":1},"attribute":{"type":"string","minLength":1}},"required":["type","themeId","attribute"],"description":"Clears one scheme cell back to inherit (the Style-Guide default). themeId and attribute must exist, else 400.","example":{"type":"clearThemeValue","themeId":"scheme-1","attribute":"color.text"}},"RenameThemeOp":{"type":"object","properties":{"type":{"type":"string","enum":["renameTheme"]},"themeId":{"type":"string","minLength":1},"name":{"type":"string","minLength":1}},"required":["type","themeId","name"],"additionalProperties":false,"description":"Renames a theme column. Only the name changes. A protected base theme (seed light/dark) cannot be renamed → 400. Unknown themeId → 400.","example":{"type":"renameTheme","themeId":"scheme-1","name":"Brand"}},"ReorderThemesOp":{"type":"object","properties":{"type":{"type":"string","enum":["reorderThemes"]},"orderedIds":{"type":"array","items":{"type":"string","minLength":1},"minItems":1}},"required":["type","orderedIds"],"additionalProperties":false,"description":"Reorders every theme column at once. orderedIds must list every existing theme exactly once (set-equal to the current themes), then order becomes the array index. Incomplete/superset/unknown → 400. Exempt from the protected-theme guard.","example":{"type":"reorderThemes","orderedIds":["light","dark","scheme-1"]}},"DuplicateThemeOp":{"type":"object","properties":{"type":{"type":"string","enum":["duplicateTheme"]},"themeId":{"type":"string","minLength":1},"name":{"type":"string","minLength":1}},"required":["type","themeId"],"additionalProperties":false,"description":"Duplicates a theme column, copying its cells and stripping all flags (the copy is always deletable). name defaults to \"<source> copy\". A protected base theme cannot be duplicated → 400. Unknown source → 400.","example":{"type":"duplicateTheme","themeId":"scheme-1","name":"Brand copy"}},"DeleteThemeOp":{"type":"object","properties":{"type":{"type":"string","enum":["deleteTheme"]},"themeId":{"type":"string","minLength":1},"mode":{"type":"string","enum":["hide","purge"]}},"required":["type","themeId"],"additionalProperties":false,"description":"Deletes a theme column. mode 'hide' (default) is a soft delete: the theme is marked hidden but its cells stay so live sites keep resolving. mode 'purge' hard-deletes meta and cells. A protected base theme cannot be deleted in either mode → 400. Unknown themeId → 400.","example":{"type":"deleteTheme","themeId":"scheme-1","mode":"hide"}},"AddThemeAttributeOp":{"type":"object","properties":{"type":{"type":"string","enum":["addThemeAttribute"]},"variableType":{"type":"string","enum":["spacing","radius","shadow","color","font-family","font-size"]},"key":{"type":"string","minLength":1},"name":{"type":"string","minLength":1}},"required":["type","variableType"],"additionalProperties":false,"description":"Adds a theme attribute row (a shared axis every theme column aligns to). variableType is REQUIRED and frozen after create — there is no default. key is optional (the store generates one); a duplicate caller key → 400. The new row lands at order = max+1 with no cells.","example":{"type":"addThemeAttribute","variableType":"color","key":"color.brand","name":"Brand"}},"RenameThemeAttributeOp":{"type":"object","properties":{"type":{"type":"string","enum":["renameThemeAttribute"]},"key":{"type":"string","minLength":1},"name":{"type":"string","minLength":1}},"required":["type","key","name"],"additionalProperties":false,"description":"Renames a theme attribute row. Only the display name changes — the row key is immutable (rekeying would orphan every document's token refs). A protected row → 400. Unknown key → 400.","example":{"type":"renameThemeAttribute","key":"color.brand","name":"Accent"}},"ReorderThemeAttributesOp":{"type":"object","properties":{"type":{"type":"string","enum":["reorderThemeAttributes"]},"orderedKeys":{"type":"array","items":{"type":"string","minLength":1},"minItems":1}},"required":["type","orderedKeys"],"additionalProperties":false,"description":"Reorders every attribute row at once. orderedKeys must list every existing row exactly once (set-equal to the current rows, including soft-deleted ones), then order becomes the array index. Incomplete/superset/unknown → 400. Exempt from the protected guard.","example":{"type":"reorderThemeAttributes","orderedKeys":["color.background","color.text","color.brand"]}},"DeleteThemeAttributeOp":{"type":"object","properties":{"type":{"type":"string","enum":["deleteThemeAttribute"]},"key":{"type":"string","minLength":1},"mode":{"type":"string","enum":["soft","purge"]}},"required":["type","key"],"additionalProperties":false,"description":"Deletes a theme attribute row. mode 'soft' (default) marks the row isDeleted but keeps every scheme cell so live sites keep resolving. mode 'purge' removes the row AND cascades its cell out of every theme column. A protected row → 400 in either mode. Unknown key → 400.","example":{"type":"deleteThemeAttribute","key":"color.brand","mode":"soft"}},"CodeBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1},"name":{"type":"string","minLength":1},"code":{"type":"string","maxLength":65536},"language":{"type":"string","enum":["javascript","html","css"]},"placement":{"type":"string","enum":["header","footer"]},"isCmsVisible":{"type":"boolean"}},"required":["id","name","code","language","placement"],"description":"A snippet of custom code injected into the rendered site head or footer. Ids are minted server-side.","example":{"id":"V1StGXR8_Z5jdHi6B-myT","name":"Analytics","code":"<script>/* … */</script>","language":"javascript","placement":"footer"}},"CodeBlockInput":{"type":"object","properties":{"name":{"type":"string","minLength":1},"code":{"type":"string","maxLength":65536},"language":{"type":"string","enum":["javascript","html","css"]},"placement":{"type":"string","enum":["header","footer"]},"isCmsVisible":{"type":"boolean"}},"required":["name","code","language","placement"]},"CodeBlockPatch":{"type":"object","properties":{"name":{"type":"string","minLength":1},"code":{"type":"string","maxLength":65536},"language":{"type":"string","enum":["javascript","html","css"]},"placement":{"type":"string","enum":["header","footer"]},"isCmsVisible":{"type":"boolean"}}},"InitialSeed":{"type":"object","properties":{"data":{"type":"object","properties":{"designVariables":{"type":"object","additionalProperties":{"nullable":true}},"variableGroupsMeta":{"type":"object","additionalProperties":{"nullable":true}},"variables":{"type":"object","additionalProperties":{"nullable":true}},"schemes":{"type":"object","additionalProperties":{"nullable":true}},"schemeMeta":{"type":"object","additionalProperties":{"nullable":true}},"schemeVariables":{"type":"object","additionalProperties":{"nullable":true}},"projectTokens":{"type":"object","additionalProperties":{"nullable":true}},"elementStyles":{"type":"object","additionalProperties":{"nullable":true}},"classes":{"type":"object","additionalProperties":{"type":"string"}},"codeBlocks":{"type":"object","additionalProperties":{"nullable":true}},"forms":{"type":"object","additionalProperties":{"nullable":true}},"emailSettings":{"type":"object","additionalProperties":{"nullable":true}}},"required":["designVariables","variableGroupsMeta","variables","schemes","schemeMeta","schemeVariables","projectTokens","elementStyles","classes","codeBlocks","forms","emailSettings"]},"pages":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"label":{"type":"string"},"uri":{"type":"string"},"type":{"type":"string","enum":["page"]},"isPublished":{"type":"boolean","default":false},"isProtected":{"type":"boolean","default":false},"isHomepage":{"type":"boolean","default":false},"isUtility":{"type":"boolean","default":false},"document":{"type":"object","properties":{"rootLayoutId":{"type":"string"},"nodes":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/LayoutNode"},"description":"Key/value map of layout nodes in the document, where key is the node ID"}},"required":["rootLayoutId","nodes"]}},"required":["label","type","document"]}}},"required":["data","pages"],"description":"The complete initial seed for a new web: a `data` record (one key per persisted design row — design variables, schemes, scheme meta, scheme variables, variable groups, project tokens, element styles, classes, code blocks, email settings) and seed pages (currently the protected 404 page). Read-only — never written by this endpoint.","example":{"data":{"designVariables":{},"variableGroupsMeta":{},"variables":{},"schemes":{},"schemeMeta":{},"schemeVariables":{},"projectTokens":{},"elementStyles":{},"classes":{},"codeBlocks":{},"forms":{},"emailSettings":{"brandLogo":{"light":null,"dark":null},"signature":{"content":null,"rendered":""},"senderName":"","senderEmail":""}},"pages":[{"name":"page_404","label":"404","uri":"404","type":"page","isPublished":true,"isProtected":true,"isHomepage":false,"isUtility":true,"document":{"nodes":{},"rootLayoutId":"node-0"}}]}},"SeedPage":{"type":"object","properties":{"page":{"type":"object","properties":{"name":{"type":"string"},"label":{"type":"string"},"uri":{"type":"string"},"type":{"type":"string","enum":["page"]},"isPublished":{"type":"boolean","default":false},"isProtected":{"type":"boolean","default":false},"isHomepage":{"type":"boolean","default":false},"isUtility":{"type":"boolean","default":false},"document":{"type":"object","properties":{"rootLayoutId":{"type":"string"},"nodes":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/LayoutNode"},"description":"Key/value map of layout nodes in the document, where key is the node ID"}},"required":["rootLayoutId","nodes"]}},"required":["label","type","document"]}},"required":["page"],"description":"The seed for a single page: the page metadata plus its starting document as flat CMS node JSON. Read-only — never written by these endpoints."}},"parameters":{}},"paths":{"/healthz":{"get":{"tags":["Health"],"summary":"Liveness probe","responses":{"200":{"description":"Service is running","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["ok"]}},"required":["status"]}}}}}}},"/v1/pages/{pageId}/documents/{documentId}/ops":{"post":{"tags":["Documents"],"summary":"Apply a single mutation op to a page document","description":"Applies one op to the page document, serialized per-document via a Valkey lock. Node ids in the payload are regenerated server-side; ops that create a node (addNodes/wrapNode/addSymbol) return the new `rootId` in their ack. Ops that reference a node not present in the document return NODE_NOT_FOUND.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Page id (UUIDv7). Listed under `documents[]` on the page resource in the data service.","example":"019e1cdb-d0c0-7b75-9319-37e3447d0b18"},"required":true,"description":"Page id (UUIDv7). Listed under `documents[]` on the page resource in the data service.","name":"pageId","in":"path"},{"schema":{"type":"string","description":"Document id (UUIDv7). A page has separate `preview` and `published` documents — pick the one you want to edit.","example":"019e1cdb-d0d4-7e2c-ba39-1970107ec5b5"},"required":true,"description":"Document id (UUIDv7). A page has separate `preview` and `published` documents — pick the one you want to edit.","name":"documentId","in":"path"},{"schema":{"type":"string","pattern":"^lng_","description":"Solidpixels-prefixed language id (`lng_…`) scoping the document lookup in the data service. Omitted = the website's default language.","example":"lng_abc123"},"required":false,"description":"Solidpixels-prefixed language id (`lng_…`) scoping the document lookup in the data service. Omitted = the website's default language.","name":"lang","in":"query"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Op"}}}},"responses":{"200":{"description":"Op applied. Returns a minimal `{ \"ok\": true }` ack — the caller already knows the node ids it supplied. Ops that create a node (addNodes/wrapNode/addSymbol) also return the server-generated `rootId` plus an `ids` map from each supplied node id to its regenerated server-side id; follow with a get_subtree if the resulting tree is needed.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"rootId":{"type":"string"},"ids":{"type":"object","additionalProperties":{"type":"string"}}},"required":["ok"]}}}},"400":{"description":"INVALID_OP — request body did not match the op schema, or the op is structurally disallowed (e.g. removeNode targeting the document root)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["INVALID_OP"]},"issues":{"type":"array","items":{"nullable":true}}},"required":["error","issues"]}}}},"401":{"description":"Missing or invalid JWT"},"404":{"description":"NODE_NOT_FOUND — referenced node does not exist (also returned for any op other than addNodes on an empty document). SYMBOL_NOT_FOUND — the symbolId on addSymbol/updateSymbol does not resolve in the catalog. DOCUMENT_NOT_FOUND — the page document does not exist in the data service.","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["NODE_NOT_FOUND"]},"nodeId":{"type":"string"}},"required":["error","nodeId"]},{"type":"object","properties":{"error":{"type":"string","enum":["SYMBOL_NOT_FOUND"]},"symbolId":{"type":"string"}},"required":["error","symbolId"]},{"type":"object","properties":{"error":{"type":"string","enum":["DOCUMENT_NOT_FOUND"]},"documentId":{"type":"string"}},"required":["error","documentId"]}]}}}},"409":{"description":"LOCK_CONTENDED — another writer holds the lock; LOCK_EXPIRING — lock TTL would expire mid-flight, retry","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["LOCK_CONTENDED"]},"documentId":{"type":"string"}},"required":["error","documentId"]},{"type":"object","properties":{"error":{"type":"string","enum":["LOCK_EXPIRING"]},"documentId":{"type":"string"},"remainingMs":{"type":"number"}},"required":["error","documentId","remainingMs"]}]}}}},"422":{"description":"VALIDATION_FAILED — the resulting tree failed structural validation (e.g. cyclic reference, depth, orphan); not persisted","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["VALIDATION_FAILED"]},"details":{"nullable":true}},"required":["error"]}}}},"500":{"description":"LOCK_BACKEND_UNAVAILABLE — Valkey unreachable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["LOCK_BACKEND_UNAVAILABLE"]},"documentId":{"type":"string"}},"required":["error","documentId"]}}}},"502":{"description":"DATA_SERVICE_ERROR — upstream data service failed. SOLIDPIXELS_SERVICE_ERROR — upstream solidpixels service failed while resolving a symbol for addSymbol/updateSymbol.","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["DATA_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]},{"type":"object","properties":{"error":{"type":"string","enum":["SOLIDPIXELS_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]}]}}}}}}},"/v1/pages/{pageId}/documents/{documentId}/nodes/{nodeId}":{"get":{"tags":["Documents"],"summary":"Read a subtree of a page document","description":"Returns the node identified by `nodeId` and a flat map of all its descendants. The full tree shape is recovered by walking `children` from `node`. Unlocked — safe to call concurrently with writers. Returns 404 NODE_NOT_FOUND when the document exists but `nodeId` is not present, and 404 DOCUMENT_NOT_FOUND when the page document itself does not exist.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Page id (UUIDv7). Listed under `documents[]` on the page resource in the data service.","example":"019e1cdb-d0c0-7b75-9319-37e3447d0b18"},"required":true,"description":"Page id (UUIDv7). Listed under `documents[]` on the page resource in the data service.","name":"pageId","in":"path"},{"schema":{"type":"string","description":"Document id (UUIDv7). A page has separate `preview` and `published` documents — pick the one you want to edit.","example":"019e1cdb-d0d4-7e2c-ba39-1970107ec5b5"},"required":true,"description":"Document id (UUIDv7). A page has separate `preview` and `published` documents — pick the one you want to edit.","name":"documentId","in":"path"},{"schema":{"type":"string","description":"Node id within the document tree. Use the document's `rootLayoutId` to fetch the entire tree.","example":"root"},"required":true,"description":"Node id within the document tree. Use the document's `rootLayoutId` to fetch the entire tree.","name":"nodeId","in":"path"},{"schema":{"type":"string","pattern":"^lng_","description":"Solidpixels-prefixed language id (`lng_…`) scoping the document lookup in the data service. Omitted = the website's default language.","example":"lng_abc123"},"required":false,"description":"Solidpixels-prefixed language id (`lng_…`) scoping the document lookup in the data service. Omitted = the website's default language.","name":"lang","in":"query"}],"responses":{"200":{"description":"Subtree rooted at nodeId","content":{"application/json":{"schema":{"type":"object","properties":{"node":{"$ref":"#/components/schemas/LayoutNode"},"descendants":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/LayoutNode"}}},"required":["node","descendants"]}}}},"401":{"description":"Missing or invalid JWT"},"404":{"description":"NODE_NOT_FOUND — the document exists but `nodeId` is absent. DOCUMENT_NOT_FOUND — the page document itself does not exist.","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["NODE_NOT_FOUND"]},"nodeId":{"type":"string"}},"required":["error","nodeId"]},{"type":"object","properties":{"error":{"type":"string","enum":["DOCUMENT_NOT_FOUND"]},"documentId":{"type":"string"}},"required":["error","documentId"]}]}}}},"502":{"description":"DATA_SERVICE_ERROR","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["DATA_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]}}}}}}},"/v1/symbols/{id}":{"get":{"tags":["Symbols"],"summary":"Read the interface of a single symbol","description":"Website-scoped from the JWT. `{id}` is the symbol's `content.id` (the value used as a node's `symbolId`), not the `li_` library item id. Returns everything needed to place a linked instance — variants (with `isDefault`), props, slots, states, insertion mode, and preview. The per-variant layout node trees are omitted unless `?include=layout` is set. Unknown id → 404 SYMBOL_NOT_FOUND.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Symbol id (the symbol's `content.id`).","example":"sym_hero"},"required":true,"description":"Symbol id (the symbol's `content.id`).","name":"id","in":"path"},{"schema":{"type":"string","enum":["layout"],"description":"Set to `layout` to include each variant's node tree, so the symbol can be read back and modified. Omitted by default.","example":"layout"},"required":false,"description":"Set to `layout` to include each variant's node tree, so the symbol can be read back and modified. Omitted by default.","name":"include","in":"query"}],"responses":{"200":{"description":"Symbol interface","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"serverId":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"libraryId":{"type":"string"},"isSystem":{"type":"boolean"},"preview":{"type":"string"},"defaultVariantId":{"type":"string"},"variants":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"isDefault":{"type":"boolean"},"rootNodeId":{"type":"string"},"layout":{"nullable":true},"originalVariantId":{"type":"string"},"overrides":{"nullable":true}},"required":["id","name","isDefault"]}},"props":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["list"]},"key":{"type":"string"},"label":{"type":"string"},"defaultValue":{"type":"array","items":{"nullable":true}}},"required":["type","key","label"]},{"type":"object","properties":{"type":{"type":"string","enum":["text","number","boolean","richTextBlock","richTextInline","file","link"]},"key":{"type":"string"},"label":{"type":"string"},"defaultValue":{"nullable":true},"placeholder":{"type":"string"},"meta":{"type":"object","properties":{"type":{"type":"string","enum":["id","label","slot","activeId"]}}}},"required":["type","key","label"]}]}},"slots":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]}},"states":{"type":"array","items":{"type":"string"}},"placement":{"type":"string","enum":["blocks","library","form"],"description":"where the CMS offers this symbol; `form` marks a form part. Only the seeders write it and nothing upstream enforces it, so treat the value as advisory"},"meta":{"type":"object","properties":{"insertionMode":{"type":"string","enum":["linked","unlinked"]},"cmsType":{"type":"string","description":"what kind of form field this symbol is, if it is one. Form fields: formTextField, formTextarea, formSelect, formCheckbox, formRadioButton. Also seen: formSubmitButton (not a field), languageSwitcher, header"},"isFormSymbol":{"type":"boolean","description":"true on a form container symbol"},"forkable":{"type":"boolean","description":"websites may fork this system symbol into their own library"},"isFork":{"type":"boolean","description":"website-library override of the system symbol with the same id"}},"required":["insertionMode"]}},"required":["id","serverId","name","libraryId","isSystem","defaultVariantId","variants","props","slots","states","meta"]}}}},"400":{"description":"INVALID_OP — the query did not match the schema","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["INVALID_OP"]},"issues":{"type":"array","items":{"nullable":true}}},"required":["error","issues"]}}}},"401":{"description":"Missing or invalid JWT"},"404":{"description":"SYMBOL_NOT_FOUND — no symbol with that id is usable by the website","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["SYMBOL_NOT_FOUND"]},"symbolId":{"type":"string"}},"required":["error","symbolId"]}}}},"502":{"description":"SOLIDPIXELS_SERVICE_ERROR — upstream solidpixels service failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["SOLIDPIXELS_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]}}}}}},"put":{"tags":["Symbols"],"summary":"Update an existing symbol definition","description":"Resolves the symbol by its content id, then rewrites it via the solidpixels library API. With `rootNodeId`+`layout` it rewrites the layout of the DEFAULT variant only, and every sibling variant is preserved. With `variants` it replaces the whole variant map, so a variant the map does not carry is deleted — the map must still carry the symbol's `defaultVariantId`, and every extended variant must inherit a definition variant inside it. Sending both is refused. `props`, `classes`, `description`, `placement`, `states`, `slots` and `meta` are left as stored when omitted; `meta.cmsType` and `meta.isFormSymbol` are never writable. Library-scoped write: the bearer account must hold `library:update` on the symbol's library. Returns the `symbolId` (content id) and `serverId` (the library item id).","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Symbol content id (as returned by GET /v1/symbols).","example":"sym_hero"},"required":true,"description":"Symbol content id (as returned by GET /v1/symbols).","name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Human-readable symbol name shown in the library.","example":"Hero"},"rootNodeId":{"type":"string","description":"Id (a key in `layout`) of the variant root node. Send with `layout`, and without `variants`.","example":"node-0"},"layout":{"type":"object","additionalProperties":{"type":"object","additionalProperties":{"nullable":true}},"description":"The symbol body: a self-contained node subtree keyed by node id. Replaces the default variant layout wholesale, leaving every sibling variant alone. Must contain `rootNodeId`.","example":{"node-0":{"id":"node-0","type":"element","tag":"div","attrs":{},"classes":["flex","p-4"],"children":[],"content":null}}},"variants":{"type":"object","additionalProperties":{"type":"object","additionalProperties":{"nullable":true}},"description":"The WHOLE variant map, keyed by variant id, replacing what is stored: a variant the map does not carry is deleted. Each value is a definition variant (`rootNodeId` + `layout`) or an extended one (`originalVariantId` + `overrides`), plus the usual `id`, `name`, `rect` and `order`. Send instead of `rootNodeId`+`layout`, never with them.","example":{"text":{"id":"text","name":"Text","rootNodeId":"node-0","layout":{}},"email":{"id":"email","name":"Email","originalVariantId":"text","overrides":{"field":{"attrs":{"type":"email"}}}}}},"props":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}},"description":"Symbol prop definitions. Left as stored when omitted.","example":[]},"classes":{"type":"array","items":{"type":"string"},"description":"Symbol-level utility classes. Left as stored when omitted.","example":[]},"description":{"type":"string","description":"Symbol description. Left as stored when omitted.","example":"One line of text"},"placement":{"type":"string","enum":["blocks","library","form"],"description":"Where the CMS offers this symbol. Left as stored when omitted.","example":"form"},"states":{"type":"array","items":{"type":"string"},"description":"Design states. Left as stored when omitted.","example":["default","hover"]},"slots":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]},"description":"Slot declarations. Left as stored when omitted.","example":[{"name":"actions"}]},"meta":{"type":"object","additionalProperties":{"nullable":true},"description":"Symbol metadata, replaced wholesale when present. `cmsType` and `isFormSymbol` are IGNORED here and kept as stored — they decide whether canvas treats the symbol as a form field for every page that places it. Sending them is not an error.","example":{"insertionMode":"linked"}}},"required":["name"]}}}},"responses":{"200":{"description":"Symbol updated","content":{"application/json":{"schema":{"type":"object","properties":{"symbolId":{"type":"string"},"serverId":{"type":"string"},"formDefinition":{"type":"string","enum":["derived","dropped","ambiguous","unextractable","failed"],"description":"What happened to the derived form definition. Absent = the symbol has no form and had none. `derived` = written. `dropped` = the symbol stopped being a form, so its record was removed. `ambiguous` = several variants carry a form, so none was written rather than guess which one the pages render. `unextractable` = the layout carries a form node but the variant has no `rootNodeId`, so nothing could be derived and no record exists; fix the variant and write again. `failed` = the symbol was written but its record was not, so the form will 404 until it is rebuilt."}},"required":["symbolId","serverId"]}}}},"400":{"description":"INVALID_OP — request body did not match the schema, or OUT_OF_PARITY — the layout carries form settings canvas will not write: rules the CMS cannot show or remove, or settings nothing consumes yet","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["INVALID_OP"]},"issues":{"type":"array","items":{"nullable":true}}},"required":["error","issues"]},{"type":"object","properties":{"error":{"type":"string","enum":["OUT_OF_PARITY"]},"keys":{"type":"array","items":{"type":"string"}}},"required":["error","keys"]}]}}}},"401":{"description":"Missing or invalid JWT"},"403":{"description":"SYSTEM_LIBRARY_READONLY — the symbol lives in the shared system library, which takes no in-place write. Copy it into the website library with `POST /v1/symbols/{id}/copy` and write to the copy. FORK_REQUIRED — the symbol is a forkable system symbol. Fork it with `POST /v1/symbols/{id}/fork`, which keeps the same id, then write to the fork instead of the system original.","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["SYSTEM_LIBRARY_READONLY"]}},"required":["error"]},{"type":"object","properties":{"error":{"type":"string","enum":["FORK_REQUIRED"]}},"required":["error"]}]}}}},"404":{"description":"SYMBOL_NOT_FOUND — no symbol with that content id exists","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["SYMBOL_NOT_FOUND"]}},"required":["error"]}}}},"409":{"description":"ORPHANED_OVERRIDES — the layout drops node ids that extended variants of this symbol override. Keep those node ids, or edit the extended variants first. EXTENDED_VARIANT_TARGET — this symbol’s default variant inherits another one, so it holds overrides rather than a layout and cannot be written through this route. UNKNOWN_DEFAULT_VARIANT — the `variants` map does not carry the symbol’s default variant. UNKNOWN_ORIGINAL_VARIANT — an extended variant inherits a variant the map does not carry. EXTENDED_ORIGINAL_VARIANT — an extended variant inherits another extended one, and the resolver does not follow a chain. FORK_RENAME_LOCKED — the symbol is a fork and this write would rename it; resend its stored name unchanged.","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["ORPHANED_OVERRIDES"]},"variantIds":{"type":"array","items":{"type":"string"}},"nodeIds":{"type":"array","items":{"type":"string"}}},"required":["error","variantIds","nodeIds"]},{"type":"object","properties":{"error":{"type":"string","enum":["EXTENDED_VARIANT_TARGET","UNKNOWN_DEFAULT_VARIANT","UNKNOWN_ORIGINAL_VARIANT","EXTENDED_ORIGINAL_VARIANT"]},"variantId":{"type":"string"}},"required":["error","variantId"]},{"type":"object","properties":{"error":{"type":"string","enum":["FORK_RENAME_LOCKED"]}},"required":["error"]}]}}}},"502":{"description":"SOLIDPIXELS_SERVICE_ERROR — upstream solidpixels service failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["SOLIDPIXELS_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]}}}}}},"delete":{"tags":["Symbols"],"summary":"Delete a symbol definition","description":"Resolves the symbol by its content id, then deletes the backing library item via the solidpixels library API. Library-scoped write: the bearer account must hold the delete ability on the symbol's library.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Symbol content id (as returned by GET /v1/symbols).","example":"sym_hero"},"required":true,"description":"Symbol content id (as returned by GET /v1/symbols).","name":"id","in":"path"}],"responses":{"200":{"description":"Symbol deleted","content":{"application/json":{"schema":{"type":"object","properties":{"formDefinition":{"type":"string","enum":["derived","dropped","ambiguous","unextractable","failed"],"description":"What happened to the derived form definition. Absent = the symbol has no form and had none. `derived` = written. `dropped` = the symbol stopped being a form, so its record was removed. `ambiguous` = several variants carry a form, so none was written rather than guess which one the pages render. `unextractable` = the layout carries a form node but the variant has no `rootNodeId`, so nothing could be derived and no record exists; fix the variant and write again. `failed` = the symbol was written but its record was not, so the form will 404 until it is rebuilt."}}}}}},"401":{"description":"Missing or invalid JWT"},"403":{"description":"SYSTEM_LIBRARY_READONLY — the symbol lives in the shared system library, which takes no in-place write. Copy it into the website library with `POST /v1/symbols/{id}/copy` and write to the copy. FORK_REQUIRED — the symbol is a forkable system symbol. Fork it with `POST /v1/symbols/{id}/fork`, which keeps the same id, then write to the fork instead of the system original.","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["SYSTEM_LIBRARY_READONLY"]}},"required":["error"]},{"type":"object","properties":{"error":{"type":"string","enum":["FORK_REQUIRED"]}},"required":["error"]}]}}}},"404":{"description":"SYMBOL_NOT_FOUND — no symbol with that content id exists","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["SYMBOL_NOT_FOUND"]}},"required":["error"]}}}},"409":{"description":"SYMBOL_IS_FORK — the symbol is a fork. Unfork it with `POST /v1/symbols/{id}/unfork` instead of deleting it here.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["SYMBOL_IS_FORK"]}},"required":["error"]}}}},"502":{"description":"SOLIDPIXELS_SERVICE_ERROR — upstream solidpixels service failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["SOLIDPIXELS_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]}}}}}}},"/v1/symbols":{"get":{"tags":["Symbols"],"summary":"List the symbols usable by the current website","description":"Website-scoped from the JWT. Aggregates every library attached to the website and returns a flat catalog of symbols, each tagged with `isSystem`, `libraryId`, and `libraryName`. This is the tier-1 \"what exists\" view: it carries no props, variants, slots, or layout trees. Use `id` (the symbol's `content.id`) as `symbolId` when placing a symbol, and `GET /v1/symbols/{id}` to fetch the interface needed to place one.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Flattened symbol catalog for the website","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"serverId":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"thumbnail":{"type":"string"},"isSystem":{"type":"boolean"},"libraryId":{"type":"string"},"libraryName":{"type":"string"},"placement":{"type":"string","enum":["blocks","library","form"],"description":"where the CMS offers this symbol; `form` marks a form part. Only the seeders write it and nothing upstream enforces it, so treat the value as advisory"},"cmsType":{"type":"string","description":"what kind of form field this symbol is, if it is one. Form fields: formTextField, formTextarea, formSelect, formCheckbox, formRadioButton. Also seen: formSubmitButton (not a field), languageSwitcher, header"},"isFormSymbol":{"type":"boolean","description":"true on a form container symbol"},"forkable":{"type":"boolean","description":"websites may fork this system symbol into their own library"},"isFork":{"type":"boolean","description":"website-library override of the system symbol with the same id"}},"required":["id","serverId","name","isSystem","libraryId","libraryName"]}}}}},"401":{"description":"Missing or invalid JWT"},"502":{"description":"SOLIDPIXELS_SERVICE_ERROR — upstream solidpixels service failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["SOLIDPIXELS_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]}}}}}},"post":{"tags":["Symbols"],"summary":"Create a new symbol definition in a website library","description":"Assembles a symbol `content` from the supplied node subtree and stores it as a library item via the solidpixels library API. Library-scoped write: the bearer account must hold `library:update` on the target library. Returns the new `symbolId` (the content id, used as `symbolId` when placing) and `serverId` (the library item id).","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Human-readable symbol name shown in the library.","example":"Hero"},"rootNodeId":{"type":"string","description":"Id (a key in `layout`) of the variant root node.","example":"node-0"},"layout":{"type":"object","additionalProperties":{"type":"object","additionalProperties":{"nullable":true}},"description":"The symbol body: a self-contained node subtree keyed by node id. Becomes the default variant layout. Must contain `rootNodeId`.","example":{"node-0":{"id":"node-0","type":"element","tag":"div","attrs":{},"classes":["flex","p-4"],"children":[],"content":null}}},"libraryId":{"type":"string","description":"Target library id. When omitted, the first non-system library attached to the website is used.","example":"lib_fc861d78e9364efbac35a73ab8e8466f"},"id":{"type":"string","description":"Symbol content id (referenced as `symbolId` when placing). When omitted, one is minted server-side.","example":"sym_hero"},"props":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}},"description":"Symbol prop definitions. Defaults to none.","example":[]},"classes":{"type":"array","items":{"type":"string"},"description":"Symbol-level utility classes. Defaults to none.","example":[]}},"required":["name","rootNodeId","layout"]}}}},"responses":{"201":{"description":"Symbol created","content":{"application/json":{"schema":{"type":"object","properties":{"symbolId":{"type":"string"},"serverId":{"type":"string"},"formDefinition":{"type":"string","enum":["derived","dropped","ambiguous","unextractable","failed"],"description":"What happened to the derived form definition. Absent = the symbol has no form and had none. `derived` = written. `dropped` = the symbol stopped being a form, so its record was removed. `ambiguous` = several variants carry a form, so none was written rather than guess which one the pages render. `unextractable` = the layout carries a form node but the variant has no `rootNodeId`, so nothing could be derived and no record exists; fix the variant and write again. `failed` = the symbol was written but its record was not, so the form will 404 until it is rebuilt."}},"required":["symbolId","serverId"]}}}},"400":{"description":"INVALID_OP — request body did not match the schema, or OUT_OF_PARITY — the layout carries form settings canvas will not write: rules the CMS cannot show or remove, or settings nothing consumes yet","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["INVALID_OP"]},"issues":{"type":"array","items":{"nullable":true}}},"required":["error","issues"]},{"type":"object","properties":{"error":{"type":"string","enum":["OUT_OF_PARITY"]},"keys":{"type":"array","items":{"type":"string"}}},"required":["error","keys"]}]}}}},"401":{"description":"Missing or invalid JWT"},"404":{"description":"LIBRARY_NOT_FOUND — no writable (non-system) library is attached to the website, or the given libraryId does not resolve","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["LIBRARY_NOT_FOUND"]}},"required":["error"]}}}},"409":{"description":"SYMBOL_ID_TAKEN — `id` is already used by a symbol","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["SYMBOL_ID_TAKEN"]},"symbolId":{"type":"string"}},"required":["error","symbolId"]}}}},"502":{"description":"SOLIDPIXELS_SERVICE_ERROR — upstream solidpixels service failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["SOLIDPIXELS_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]}}}}}}},"/v1/symbols/{id}/variants":{"post":{"tags":["Symbols"],"summary":"Add a variant to an existing symbol","description":"Reads the stored symbol, inserts one variant and writes it back. Every existing variant, `defaultVariantId` and the symbol envelope are preserved. Rewrite one with `PUT /v1/symbols/{id}/variants/{variantId}`; there is no delete, because removing a variant orphans every placed instance that names it. Library-scoped write: the bearer account must hold `library:update` on the symbol's library.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Symbol content id (not the `li_` library-item id).","example":"textField"},"required":true,"description":"Symbol content id (not the `li_` library-item id).","name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Human-readable variant name shown in the CMS.","example":"Email"},"variantId":{"type":"string","description":"Variant id, unique inside this symbol. Minted when omitted.","example":"email"},"isDefault":{"type":"boolean","description":"Point the symbol's `defaultVariantId` at the new variant.","example":false},"order":{"type":"number","description":"Sort order in the CMS variant list.","example":2},"rootNodeId":{"type":"string","description":"Definition variant: id (a key in `layout`) of the variant root node. Send with `layout`, and without `originalVariantId`.","example":"node-0"},"layout":{"type":"object","additionalProperties":{"type":"object","additionalProperties":{"nullable":true}},"description":"Definition variant: a self-contained node subtree keyed by node id."},"originalVariantId":{"type":"string","description":"Extended variant: the sibling variant to inherit. Must be a definition variant — inheriting an extended one is refused, because the resolver does not follow a chain.","example":"text"},"overrides":{"type":"object","additionalProperties":{"nullable":true},"description":"Extended variant: patches keyed by base node id. A partial object rewrites that node, a complete node adds one, `null` blanks it out.","example":{"field":{"attrs":{"type":"email"}}}}},"required":["name"]}}}},"responses":{"201":{"description":"Variant created","content":{"application/json":{"schema":{"type":"object","properties":{"symbolId":{"type":"string"},"variantId":{"type":"string"},"formDefinition":{"type":"string","enum":["derived","dropped","ambiguous","unextractable","failed"],"description":"What happened to the derived form definition. Absent = the symbol has no form and had none. `derived` = written. `dropped` = the symbol stopped being a form, so its record was removed. `ambiguous` = several variants carry a form, so none was written rather than guess which one the pages render. `unextractable` = the layout carries a form node but the variant has no `rootNodeId`, so nothing could be derived and no record exists; fix the variant and write again. `failed` = the symbol was written but its record was not, so the form will 404 until it is rebuilt."},"serverId":{"type":"string"}},"required":["symbolId","variantId","serverId"]}}}},"400":{"description":"INVALID_OP — request body did not match the schema, or OUT_OF_PARITY — the layout carries form settings canvas will not write: rules the CMS cannot show or remove, or settings nothing consumes yet","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["INVALID_OP"]},"issues":{"type":"array","items":{"nullable":true}}},"required":["error","issues"]},{"type":"object","properties":{"error":{"type":"string","enum":["OUT_OF_PARITY"]},"keys":{"type":"array","items":{"type":"string"}}},"required":["error","keys"]}]}}}},"401":{"description":"Missing or invalid JWT"},"403":{"description":"SYSTEM_LIBRARY_READONLY — the symbol lives in the shared system library, which takes no in-place write. Copy it into the website library with `POST /v1/symbols/{id}/copy` and write to the copy. FORK_REQUIRED — the symbol is a forkable system symbol. Fork it with `POST /v1/symbols/{id}/fork`, which keeps the same id, then write to the fork instead of the system original.","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["SYSTEM_LIBRARY_READONLY"]}},"required":["error"]},{"type":"object","properties":{"error":{"type":"string","enum":["FORK_REQUIRED"]}},"required":["error"]}]}}}},"404":{"description":"SYMBOL_NOT_FOUND — no symbol with that content id exists","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["SYMBOL_NOT_FOUND"]}},"required":["error"]}}}},"409":{"description":"VARIANT_EXISTS — that variant id is already taken in this symbol. UNKNOWN_ORIGINAL_VARIANT — the variant to inherit is not there. EXTENDED_ORIGINAL_VARIANT — the variant to inherit is itself extended, and the resolver does not follow a chain.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["VARIANT_EXISTS","UNKNOWN_ORIGINAL_VARIANT","EXTENDED_ORIGINAL_VARIANT"]},"variantId":{"type":"string"}},"required":["error","variantId"]}}}},"502":{"description":"SOLIDPIXELS_SERVICE_ERROR — upstream solidpixels service failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["SOLIDPIXELS_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]}}}}}}},"/v1/symbols/{id}/variants/{variantId}":{"put":{"tags":["Symbols"],"summary":"Rewrite one variant of an existing symbol","description":"Reads the stored symbol, rewrites one variant and writes it back. `PUT /v1/symbols/{id}` only ever reaches the default variant, so this is the way to change a named one. A patch, not a replacement: `name`, `order` and everything else the stored variant carries survive when the body omits them, and so do every other variant, `defaultVariantId` and the symbol envelope. Sending the other body kind converts the variant and drops the half it no longer holds. Library-scoped write: the bearer account must hold `library:update` on the symbol's library.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Symbol content id (not the `li_` library-item id).","example":"textField"},"required":true,"description":"Symbol content id (not the `li_` library-item id).","name":"id","in":"path"},{"schema":{"type":"string","description":"Id of the variant to rewrite. It must already exist.","example":"email"},"required":true,"description":"Id of the variant to rewrite. It must already exist.","name":"variantId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Human-readable variant name shown in the CMS. Kept as stored when omitted.","example":"Email"},"isDefault":{"type":"boolean","description":"Point the symbol's `defaultVariantId` at this variant.","example":false},"order":{"type":"number","description":"Sort order in the CMS variant list. Kept when omitted.","example":2},"rootNodeId":{"type":"string","description":"Definition variant: id (a key in `layout`) of the variant root node. Send with `layout`, and without `originalVariantId`.","example":"node-0"},"layout":{"type":"object","additionalProperties":{"type":"object","additionalProperties":{"nullable":true}},"description":"Definition variant: a self-contained node subtree keyed by node id. Replaces the stored layout wholesale."},"originalVariantId":{"type":"string","description":"Extended variant: the sibling variant to inherit. Must be a definition variant — inheriting an extended one is refused, because the resolver does not follow a chain.","example":"text"},"overrides":{"type":"object","additionalProperties":{"nullable":true},"description":"Extended variant: patches keyed by base node id, replacing the stored ones wholesale. A partial object rewrites that node, a complete node adds one, `null` blanks it out.","example":{"field":{"attrs":{"type":"email"}}}}}}}}},"responses":{"200":{"description":"Variant rewritten","content":{"application/json":{"schema":{"type":"object","properties":{"symbolId":{"type":"string"},"variantId":{"type":"string"},"formDefinition":{"type":"string","enum":["derived","dropped","ambiguous","unextractable","failed"],"description":"What happened to the derived form definition. Absent = the symbol has no form and had none. `derived` = written. `dropped` = the symbol stopped being a form, so its record was removed. `ambiguous` = several variants carry a form, so none was written rather than guess which one the pages render. `unextractable` = the layout carries a form node but the variant has no `rootNodeId`, so nothing could be derived and no record exists; fix the variant and write again. `failed` = the symbol was written but its record was not, so the form will 404 until it is rebuilt."},"serverId":{"type":"string"}},"required":["symbolId","variantId","serverId"]}}}},"400":{"description":"INVALID_OP — request body did not match the schema, or OUT_OF_PARITY — the layout carries form settings canvas will not write: rules the CMS cannot show or remove, or settings nothing consumes yet","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["INVALID_OP"]},"issues":{"type":"array","items":{"nullable":true}}},"required":["error","issues"]},{"type":"object","properties":{"error":{"type":"string","enum":["OUT_OF_PARITY"]},"keys":{"type":"array","items":{"type":"string"}}},"required":["error","keys"]}]}}}},"401":{"description":"Missing or invalid JWT"},"403":{"description":"SYSTEM_LIBRARY_READONLY — the symbol lives in the shared system library, which takes no in-place write. Copy it into the website library with `POST /v1/symbols/{id}/copy` and write to the copy. FORK_REQUIRED — the symbol is a forkable system symbol. Fork it with `POST /v1/symbols/{id}/fork`, which keeps the same id, then write to the fork instead of the system original.","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["SYSTEM_LIBRARY_READONLY"]}},"required":["error"]},{"type":"object","properties":{"error":{"type":"string","enum":["FORK_REQUIRED"]}},"required":["error"]}]}}}},"404":{"description":"SYMBOL_NOT_FOUND — no symbol with that content id exists. VARIANT_NOT_FOUND — the symbol carries no variant with that id; add it with `POST /v1/symbols/{id}/variants`","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["SYMBOL_NOT_FOUND"]}},"required":["error"]},{"type":"object","properties":{"error":{"type":"string","enum":["VARIANT_NOT_FOUND"]},"variantId":{"type":"string"}},"required":["error","variantId"]}]}}}},"409":{"description":"ORPHANED_OVERRIDES — the new layout drops node ids that extended variants override. INHERITED_VARIANT_TARGET — other variants inherit this one, so it cannot become an extended variant: the resolver does not follow a chain. UNKNOWN_ORIGINAL_VARIANT — the variant to inherit is not there. EXTENDED_ORIGINAL_VARIANT — the variant to inherit is itself extended.","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["ORPHANED_OVERRIDES"]},"variantIds":{"type":"array","items":{"type":"string"}},"nodeIds":{"type":"array","items":{"type":"string"}}},"required":["error","variantIds","nodeIds"]},{"type":"object","properties":{"error":{"type":"string","enum":["INHERITED_VARIANT_TARGET"]},"variantIds":{"type":"array","items":{"type":"string"}}},"required":["error","variantIds"]},{"type":"object","properties":{"error":{"type":"string","enum":["UNKNOWN_ORIGINAL_VARIANT","EXTENDED_ORIGINAL_VARIANT"]},"variantId":{"type":"string"}},"required":["error","variantId"]}]}}}},"502":{"description":"SOLIDPIXELS_SERVICE_ERROR — upstream solidpixels service failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["SOLIDPIXELS_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]}}}}}}},"/v1/symbols/{id}/copy":{"post":{"tags":["Symbols"],"summary":"Copy a symbol into a writable library under a new id","description":"Copies a symbol — every variant, prop and envelope field — into a library the website can write to, under a **new** content id. This is how you get an editable version of a system-library symbol such as Button, Card or Text Field: the system library is shared by every website, so writing to it is refused. The copy records the source id as `sourceSymbolId`, which is provenance only and is never resolved at render time. Copying is always explicit — no other route copies on your behalf, so you always know which symbol you are holding.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Symbol content id (not the `li_` library-item id).","example":"textField"},"required":true,"description":"Symbol content id (not the `li_` library-item id).","name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Name for the copy. Defaults to the source symbol's name.","example":"My Text Field"},"newId":{"type":"string","description":"Content id for the copy. Minted when omitted. Never reuses the source's id.","example":"my_text_field"},"libraryId":{"type":"string","description":"Target library. When omitted, the first non-system library attached to the website is used.","example":"lib_fc861d78e9364efbac35a73ab8e8466f"}}}}}},"responses":{"201":{"description":"Symbol copied","content":{"application/json":{"schema":{"type":"object","properties":{"symbolId":{"type":"string"},"serverId":{"type":"string"},"sourceSymbolId":{"type":"string"},"formDefinition":{"type":"string","enum":["derived","dropped","ambiguous","unextractable","failed"],"description":"What happened to the derived form definition. Absent = the symbol has no form and had none. `derived` = written. `dropped` = the symbol stopped being a form, so its record was removed. `ambiguous` = several variants carry a form, so none was written rather than guess which one the pages render. `unextractable` = the layout carries a form node but the variant has no `rootNodeId`, so nothing could be derived and no record exists; fix the variant and write again. `failed` = the symbol was written but its record was not, so the form will 404 until it is rebuilt."}},"required":["symbolId","serverId","sourceSymbolId"]}}}},"400":{"description":"INVALID_OP — request body did not match the schema","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["INVALID_OP"]},"issues":{"type":"array","items":{"nullable":true}}},"required":["error","issues"]}}}},"401":{"description":"Missing or invalid JWT"},"404":{"description":"SYMBOL_NOT_FOUND — no symbol with that content id is usable by the website. LIBRARY_NOT_FOUND — the website has no writable library.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["SYMBOL_NOT_FOUND","LIBRARY_NOT_FOUND"]}},"required":["error"]}}}},"409":{"description":"SYMBOL_ID_TAKEN — `newId` is already used by a symbol","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["SYMBOL_ID_TAKEN"]},"symbolId":{"type":"string"}},"required":["error","symbolId"]}}}},"502":{"description":"SOLIDPIXELS_SERVICE_ERROR — upstream solidpixels service failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["SOLIDPIXELS_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]}}}}}}},"/v1/symbols/{id}/fork":{"post":{"tags":["Symbols"],"summary":"Fork a forkable system symbol, keeping its id","description":"Creates a website-library item under the SAME content id as a system symbol — unlike `POST /v1/symbols/{id}/copy`, which mints a new one. Every reader resolves the catalog system-first, website-second, so the fork takes the system symbol's place for this website, and every existing reference to the id keeps resolving. Only a symbol with `meta.forkable` can be forked this way; a non-forkable system symbol still takes `POST /v1/symbols/{id}/copy`. Once forked, write to the SAME id through the normal routes. A fork's name and `forkable` follow the source and cannot be renamed in place (`FORK_RENAME_LOCKED`); drop the customization with `POST /v1/symbols/{id}/unfork`.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Symbol content id (not the `li_` library-item id).","example":"textField"},"required":true,"description":"Symbol content id (not the `li_` library-item id).","name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"libraryId":{"type":"string","description":"Target library. When omitted, the first non-system library attached to the website is used.","example":"lib_fc861d78e9364efbac35a73ab8e8466f"}}}}}},"responses":{"201":{"description":"Symbol forked","content":{"application/json":{"schema":{"type":"object","properties":{"symbolId":{"type":"string"},"serverId":{"type":"string"},"formDefinition":{"type":"string","enum":["derived","dropped","ambiguous","unextractable","failed"],"description":"What happened to the derived form definition. Absent = the symbol has no form and had none. `derived` = written. `dropped` = the symbol stopped being a form, so its record was removed. `ambiguous` = several variants carry a form, so none was written rather than guess which one the pages render. `unextractable` = the layout carries a form node but the variant has no `rootNodeId`, so nothing could be derived and no record exists; fix the variant and write again. `failed` = the symbol was written but its record was not, so the form will 404 until it is rebuilt."}},"required":["symbolId","serverId"]}}}},"400":{"description":"INVALID_OP — request body did not match the schema","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["INVALID_OP"]},"issues":{"type":"array","items":{"nullable":true}}},"required":["error","issues"]}}}},"401":{"description":"Missing or invalid JWT"},"404":{"description":"SYMBOL_NOT_FOUND — no symbol with that content id is usable by the website. LIBRARY_NOT_FOUND — the website has no writable library.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["SYMBOL_NOT_FOUND","LIBRARY_NOT_FOUND"]}},"required":["error"]}}}},"409":{"description":"SYMBOL_NOT_FORKABLE — the id is not a forkable system symbol: either a plain website symbol, or a system symbol without `meta.forkable`. Copy it instead with `POST /v1/symbols/{id}/copy`. SYMBOL_ALREADY_FORKED — the website already holds a fork of this id; write to it directly, or remove it first with `POST /v1/symbols/{id}/unfork`.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["SYMBOL_NOT_FORKABLE","SYMBOL_ALREADY_FORKED"]}},"required":["error"]}}}},"502":{"description":"SOLIDPIXELS_SERVICE_ERROR — upstream solidpixels service failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["SOLIDPIXELS_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]}}}}}}},"/v1/symbols/{id}/unfork":{"post":{"tags":["Symbols"],"summary":"Remove a fork and let the system original take its id back","description":"Deletes the website-library item `POST /v1/symbols/{id}/fork` created. The catalog resolves system-first, so with the fork gone the id falls through to the system symbol it overrode, and the website's derived form definition is re-pointed at that original. There is no undo: the customization the fork held is gone once this returns.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Symbol content id (not the `li_` library-item id).","example":"textField"},"required":true,"description":"Symbol content id (not the `li_` library-item id).","name":"id","in":"path"}],"responses":{"200":{"description":"Fork removed","content":{"application/json":{"schema":{"type":"object","properties":{"symbolId":{"type":"string"},"serverId":{"type":"string"},"formDefinition":{"type":"string","enum":["derived","dropped","ambiguous","unextractable","failed"],"description":"What happened to the derived form definition. Absent = the symbol has no form and had none. `derived` = written. `dropped` = the symbol stopped being a form, so its record was removed. `ambiguous` = several variants carry a form, so none was written rather than guess which one the pages render. `unextractable` = the layout carries a form node but the variant has no `rootNodeId`, so nothing could be derived and no record exists; fix the variant and write again. `failed` = the symbol was written but its record was not, so the form will 404 until it is rebuilt."}},"required":["symbolId","serverId"]}}}},"401":{"description":"Missing or invalid JWT"},"404":{"description":"SYMBOL_NOT_FOUND — no symbol with that content id exists","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["SYMBOL_NOT_FOUND"]}},"required":["error"]}}}},"409":{"description":"SYMBOL_NOT_A_FORK — the id is not a website-library override of a system symbol: either a plain website symbol, or the system original itself.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["SYMBOL_NOT_A_FORK"]}},"required":["error"]}}}},"502":{"description":"SOLIDPIXELS_SERVICE_ERROR — upstream solidpixels service failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["SOLIDPIXELS_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]}}}}}}},"/v1/symbols/form-definitions":{"post":{"tags":["Symbols"],"summary":"Re-derive the stored form definitions from the symbols","description":"Re-derives the `forms` record — the contract a published page loads before it lets a visitor submit — from the symbols as they are stored now. No symbol is written. This is the repair for a record a write left `failed`, one an older CMS build derived, and one written through a generic data passthrough, which triggers no derivation at all.\n\nName a `symbolId` to rebuild (or create) that one key. With no `symbolId` it sweeps the record: every key it already has is rebuilt, and **no key is added**. The symbol catalog is every library attached to the website, not what this website built, and a key is a live public endpoint — so deriving the catalog would open mail and webhook relays on a site that never built those forms. Create a missing key by naming its symbol.\n\nA key is removed only when its symbol resolves and declares no form node. A symbol declaring several forms is left alone and reported in `skipped`: canvas cannot tell which variant the pages render, and only the CMS can resolve that. A key whose symbol no library carries is left alone and reported in `orphaned` — a short catalog read looks exactly like a deleted symbol.\n\nSend `prune: true` **with** a `symbolId` to remove such an orphan: the key goes and comes back in `removed`, and `404 SYMBOL_NOT_FOUND` is not raised, because the missing symbol is the point of the call. Without it a symbol delete leaves a key nothing can remove, and that key is still a live public submit/email/webhook endpoint. `prune` without a `symbolId` is refused with `400 INVALID_OP`: canvas cannot tell a deleted symbol from a short catalog read, so a sweep-wide prune would guess and could delete a live form. Naming one symbol moves that decision to the caller. A named symbol that still resolves is rebuilt as usual — a prune never deletes a live key.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"symbolId":{"type":"string","minLength":1,"description":"Rebuild this symbol's key only, creating it when the record has none. Omitted = rebuild every key the record already has.","example":"sym_contact"},"prune":{"type":"boolean","default":false,"description":"Also remove `symbolId`'s key when no library carries that symbol any more. Requires `symbolId`. A key whose symbol resolves is rebuilt as usual — a prune never deletes a live form.","example":true}}}}}},"responses":{"200":{"description":"Record rebuilt — the four lists name what happened. A pruned orphan is reported in `removed`, not `orphaned`","content":{"application/json":{"schema":{"type":"object","properties":{"rebuilt":{"type":"array","items":{"type":"string"}},"removed":{"type":"array","items":{"type":"string"}},"skipped":{"type":"array","items":{"type":"object","properties":{"symbolId":{"type":"string"},"reason":{"type":"string","enum":["ambiguous","not_a_form","unextractable","error"],"description":"Why the key was left alone. `ambiguous` = several variants carry a form, so a human picks one in the CMS. `not_a_form` = the symbol resolves and declares no form, and there was no key to remove. `unextractable` = a variant looks like a form but yields none. `error` = the stored symbol broke the extractor."}},"required":["symbolId","reason"]}},"orphaned":{"type":"array","items":{"type":"string"}}},"required":["rebuilt","removed","skipped","orphaned"]}}}},"400":{"description":"INVALID_OP — request body did not match the schema, or `prune` arrived without a `symbolId`","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["INVALID_OP"]},"issues":{"type":"array","items":{"nullable":true}}},"required":["error","issues"]}}}},"401":{"description":"Missing or invalid JWT"},"404":{"description":"SYMBOL_NOT_FOUND — no symbol with that content id is usable by the website. Never raised under `prune`","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["SYMBOL_NOT_FOUND"]}},"required":["error"]}}}},"409":{"description":"LOCK_CONTENDED — a symbol write holds the website `forms` record right now; retry","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["LOCK_CONTENDED"]}},"required":["error"]}}}},"502":{"description":"DATA_SERVICE_ERROR — the record could not be read or written. SOLIDPIXELS_SERVICE_ERROR — the symbol catalog could not be read.","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["DATA_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]},{"type":"object","properties":{"error":{"type":"string","enum":["SOLIDPIXELS_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]}]}}}}}}},"/v1/design/apply":{"post":{"tags":["Design"],"summary":"Create, update, or delete website design tokens and prose styles","description":"Applies a batch of design ops (color/font/typography tokens, plus prose-element styles) to the website styleguide. The batch is atomic: the ops are applied in array order to the current designVariables and persisted in a single write, so a font added in an earlier op can be referenced by a later typography op. Each op result carries the ready-to-use node classes — `setColor` returns `bg-<key>-*`/`text-<key>-*`, `setTypography` returns `font-<key>`; `setFont` returns none (pair it with a `setTypography` that references its key). The `delete*` ops remove a token by key and are idempotent; `deleteFont` is rejected (400) if a typography token still references the font. `setProseStyle` replaces the class list of a prose element (h1-h6, p, ul, …) by selector, restricted to an allowlist.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"ops":{"type":"array","items":{"oneOf":[{"$ref":"#/components/schemas/SetColorOp"},{"$ref":"#/components/schemas/SetFontOp"},{"$ref":"#/components/schemas/SetTypographyOp"},{"$ref":"#/components/schemas/DeleteColorOp"},{"$ref":"#/components/schemas/DeleteFontOp"},{"$ref":"#/components/schemas/DeleteTypographyOp"},{"$ref":"#/components/schemas/SetProseStyleOp"}],"discriminator":{"propertyName":"type","mapping":{"setColor":"#/components/schemas/SetColorOp","setFont":"#/components/schemas/SetFontOp","setTypography":"#/components/schemas/SetTypographyOp","deleteColor":"#/components/schemas/DeleteColorOp","deleteFont":"#/components/schemas/DeleteFontOp","deleteTypography":"#/components/schemas/DeleteTypographyOp","setProseStyle":"#/components/schemas/SetProseStyleOp"}}},"minItems":1}},"required":["ops"]}}}},"responses":{"200":{"description":"Tokens upserted; returns per-op results with node classes.","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"key":{"type":"string"},"classes":{"type":"array","items":{"type":"string"}}},"required":["type","key","classes"]}}},"required":["results"]}}}},"400":{"description":"INVALID_DESIGN_OP — an op is internally inconsistent (e.g. a typography op references a font that does not exist)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["INVALID_DESIGN_OP"]},"message":{"type":"string"}},"required":["error","message"]}}}},"401":{"description":"Missing or invalid JWT"},"409":{"description":"DESIGN_LOCKED — another design write for this website is in progress","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["DESIGN_LOCKED"]}},"required":["error"]}}}},"500":{"description":"LOCK_BACKEND_UNAVAILABLE — Valkey unreachable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["LOCK_BACKEND_UNAVAILABLE"]}},"required":["error"]}}}},"502":{"description":"DATA_SERVICE_ERROR — upstream data service failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["DATA_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]}}}}}}},"/v2/design/apply":{"post":{"tags":["Design"],"summary":"Edit project-layer design tokens (token-cascade model)","description":"Applies a batch of token-cascade ops to the website. v2 writes the projectTokens row (the project layer of the token cascade) for the derived/registered tokens (setColor shades, setVariable values, setElementStyle/deleteElementStyle) AND the same designVariables row as v1 for setColor/setVariable/setFont/setTypography. The batch is atomic and order-sensitive. Each result echoes the stored state, so callers get read-after-write without a separate GET.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"ops":{"type":"array","items":{"oneOf":[{"$ref":"#/components/schemas/SetColorOpV2"},{"$ref":"#/components/schemas/SetVariableOp"},{"$ref":"#/components/schemas/SetFontOpV2"},{"$ref":"#/components/schemas/SetTypographyOpV2"},{"$ref":"#/components/schemas/SetElementStyleOp"},{"$ref":"#/components/schemas/DeleteElementStyleOp"}],"discriminator":{"propertyName":"type","mapping":{"setColor":"#/components/schemas/SetColorOpV2","setVariable":"#/components/schemas/SetVariableOp","setFont":"#/components/schemas/SetFontOpV2","setTypography":"#/components/schemas/SetTypographyOpV2","setElementStyle":"#/components/schemas/SetElementStyleOp","deleteElementStyle":"#/components/schemas/DeleteElementStyleOp"}}},"minItems":1}},"required":["ops"]}}}},"responses":{"200":{"description":"Ops applied; per-op results echo the stored state.","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"key":{"type":"string"},"value":{"nullable":true},"overrides":{"nullable":true},"deleted":{"type":"boolean"},"classes":{"type":"array","items":{"type":"string"}},"group":{"type":"string"}},"required":["type","key"]}},"warnings":{"type":"array","items":{"type":"object","properties":{"opIndex":{"type":"number"},"code":{"type":"string"},"message":{"type":"string"}},"required":["opIndex","code","message"]}}},"required":["results","warnings"]}}}},"400":{"description":"INVALID_DESIGN_OP — an op failed validation; the message names the offending field and the allowed format/set","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["INVALID_DESIGN_OP"]},"message":{"type":"string"}},"required":["error","message"]}}}},"401":{"description":"Missing or invalid JWT"},"409":{"description":"DESIGN_LOCKED — another design write for this website is in progress","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["DESIGN_LOCKED"]}},"required":["error"]}}}},"500":{"description":"LOCK_BACKEND_UNAVAILABLE — Valkey unreachable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["LOCK_BACKEND_UNAVAILABLE"]}},"required":["error"]}}}},"502":{"description":"DATA_SERVICE_ERROR — upstream data service failed, or FILES_SERVICE_ERROR — the files service was unreachable or errored while checking a setFont op's weightFiles ids","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["DATA_SERVICE_ERROR","FILES_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]}}}}}}},"/v2/theme/apply":{"post":{"tags":["Theme"],"summary":"Edit website themes (scheme columns)","description":"Applies a batch of theme ops to the website. Writes the three scheme rows (schemes / schemeMeta / schemeVariables). Ops are applied in order under a per-website lock; either every op applies or none are persisted (the three rows are then written sequentially). Each result echoes the new scheme id.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"ops":{"type":"array","items":{"oneOf":[{"$ref":"#/components/schemas/CreateThemeOp"},{"$ref":"#/components/schemas/SetThemeValueOp"},{"$ref":"#/components/schemas/ClearThemeValueOp"},{"$ref":"#/components/schemas/RenameThemeOp"},{"$ref":"#/components/schemas/ReorderThemesOp"},{"$ref":"#/components/schemas/DuplicateThemeOp"},{"$ref":"#/components/schemas/DeleteThemeOp"},{"$ref":"#/components/schemas/AddThemeAttributeOp"},{"$ref":"#/components/schemas/RenameThemeAttributeOp"},{"$ref":"#/components/schemas/ReorderThemeAttributesOp"},{"$ref":"#/components/schemas/DeleteThemeAttributeOp"}],"discriminator":{"propertyName":"type","mapping":{"createTheme":"#/components/schemas/CreateThemeOp","setThemeValue":"#/components/schemas/SetThemeValueOp","clearThemeValue":"#/components/schemas/ClearThemeValueOp","renameTheme":"#/components/schemas/RenameThemeOp","reorderThemes":"#/components/schemas/ReorderThemesOp","duplicateTheme":"#/components/schemas/DuplicateThemeOp","deleteTheme":"#/components/schemas/DeleteThemeOp","addThemeAttribute":"#/components/schemas/AddThemeAttributeOp","renameThemeAttribute":"#/components/schemas/RenameThemeAttributeOp","reorderThemeAttributes":"#/components/schemas/ReorderThemeAttributesOp","deleteThemeAttribute":"#/components/schemas/DeleteThemeAttributeOp"}}},"minItems":1}},"required":["ops"]}}}},"responses":{"200":{"description":"Ops applied; per-op results echo the new scheme ids.","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"id":{"type":"string"},"themeId":{"type":"string"},"attribute":{"type":"string"},"ref":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["token"]},"scope":{"type":"string","enum":["primitive","platform","project"]},"key":{"type":"string","minLength":1}},"required":["type","scope","key"]},{"type":"object","properties":{"type":{"type":"string","enum":["keyword"]},"value":{"type":"string"}},"required":["type","value"]}]},"name":{"type":"string"},"newThemeId":{"type":"string"},"mode":{"type":"string","enum":["hide","purge","soft"]},"hidden":{"type":"boolean"},"deleted":{"type":"boolean"},"orderedIds":{"type":"array","items":{"type":"string"}},"key":{"type":"string"},"order":{"type":"number"},"orderedKeys":{"type":"array","items":{"type":"string"}}},"required":["type"]}},"warnings":{"type":"array","items":{"type":"object","properties":{"opIndex":{"type":"number"},"code":{"type":"string"},"message":{"type":"string"}},"required":["opIndex","code","message"]}}},"required":["results","warnings"]}}}},"400":{"description":"INVALID_DESIGN_OP — an op failed validation; the message names the offending field and the allowed format/set","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["INVALID_DESIGN_OP"]},"message":{"type":"string"}},"required":["error","message"]}}}},"401":{"description":"Missing or invalid JWT"},"409":{"description":"DESIGN_LOCKED — another design write for this website is in progress","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["DESIGN_LOCKED"]}},"required":["error"]}}}},"500":{"description":"LOCK_BACKEND_UNAVAILABLE — Valkey unreachable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["LOCK_BACKEND_UNAVAILABLE"]}},"required":["error"]}}}},"502":{"description":"DATA_SERVICE_ERROR — upstream data service failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["DATA_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]}}}}}}},"/v2/design":{"get":{"tags":["Design"],"summary":"Read the full design state of the website","description":"Returns the design state as stored, in one call: `projectTokens` (the project layer of the token cascade), `elementStyles` (the global per-element styleguide), `designVariables` (colors, fonts, typography, breakpoints, prose styles), `variables` (registered design variables, keyed by token key), and `variableGroupsMeta` (custom variable groups, keyed by group id). Rows that were never written come back as `{}` (designVariables as `null`). Intended for agents to inspect current state before mutating via the apply endpoints.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Current design state.","content":{"application/json":{"schema":{"type":"object","properties":{"projectTokens":{"type":"object","additionalProperties":{"nullable":true}},"elementStyles":{"type":"object","additionalProperties":{"nullable":true}},"designVariables":{"nullable":true},"variables":{"type":"object","additionalProperties":{"nullable":true}},"variableGroupsMeta":{"type":"object","additionalProperties":{"nullable":true}}},"required":["projectTokens","elementStyles","variables","variableGroupsMeta"]}}}},"401":{"description":"Missing or invalid JWT"},"502":{"description":"DATA_SERVICE_ERROR — upstream data service failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["DATA_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]}}}}}}},"/v2/design/tokens":{"get":{"tags":["Design"],"summary":"Read only the project-layer design tokens","description":"Returns the projectTokens row as stored — the project layer of the token cascade. A never-written row comes back as `{}`.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Current project tokens.","content":{"application/json":{"schema":{"type":"object","properties":{"projectTokens":{"type":"object","additionalProperties":{"nullable":true}}},"required":["projectTokens"]}}}},"401":{"description":"Missing or invalid JWT"},"502":{"description":"DATA_SERVICE_ERROR — upstream data service failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["DATA_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]}}}}}}},"/v2/design/element-styles":{"get":{"tags":["Design"],"summary":"Read only the global element styleguide","description":"Returns the elementStyles row as stored — the per-element styleguide layer of the token cascade. A never-written row comes back as `{}`.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Current element styles.","content":{"application/json":{"schema":{"type":"object","properties":{"elementStyles":{"type":"object","additionalProperties":{"nullable":true}}},"required":["elementStyles"]}}}},"401":{"description":"Missing or invalid JWT"},"502":{"description":"DATA_SERVICE_ERROR — upstream data service failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["DATA_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]}}}}}}},"/v2/theme":{"get":{"tags":["Theme"],"summary":"Read the full theme state of the website","description":"Returns the theme state as stored, in one call: `schemes` (per-scheme token overrides), `schemeMeta` (scheme id → name/order metadata), and `schemeVariables` (per-variable, per-scheme values). Rows echo the raw ids and keys the theme apply ops address. Rows that were never written come back as `{}`. Intended for agents to inspect current state before mutating via POST /v2/theme/apply.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Current theme state.","content":{"application/json":{"schema":{"type":"object","properties":{"schemes":{"type":"object","additionalProperties":{"nullable":true}},"schemeMeta":{"type":"object","additionalProperties":{"nullable":true}},"schemeVariables":{"type":"object","additionalProperties":{"nullable":true}}},"required":["schemes","schemeMeta","schemeVariables"]}}}},"401":{"description":"Missing or invalid JWT"},"502":{"description":"DATA_SERVICE_ERROR — upstream data service failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["DATA_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]}}}}}}},"/v2/code-blocks":{"get":{"tags":["Code blocks"],"summary":"List all code blocks","description":"Returns every code block as an array. A never-written row comes back as an empty array.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Current code blocks.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CodeBlock"}}}}},"401":{"description":"Missing or invalid JWT"},"502":{"description":"DATA_SERVICE_ERROR — upstream data service failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["DATA_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]}}}}}},"post":{"tags":["Code blocks"],"summary":"Create a code block","description":"Creates a code block with a server-minted id.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CodeBlockInput"}}}},"responses":{"201":{"description":"The created code block.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CodeBlock"}}}},"400":{"description":"Invalid request. `INVALID_CODE_BLOCK` — the body/params failed schema validation (`message` lists the offending fields). `LANGUAGE_NOT_AVAILABLE` — the requested language cannot be created or set (currently only `javascript` and `css` are available on write).","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["INVALID_CODE_BLOCK"]},"message":{"type":"string"}},"required":["error","message"]},{"type":"object","properties":{"error":{"type":"string","enum":["LANGUAGE_NOT_AVAILABLE"]},"language":{"type":"string"}},"required":["error","language"]}]}}}},"401":{"description":"Missing or invalid JWT"},"409":{"description":"DESIGN_LOCKED — a concurrent design write holds the lock","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["DESIGN_LOCKED"]}},"required":["error"]}}}},"500":{"description":"LOCK_BACKEND_UNAVAILABLE — the lock backend is unreachable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["LOCK_BACKEND_UNAVAILABLE"]}},"required":["error"]}}}},"502":{"description":"DATA_SERVICE_ERROR — upstream data service failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["DATA_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]}}}}}}},"/v2/code-blocks/{id}":{"get":{"tags":["Code blocks"],"summary":"Read a single code block","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The code block.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CodeBlock"}}}},"401":{"description":"Missing or invalid JWT"},"404":{"description":"CODE_BLOCK_NOT_FOUND — no code block with that id","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["CODE_BLOCK_NOT_FOUND"]}},"required":["error"]}}}},"502":{"description":"DATA_SERVICE_ERROR — upstream data service failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["DATA_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]}}}}}},"patch":{"tags":["Code blocks"],"summary":"Update a code block","description":"Partial merge — only the fields present in the body change.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CodeBlockPatch"}}}},"responses":{"200":{"description":"The updated code block.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CodeBlock"}}}},"400":{"description":"Invalid request. `INVALID_CODE_BLOCK` — the body/params failed schema validation (`message` lists the offending fields). `LANGUAGE_NOT_AVAILABLE` — the requested language cannot be created or set (currently only `javascript` and `css` are available on write).","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["INVALID_CODE_BLOCK"]},"message":{"type":"string"}},"required":["error","message"]},{"type":"object","properties":{"error":{"type":"string","enum":["LANGUAGE_NOT_AVAILABLE"]},"language":{"type":"string"}},"required":["error","language"]}]}}}},"401":{"description":"Missing or invalid JWT"},"404":{"description":"CODE_BLOCK_NOT_FOUND — no code block with that id","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["CODE_BLOCK_NOT_FOUND"]}},"required":["error"]}}}},"409":{"description":"DESIGN_LOCKED — a concurrent design write holds the lock","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["DESIGN_LOCKED"]}},"required":["error"]}}}},"500":{"description":"LOCK_BACKEND_UNAVAILABLE — the lock backend is unreachable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["LOCK_BACKEND_UNAVAILABLE"]}},"required":["error"]}}}},"502":{"description":"DATA_SERVICE_ERROR — upstream data service failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["DATA_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]}}}}}},"delete":{"tags":["Code blocks"],"summary":"Delete a code block","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"responses":{"204":{"description":"Deleted."},"401":{"description":"Missing or invalid JWT"},"404":{"description":"CODE_BLOCK_NOT_FOUND — no code block with that id","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["CODE_BLOCK_NOT_FOUND"]}},"required":["error"]}}}},"409":{"description":"DESIGN_LOCKED — a concurrent design write holds the lock","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["DESIGN_LOCKED"]}},"required":["error"]}}}},"500":{"description":"LOCK_BACKEND_UNAVAILABLE — the lock backend is unreachable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["LOCK_BACKEND_UNAVAILABLE"]}},"required":["error"]}}}},"502":{"description":"DATA_SERVICE_ERROR — upstream data service failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["DATA_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]}}}}}}},"/v1/admin/migrations/run":{"post":{"tags":["Admin migrations"],"summary":"Run a blob migration over this website","description":"Moves this website's stored JSON blobs up their version chains — the same run `src/cli.ts` drives from a shell, behind HTTP so datamanagement can trigger it without a container.\n\n**Scope is the token, not the body.** The website comes from the JWT, so one call covers one website and there is no way to ask for another one. The CLI's `--website all` has no counterpart here on purpose: a fleet run is a batch job, not a request.\n\nSend `dryRun: true` first. A dry run reads every item, reports the same counts a real run would, writes nothing and journals nothing — it is safe against production data. `dryRun` is mandatory, so neither answer is ever the one nobody chose.\n\nA real run journals each item's previous value before writing it and returns the whole journal in `journal` — **the response is the undo material**. Canvas keeps nothing: store these entries to be able to roll the run back. A dry run journals nothing, so `journal` is `[]`.\n\n**Not all of it belongs to this website.** A run also migrates the shared libraries attached to it, and a shared library is one row read by many websites — only the first website to reach it journals its `before`. Each entry therefore carries a `scopeId`: either this website, or the library the row belongs to. **Split the journal by `scopeId` before storing it**, replay the entries whose scope is this website against `/v1/admin/migrations/replay`, and the rest against `/v1/admin/migrations/replay-library` as a separate, deliberate action. Posting the whole journal back under this website reverts those shared libraries for every website that links them, with no record on their side, and it succeeds silently.\n\nFailures are counted per item, never raised: a run that could not write four rows still answers `200` and reports what it did to the rest.\n\n`repairs` runs a versionless fix after `groups` — or instead of them, on a repairs-only run: `groups: []`, or `groups` omitted while `repairs` is named. Unlike the version chain a repair never bumps `_v` and can run any number of times; see the field descriptions.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"groups":{"anyOf":[{"type":"string","enum":["all"]},{"type":"array","items":{"type":"string","enum":["documents","library","design","forms","codeBlocks"]}}],"description":"Which blob groups to move. Omitted covers every group the chain registry knows — unless `repairs` names at least one repair, in which case omitted means repairs-only and the version chain is skipped entirely. `[]` is the explicit form of repairs-only, and requires `repairs`; `[]` with no `repairs` is refused as nothing to run.","example":["design","forms"]},"targetVersion":{"anyOf":[{"type":"string","enum":["latest"]},{"type":"integer","minimum":0,"exclusiveMinimum":true}],"default":"latest","description":"The version to migrate to. `latest` (the default) resolves each group's own latest version — needed whenever more than one group runs, since the chains are not all the same length (`documents` reaches v2, the rest v1).","example":"latest"},"dryRun":{"type":"boolean","description":"Report what would change and touch nothing, or apply the run. Mandatory and deliberately not defaulted: a default `false` writes to a live website on a typo, and a default `true` silently does nothing when the caller meant to apply.","example":true},"runId":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,128}$","description":"Names the run, for whoever stores its journal. Defaults to the start timestamp plus the website id. Not checked for reuse here: nothing on this side outlives the request, so uniqueness is the caller's own key (datamanagement's `UNIQUE (run_id, scope_id)`).","example":"nightly-2026-09-04"},"repairs":{"type":"array","items":{"type":"string","enum":["symbolIdRenames"]},"minItems":1,"description":"Versionless repairs to run after `groups` for this website — or instead of them, when `groups` is `[]` or omitted with `repairs` named (see `groups`). A repair fixes content rather than format, so it never bumps a blob's `_v` and can run any number of times. Omitted by default: a plain version run never pays for the extra lookup a repair may need. An empty list is refused, like an empty `groups` with no `repairs` to fall back on.","example":["symbolIdRenames"]}},"required":["dryRun"]}}}},"responses":{"200":{"description":"The run finished. `results` carries one row per group with the per-item counts, and `journal` one entry per item written; a non-zero `failed` is reported here, not as an error status","content":{"application/json":{"schema":{"type":"object","properties":{"runId":{"type":"string"},"dryRun":{"type":"boolean"},"results":{"type":"array","items":{"type":"object","properties":{"websiteId":{"type":"string"},"group":{"type":"string"},"migrated":{"type":"number"},"skipped":{"type":"number"},"ahead":{"type":"number"},"failed":{"type":"number"},"filtered":{"type":"number"},"refused":{"type":"number"},"unchecked":{"type":"number"},"errors":{"type":"array","items":{"type":"string"}}},"required":["websiteId","group","migrated","skipped","ahead","failed","filtered","refused","unchecked","errors"]}},"journal":{"type":"array","items":{"type":"object","properties":{"group":{"type":"string"},"targetVersion":{"type":"integer","minimum":0},"ref":{"type":"object","properties":{"id":{"type":"string","minLength":1}},"required":["id"],"additionalProperties":{"nullable":true}},"before":{"nullable":true},"kind":{"type":"string","enum":["repair"]},"repair":{"type":"string"},"after":{"nullable":true},"scopeId":{"type":"string","description":"The scope this entry has to be replayed under — this website, or the shared library the row belongs to. Store entries by this value and replay each group under its own scope.","example":"lib_b06a14cd23564d448ff8c90f5946fd78"}},"required":["group","targetVersion","ref","scopeId"]}}},"required":["runId","dryRun","results","journal"]}}}},"400":{"description":"INVALID_OP — request body did not match the schema","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["INVALID_OP"]},"issues":{"type":"array","items":{"nullable":true}}},"required":["error","issues"]}}}},"401":{"description":"Missing or invalid JWT"},"403":{"description":"Account actor, a component actor from an external peer, or a component token with no `ctx.web` — this route takes a component token with `ctx.web`, from inside the cluster"}}}},"/v1/admin/migrations/run-library":{"post":{"tags":["Admin migrations"],"summary":"Run a blob migration over shared libraries","description":"Moves library items up the `library` version chain, scoped by the library instead of by a website — the CLI's `--library` mode behind HTTP.\n\n**Scope is the account, not a website.** A shared library is one row serving many websites, so `/v1/admin/migrations/run` either migrates it once per website or skips it entirely when its owner account is attached to none of them. Send a component token minted for the library's owner (`ctx.acc`, **no** `ctx.web`); that account is the authorization boundary, and the body names which of its libraries to move.\n\nSend `dryRun: true` first. A dry run reads every item, reports the same counts a real run would, writes nothing and journals nothing. `dryRun` is mandatory, so neither answer is ever the one nobody chose.\n\nA real run journals each item's previous value before writing it and returns the whole journal in `journal` — **the response is the undo material**. Every entry's `ref.libraryId` names its library, so a multi-library run can be stored and rolled back per library through `/v1/admin/migrations/replay-library`. A dry run journals nothing, so `journal` is `[]`.\n\nFailures are counted per item, never raised: a run that could not write four items still answers `200` and reports what it did to the rest.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"libraries":{"type":"array","items":{"type":"string","pattern":"^lib_[A-Za-z0-9]{1,64}$"},"minItems":1,"maxItems":50,"description":"The solidpixels library ids to migrate. Non-empty, unique, and at most 50 per call — the token reaches every library its owner account holds, and walking all of them is a batch job.","example":["lib_b06a14cd23564d448ff8c90f5946fd78"]},"targetVersion":{"anyOf":[{"type":"string","enum":["latest"]},{"type":"integer","minimum":0,"exclusiveMinimum":true}],"default":"latest","description":"The version to migrate to. `latest` (the default) resolves the `library` chain's own latest version.","example":"latest"},"dryRun":{"type":"boolean","description":"Report what would change and touch nothing, or apply the run. Mandatory and deliberately not defaulted: a default `false` writes to a live library on a typo, and a default `true` silently does nothing when the caller meant to apply.","example":true},"runId":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,128}$","description":"Names the run, for whoever stores its journal. Defaults to the start timestamp plus `-library`. Not checked for reuse here: nothing on this side outlives the request, so uniqueness is the caller's own key.","example":"library-2026-09-05"}},"required":["libraries","dryRun"]}}}},"responses":{"200":{"description":"The run finished. One `results` row per library, with `websiteId` carrying the `lib_` id — the runner treats a scope id as opaque — and `journal` one entry per item written. A non-zero `failed` is reported here, not as an error status","content":{"application/json":{"schema":{"type":"object","properties":{"runId":{"type":"string"},"dryRun":{"type":"boolean"},"results":{"type":"array","items":{"type":"object","properties":{"websiteId":{"type":"string"},"group":{"type":"string"},"migrated":{"type":"number"},"skipped":{"type":"number"},"ahead":{"type":"number"},"failed":{"type":"number"},"filtered":{"type":"number"},"refused":{"type":"number"},"unchecked":{"type":"number"},"errors":{"type":"array","items":{"type":"string"}}},"required":["websiteId","group","migrated","skipped","ahead","failed","filtered","refused","unchecked","errors"]}},"journal":{"type":"array","items":{"type":"object","properties":{"group":{"type":"string"},"targetVersion":{"type":"integer","minimum":0},"ref":{"type":"object","properties":{"id":{"type":"string","minLength":1}},"required":["id"],"additionalProperties":{"nullable":true}},"before":{"nullable":true},"kind":{"type":"string","enum":["repair"]},"repair":{"type":"string"},"after":{"nullable":true},"scopeId":{"type":"string","description":"The scope this entry has to be replayed under — this website, or the shared library the row belongs to. Store entries by this value and replay each group under its own scope.","example":"lib_b06a14cd23564d448ff8c90f5946fd78"}},"required":["group","targetVersion","ref","scopeId"]}}},"required":["runId","dryRun","results","journal"]}}}},"400":{"description":"INVALID_OP — request body did not match the schema","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["INVALID_OP"]},"issues":{"type":"array","items":{"nullable":true}}},"required":["error","issues"]}}}},"401":{"description":"Missing or invalid JWT"},"403":{"description":"Account actor, a component actor from an external peer, or a component token with no `ctx.acc` — this route takes a component token delegated to the library's owner account, from inside the cluster"}}}},"/v1/admin/migrations/replay":{"post":{"tags":["Admin migrations"],"summary":"Roll a blob migration run back on this website","description":"Writes a run's journalled `before` values back through the same stores the run wrote with — the same `replayRun` `src/cli.ts replay` drives, behind HTTP so a rollback no longer needs the pod that ran the migration.\n\n**The undo material comes in the body.** Canvas keeps nothing: send the `journal` a run returned (`/v1/admin/migrations/run`) exactly as it came back. `scopeId` names the website it was written for and must match the token.\n\nSend `dryRun: true` first. It reports what would be restored and writes nothing.\n\nAn item goes back only when it still holds what the run wrote: `after` is not journalled, so it is recomputed as migrate(before) and compared. Anything edited since the run is `skipped` and reported, an item already at its original value is a `noop` (a killed run, or a second replay of the same one), and a deleted item cannot be recreated. Replaying twice is safe.\n\nFailures are counted per item, never raised: a rollback that could not write four rows still answers `200` and reports what it did to the rest.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"runId":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,128}$","description":"The run being rolled back. Reported back and logged; nothing is looked up by it, because the entries are in this body.","example":"nightly-2026-09-04"},"scopeId":{"type":"string","pattern":"^web_[A-Za-z0-9]{1,64}$","description":"The website this journal was written for. It must equal the token's website (`403` otherwise). Redundant on purpose: a journal replayed under another website’s token reads as every item `gone since the run` and rolls nothing back, which is worse than a refusal.","example":"web_f96f798fb4704a28991dadfb9c7ae3f9"},"entries":{"type":"array","items":{"type":"object","properties":{"group":{"type":"string"},"targetVersion":{"type":"integer","minimum":0},"ref":{"type":"object","properties":{"id":{"type":"string","minLength":1}},"required":["id"],"additionalProperties":{"nullable":true}},"before":{"nullable":true},"kind":{"type":"string","enum":["repair"]},"repair":{"type":"string"},"after":{"nullable":true}},"required":["group","targetVersion","ref"]},"minItems":1,"description":"The `journal` a run returned for this website, verbatim. Non-empty: an empty rollback reads as \"nothing to do\" but would report a clean pass over a run nobody undid."},"dryRun":{"type":"boolean","description":"Rehearse the rollback and touch nothing, or apply it. Mandatory and deliberately not defaulted, exactly as on a run.","example":true}},"required":["runId","scopeId","entries","dryRun"]}}}},"responses":{"200":{"description":"The rollback finished. `results` carries one row per website with the per-item counts; `skipped` and a non-zero `failed` are reported here, not as an error status","content":{"application/json":{"schema":{"type":"object","properties":{"runId":{"type":"string"},"dryRun":{"type":"boolean"},"results":{"type":"array","items":{"type":"object","properties":{"websiteId":{"type":"string"},"restored":{"type":"number"},"noop":{"type":"number"},"skipped":{"type":"number"},"failed":{"type":"number"},"errors":{"type":"array","items":{"type":"string"}}},"required":["websiteId","restored","noop","skipped","failed","errors"]}}},"required":["runId","dryRun","results"]}}}},"400":{"description":"INVALID_OP — request body did not match the schema","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["INVALID_OP"]},"issues":{"type":"array","items":{"nullable":true}}},"required":["error","issues"]}}}},"401":{"description":"Missing or invalid JWT"},"403":{"description":"Account actor, a component actor from an external peer, a component token with no `ctx.web`, or a `scopeId` that is not the token’s website","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["Forbidden"]}},"required":["error"]}}}},"413":{"description":"JOURNAL_TOO_LARGE — body over 8388608 bytes","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["JOURNAL_TOO_LARGE"]}},"required":["error"]}}}}}}},"/v1/admin/migrations/replay-library":{"post":{"tags":["Admin migrations"],"summary":"Roll a blob migration run back on shared libraries","description":"The library twin of `/v1/admin/migrations/replay`: same `replayRun`, same direct library store `/v1/admin/migrations/run-library` writes through, scoped by the owner account instead of by a website.\n\n**Scope is the account plus the ids in the body.** Send a component token minted for the libraries' owner (`ctx.acc`, **no** `ctx.web`) and the `journal` that run returned. Every entry has to name a library the body lists.\n\nSend `dryRun: true` first. It reports what would be restored and writes nothing. The per-item rules are the run’s mirror image and are described on `/v1/admin/migrations/replay`.\n\nFailures are counted per item, never raised: a rollback that could not write four items still answers `200` and reports what it did to the rest.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"runId":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,128}$","description":"The run being rolled back. Reported back and logged; nothing is looked up by it, because the entries are in this body.","example":"library-2026-09-05"},"libraries":{"type":"array","items":{"type":"string","pattern":"^lib_[A-Za-z0-9]{1,64}$"},"minItems":1,"maxItems":50,"description":"The libraries to roll back. Every entry must name one of these in `ref.libraryId` (`400` otherwise) — this list is the scope the caller is asking to touch, and an entry outside it would be dropped while the response still read as a clean rollback.","example":["lib_b06a14cd23564d448ff8c90f5946fd78"]},"entries":{"type":"array","items":{"type":"object","properties":{"group":{"type":"string"},"targetVersion":{"type":"integer","minimum":0},"ref":{"type":"object","properties":{"id":{"type":"string","minLength":1}},"required":["id"],"additionalProperties":{"nullable":true}},"before":{"nullable":true},"kind":{"type":"string","enum":["repair"]},"repair":{"type":"string"},"after":{"nullable":true}},"required":["group","targetVersion","ref"]},"minItems":1,"description":"The `journal` a run returned, verbatim. One flat list across libraries: each entry's `ref.libraryId` says which one it belongs to."},"dryRun":{"type":"boolean","description":"Rehearse the rollback and touch nothing, or apply it. Mandatory and deliberately not defaulted, exactly as on a run.","example":true}},"required":["runId","libraries","entries","dryRun"]}}}},"responses":{"200":{"description":"The rollback finished. One `results` row per library, with `websiteId` carrying the `lib_` id — the runner treats a scope id as opaque. `skipped` and a non-zero `failed` are reported here, not as an error status","content":{"application/json":{"schema":{"type":"object","properties":{"runId":{"type":"string"},"dryRun":{"type":"boolean"},"results":{"type":"array","items":{"type":"object","properties":{"websiteId":{"type":"string"},"restored":{"type":"number"},"noop":{"type":"number"},"skipped":{"type":"number"},"failed":{"type":"number"},"errors":{"type":"array","items":{"type":"string"}}},"required":["websiteId","restored","noop","skipped","failed","errors"]}}},"required":["runId","dryRun","results"]}}}},"400":{"description":"INVALID_OP — request body did not match the schema, or an entry names a library `libraries` does not list","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["INVALID_OP"]},"issues":{"type":"array","items":{"nullable":true}}},"required":["error","issues"]}}}},"401":{"description":"Missing or invalid JWT"},"403":{"description":"Account actor, a component actor from an external peer, or a component token with no `ctx.acc`","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["Forbidden"]}},"required":["error"]}}}},"413":{"description":"JOURNAL_TOO_LARGE — body over 8388608 bytes","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["JOURNAL_TOO_LARGE"]}},"required":["error"]}}}}}}},"/v2/design/capabilities":{"get":{"tags":["Design"],"summary":"Read the design authoring vocabulary (slots, states, primitives, fonts)","description":"Static discovery doc: the complete vocabulary for authoring design ops. `slots` are the style slots a `setElementStyle`/node style accepts, each with the token `category` it expects and whether a keyword form is allowed. A slot value is a StyleRef — `{type:\"value\"|\"token\"|\"keyword\"}`; token refs resolve project → platform → primitive (late binding). `fonts` lists the `setFont`/`setTypography` vocabulary: allowed sources, the `weightFiles` key pattern, accepted font file formats, and typography roles. Not website-scoped; safe to cache.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"The design authoring vocabulary.","content":{"application/json":{"schema":{"type":"object","properties":{"slots":{"type":"object","additionalProperties":{"type":"object","properties":{"category":{"type":"string"},"kind":{"type":"string"},"keyword":{"type":"boolean"}},"required":["category","kind","keyword"]}},"states":{"type":"array","items":{"type":"string"}},"primitives":{"type":"object","additionalProperties":{"type":"object","additionalProperties":{"nullable":true}}},"variableTypes":{"type":"array","items":{"type":"string"}},"fonts":{"type":"object","properties":{"sources":{"type":"array","items":{"type":"string"}},"weightKeyPattern":{"type":"string"},"fileFormats":{"type":"array","items":{"type":"string"}},"typographyRoles":{"type":"array","items":{"type":"string"}}},"required":["sources","weightKeyPattern","fileFormats","typographyRoles"]}},"required":["slots","states","primitives","variableTypes","fonts"]}}}},"401":{"description":"Missing or invalid JWT"}}}},"/v1/seed":{"get":{"tags":["Seed"],"summary":"Return the complete initial seed for a new web","description":"Returns the full initial seed (design variables, token layers, seed pages) for a freshly created web as JSON, for Data Service to persist during web creation. Seed page copy follows `?locale`. Read-only — does not write to the data store.","security":[],"parameters":[{"schema":{"type":"string","enum":["en","cs"],"default":"en","description":"Locale of the seed copy. The layout is identical across locales; only the authored text differs. Defaults to `en`.","example":"en"},"required":false,"description":"Locale of the seed copy. The layout is identical across locales; only the authored text differs. Defaults to `en`.","name":"locale","in":"query"}],"responses":{"200":{"description":"The initial seed for a new web.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InitialSeed"}}}}}}},"/v1/seed/404":{"get":{"tags":["Seed"],"summary":"Return the seed for the protected 404 page","description":"Returns the seed for the protected 404 page (page metadata plus its starting document) as JSON. The same page the whole-web seed bundles in `GET /v1/seed`. Read-only — does not write to the data store.","security":[],"parameters":[{"schema":{"type":"string","enum":["en","cs"],"default":"en","description":"Locale of the seed copy. The layout is identical across locales; only the authored text differs. Defaults to `en`.","example":"en"},"required":false,"description":"Locale of the seed copy. The layout is identical across locales; only the authored text differs. Defaults to `en`.","name":"locale","in":"query"}],"responses":{"200":{"description":"Return the seed for the protected 404 page","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SeedPage"},"example":{"page":{"name":"page_404","label":"404","uri":"404","type":"page","isPublished":true,"isProtected":true,"isHomepage":false,"isUtility":true,"document":{"nodes":{},"rootLayoutId":"node-0"}}}}}}}}},"/v1/seed/collection-template":{"get":{"tags":["Seed"],"summary":"Return the seed for a new collection template page","description":"Returns the seed for a freshly created collection template page (page metadata plus its starting document, bound to the rendered collection) as JSON. Read-only — does not write to the data store.","security":[],"parameters":[{"schema":{"type":"string","enum":["en","cs"],"default":"en","description":"Locale of the seed copy. The layout is identical across locales; only the authored text differs. Defaults to `en`.","example":"en"},"required":false,"description":"Locale of the seed copy. The layout is identical across locales; only the authored text differs. Defaults to `en`.","name":"locale","in":"query"}],"responses":{"200":{"description":"Return the seed for a new collection template page","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SeedPage"},"example":{"page":{"name":"page_collection_template","label":"New Collection Template","uri":"collection-template","type":"template","isPublished":false,"isProtected":false,"isHomepage":false,"isUtility":false,"document":{"nodes":{},"rootLayoutId":"node-0"}}}}}}}}},"/v1/settings/favicon":{"put":{"tags":["Settings"],"summary":"Set or clear the website favicon","description":"Stores the favicon file id as the `favicon` website setting via the solidpixels website-settings API, creating the setting row on first write. Pass `fileId: null` to clear it. Website-scoped write. **Experimental — API subject to change.**","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"fileId":{"type":"string","nullable":true,"description":"Id of the favicon file (as returned by the files API), or `null` to clear the favicon.","example":"fi_6gt4odehaf7g"}},"required":["fileId"]}}}},"responses":{"200":{"description":"Favicon setting updated","content":{"application/json":{"schema":{"type":"object","properties":{"fileId":{"type":"string","nullable":true}},"required":["fileId"]}}}},"400":{"description":"INVALID_OP — request body did not match the schema","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["INVALID_OP"]},"issues":{"type":"array","items":{"nullable":true}}},"required":["error","issues"]}}}},"401":{"description":"Missing or invalid JWT"},"502":{"description":"SOLIDPIXELS_SERVICE_ERROR — upstream solidpixels service failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["SOLIDPIXELS_SERVICE_ERROR"]},"upstreamStatus":{"type":"number"}},"required":["error","upstreamStatus"]}}}}}}}}}