{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "InfographicLayout", "type": "object", "description": "Infographic layout description with theme and node tree", "properties": { "theme": { "type": "object", "description": "Global design tokens (colors, typography, etc.)", "properties": { "colors": { "type": "object", "description": "Color tokens used across the infographic", "patternProperties": { "^[a-zA-Z_][a-zA-Z0-9_]*$": { "type": "string", "description": "Color value (e.g. hex, rgba, or implementation-defined token)" } }, "additionalProperties": false }, "typography": { "type": "object", "description": "Typography style tokens (e.g. H1, H2, Body)", "patternProperties": { "^[a-zA-Z_][a-zA-Z0-9_]*$": { "type": "object", "properties": { "font": { "type": "string", "description": "Font family name (and optionally style info, implementation-defined)" }, "size": { "type": "number", "description": "Font size, typically in px" }, "weight": { "type": "string", "description": "Font weight (e.g. 'normal', 'bold', '600')" } }, "required": ["font", "size"], "additionalProperties": true } }, "additionalProperties": false } }, "additionalProperties": false }, "root": { "$ref": "#/definitions/Node", "description": "Root node of the infographic layout tree" } }, "required": ["root"], "additionalProperties": false, "definitions": { "Node": { "oneOf": [ { "$ref": "#/definitions/Group" }, { "$ref": "#/definitions/Stack" }, { "$ref": "#/definitions/Text" }, { "$ref": "#/definitions/Image" }, { "$ref": "#/definitions/Chart" }, { "$ref": "#/definitions/Shape" } ] }, "Padding": { "oneOf": [ { "type": "number", "description": "Uniform padding on all sides (px)" }, { "type": "object", "description": "Per-side padding (px)", "properties": { "top": { "type": "number" }, "right": { "type": "number" }, "bottom": { "type": "number" }, "left": { "type": "number" } }, "required": ["top", "right", "bottom", "left"], "additionalProperties": false } ] }, "OverlapConstraint": { "type": "object", "description": "Relative overlap constraint between two children in a STACK", "properties": { "sourceId": { "type": "string", "description": "ID of the element being constrained" }, "targetId": { "type": "string", "description": "ID of the reference element" }, "type": { "type": "string", "enum": ["FULLY_INSIDE", "NON_OVERLAP", "PARTIALLY_OVERLAP"], "description": "Overlap constraint type" }, "minDistance": { "type": "number", "description": "Minimum distance in pixels when type is NON_OVERLAP" }, "overlapPercentage": { "type": "number", "minimum": 0, "maximum": 100, "description": "Required overlap percentage (0–100) when type is PARTIALLY_OVERLAP" } }, "required": ["sourceId", "targetId", "type"], "additionalProperties": false }, "AlignmentConstraint": { "type": "object", "description": "Simple pairwise alignment constraint between two children in a STACK", "properties": { "sourceId": { "type": "string", "description": "ID of the element being aligned" }, "targetId": { "type": "string", "description": "ID of the reference element to align to" }, "type": { "type": "string", "enum": ["TOP", "BOTTOM", "LEFT", "RIGHT"], "description": "Which edge of source should align to the same edge of target" } }, "required": ["sourceId", "targetId", "type"], "additionalProperties": false }, "Group": { "type": "object", "description": "Flow layout container (row/column)", "properties": { "id": { "type": "string", "description": "Unique identifier for the group element" }, "type": { "const": "GROUP" }, "direction": { "type": "string", "enum": ["ROW", "COLUMN"], "description": "Layout direction of children" }, "alignment": { "type": "object", "description": "Main-axis and cross-axis alignment (simplified)", "properties": { "main": { "type": "string", "enum": ["START", "CENTER", "END"], "description": "Alignment along the layout direction" }, "cross": { "type": "string", "enum": ["START", "CENTER", "END", "STRETCH"], "description": "Alignment perpendicular to the layout direction" } }, "required": ["main", "cross"], "additionalProperties": false }, "spacing": { "type": "number", "description": "Spacing between children (px)" }, "padding": { "$ref": "#/definitions/Padding" }, "children": { "type": "array", "items": { "$ref": "#/definitions/Node" } } }, "required": ["id", "type", "direction", "alignment", "children"], "additionalProperties": false }, "Stack": { "type": "object", "description": "Stacked layout (children layered in z-order, like a Stack/ZStack)", "properties": { "id": { "type": "string", "description": "Unique identifier for the stack element" }, "type": { "const": "STACK" }, "alignment": { "type": "string", "enum": [ "TOP_LEFT", "TOP_CENTER", "TOP_RIGHT", "CENTER_LEFT", "CENTER", "CENTER_RIGHT", "BOTTOM_LEFT", "BOTTOM_CENTER", "BOTTOM_RIGHT" ], "description": "Default alignment of children within the stack bounds" }, "children": { "type": "array", "items": { "$ref": "#/definitions/Node" } }, "overlapConstraints": { "type": "array", "description": "Overlap constraints between children in this stack", "items": { "$ref": "#/definitions/OverlapConstraint" } }, "alignmentConstraints": { "type": "array", "description": "Pairwise alignment constraints between children in this stack", "items": { "$ref": "#/definitions/AlignmentConstraint" } } }, "required": ["id", "type", "alignment", "children"], "additionalProperties": false }, "Chart": { "type": "object", "description": "Chart placeholder node (semantics handled outside this grammar)", "properties": { "id": { "type": "string", "description": "Unique identifier for the chart element" }, "type": { "const": "CHART" }, "width": { "type": "number", "description": "Chart width (px)" }, "height": { "type": "number", "description": "Chart height (px)" } }, "required": ["id", "type", "width", "height"], "additionalProperties": false }, "Text": { "type": "object", "description": "Text node; visual style is driven mainly by theme.typography + role", "properties": { "id": { "type": "string", "description": "Unique identifier for the text element" }, "type": { "const": "TEXT" }, "content": { "type": "string", "description": "Text content" }, "role": { "type": "string", "enum": [ "TITLE_PRIMARY", "TITLE_NUMBER", "TITLE_CONTEXT", "SUBTITLE", "CAPTION" ], "description": "Semantic role of the text, used to map to typography tokens" }, "color": { "type": "string", "description": "Optional color override; if omitted, renderer may use theme colors based on role" }, "maxLines": { "type": "integer", "description": "Maximum number of lines to render (truncation behavior is implementation-defined)" } }, "required": ["id", "type", "content", "role"], "additionalProperties": false }, "Image": { "type": "object", "description": "Image node", "properties": { "id": { "type": "string", "description": "Unique identifier for the image element" }, "type": { "const": "IMAGE" }, "src": { "type": "string", "description": "Image source (URL or asset identifier)" }, "width": { "type": "number", "description": "Image width (px)" }, "height": { "type": "number", "description": "Image height (px)" }, "fit": { "type": "string", "enum": ["COVER", "CONTAIN", "FILL"], "description": "How the image fits into its bounding box" }, "radius": { "type": "number", "description": "Corner radius for rounded images (px)" } }, "required": ["id", "type", "src"], "additionalProperties": false }, "Shape": { "type": "object", "description": "Basic geometric or path-based shape with free-form attributes", "properties": { "id": { "type": "string", "description": "Unique identifier for the shape element" }, "type": { "type": "string", "enum": ["RECT", "CIRCLE", "PATH"], "description": "Shape type" }, "attrs": { "type": "object", "description": "Implementation-defined attributes for the shape (e.g. width, height, radius, path, color, strokeColor, strokeWidth, etc.)", "additionalProperties": true } }, "required": ["id", "type"], "additionalProperties": false } } }