{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://nuncaeslupus.github.io/drawspec/schema/drawspec-v1.schema.json",
  "title": "drawspec document, version 1",
  "description": "A declarative diagram. The author describes what the diagram means; every decision that requires seeing the output — coordinates, type size, colour, arrow-head geometry, z-order — is taken by drawspec and has no field here. Referential rules (node ids are unique; an edge names nodes that exist) are beyond JSON Schema and are enforced by `drawspec validate`, as are the readability budget (the most entries each kind may hold) and the cap of 2 elements with the 'emphasis' role (docs/format.md).",
  "oneOf": [
    {
      "type": "object",
      "title": "flow",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "flow"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "nodes": {
          "type": "array",
          "description": "The boxes. Order is not a coordinate — the layout decides where a box goes — but it is the order siblings are drawn in: where nothing else separates two boxes of the same rank, they read in the order written here.",
          "items": {
            "$ref": "#/$defs/node"
          },
          "minItems": 1
        },
        "edges": {
          "type": "array",
          "description": "What connects to what. A `tree` takes one edge per child.",
          "items": {
            "$ref": "#/$defs/edge"
          }
        },
        "groups": {
          "type": "array",
          "description": "Boxes drawn around sets of nodes, each with its own caption.",
          "items": {
            "$ref": "#/$defs/group"
          }
        },
        "bands": {
          "type": "array",
          "description": "Named things that run alongside a set of boxes rather than containing them — drawn as a labelled bar beside the boxes they accompany. For the activity that goes on throughout: a source sheet with one continuous concern above its steps and another below says the steps are *surrounded* by them, and two such bands are peers. A `group` cannot say that — a box sits inside one container or none, so two groups over the same members had to be nested, which draws a hierarchy that is not there.",
          "items": {
            "$ref": "#/$defs/band"
          }
        },
        "classes": {
          "type": "array",
          "description": "The classes the boxes are sorted into, each `{id, text}`: 1 to 4, every one used by some node. Each is drawn as a faint fill from the theme's fixed sequence (`[classes] fills`: a grey wash, then patterns), in the order declared, and the key under the drawing names each by its `text`. For a grouping the reader must see across the whole drawing — external systems greyed in a C4 context, steps by owning team.",
          "items": {
            "$ref": "#/$defs/class"
          },
          "minItems": 1
        },
        "loops": {
          "type": "array",
          "description": "The feedback loops of a causal loop diagram, each named and marked R (reinforcing) or B (balancing) inside the loop it closes — the type derived from the signs, never chosen. Needs `polarity` on the edges.",
          "items": {
            "$ref": "#/$defs/loop"
          }
        }
      },
      "required": [
        "version",
        "kind",
        "nodes"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "tree",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "tree"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "nodes": {
          "type": "array",
          "description": "The boxes. Order is not a coordinate — the layout decides where a box goes — but it is the order siblings are drawn in: where nothing else separates two boxes of the same rank, they read in the order written here.",
          "items": {
            "$ref": "#/$defs/node"
          },
          "minItems": 1
        },
        "edges": {
          "type": "array",
          "description": "What connects to what. A `tree` takes one edge per child.",
          "items": {
            "$ref": "#/$defs/edge"
          }
        },
        "groups": {
          "type": "array",
          "description": "Boxes drawn around sets of nodes, each with its own caption.",
          "items": {
            "$ref": "#/$defs/group"
          }
        },
        "bands": {
          "type": "array",
          "description": "Named things that run alongside a set of boxes rather than containing them — drawn as a labelled bar beside the boxes they accompany. For the activity that goes on throughout: a source sheet with one continuous concern above its steps and another below says the steps are *surrounded* by them, and two such bands are peers. A `group` cannot say that — a box sits inside one container or none, so two groups over the same members had to be nested, which draws a hierarchy that is not there.",
          "items": {
            "$ref": "#/$defs/band"
          }
        },
        "classes": {
          "type": "array",
          "description": "The classes the boxes are sorted into, each `{id, text}`: 1 to 4, every one used by some node. Each is drawn as a faint fill from the theme's fixed sequence (`[classes] fills`: a grey wash, then patterns), in the order declared, and the key under the drawing names each by its `text`. For a grouping the reader must see across the whole drawing — external systems greyed in a C4 context, steps by owning team.",
          "items": {
            "$ref": "#/$defs/class"
          },
          "minItems": 1
        }
      },
      "required": [
        "version",
        "kind",
        "nodes"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "cycle",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "cycle"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "nodes": {
          "type": "array",
          "description": "The boxes. Order is not a coordinate — the layout decides where a box goes — but it is the order siblings are drawn in: where nothing else separates two boxes of the same rank, they read in the order written here.",
          "items": {
            "$ref": "#/$defs/node"
          },
          "minItems": 1
        },
        "edges": {
          "type": "array",
          "description": "What connects to what. A `tree` takes one edge per child.",
          "items": {
            "$ref": "#/$defs/edge"
          }
        },
        "groups": {
          "type": "array",
          "description": "Boxes drawn around sets of nodes, each with its own caption.",
          "items": {
            "$ref": "#/$defs/group"
          }
        },
        "bands": {
          "type": "array",
          "description": "Named things that run alongside a set of boxes rather than containing them — drawn as a labelled bar beside the boxes they accompany. For the activity that goes on throughout: a source sheet with one continuous concern above its steps and another below says the steps are *surrounded* by them, and two such bands are peers. A `group` cannot say that — a box sits inside one container or none, so two groups over the same members had to be nested, which draws a hierarchy that is not there.",
          "items": {
            "$ref": "#/$defs/band"
          }
        },
        "hub": {
          "$ref": "#/$defs/hub",
          "description": "What the loop turns around: the system a quality cycle improves, the model a data flywheel retrains. Not a step — it is drawn in the middle of the ring, outside the check that the ring closes through every node. An edge may join it to a step only as a spoke, in the roles 'aside', 'weak', 'link': a solid arrow to the middle would read as one more step. Needs a ring of at least 3 steps."
        }
      },
      "required": [
        "version",
        "kind",
        "nodes"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "stack",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "stack"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "items": {
          "type": "array",
          "description": "The entries, in the order they are meant to be read: down for `stack`, along for `timeline` and `columns`.",
          "items": {
            "$ref": "#/$defs/item"
          },
          "minItems": 1
        }
      },
      "required": [
        "version",
        "kind",
        "items"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "timeline",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "timeline"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "items": {
          "type": "array",
          "description": "The entries, in the order they are meant to be read: down for `stack`, along for `timeline` and `columns`.",
          "items": {
            "$ref": "#/$defs/item"
          },
          "minItems": 1
        },
        "rise": {
          "type": "boolean",
          "description": "Whether the series ascends: each entry drawn taller than the one before it, all sitting on a common baseline — the canvas floor for `columns`, the axis itself for `timeline`. For a scale where the order is the content and not merely the reading direction — five levels of open data, three degrees of a change — and where equal entries say they are peers, which is the opposite. The author says the series rises; the theme's `[box] rise` says by how much, so there is no per-column height to get wrong. Not a `pyramid`: that draws the last level as the *narrowest*, which is the right shape for a maturity model and the wrong one for a ladder."
        },
        "spans": {
          "type": "array",
          "description": "Named intervals between two entries, drawn as bars under the axis. For the quantity that is not a thing on the diagram but the distance between two things on it: a recovery objective is not an event, it is how much lies between the last backup and the disaster.",
          "items": {
            "$ref": "#/$defs/span"
          }
        }
      },
      "required": [
        "version",
        "kind",
        "items"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "columns",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "columns"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "items": {
          "type": "array",
          "description": "The entries, in the order they are meant to be read: down for `stack`, along for `timeline` and `columns`.",
          "items": {
            "$ref": "#/$defs/item"
          },
          "minItems": 1
        },
        "rise": {
          "type": "boolean",
          "description": "Whether the series ascends: each entry drawn taller than the one before it, all sitting on a common baseline — the canvas floor for `columns`, the axis itself for `timeline`. For a scale where the order is the content and not merely the reading direction — five levels of open data, three degrees of a change — and where equal entries say they are peers, which is the opposite. The author says the series rises; the theme's `[box] rise` says by how much, so there is no per-column height to get wrong. Not a `pyramid`: that draws the last level as the *narrowest*, which is the right shape for a maturity model and the wrong one for a ladder."
        }
      },
      "required": [
        "version",
        "kind",
        "items"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "matrix",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "matrix"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "cells": {
          "type": "array",
          "description": "What is in the grid. A cell states where it starts, not where it is drawn.",
          "items": {
            "$ref": "#/$defs/cell"
          },
          "minItems": 1
        },
        "columns": {
          "type": "array",
          "description": "Column headings, left to right. Omit for a matrix with none.",
          "items": {
            "type": "string"
          }
        },
        "rows": {
          "type": "array",
          "description": "Row headings, top to bottom.",
          "items": {
            "type": "string"
          }
        },
        "edges": {
          "type": "array",
          "description": "What connects to what, between cells that carry an `id`. The cells of a grid are not always only cells: one may produce another, or come before it. The grid places them; the relations are a separate thing, and without them a reader sees a table where the source drew a process. An edge between cells in neighbouring rows that share no column, such as a return from the last output to the first process, turns along the join between the rows, and its label is wrapped onto a stretch of that join no other edge crosses.",
          "items": {
            "$ref": "#/$defs/edge"
          }
        },
        "scale": {
          "type": "array",
          "description": "Says the groups are **ordered**, and in what order: 2 to 5 group names, **weakest first** — `[\"rare\", \"sometimes\", \"often\"]`. For a heatmap, a risk matrix, a skills matrix: a grid whose cells say *how much*. The cells are then filled by tone, light to dark, from the theme's `[mark] ramp` instead of with unrelated patterns, and the key lists every step in this order (with `key` texts where given). Every cell `group` must be one of these; a cell with no `group` stays blank, for *not assessed*. Names, not numbers: the author buckets the values.",
          "items": {
            "type": "string"
          },
          "minItems": 2
        },
        "key": {
          "type": "array",
          "description": "What each group of cells is called, for the key drawn under the grid. Without one, a group is announced to the reader under the name the cells use for it — which is fine when that name is a name, and is how an id-shaped key like `carrega` ends up as visible text.",
          "items": {
            "$ref": "#/$defs/key"
          }
        }
      },
      "required": [
        "version",
        "kind",
        "cells"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "pyramid",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "pyramid"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "levels": {
          "type": "array",
          "description": "Apex first. The widest band is the last one written.",
          "items": {
            "$ref": "#/$defs/level"
          },
          "minItems": 1
        }
      },
      "required": [
        "version",
        "kind",
        "levels"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "rings",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "rings"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "rings": {
          "type": "array",
          "description": "Innermost first, working outwards.",
          "items": {
            "$ref": "#/$defs/ring"
          },
          "minItems": 1
        }
      },
      "required": [
        "version",
        "kind",
        "rings"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "funnel",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "funnel"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "stages": {
          "type": "array",
          "description": "Widest first: a funnel is a pyramid lying down.",
          "items": {
            "$ref": "#/$defs/stage"
          },
          "minItems": 1
        },
        "unit": {
          "type": "string",
          "description": "What the stages' amounts count — `visitors`, `applications`, `£k` — written after each one. Only with amounts."
        },
        "values": {
          "type": "boolean",
          "description": "`false` leaves the amounts and shares out and writes the stage names alone. Defaults to true."
        }
      },
      "required": [
        "version",
        "kind",
        "stages"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "chart",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "chart"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "axes": {
          "$ref": "#/$defs/axes",
          "description": "Both axes. An unlabelled axis cannot be read, so both are required."
        },
        "series": {
          "type": "array",
          "description": "What is plotted. More than one gets a legend.",
          "items": {
            "$ref": "#/$defs/series"
          },
          "minItems": 1
        },
        "values": {
          "type": "boolean",
          "description": "Whether to write each point's own number on the drawing. Defaults to true; set false for a chart whose shape is the message and whose numbers would be noise."
        }
      },
      "required": [
        "version",
        "kind",
        "axes",
        "series"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "quadrant",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "quadrant"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "axes": {
          "$ref": "#/$defs/axes-quadrant",
          "description": "The two named axes whose crossing makes the four quadrants."
        },
        "quadrants": {
          "type": "array",
          "description": "Exactly four names, one per quarter, written faint in its outer corner: top right first, then counter-clockwise — top left, bottom left, bottom right (Mermaid's order). An empty string leaves that quarter unnamed.",
          "items": {
            "type": "string"
          }
        },
        "positions": {
          "type": "array",
          "description": "The items placed in the plane, each by what it scores, not by where it goes.",
          "items": {
            "$ref": "#/$defs/position"
          },
          "minItems": 1
        }
      },
      "required": [
        "version",
        "kind",
        "axes",
        "positions"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "scatter",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "scatter"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "axes": {
          "$ref": "#/$defs/axes-continuous",
          "description": "Both axes, each read as a measurement — unlike `quadrant`'s."
        },
        "positions": {
          "type": "array",
          "description": "The points, each placed by its two measured values.",
          "items": {
            "$ref": "#/$defs/position"
          },
          "minItems": 1
        }
      },
      "required": [
        "version",
        "kind",
        "axes",
        "positions"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "curve",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "curve"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "spans": {
          "type": "array",
          "description": "Named distances between two waypoints, drawn as a capped line with the name beside it. For the quantity that is the gap itself: a cost variance is not a point on the drawing, it is how far one curve is from another, and a caption saying so states it without showing it. Either way round — two waypoints at one moment measure vertically, two at one value measure along.",
          "items": {
            "$ref": "#/$defs/span"
          }
        },
        "axes": {
          "$ref": "#/$defs/axes",
          "description": "Both axes. A named shape still needs saying what it is a shape of."
        },
        "curves": {
          "type": "array",
          "description": "The shapes drawn, each through its own waypoints.",
          "items": {
            "$ref": "#/$defs/curve"
          },
          "minItems": 1
        }
      },
      "required": [
        "version",
        "kind",
        "axes",
        "curves"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "files",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "files"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "root": {
          "type": "string",
          "description": "The folder everything is in, drawn as the top row. Omit it for a listing with several top-level entries and no common parent."
        },
        "entries": {
          "type": "array",
          "description": "The paths, one per entry. Siblings keep the order written here.",
          "items": {
            "$ref": "#/$defs/entry"
          },
          "minItems": 1
        },
        "sort": {
          "type": "string",
          "description": "How siblings are ordered: `given` (the default) keeps the order written, `name` sorts naturally (`file2` before `file10`), `folders-first` sorts by name with folders above files. A `...` row stays last.",
          "enum": [
            "given",
            "name",
            "folders-first"
          ]
        },
        "style": {
          "type": "string",
          "description": "`icons` (the default) draws folder and file pictures; `plain` draws the names and guides only; `unicode` and `ascii` draw the tree as monospace text, with box-drawing or plain ASCII branches.",
          "enum": [
            "icons",
            "plain",
            "unicode",
            "ascii"
          ]
        }
      },
      "required": [
        "version",
        "kind",
        "entries"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "states",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "states"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "states": {
          "type": "array",
          "description": "The conditions the machine can be in. A newline in `text` is a lead and a detail, as everywhere: the state's name over what holds in it. Every state must be reachable from `initial`.",
          "items": {
            "$ref": "#/$defs/state"
          },
          "minItems": 1
        },
        "initial": {
          "type": "string",
          "description": "The state the machine starts in, drawn as a filled dot with an arrow to it. Required: reachability is measured from here. May name a group, which must then say its own `initial`."
        },
        "final": {
          "type": "array",
          "description": "The states the machine ends in, each drawn with an arrow to a ringed dot. A final state has no outgoing transition.",
          "items": {
            "type": "string"
          }
        },
        "transitions": {
          "type": "array",
          "description": "What moves the machine from one state to another, each labelled `event [guard] / action` from its own fields.",
          "items": {
            "$ref": "#/$defs/transition"
          }
        },
        "groups": {
          "type": "array",
          "description": "Composite states: a frame around the states inside it, named at its corner. Groups may nest. A transition from a group leaves it from any state inside; one to a group enters it at the group's `initial`. A composite with `regions` is drawn divided by dashed lines, every region current at once.",
          "items": {
            "$ref": "#/$defs/composite"
          }
        }
      },
      "required": [
        "version",
        "kind",
        "states",
        "initial"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "sequence",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "sequence"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "participants": {
          "type": "array",
          "description": "Who takes part, drawn left to right in the order written, each a head with a dashed lifeline under it. The order is the reading order, not a coordinate. Every participant must send or receive a message. A person taking part is `role: \"actor\"`, drawn as the UML stick figure with the name under it.",
          "items": {
            "$ref": "#/$defs/participant"
          },
          "minItems": 2
        },
        "messages": {
          "type": "array",
          "description": "What is said, drawn top to bottom in the order written: the order is the diagram. A call (`flow`) answered later by a `weak` reply opens an activation bar on the receiver from the call's row to the reply's; nobody writes how tall it is. An `async` message (solid line, open head) is sent without waiting, opens no bar and takes no reply.",
          "items": {
            "$ref": "#/$defs/message"
          },
          "minItems": 1
        },
        "fragments": {
          "type": "array",
          "description": "Frames round a run of messages, `from` to `to`, and every participant they touch. Fragments nest or are apart; one that starts inside another and ends outside it is refused.",
          "items": {
            "$ref": "#/$defs/fragment"
          }
        },
        "groups": {
          "type": "array",
          "description": "A frame round a run of neighbouring lifelines, named at its top — *inside our account*. Members must be next to each other in `participants`, and a participant is in one group or none.",
          "items": {
            "$ref": "#/$defs/group"
          }
        }
      },
      "required": [
        "version",
        "kind",
        "participants",
        "messages"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "lanes",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "lanes"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "nodes": {
          "type": "array",
          "description": "The steps, each in the lane its `actor` names. Ranked along the lanes as a `flow` is; within one lane, order is the order siblings are drawn in.",
          "items": {
            "$ref": "#/$defs/lane-node"
          },
          "minItems": 1
        },
        "edges": {
          "type": "array",
          "description": "What follows what, as on a `flow`. An edge between two lanes crosses the boundaries between them: that crossing is the hand-off.",
          "items": {
            "$ref": "#/$defs/edge"
          }
        },
        "lanes": {
          "type": "array",
          "description": "The lanes in order — top to bottom when they run across the page, left to right when they run down it; the theme decides which. Each must be some node's `actor`, spelled exactly, and every actor must be listed. Omit it and the lanes come in the order their actors first appear in `nodes`. At most 6.",
          "items": {
            "type": "string"
          },
          "minItems": 1
        },
        "phases": {
          "type": "array",
          "description": "The stages the process passes through, in the order it runs — named in a band along the lanes' edge and divided by faint lines across every lane (a cross-functional flowchart's phases). Each phase lists its steps, and with `phases` given every step is in exactly one. A phase's steps are drawn after every step of the phases before it, so the phases never interleave. 2 to 6.",
          "items": {
            "$ref": "#/$defs/phase"
          },
          "minItems": 2
        },
        "classes": {
          "type": "array",
          "description": "The classes the boxes are sorted into, each `{id, text}`: 1 to 4, every one used by some node. Each is drawn as a faint fill from the theme's fixed sequence (`[classes] fills`: a grey wash, then patterns), in the order declared, and the key under the drawing names each by its `text`. For a grouping the reader must see across the whole drawing — external systems greyed in a C4 context, steps by owning team.",
          "items": {
            "$ref": "#/$defs/class"
          },
          "minItems": 1
        }
      },
      "required": [
        "version",
        "kind",
        "nodes"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "entities",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "entities"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "entities": {
          "type": "array",
          "description": "The boxes: each a name (and a stereotype), a rule, its fields, and its operations under a second rule. Placed by their relations: general above specific when there is a hierarchy, side by side otherwise; round the one marked `centre`, a star schema's fact table, when one is.",
          "items": {
            "$ref": "#/$defs/entity"
          },
          "minItems": 1
        },
        "edges": {
          "type": "array",
          "description": "The relations between entities, each landing on a box — or, with `from_field` / `to_field`, on one row of it — and carrying a cardinality at either end. A hierarchy may not loop.",
          "items": {
            "$ref": "#/$defs/relation"
          }
        }
      },
      "required": [
        "version",
        "kind",
        "entities"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "gantt",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "gantt"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "axis": {
          "$ref": "#/$defs/axis-gantt",
          "description": "The one axis the plan runs along: what its numbers count, in a unit you name. There are no dates."
        },
        "tasks": {
          "type": "array",
          "description": "One row each, in the order written — that order is the reading order. `start` and `end` make a bar; `at` makes a milestone.",
          "items": {
            "$ref": "#/$defs/task"
          },
          "minItems": 1
        },
        "groups": {
          "type": "array",
          "description": "Phases, each a run of consecutive tasks, drawn as a heading row with a bracket over the phase's span. With groups, every task is in one.",
          "items": {
            "$ref": "#/$defs/group"
          }
        },
        "edges": {
          "type": "array",
          "description": "Finish-to-start dependencies between tasks: drawn from the end of `from` into the start of `to`.",
          "items": {
            "$ref": "#/$defs/dependency"
          }
        },
        "marks": {
          "type": "array",
          "description": "Named points in time — today, a deadline, a freeze — each a line across every row with its name above.",
          "items": {
            "$ref": "#/$defs/mark"
          }
        }
      },
      "required": [
        "version",
        "kind",
        "axis",
        "tasks"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "board",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "board"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "columns": {
          "type": "array",
          "description": "Left to right as written: states on a kanban board, prompts on a retrospective, the steps of a story on a story map. All one width.",
          "items": {
            "$ref": "#/$defs/board-column"
          },
          "minItems": 1
        },
        "rows": {
          "type": "array",
          "description": "Slices across every column, top to bottom — the releases of a story map. With rows, every card names one.",
          "items": {
            "$ref": "#/$defs/slice"
          },
          "minItems": 1
        },
        "cut": {
          "type": "string",
          "description": "The id of a row: a heavy rule is drawn under it — everything above ships first. Not the last row, which has nothing below it to cut from."
        },
        "cards": {
          "type": "array",
          "description": "Each in a column (and a row, with rows). Within a cell they stack in the order written, top-aligned, so a short column looks short.",
          "items": {
            "$ref": "#/$defs/card"
          },
          "minItems": 1
        }
      },
      "required": [
        "version",
        "kind",
        "columns",
        "cards"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "fishbone",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "fishbone"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "effect": {
          "$ref": "#/$defs/effect",
          "description": "The observed problem, stated as a fact: drawn in the head box at the end of the spine, always as the diagram's emphasis."
        },
        "categories": {
          "type": "array",
          "description": "The bones, drawn alternately above and below the spine, nearest the head first: the written order is the reading order from the head outwards.",
          "items": {
            "$ref": "#/$defs/category"
          },
          "minItems": 2
        }
      },
      "required": [
        "version",
        "kind",
        "effect",
        "categories"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "venn",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "venn"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "sets": {
          "type": "array",
          "description": "Two to four sets, each a circle of one size with its name outside it — four are four equal ellipses, so all fifteen regions exist. Not sizes: the shapes are equal, because a Venn diagram says what overlaps, not how much.",
          "items": {
            "$ref": "#/$defs/venn-set"
          },
          "minItems": 2
        },
        "regions": {
          "type": "array",
          "description": "What each region holds, named by membership. A region not listed is drawn empty: its set's name says enough.",
          "items": {
            "$ref": "#/$defs/region"
          }
        }
      },
      "required": [
        "version",
        "kind",
        "sets"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "journey",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "journey"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "feelings": {
          "type": "array",
          "description": "The named levels a stage's feeling may take, **worst first**: drawn as guides across the map, the worst at the bottom, each named once on the left. Names, not scores.",
          "items": {
            "type": "string"
          },
          "minItems": 2
        },
        "rows": {
          "type": "array",
          "description": "The detail rows under the feeling line, top to bottom: what the person does, where, what gets in the way. Optional: without rows the map is the stages and the line.",
          "items": {
            "$ref": "#/$defs/journey-row"
          },
          "minItems": 1
        },
        "stages": {
          "type": "array",
          "description": "Left to right as written, one column each, all one width. The feeling line passes through every stage's point.",
          "items": {
            "$ref": "#/$defs/journey-stage"
          },
          "minItems": 2
        }
      },
      "required": [
        "version",
        "kind",
        "feelings",
        "stages"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "treemap",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "treemap"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "parts": {
          "type": "array",
          "description": "The parts of one total, each a rectangle whose area is in proportion to its `amount`, with its words inside it. Laid out largest first whatever the written order, which only breaks ties; `note` parts go last.",
          "items": {
            "$ref": "#/$defs/treemap-part"
          },
          "minItems": 2
        },
        "groups": {
          "type": "array",
          "description": "One level of grouping: each group is a captioned frame holding the parts that name it, filled with the theme's mark fills in the order written. Groups do not nest.",
          "items": {
            "$ref": "#/$defs/treemap-group"
          },
          "minItems": 1
        },
        "unit": {
          "type": "string",
          "description": "What the values are in — `kB`, `GB`, `hours` — written after each one."
        },
        "values": {
          "type": "boolean",
          "description": "Whether to write each part's amount under its words, and each group's total beside its name. Defaults to true."
        }
      },
      "required": [
        "version",
        "kind",
        "parts"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "sankey",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "sankey"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "nodes": {
          "type": "array",
          "description": "Where the quantity starts, passes and ends. A node's column is derived from the flows — sources left, ends right — never written; the written order is where the order down each column starts.",
          "items": {
            "$ref": "#/$defs/sankey-node"
          },
          "minItems": 2
        },
        "flows": {
          "type": "array",
          "description": "How much goes from one node to another, each a band whose thickness is in proportion to its `amount`. What reaches a node in the middle must all leave it, and nothing flows back.",
          "items": {
            "$ref": "#/$defs/sankey-flow"
          },
          "minItems": 1
        },
        "unit": {
          "type": "string",
          "description": "What the amounts are in — `tickets`, `cores`, `€ million` — written after each total."
        },
        "values": {
          "type": "boolean",
          "description": "Whether to write each node's total under its name. Defaults to true."
        }
      },
      "required": [
        "version",
        "kind",
        "nodes",
        "flows"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "numberline",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "numberline"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "axis": {
          "$ref": "#/$defs/axis-numberline",
          "description": "The one scale, drawn across the canvas with an arrowhead at each end: numbered ticks, or two named `ends`."
        },
        "points": {
          "type": "array",
          "description": "Values marked on the axis, each a dot with its words above it — or below the numbers, with a leader, when the words above would touch.",
          "items": {
            "$ref": "#/$defs/numberline-point"
          }
        },
        "ranges": {
          "type": "array",
          "description": "Stretches of the scale, each a line in its own track above the axis, in the order written — the last nearest the axis. Each end is closed, open, or missing: a range with no `to` runs on past `max`.",
          "items": {
            "$ref": "#/$defs/numberline-range"
          }
        }
      },
      "required": [
        "version",
        "kind",
        "axis"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "barmodel",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "barmodel"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "bars": {
          "type": "array",
          "description": "One to three bars, top to bottom, all starting at one left edge, every length in one scale: the longest bar fills the width.",
          "items": {
            "$ref": "#/$defs/barmodel-bar"
          },
          "minItems": 1
        },
        "braces": {
          "type": "array",
          "description": "What a stretch adds up to — the whole, a difference, a total over two bars — each a brace with its amount or its `?`.",
          "items": {
            "$ref": "#/$defs/barmodel-brace"
          }
        }
      },
      "required": [
        "version",
        "kind",
        "bars"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "waterfall",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "waterfall"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "axis": {
          "$ref": "#/$defs/waterfall-axis",
          "description": "The vertical axis: its `label`, what the numbers are and their unit."
        },
        "bars": {
          "type": "array",
          "description": "The bars, left to right: a `total` first, signed `amount` steps, any subtotals (a `total` mid-way, checked against the running sum), and a `total` last.",
          "items": {
            "$ref": "#/$defs/waterfall-bar"
          },
          "minItems": 3
        }
      },
      "required": [
        "version",
        "kind",
        "axis",
        "bars"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "pie",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "pie"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "parts": {
          "type": "array",
          "description": "The parts of one total, 2 to 8, clockwise from twelve o'clock in the order written (a `note` part last), each labelled with its `text` and amount — inside its sector, or beside it on a leader line.",
          "items": {
            "$ref": "#/$defs/pie-part"
          },
          "minItems": 2
        },
        "unit": {
          "type": "string",
          "description": "What the amounts are in — `pupils`, `£m`, `%` — written after each one. With `%` the amounts must add up to 100, within one point of rounding."
        },
        "values": {
          "type": "boolean",
          "description": "`false` leaves the amounts out and writes the names alone."
        }
      },
      "required": [
        "version",
        "kind",
        "parts"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "mindmap",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "mindmap"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "centre": {
          "type": "string",
          "description": "The topic: the one strongly boxed element, in the middle of the map. Every main branch is a peer round it."
        },
        "branches": {
          "type": "array",
          "description": "The main branches, 2 to 8, placed clockwise from the top right in the order written and split between the two sides so they balance: the first is always on the right. Nested, up to three levels, 30 branches in all; the nesting is the structure, so there are no edges.",
          "items": {
            "$ref": "#/$defs/mindmap-branch"
          },
          "minItems": 2
        }
      },
      "required": [
        "version",
        "kind",
        "centre",
        "branches"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "argument",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "argument"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "claim": {
          "type": "string",
          "description": "The contention, drawn at the top in the heavy outline. Points name it as `\"on\": \"claim\"`. A qualifier (*probably*, *in most cases*) is a word in it."
        },
        "points": {
          "type": "array",
          "description": "Every reason, objection, rebuttal and piece of evidence, each `on` the box it bears on, `for` or `against` it. Drawn as a tree down from the claim, siblings in the order written; at most 15, and 4 deep.",
          "items": {
            "$ref": "#/$defs/argument-point"
          },
          "minItems": 1
        }
      },
      "required": [
        "version",
        "kind",
        "claim",
        "points"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "familytree",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "familytree"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "people": {
          "type": "array",
          "description": "Everyone in the tree. Generations and numbers are derived: a child is one row below its parents, a partner shares their partner's row, and people are numbered left to right in each row (II-3). At most 30, in 4 generations.",
          "items": {
            "$ref": "#/$defs/familytree-person"
          },
          "minItems": 2
        },
        "couples": {
          "type": "array",
          "description": "Who partnered whom, and their children. Everyone is in at least one couple, as a partner or a child.",
          "items": {
            "$ref": "#/$defs/familytree-couple"
          },
          "minItems": 1
        }
      },
      "required": [
        "version",
        "kind",
        "people",
        "couples"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "meter",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "meter"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "style": {
          "type": "string",
          "description": "How every meter in the document is drawn: `bar` (the default, a progress bar), `thermometer` (a goal filling up), `dial` (a needle on a half-circle) or `bullet` (a bar on named bands, with a target tick). One for the whole panel, so like is compared with like.",
          "enum": [
            "bar",
            "thermometer",
            "dial",
            "bullet"
          ]
        },
        "meters": {
          "type": "array",
          "description": "The meters, 1 to 6, in reading order: rows for bars and bullets, columns for thermometers, up to three dials to a row. Each has its own scale.",
          "items": {
            "$ref": "#/$defs/meter-meter"
          },
          "minItems": 1
        }
      },
      "required": [
        "version",
        "kind",
        "meters"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "rag",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "rag"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "rows": {
          "type": "array",
          "description": "The workstreams or risks, 1 to 15, in the order written: each a name, its `rag`, and optionally a `trend` and a `note`.",
          "items": {
            "$ref": "#/$defs/rag-row"
          },
          "minItems": 1
        }
      },
      "required": [
        "version",
        "kind",
        "rows"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "clock",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "clock"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "clocks": {
          "type": "array",
          "description": "The faces, 1 to 12, in reading order, up to four to a row: each a `time`, and optionally a `text` under it and a `since`.",
          "items": {
            "$ref": "#/$defs/clock-face"
          },
          "minItems": 1
        },
        "numerals": {
          "type": "string",
          "description": "The numbers round every face: `arabic` (the default, 1 to 12), `roman` (I to XII), `quarters` (12, 3, 6 and 9 only) or `none`.",
          "enum": [
            "arabic",
            "roman",
            "quarters",
            "none"
          ]
        },
        "readout": {
          "type": "string",
          "description": "What is written under each face: `words` (the default: `quarter past three`), `digits` (`3:15`, as written), `both`, or `none` for a worksheet.",
          "enum": [
            "words",
            "digits",
            "both",
            "none"
          ]
        }
      },
      "required": [
        "version",
        "kind",
        "clocks"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "title": "sunburst",
      "properties": {
        "$schema": {
          "type": "string",
          "description": "Optional, and only for editors: the URL of this schema."
        },
        "version": {
          "const": 1
        },
        "kind": {
          "type": "string",
          "enum": [
            "sunburst"
          ]
        },
        "title": {
          "type": "string",
          "description": "The diagram's accessible name."
        },
        "description": {
          "type": "string",
          "description": "The diagram's accessible description."
        },
        "caption": {
          "type": "string",
          "description": "A line of text belonging to the whole diagram rather than to any one element — an axis's units, a condition that holds throughout, the sentence the original wrote alongside the figure. Drawn outside the drawing; the theme's `[canvas] caption` says above or below. Use a `note` for something attached to one element."
        },
        "width": {
          "type": "number",
          "description": "Overrides the theme's canvas width. Binding.",
          "exclusiveMinimum": 0
        },
        "height": {
          "type": "number",
          "description": "Advisory unless height_binding is true.",
          "exclusiveMinimum": 0
        },
        "height_binding": {
          "type": "boolean",
          "description": "Makes height a constraint rather than a hint."
        },
        "theme": {
          "type": "string",
          "description": "A bundled theme name or the path of a theme file. A relative path is read from the document's own folder when the file is there, so a theme can sit beside the diagrams that use it."
        },
        "centre": {
          "type": "string",
          "description": "An optional hub label in the middle — the overall topic. Left out, the first ring fills the centre."
        },
        "nodes": {
          "type": "array",
          "description": "The first ring, 2 to 8, clockwise from twelve o'clock in the order written, each with optional `children` for the ring nested inside it. Nested up to three rings, 150 sectors in all; every terminal sector takes an equal angle, so there are no amounts.",
          "items": {
            "$ref": "#/$defs/sunburst-node"
          },
          "minItems": 2
        }
      },
      "required": [
        "version",
        "kind",
        "nodes"
      ],
      "additionalProperties": false
    }
  ],
  "$defs": {
    "argument-point": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique within the document, and not `claim`: what `on` and `with` name."
        },
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "on": {
          "type": "string",
          "description": "The box this point bears on: `claim`, or another point's id. The points hang below it, in the order written."
        },
        "stance": {
          "type": "string",
          "description": "`for` (a reason, drawn plain, tagged *because*) or `against` (an objection, hatched, tagged *but*) the box it is `on`. A rebuttal is an `against` on an `against`.",
          "enum": [
            "for",
            "against"
          ]
        },
        "with": {
          "type": "array",
          "description": "Co-premises: the ids of points with the same `on` and `stance` that support it only together. Written once, on any member; the group is every point joined this way, at most 4, drawn side by side under one bracket with one connector.",
          "items": {
            "type": "string"
          },
          "minItems": 1
        },
        "role": {
          "type": "string",
          "description": "`step` (the default), `emphasis` (the decisive point: heavy outline and connector, bold words) or `note` (evidence or a source rather than a reason: the note type, unboxed, on a dashed connector).",
          "enum": [
            "step",
            "emphasis",
            "note"
          ]
        }
      },
      "required": [
        "id",
        "text",
        "on",
        "stance"
      ],
      "additionalProperties": false
    },
    "axes": {
      "type": "object",
      "properties": {
        "horizontal": {
          "$ref": "#/$defs/axis",
          "description": "The axis across."
        },
        "vertical": {
          "$ref": "#/$defs/axis",
          "description": "The axis up."
        }
      },
      "required": [
        "horizontal",
        "vertical"
      ],
      "additionalProperties": false
    },
    "axes-continuous": {
      "type": "object",
      "properties": {
        "horizontal": {
          "$ref": "#/$defs/axis-continuous",
          "description": "The axis across, read as a measurement — unlike `quadrant`'s."
        },
        "vertical": {
          "$ref": "#/$defs/axis-continuous",
          "description": "The axis up, read as a measurement — unlike `quadrant`'s."
        }
      },
      "required": [
        "horizontal",
        "vertical"
      ],
      "additionalProperties": false
    },
    "axes-quadrant": {
      "type": "object",
      "properties": {
        "horizontal": {
          "$ref": "#/$defs/axis-quadrant",
          "description": "The judgement across."
        },
        "vertical": {
          "$ref": "#/$defs/axis-quadrant",
          "description": "The judgement up."
        }
      },
      "required": [
        "horizontal",
        "vertical"
      ],
      "additionalProperties": false
    },
    "axis": {
      "type": "object",
      "properties": {
        "label": {
          "type": "string",
          "description": "Required: an unlabelled axis cannot be read."
        },
        "unit": {
          "type": "string",
          "description": "What the numbers are in, written after the label."
        },
        "min": {
          "type": "number",
          "description": "Where the axis starts. Omit to take it from the data."
        },
        "max": {
          "type": "number",
          "description": "Where the axis ends. Omit to take it from the data."
        },
        "categories": {
          "type": "array",
          "description": "Names for the positions 1, 2, 3 … along this axis, instead of numbers. What a bar chart's horizontal axis usually is: the quarters, the service models, the teams. On a chart's vertical axis they make horizontal bars: every series a `bar`, each point `[amount, position]`, the first category the top row, names on the left.",
          "items": {
            "type": "string"
          }
        }
      },
      "required": [
        "label"
      ],
      "additionalProperties": false
    },
    "axis-continuous": {
      "type": "object",
      "properties": {
        "label": {
          "type": "string",
          "description": "Required: an unlabelled axis cannot be read."
        },
        "unit": {
          "type": "string",
          "description": "What the numbers are in, written after the label."
        },
        "min": {
          "type": "number",
          "description": "Where the axis starts. Omit to take it from the data."
        },
        "max": {
          "type": "number",
          "description": "Where the axis ends. Omit to take it from the data."
        }
      },
      "required": [
        "label"
      ],
      "additionalProperties": false
    },
    "axis-gantt": {
      "type": "object",
      "properties": {
        "label": {
          "type": "string",
          "description": "Required, and the unit's name: `Week`, `Day`, `Minutes after 02:00`."
        },
        "unit": {
          "type": "string",
          "description": "What the numbers are in, written after the label."
        },
        "min": {
          "type": "number",
          "description": "Where the plan starts. Omit to take it from the tasks."
        },
        "max": {
          "type": "number",
          "description": "Where the plan ends. Omit to take it from the tasks."
        },
        "categories": {
          "type": "array",
          "description": "Names for the periods, in order, instead of numbers — months, sprints, quarters. The first period runs from 1 to 2, the second from 2 to 3, so a task over the first three is `start` 1, `end` 4. Sets the range itself, so not with `min` or `max`.",
          "items": {
            "type": "string"
          },
          "minItems": 1
        }
      },
      "required": [
        "label"
      ],
      "additionalProperties": false
    },
    "axis-numberline": {
      "type": "object",
      "properties": {
        "min": {
          "type": "number",
          "description": "Where the scale starts, at the left arrowhead's side."
        },
        "max": {
          "type": "number",
          "description": "Where the scale ends: more than `min`."
        },
        "step": {
          "type": "number",
          "description": "The distance between two ticks, each labelled with its number. Omit it for a step a reader can count in, chosen from the range.",
          "exclusiveMinimum": 0
        },
        "label": {
          "type": "string",
          "description": "What the numbers measure, centred under them: `pH`, `Temperature`."
        },
        "unit": {
          "type": "string",
          "description": "What the numbers are in, written after the label: `°C`, `cm`."
        },
        "ends": {
          "type": "array",
          "description": "Two words for the low and the high end — `past` and `future`, `fully remote` and `fully on site` — written under the arrowheads, for a scale that is named rather than measured. No numbers are drawn: only the order and the gaps count, so not with `step` or `unit`.",
          "items": {
            "type": "string"
          },
          "minItems": 2
        }
      },
      "required": [
        "min",
        "max"
      ],
      "additionalProperties": false
    },
    "axis-quadrant": {
      "type": "object",
      "properties": {
        "label": {
          "type": "string",
          "description": "Required: an unlabelled axis cannot be read."
        },
        "unit": {
          "type": "string",
          "description": "What the scores are in, written after the label."
        },
        "min": {
          "type": "number",
          "description": "Where the axis starts. Omit to take it from the positions."
        },
        "max": {
          "type": "number",
          "description": "Where the axis ends. Omit to take it from the positions."
        },
        "ends": {
          "type": "array",
          "description": "Two words for the low and the high end — `Low` and `High`, `Rarely` and `Often` — written at the two ends of the axis, as on a `numberline`.",
          "items": {
            "type": "string"
          },
          "minItems": 2
        }
      },
      "required": [
        "label"
      ],
      "additionalProperties": false
    },
    "band": {
      "type": "object",
      "properties": {
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "members": {
          "type": "array",
          "description": "The ids of the nodes this band accompanies. Unlike a group's, they are a set rather than a container: a band names something that runs alongside those boxes, and the same box may be under any number of bands.",
          "items": {
            "type": "string"
          },
          "minItems": 1
        }
      },
      "required": [
        "text",
        "members"
      ],
      "additionalProperties": false
    },
    "barmodel-bar": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "What a brace's `over` names, for a brace over the whole bar. Unique among the bars and the parts."
        },
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "parts": {
          "type": "array",
          "description": "The bar's parts, left to right, each as long as its `value` or its `units` say — in one scale for every bar.",
          "items": {
            "$ref": "#/$defs/barmodel-part"
          },
          "minItems": 1
        }
      },
      "required": [
        "parts"
      ],
      "additionalProperties": false
    },
    "barmodel-brace": {
      "type": "object",
      "properties": {
        "over": {
          "type": "array",
          "description": "What the brace spans: the ids of side-by-side parts of one bar, drawn over it (under it, for the last of several bars), or of whole bars — one bar the same way, several consecutive bars with an upright brace at their right.",
          "items": {
            "type": "string"
          },
          "minItems": 1
        },
        "amount": {
          "type": "number",
          "description": "What the stretch adds up to. Checked: the parts' amounts must sum to it, and with units every brace must make one unit worth the same. Written unless `text` is given.",
          "exclusiveMinimum": 0
        },
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        }
      },
      "required": [
        "over"
      ],
      "additionalProperties": false
    },
    "barmodel-part": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "What a brace's `over` names. Unique among the bars and the parts."
        },
        "amount": {
          "type": "number",
          "description": "How much the part is, more than 0: its length is in proportion, and its words default to the number. Give it even for the unknown — the `?` is its `text`.",
          "exclusiveMinimum": 0
        },
        "units": {
          "type": "integer",
          "description": "How many equal boxes the part is, each one unit long: groups to multiply, the shares of a ratio, the fifths of a fraction. Not with `amount`, and not in a document whose parts have amounts.",
          "exclusiveMinimum": 0
        },
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "role": {
          "type": "string",
          "description": "`step` (the default), `emphasis` (the part the problem asks about: bold words, filled) or `note` (a part that is not there — the difference a shorter bar lacks: dashed).",
          "enum": [
            "step",
            "emphasis",
            "note"
          ]
        }
      },
      "additionalProperties": false
    },
    "board-column": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique among the columns; what a card's `column` names."
        },
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "limit": {
          "type": "integer",
          "description": "A work-in-progress limit. drawspec counts the column's cards (a `note` card is not work, so it is not counted) and writes `n / limit` in the heading; over the limit the heading takes `emphasis`. Never write the count yourself.",
          "exclusiveMinimum": 0
        },
        "role": {
          "type": "string",
          "description": "`step` (the default) or `emphasis` (the column the board is about), drawn as the weight of the rule under the heading.",
          "enum": [
            "step",
            "emphasis"
          ]
        }
      },
      "required": [
        "id",
        "text"
      ],
      "additionalProperties": false
    },
    "branch": {
      "type": "object",
      "properties": {
        "at": {
          "type": "string",
          "description": "The id of the first message of this branch. The divider is drawn above it, so it is after the fragment's first message and no later than its last."
        },
        "text": {
          "type": "string",
          "description": "This branch's condition. Written plainly; drawspec adds the brackets. Omit it for a `par` branch, which runs alongside the others and has none."
        }
      },
      "required": [
        "at"
      ],
      "additionalProperties": false
    },
    "card": {
      "type": "object",
      "properties": {
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "column": {
          "type": "string",
          "description": "The id of the column it is in. Its kind is its column."
        },
        "row": {
          "type": "string",
          "description": "The id of the row (slice) it is in. Required when the board has `rows`, refused when it has none."
        },
        "role": {
          "type": "string",
          "description": "`step` (the default), `emphasis` (blocked, at risk, the one that matters) or `note` (a placeholder or a summary such as `+ 6 more`, drawn lighter and not counted against a limit).",
          "enum": [
            "step",
            "emphasis",
            "note"
          ]
        },
        "actor": {
          "type": "string",
          "description": "Who holds it — free text, drawn as the card's lead, as in a `flow` box. A card with an actor may not put a newline in `text`."
        },
        "note": {
          "type": "string",
          "description": "A short aside hung under the card, smaller: `blocked on a decision`."
        }
      },
      "required": [
        "text",
        "column"
      ],
      "additionalProperties": false
    },
    "category": {
      "type": "object",
      "properties": {
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "causes": {
          "type": "array",
          "description": "What was investigated under this category, in reading order from the category's name inwards to the spine. Leaves: a cause has no causes.",
          "items": {
            "$ref": "#/$defs/cause"
          },
          "minItems": 1
        }
      },
      "required": [
        "text",
        "causes"
      ],
      "additionalProperties": false
    },
    "cause": {
      "type": "object",
      "properties": {
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "role": {
          "type": "string",
          "description": "`step` (the default), `emphasis` (the confirmed root cause: its bone is drawn heavy up to the spine) or `note` (investigated and ruled out, its tick drawn light and dashed).",
          "enum": [
            "step",
            "emphasis",
            "note"
          ]
        }
      },
      "required": [
        "text"
      ],
      "additionalProperties": false
    },
    "cell": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Optional, and only needed to join this cell to another: an edge names the two cells it runs between. Unique within the document."
        },
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "column": {
          "type": "integer",
          "description": "Which column this cell starts in, counting from zero."
        },
        "row": {
          "type": "integer",
          "description": "Which row it starts in, from zero."
        },
        "across": {
          "type": "integer",
          "description": "How many columns it covers. Default 1."
        },
        "down": {
          "type": "integer",
          "description": "How many rows it covers. Default 1."
        },
        "group": {
          "type": "string",
          "description": "Which group this cell belongs to. Cells sharing a group are filled alike; the theme decides how. Naming the fill itself is not an author's decision."
        },
        "role": {
          "type": "string",
          "description": "The semantic role, which the theme resolves to an appearance. Defaults to 'step'.",
          "enum": [
            "start",
            "step",
            "decision",
            "terminal",
            "emphasis",
            "note",
            "group"
          ]
        }
      },
      "required": [
        "text",
        "column",
        "row"
      ],
      "additionalProperties": false
    },
    "class": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "What a node's `class` names. Unique among the classes."
        },
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        }
      },
      "required": [
        "id",
        "text"
      ],
      "additionalProperties": false
    },
    "clock-face": {
      "type": "object",
      "properties": {
        "time": {
          "type": "string",
          "description": "The time the hands show, `H:MM` or `HH:MM` from `0:00` to `23:59` — `15:40` for twenty to four in the afternoon. No seconds, no date. Leave it out for a face with no hands, to draw them on."
        },
        "text": {
          "type": "string",
          "description": "A name or a prompt under the face: `Home time`, `Draw half past seven`."
        },
        "since": {
          "type": "string",
          "description": "An earlier time, `H:MM`, up to 12 hours before `time`: the face shades what has passed since it, and the readout says how long."
        }
      },
      "additionalProperties": false
    },
    "composite": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique within the document, among the states and the groups."
        },
        "text": {
          "type": "string",
          "description": "The composite state's name, drawn at its frame's corner."
        },
        "members": {
          "type": "array",
          "description": "The states (or groups) inside this composite state. A composite lists its `members` or its `regions`, not both.",
          "items": {
            "type": "string"
          },
          "minItems": 1
        },
        "initial": {
          "type": "string",
          "description": "The member this composite is entered at, drawn as a dot inside the frame. Required when a transition, or the machine's own `initial`, names the group. With `regions`, each region names its own instead."
        },
        "regions": {
          "type": "array",
          "description": "Orthogonal regions: parts of this composite that are all current at once, drawn side by side (or stacked) and divided by dashed lines. Each region lists its own members and its own `initial` — unless every way into the composite is a `fork` with an arrow into that region, which says where it starts — and entering the composite enters every region there. A transition may not run between two regions of one composite. In place of `members`.",
          "items": {
            "$ref": "#/$defs/state_region"
          },
          "minItems": 2
        }
      },
      "required": [
        "id",
        "text"
      ],
      "additionalProperties": false
    },
    "curve": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "Drawn where the curve ends. Omit it when there is only one curve and the axes already say what it is."
        },
        "waypoints": {
          "type": "array",
          "description": "The points the curve passes through, in order. Two is a line.",
          "items": {
            "$ref": "#/$defs/waypoint"
          },
          "minItems": 2
        },
        "role": {
          "type": "string",
          "description": "The semantic role, which the theme resolves to an appearance. Defaults to 'step'.",
          "enum": [
            "start",
            "step",
            "decision",
            "terminal",
            "emphasis",
            "note",
            "group"
          ]
        }
      },
      "required": [
        "waypoints"
      ],
      "additionalProperties": false
    },
    "dependency": {
      "type": "object",
      "properties": {
        "from": {
          "type": "string",
          "description": "The id of the task that has to finish first."
        },
        "to": {
          "type": "string",
          "description": "The id of the task that waits for it, which may not start before `from` ends. Drawn from the end of one bar into the start of the other."
        },
        "role": {
          "type": "string",
          "description": "`flow` (the default), `strong` (the critical path) or `weak` (a soft dependency, dashed).",
          "enum": [
            "flow",
            "strong",
            "weak"
          ]
        }
      },
      "required": [
        "from",
        "to"
      ],
      "additionalProperties": false
    },
    "detail": {
      "type": "object",
      "properties": {
        "row": {
          "type": "string",
          "description": "The id of one of the journey's `rows`, at most once per stage."
        },
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        }
      },
      "required": [
        "row",
        "text"
      ],
      "additionalProperties": false
    },
    "edge": {
      "type": "object",
      "properties": {
        "from": {
          "type": "string",
          "description": "The id of the source node — or, in a `flow` or a `tree`, of a group: an edge may name a container, for a relation that belongs to the whole of it rather than to any one box inside. It may not join a container to something already within it. A `cycle` draws no containers, so an edge in one names a node — or its `hub`, as a spoke."
        },
        "to": {
          "type": "string",
          "description": "The id of the target node — or, in a `flow` or a `tree`, of a group. The same id space as `from`. The same id as `from` draws a loop on the side of that box, across the reading direction, with its label outside it: two per box at most, and never on a group."
        },
        "label": {
          "type": "string",
          "description": "A short label placed along the edge."
        },
        "role": {
          "type": "string",
          "description": "The semantic role, which the theme resolves to an appearance. Defaults to 'flow'.",
          "enum": [
            "flow",
            "link",
            "exchange",
            "weak",
            "owns",
            "strong",
            "aside",
            "async"
          ]
        },
        "status": {
          "type": "string",
          "description": "What a proposed change does to this connection: the same marks as a node's, written before the label (`+`, `~`, `-`), with a key of the marks under the drawing. A removed edge is drawn in the `aside` treatment — dashed, no head — whatever its role. **Only a `flow`, a `tree` or `lanes`.**",
          "enum": [
            "added",
            "changed",
            "removed"
          ]
        },
        "polarity": {
          "type": "string",
          "description": "A causal link's sign: more of the source means more (`+`) or less (`-`) of the target, written as the edge's label (`s`/`o` under a theme that says so). Every `flow` or `strong` edge of the document has one, or none does. **Only a `flow`.**",
          "enum": [
            "+",
            "-"
          ]
        },
        "delay": {
          "type": "boolean",
          "description": "The effect takes time: drawn as the double stroke across the shaft. Needs `polarity`. **Only a `flow`.**"
        }
      },
      "required": [
        "from",
        "to"
      ],
      "additionalProperties": false
    },
    "effect": {
      "type": "object",
      "properties": {
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        }
      },
      "required": [
        "text"
      ],
      "additionalProperties": false
    },
    "entity": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique among the entities."
        },
        "text": {
          "type": "string",
          "description": "The entity's name, drawn bold over its fields. One line: may carry `code` and **bold** spans — a table name is usually `code`."
        },
        "tag": {
          "type": "string",
          "description": "A short stereotype drawn over the name in guillemets — `interface` is drawn «interface». Free text, 16 characters at most."
        },
        "role": {
          "type": "string",
          "description": "The semantic role, which the theme resolves to an appearance. Defaults to 'step'.",
          "enum": [
            "step",
            "emphasis",
            "note"
          ]
        },
        "centre": {
          "type": "boolean",
          "description": "Whether this entity is the one the rest are arranged around: a star schema's fact table, its dimensions round it — the first above, the rest clockwise in the order written. One entity per document may say so, and not in a class hierarchy, which is drawn general above specific."
        },
        "fields": {
          "type": "array",
          "description": "What the entity holds, one row each under its name: attributes, columns. A last field of `...` stands for those not shown.",
          "items": {
            "$ref": "#/$defs/field"
          }
        },
        "operations": {
          "type": "array",
          "description": "What a class can do — `area() → float` — drawn in a compartment of their own under the fields. Strings, not objects: an operation is read, never linked to.",
          "items": {
            "type": "string"
          }
        }
      },
      "required": [
        "id",
        "text"
      ],
      "additionalProperties": false
    },
    "entry": {
      "type": "object",
      "properties": {
        "path": {
          "type": "string",
          "description": "Where this sits, from the top of the tree: `src/app/main.py`. The folders it passes through are drawn without being listed. A trailing `/` makes it a folder — needed only for one with nothing listed inside. A last segment of `...` is a row standing for entries not listed."
        },
        "note": {
          "type": "string",
          "description": "A short comment drawn after the name, in the smaller label type."
        },
        "link": {
          "type": "string",
          "description": "Makes this entry a symbolic link, drawn with an arrow to this target. Written, never followed: the target need not be in the tree."
        },
        "status": {
          "type": "string",
          "description": "What a change did to this entry, as a diff would say it. Drawn as a labelled mark after the name — never as a colour alone.",
          "enum": [
            "added",
            "changed",
            "removed"
          ]
        }
      },
      "required": [
        "path"
      ],
      "additionalProperties": false
    },
    "familytree-couple": {
      "type": "object",
      "properties": {
        "between": {
          "type": "array",
          "description": "The two partners' ids, in either order: drawspec puts them side by side, joined by the partner line. A person's couples are their partners in the order written — marriage order — at most 6.",
          "items": {
            "type": "string"
          },
          "minItems": 2
        },
        "children": {
          "type": "array",
          "description": "Their children's ids, in birth order: left to right under the sibship line. Leave it out for a couple with none.",
          "items": {
            "type": "string"
          }
        },
        "twins": {
          "type": "array",
          "description": "Children of one birth, each set written next to each other in `children`.",
          "items": {
            "$ref": "#/$defs/familytree-twins"
          }
        },
        "separated": {
          "type": "boolean",
          "description": "The relationship has ended: two short strokes across the partner line."
        },
        "consanguineous": {
          "type": "boolean",
          "description": "The partners are related by blood: a double partner line."
        }
      },
      "required": [
        "between"
      ],
      "additionalProperties": false
    },
    "familytree-person": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique within the document: what `couples` name."
        },
        "sex": {
          "type": "string",
          "description": "The symbol: a square (`male`), a circle (`female`) or a diamond (`unknown`), as the standard nomenclature draws them. With `gender`, the symbol shows the gender instead and this is noted under it (`AMAB`, `AFAB`) when the two differ.",
          "enum": [
            "male",
            "female",
            "unknown"
          ]
        },
        "gender": {
          "type": "string",
          "description": "Gender identity, per the 2022 revision of the standard: the symbol becomes a square (`man`), a circle (`woman`) or a diamond (`nonbinary`), and `sex` is the sex assigned at birth, written under it when it differs. Leave it out and the symbol follows `sex`.",
          "enum": [
            "man",
            "woman",
            "nonbinary"
          ]
        },
        "text": {
          "type": "string",
          "description": "The name, or an age or a test result, under the symbol and its number. A newline makes it a lead and a detail, as anywhere: a name over the years."
        },
        "status": {
          "type": "string",
          "description": "The one trait the tree tracks: `affected` (the symbol filled), `carrier` (the theme's carrier mark: a dot in the middle, or the left half filled) or `unaffected` (the default: empty). Told apart without colour; a key under the drawing names the ones used.",
          "enum": [
            "affected",
            "carrier",
            "unaffected"
          ]
        },
        "deceased": {
          "type": "boolean",
          "description": "A diagonal stroke through the symbol. An age or year goes in `text`."
        },
        "proband": {
          "type": "boolean",
          "description": "The affected person through whom the family came to attention: an arrow at the lower left with a `P`. One per tree."
        },
        "consultand": {
          "type": "boolean",
          "description": "The person asking for advice or testing: the arrow without the `P`. May be the proband too."
        },
        "adopted": {
          "type": "boolean",
          "description": "Adopted into the couple whose `children` list them: brackets round the symbol and a dashed line down from the sibship line. A child is listed once, in the couple that raised them."
        },
        "pregnancy": {
          "type": "string",
          "description": "`ongoing`: a `P` in the symbol (the weeks go in `text`); `loss`: a small triangle in place of the symbol, shaded when `affected`. Either is a child only: no partners.",
          "enum": [
            "ongoing",
            "loss"
          ]
        },
        "role": {
          "type": "string",
          "description": "`step` (the default) or `emphasis`: the person the figure is about when there is no proband — a heavier symbol and a bold name.",
          "enum": [
            "step",
            "emphasis"
          ]
        }
      },
      "required": [
        "id",
        "sex"
      ],
      "additionalProperties": false
    },
    "familytree-twins": {
      "type": "object",
      "properties": {
        "of": {
          "type": "array",
          "description": "Two or three of the couple's children, next to each other in `children`: drawn from one point on the sibship line.",
          "items": {
            "type": "string"
          },
          "minItems": 2
        },
        "zygosity": {
          "type": "string",
          "description": "`monozygotic` (identical: a bar joins their lines), `dizygotic` (fraternal) or `unknown` (a `?` between them).",
          "enum": [
            "monozygotic",
            "dizygotic",
            "unknown"
          ]
        }
      },
      "required": [
        "of",
        "zygosity"
      ],
      "additionalProperties": false
    },
    "field": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Only needed for a relation to land on this row (`from_field`, `to_field`). Unique among the fields of the document."
        },
        "text": {
          "type": "string",
          "description": "The field's name, one line. `...` as the last field is a row standing for the fields not shown."
        },
        "type": {
          "type": "string",
          "description": "Its type — `uuid`, `float` — drawn right-aligned in the monospace face."
        },
        "key": {
          "type": "string",
          "description": "Whether it is a key, drawn as letters before the name — `PK`, `FK`, `UQ`: a word, never a colour.",
          "enum": [
            "primary",
            "foreign",
            "unique"
          ]
        }
      },
      "required": [
        "text"
      ],
      "additionalProperties": false
    },
    "fragment": {
      "type": "object",
      "properties": {
        "operator": {
          "type": "string",
          "description": "What the frame says about the messages inside it, written in its tab: `loop` repeats them, `opt` may happen, `alt` is one branch of several, `par` runs its branches at once.",
          "enum": [
            "loop",
            "alt",
            "opt",
            "par"
          ]
        },
        "from": {
          "type": "string",
          "description": "The id of the first message inside the frame."
        },
        "to": {
          "type": "string",
          "description": "The id of the last message inside the frame — the same as `from` for a frame round one message. Not before `from`."
        },
        "text": {
          "type": "string",
          "description": "The condition, beside the tab: what the loop runs over, when the option or the first branch happens. Written plainly; drawspec adds the brackets."
        },
        "else": {
          "type": "array",
          "description": "For `alt` and `par` only: where the frame is divided, each a dashed line above a message inside it, with that branch's condition under it.",
          "items": {
            "$ref": "#/$defs/branch"
          }
        }
      },
      "required": [
        "operator",
        "from",
        "to"
      ],
      "additionalProperties": false
    },
    "group": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique within the document."
        },
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "members": {
          "type": "array",
          "description": "The ids of the nodes this group contains, in the order they are meant to read — the members of a container are an ordered set.",
          "items": {
            "type": "string"
          },
          "minItems": 1
        }
      },
      "required": [
        "id",
        "members"
      ],
      "additionalProperties": false
    },
    "hub": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique within the document, and in the same id space as the nodes, so an edge may name the hub — as a spoke, never as a step of the loop."
        },
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "role": {
          "type": "string",
          "description": "The semantic role, which the theme resolves to an appearance. Defaults to 'step'.",
          "enum": [
            "start",
            "step",
            "decision",
            "terminal",
            "emphasis",
            "note",
            "group"
          ]
        }
      },
      "required": [
        "id",
        "text"
      ],
      "additionalProperties": false
    },
    "item": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Optional; generated from position when absent."
        },
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "role": {
          "type": "string",
          "description": "The semantic role, which the theme resolves to an appearance. Defaults to 'step'.",
          "enum": [
            "start",
            "step",
            "decision",
            "terminal",
            "emphasis",
            "note",
            "group"
          ]
        },
        "note": {
          "type": "string",
          "description": "A short aside attached to this element. **Only `timeline` draws one** — it goes under the axis, beside the entry's own mark. Every other kind accepts the field and has nowhere to put it, so it is not drawn; for text belonging to the whole diagram, use the top-level `caption` instead."
        },
        "at": {
          "type": "number",
          "description": "For `timeline`: when this happened, so the gaps mean something. Give it to every entry or to none."
        }
      },
      "required": [
        "text"
      ],
      "additionalProperties": false
    },
    "iteration": {
      "type": "object",
      "properties": {
        "start": {
          "type": "number",
          "description": "Where the cycle begins on the axis: the arc's head lands here."
        },
        "end": {
          "type": "number",
          "description": "Where it ends and turns back, after `start`: the arc leaves from here."
        }
      },
      "required": [
        "start",
        "end"
      ],
      "additionalProperties": false
    },
    "journey-row": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique among the rows; what a stage's `details` name in `row`."
        },
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        }
      },
      "required": [
        "id",
        "text"
      ],
      "additionalProperties": false
    },
    "journey-stage": {
      "type": "object",
      "properties": {
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "feeling": {
          "type": "string",
          "description": "One of the journey's `feelings`, by name: the level this stage's point is drawn at. A name, never a score."
        },
        "role": {
          "type": "string",
          "description": "`step` (the default) or `emphasis` (the stage the map is about, usually the trough): its column framed, its point drawn larger and solid.",
          "enum": [
            "step",
            "emphasis"
          ]
        },
        "details": {
          "type": "array",
          "description": "What this stage holds in each detail row, a `{row, text}` per row it fills. A row it does not name is drawn as an empty cell.",
          "items": {
            "$ref": "#/$defs/detail"
          }
        }
      },
      "required": [
        "text",
        "feeling"
      ],
      "additionalProperties": false
    },
    "key": {
      "type": "object",
      "properties": {
        "group": {
          "type": "string",
          "description": "Which group this names. Some cell must belong to it."
        },
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        }
      },
      "required": [
        "group",
        "text"
      ],
      "additionalProperties": false
    },
    "lane-node": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique within the document."
        },
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "role": {
          "type": "string",
          "description": "The semantic role, which the theme resolves to an appearance. Defaults to 'step'.",
          "enum": [
            "start",
            "step",
            "decision",
            "terminal",
            "emphasis",
            "note",
            "io",
            "subroutine",
            "store",
            "person"
          ]
        },
        "actor": {
          "type": "string",
          "description": "Who performs this step, and so which lane it is drawn in. Required: every box in a swimlane diagram is in a lane. Drawn once, as the lane's heading, and not repeated in the box — so `text` may again use a newline for its own lead and detail. Free text, matched exactly against `lanes` when that is given."
        },
        "status": {
          "type": "string",
          "description": "What a proposed change does to this box, drawn as on a `flow`: the labelled mark inside the box, never a colour.",
          "enum": [
            "added",
            "changed",
            "removed"
          ]
        },
        "class": {
          "type": "string",
          "description": "Which of the document's `classes` this box belongs to — an author-chosen grouping such as *external system* or *owned by the payments team*, drawn as that class's faint fill and named in a key under the drawing. Must be the `id` of a declared class. Not on a `note` or a `group`, and not with `status` (both would mark the box). **Only a `flow`, a `tree` or `lanes`.**"
        }
      },
      "required": [
        "id",
        "text",
        "actor"
      ],
      "additionalProperties": false
    },
    "level": {
      "type": "object",
      "properties": {
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "role": {
          "type": "string",
          "description": "The semantic role, which the theme resolves to an appearance. Defaults to 'step'.",
          "enum": [
            "start",
            "step",
            "decision",
            "terminal",
            "emphasis",
            "note",
            "group"
          ]
        },
        "note": {
          "type": "string",
          "description": "A short aside attached to this element. **Only `timeline` draws one** — it goes under the axis, beside the entry's own mark. Every other kind accepts the field and has nowhere to put it, so it is not drawn; for text belonging to the whole diagram, use the top-level `caption` instead."
        }
      },
      "required": [
        "text"
      ],
      "additionalProperties": false
    },
    "loop": {
      "type": "object",
      "properties": {
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "nodes": {
          "type": "array",
          "description": "The loop's variables in the order it runs: each joined to the next, and the last back to the first, by a signed edge in that direction.",
          "items": {
            "type": "string"
          },
          "minItems": 2
        },
        "type": {
          "type": "string",
          "description": "Optional, and checked: an even number of `-` links is `reinforcing`, an odd number `balancing`. Drawn as R or B, numbered in the order written.",
          "enum": [
            "reinforcing",
            "balancing"
          ]
        }
      },
      "required": [
        "text",
        "nodes"
      ],
      "additionalProperties": false
    },
    "mark": {
      "type": "object",
      "properties": {
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "at": {
          "type": "number",
          "description": "Where on the axis: a line is drawn across every row there."
        }
      },
      "required": [
        "text",
        "at"
      ],
      "additionalProperties": false
    },
    "message": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Optional, and only needed to name this message from a fragment. Unique among the messages."
        },
        "from": {
          "type": "string",
          "description": "The participant that sends it."
        },
        "to": {
          "type": "string",
          "description": "The participant that receives it. The same id as `from` is a message to itself, drawn as a hook on the right of its lifeline."
        },
        "text": {
          "type": "string",
          "description": "What is said, written above the arrow. May carry inline spans. Omit for a bare arrow."
        },
        "role": {
          "type": "string",
          "description": "The semantic role, which the theme resolves to an appearance. Defaults to 'flow'.",
          "enum": [
            "flow",
            "weak",
            "strong",
            "async"
          ]
        },
        "note": {
          "type": "string",
          "description": "A short aside about this message, drawn on its row in one column to the right of the last lifeline, so the notes read down as one margin."
        }
      },
      "required": [
        "from",
        "to"
      ],
      "additionalProperties": false
    },
    "meter-band": {
      "type": "object",
      "properties": {
        "text": {
          "type": "string",
          "description": "The band's name, written on it: `Good`, `Strained`, or `Green` when that is the word the reader is taught. One or two short words."
        },
        "to": {
          "type": "number",
          "description": "Where the band ends; it starts where the band before ends."
        }
      },
      "required": [
        "text",
        "to"
      ],
      "additionalProperties": false
    },
    "meter-meter": {
      "type": "object",
      "properties": {
        "text": {
          "type": "string",
          "description": "The meter's name. A second line after a newline is its caption, drawn plain under the name: what the reading is of — `This year's milestones only`."
        },
        "amount": {
          "type": "number",
          "description": "The reading, on the scale from `min` to `max`. Written with its `unit` in the readout; never as a percentage the author worked out."
        },
        "max": {
          "type": "number",
          "description": "The end of the scale: a thermometer's goal, a progress bar's whole, a dial's right-hand end."
        },
        "min": {
          "type": "number",
          "description": "Where the scale starts, on a `dial` only (0 by default): a needle reads a position, so it may start anywhere. A bar's length is its amount, so a bar, a bullet and a thermometer start at 0."
        },
        "unit": {
          "type": "string",
          "description": "What the numbers are in: `%`, a currency sign (`£`, `$`, `€`, `¥`, written before the number) or a word (`tasks`, after it)."
        },
        "target": {
          "type": "number",
          "description": "A mark on the scale — the plan, a stage of an appeal — drawn across the track and written in the readout. Inside the scale."
        },
        "bands": {
          "type": "array",
          "description": "Named stretches of the scale, rising: each runs from the end of the one before (or `min`) to its own `to`, and the last ends at `max`. Required on a `bullet`, optional on a `dial`, refused on the others. Drawn in tones of the page's ink with their words on them, so a band is never told by colour alone.",
          "items": {
            "$ref": "#/$defs/meter-band"
          },
          "minItems": 2
        },
        "role": {
          "type": "string",
          "description": "`step` (the default) or `emphasis` (the meter the panel is about: its name and reading bold).",
          "enum": [
            "step",
            "emphasis"
          ]
        }
      },
      "required": [
        "text",
        "amount",
        "max"
      ],
      "additionalProperties": false
    },
    "mindmap-branch": {
      "type": "object",
      "properties": {
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "role": {
          "type": "string",
          "description": "`step` (the default), `emphasis` (the branch the map is about: bold, its line heavy all the way from the centre; at most two) or `note` (context, not content: faint, and so is everything under it).",
          "enum": [
            "step",
            "emphasis",
            "note"
          ]
        },
        "branches": {
          "type": "array",
          "description": "The branches off this one, drawn top to bottom in the order written. At most three levels below the centre: a branch, a twig, a leaf.",
          "items": {
            "$ref": "#/$defs/mindmap-branch"
          },
          "minItems": 1
        }
      },
      "required": [
        "text"
      ],
      "additionalProperties": false
    },
    "node": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique within the document."
        },
        "centre": {
          "type": "boolean",
          "description": "Whether this node is the subject the rest are arranged around. One node per document may say so, and only a `flow`. For the diagram that starts in the middle rather than at the top: a thing with named relations on every side, where the relations are peers and there is no sequence between them. Ranked instead, the middle object becomes just another row."
        },
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "role": {
          "type": "string",
          "description": "The semantic role, which the theme resolves to an appearance. Defaults to 'step'.",
          "enum": [
            "start",
            "step",
            "decision",
            "terminal",
            "emphasis",
            "note",
            "group",
            "io",
            "subroutine",
            "store",
            "person"
          ]
        },
        "actor": {
          "type": "string",
          "description": "Who performs this step — free text, and orthogonal to `role`. `role` says what kind of step it is; this says whose it is, and the two are independent: a human step can be routine and an automated one can be the critical path. Drawn as the box's **lead**, the name over what belongs to it, so the same words sit in the same place in every box and a reader can scan a column of them. Free text rather than an enum on purpose: an actor is told apart by its **name**, which is legible in greyscale and in any medium, so it costs none of the four non-colour channels the roles are told apart by. **Only a `flow`, a `tree` or a `cycle` draws one**, and a node that names an actor may not also write its own lead — the box has one lead and this is it."
        },
        "note": {
          "type": "string",
          "description": "A short aside attached to this element. **Only `timeline` draws one** — it goes under the axis, beside the entry's own mark. Every other kind accepts the field and has nowhere to put it, so it is not drawn; for text belonging to the whole diagram, use the top-level `caption` instead."
        },
        "class": {
          "type": "string",
          "description": "Which of the document's `classes` this box belongs to — an author-chosen grouping such as *external system* or *owned by the payments team*, drawn as that class's faint fill and named in a key under the drawing. Must be the `id` of a declared class. Not on a `note` or a `group`, and not with `status` (both would mark the box). **Only a `flow`, a `tree` or `lanes`.**"
        },
        "status": {
          "type": "string",
          "description": "What a proposed change does to this box, as a diff would say it — for one drawing of the target state with the change marked on it, instead of a before and an after to compare by eye. Drawn as the labelled mark `files` uses (`+ added`, `~ changed`, `- removed`) inside the box, never as a colour; a removed box is also dashed and its text struck through. **Only a `flow` or a `tree`**: a loop that changes is a different loop. An edge touching a removed box must be `removed`, and one touching an added box must be `added`.",
          "enum": [
            "added",
            "changed",
            "removed"
          ]
        }
      },
      "required": [
        "id",
        "text"
      ],
      "additionalProperties": false
    },
    "numberline-point": {
      "type": "object",
      "properties": {
        "at": {
          "type": "number",
          "description": "Where the dot sits on the axis: a number between `min` and `max`."
        },
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "open": {
          "type": "boolean",
          "description": "Whether the dot is hollow: the value itself is excluded — `x ≠ 3`, a hole. Defaults to false, a filled dot."
        },
        "role": {
          "type": "string",
          "description": "`step` (the default), `emphasis` (the point the line is about: a larger dot, its words bold) or `note` (context: a smaller dot).",
          "enum": [
            "step",
            "emphasis",
            "note"
          ]
        }
      },
      "required": [
        "at"
      ],
      "additionalProperties": false
    },
    "numberline-range": {
      "type": "object",
      "properties": {
        "from": {
          "type": "number",
          "description": "Where the range starts. Omit it for a range that runs on below `min`, drawn as an arrow off the left end."
        },
        "to": {
          "type": "number",
          "description": "Where the range ends: more than `from`. Omit it for a range that runs on above `max`, drawn as an arrow off the right end."
        },
        "from_open": {
          "type": "boolean",
          "description": "Whether `from` is excluded — `x > 1` rather than `x ≥ 1`. Defaults to false. The theme's `[numberline] ends` draws it as a hollow dot or a parenthesis."
        },
        "to_open": {
          "type": "boolean",
          "description": "Whether `to` is excluded — `x < 4` rather than `x ≤ 4`. Defaults to false."
        },
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "role": {
          "type": "string",
          "description": "`step` (the default, a heavy line), `emphasis` (the range the line is about — the solution set: a heavier bar, its words bold) or `note` (context: dashed).",
          "enum": [
            "step",
            "emphasis",
            "note"
          ]
        }
      },
      "additionalProperties": false
    },
    "participant": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique within the document, among the participants and the groups."
        },
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "role": {
          "type": "string",
          "description": "The semantic role, which the theme resolves to an appearance. Defaults to 'step'.",
          "enum": [
            "step",
            "emphasis",
            "note",
            "actor"
          ]
        }
      },
      "required": [
        "id",
        "text"
      ],
      "additionalProperties": false
    },
    "phase": {
      "type": "object",
      "properties": {
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "members": {
          "type": "array",
          "description": "The ids of the steps in this phase, in any order and in any lane. Every step is in one phase, so a step left out or listed twice is refused.",
          "items": {
            "type": "string"
          },
          "minItems": 1
        }
      },
      "required": [
        "text",
        "members"
      ],
      "additionalProperties": false
    },
    "pie-part": {
      "type": "object",
      "properties": {
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "amount": {
          "type": "number",
          "description": "How much of the total this part is, more than 0, in the pie's `unit`: a count, a sum, or with `unit: \"%\"` a percentage. Its angle is its share of the sum of the amounts, computed — never written.",
          "exclusiveMinimum": 0
        },
        "role": {
          "type": "string",
          "description": "`step` (the default), `emphasis` (the part the chart is about: a heavier outline, its words bold) or `note` (the remainder, `Everything else`: unfilled and dashed, drawn last). At most one `note`.",
          "enum": [
            "step",
            "emphasis",
            "note"
          ]
        }
      },
      "required": [
        "text",
        "amount"
      ],
      "additionalProperties": false
    },
    "position": {
      "type": "object",
      "properties": {
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "across": {
          "type": "number",
          "description": "Where this sits on the horizontal axis. Data, not a coordinate."
        },
        "up": {
          "type": "number",
          "description": "Where this sits on the vertical axis. Data, not a coordinate."
        },
        "role": {
          "type": "string",
          "description": "The semantic role, which the theme resolves to an appearance. Defaults to 'step'.",
          "enum": [
            "start",
            "step",
            "decision",
            "terminal",
            "emphasis",
            "note",
            "group"
          ]
        }
      },
      "required": [
        "text",
        "across",
        "up"
      ],
      "additionalProperties": false
    },
    "rag-row": {
      "type": "object",
      "properties": {
        "text": {
          "type": "string",
          "description": "The workstream or risk. A second line after a newline is a caption under it, at the label size: an owner, a reference."
        },
        "rag": {
          "type": "string",
          "description": "The rating: `red`, `amber` or `green`. Drawn as the theme's word and shape for it (and its colour, when the theme has one), so it is never told by colour alone.",
          "enum": [
            "red",
            "amber",
            "green"
          ]
        },
        "trend": {
          "type": "string",
          "description": "The direction of travel since the last report: `better`, `same` or `worse`. Drawn as an arrow (up, across, down) with the theme's word beside it.",
          "enum": [
            "better",
            "same",
            "worse"
          ]
        },
        "note": {
          "type": "string",
          "description": "Why: a sentence or two of commentary, wrapped in the last column. `**bold**` for a decision asked for."
        }
      },
      "required": [
        "text",
        "rag"
      ],
      "additionalProperties": false
    },
    "region": {
      "type": "object",
      "properties": {
        "in": {
          "type": "array",
          "description": "The ids of exactly the sets this region is in, and no others: `[\"gdpr\"]` is what only that set holds, `[\"gdpr\", \"ens\"]` what the two share. drawspec knows where that region is.",
          "items": {
            "type": "string"
          },
          "minItems": 1
        },
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "role": {
          "type": "string",
          "description": "`step` (the default) or `emphasis` (the region the diagram is about): its words bold and the region filled with the theme's first mark fill.",
          "enum": [
            "step",
            "emphasis"
          ]
        }
      },
      "required": [
        "in",
        "text"
      ],
      "additionalProperties": false
    },
    "relation": {
      "type": "object",
      "properties": {
        "from": {
          "type": "string",
          "description": "The id of an entity. For `inherits` and `realizes`, the specific one — the subclass, the implementation."
        },
        "to": {
          "type": "string",
          "description": "The id of another entity — for `inherits` and `realizes` the general one, which gets the hollow triangle. Not the same as `from`."
        },
        "from_field": {
          "type": "string",
          "description": "The id of one of the `from` entity's fields: the line leaves that row, at the side facing the other entity, instead of the box. A foreign key drawn from its column."
        },
        "to_field": {
          "type": "string",
          "description": "As `from_field`, a field of the `to` entity: the line arrives at its row."
        },
        "from_end": {
          "type": "string",
          "description": "How many of the `from` entity there are per one of the other, drawn at the `from` end — crow's feet or numbers, as the theme's `[entities] notation` says. Not on `inherits` or `realizes`.",
          "enum": [
            "one",
            "zero-or-one",
            "many",
            "zero-or-many",
            "one-or-many"
          ]
        },
        "to_end": {
          "type": "string",
          "description": "As `from_end`, for the `to` end: how many of it per one of the other. Not on `owns`, whose `to` end is the whole, drawn as the diamond.",
          "enum": [
            "one",
            "zero-or-one",
            "many",
            "zero-or-many",
            "one-or-many"
          ]
        },
        "label": {
          "type": "string",
          "description": "A short label placed along the line."
        },
        "role": {
          "type": "string",
          "description": "What the relation is. `link` (the default) an association; `owns` composition — `from` is a part of `to`, diamond at `to`; `weak` a dependency; `strong` the relation that matters; `inherits` and `realizes` a subclass and an implementation, hollow triangle at `to`. An end with a cardinality draws it in place of the role's head.",
          "enum": [
            "link",
            "owns",
            "weak",
            "strong",
            "inherits",
            "realizes"
          ]
        }
      },
      "required": [
        "from",
        "to"
      ],
      "additionalProperties": false
    },
    "ring": {
      "type": "object",
      "properties": {
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "role": {
          "type": "string",
          "description": "The semantic role, which the theme resolves to an appearance. Defaults to 'step'.",
          "enum": [
            "start",
            "step",
            "decision",
            "terminal",
            "emphasis",
            "note",
            "group"
          ]
        }
      },
      "required": [
        "text"
      ],
      "additionalProperties": false
    },
    "sankey-flow": {
      "type": "object",
      "properties": {
        "from": {
          "type": "string",
          "description": "The id of the node the amount leaves."
        },
        "to": {
          "type": "string",
          "description": "The id of the node the amount reaches."
        },
        "amount": {
          "type": "number",
          "description": "How much flows, in the sankey's `unit`: the band's thickness is in proportion. A number you already know, more than 0.",
          "exclusiveMinimum": 0
        },
        "role": {
          "type": "string",
          "description": "`flow` (the default band) or `strong` (the path the diagram is about, drawn darker).",
          "enum": [
            "flow",
            "strong"
          ]
        }
      },
      "required": [
        "from",
        "to",
        "amount"
      ],
      "additionalProperties": false
    },
    "sankey-node": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique among the nodes; what a flow's `from` and `to` name."
        },
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "role": {
          "type": "string",
          "description": "`step` (the default), `emphasis` (the node the diagram is about: its bar outlined heavier, its words bold) or `note` (the remainder — `Lost`, `Reserved, idle` — drawn lighter, with the bands that reach it).",
          "enum": [
            "step",
            "emphasis",
            "note"
          ]
        }
      },
      "required": [
        "id",
        "text"
      ],
      "additionalProperties": false
    },
    "series": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "What to call this series, in the legend and at its end."
        },
        "data": {
          "type": "array",
          "description": "The values to plot, as [x, y] pairs. Data, not coordinates.",
          "items": {
            "type": "array",
            "items": {
              "type": "number"
            },
            "minItems": 2,
            "maxItems": 2
          },
          "minItems": 1
        },
        "role": {
          "type": "string",
          "description": "The semantic role, which the theme resolves to an appearance. Defaults to 'step'.",
          "enum": [
            "start",
            "step",
            "decision",
            "terminal",
            "emphasis",
            "note",
            "group"
          ]
        },
        "mark": {
          "type": "string",
          "description": "How this series is drawn: a line, bars, or a filled area. Default 'line'.",
          "enum": [
            "line",
            "bar",
            "area"
          ]
        },
        "stack": {
          "type": "string",
          "description": "Series sharing a stack name are piled on each other rather than drawn side by side. Bars and areas only."
        }
      },
      "required": [
        "name",
        "data"
      ],
      "additionalProperties": false
    },
    "slice": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique among the rows; what a card's `row` and the board's `cut` name."
        },
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        }
      },
      "required": [
        "id",
        "text"
      ],
      "additionalProperties": false
    },
    "span": {
      "type": "object",
      "properties": {
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "from": {
          "type": "string",
          "description": "The id of the entry the interval starts at."
        },
        "to": {
          "type": "string",
          "description": "The id of the entry it ends at. Must come after `from`."
        }
      },
      "required": [
        "text",
        "from",
        "to"
      ],
      "additionalProperties": false
    },
    "stage": {
      "type": "object",
      "properties": {
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "role": {
          "type": "string",
          "description": "The semantic role, which the theme resolves to an appearance. Defaults to 'step'.",
          "enum": [
            "start",
            "step",
            "decision",
            "terminal",
            "emphasis",
            "note",
            "group"
          ]
        },
        "gate": {
          "type": "string",
          "description": "What stands between this stage and the next — the threshold a thing has to pass to get from one to the other, which is what makes a stage-gate model one. Drawn on the divider, which breaks to let it through. The last stage has no next stage, so it may not carry one."
        },
        "note": {
          "type": "string",
          "description": "A short aside attached to this element. **Only `timeline` draws one** — it goes under the axis, beside the entry's own mark. Every other kind accepts the field and has nowhere to put it, so it is not drawn; for text belonging to the whole diagram, use the top-level `caption` instead."
        },
        "amount": {
          "type": "number",
          "description": "On a `funnel` stage: how many reached it. Written under the name, with the share kept from the stage before; the taper stays the drawing's own, not to scale. Every stage or none, never more than the stage before.",
          "exclusiveMinimum": 0
        }
      },
      "required": [
        "text"
      ],
      "additionalProperties": false
    },
    "state": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique within the document, among the states and the groups."
        },
        "text": {
          "type": "string",
          "description": "The state's name. A newline makes it a lead and a detail, as on any box. Required on every state but a `fork` or `join` bar, which has no words."
        },
        "role": {
          "type": "string",
          "description": "The semantic role, which the theme resolves to an appearance. Defaults to 'step'. `fork` and `join` make this state a bar: a fork has one transition in and two or more out, each into a different region of one composite; a join is the reverse. A bar has no `text`, and the transitions out of a fork or into a join carry no `event` or `guard`.",
          "enum": [
            "step",
            "emphasis",
            "terminal",
            "fork",
            "join"
          ]
        }
      },
      "required": [
        "id"
      ],
      "additionalProperties": false
    },
    "state_region": {
      "type": "object",
      "properties": {
        "members": {
          "type": "array",
          "description": "The states (or groups) in this region. A state is in one region; each region is a machine of its own, running alongside the others.",
          "items": {
            "type": "string"
          },
          "minItems": 1
        },
        "initial": {
          "type": "string",
          "description": "The member this region starts in when its composite is entered, drawn as a dot inside the region. Required unless every way into the composite is a `fork` with an arrow into this region, which says where it starts instead."
        }
      },
      "required": [
        "members"
      ],
      "additionalProperties": false
    },
    "sunburst-node": {
      "type": "object",
      "properties": {
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "children": {
          "type": "array",
          "description": "The sectors nested inside this one — the next ring, drawn clockwise in the order written. At most three rings in all; leave it out of a node that ends the hierarchy.",
          "items": {
            "$ref": "#/$defs/sunburst-node"
          },
          "minItems": 1
        }
      },
      "required": [
        "text"
      ],
      "additionalProperties": false
    },
    "task": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique within the document."
        },
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "start": {
          "type": "number",
          "description": "Where the task starts on the axis, with `end`. A number in the axis's unit (week 3, day 12, minute 45) — data, not a coordinate. Never a date."
        },
        "end": {
          "type": "number",
          "description": "Where it ends, after `start`. With categories, 4 is where the fourth period begins."
        },
        "at": {
          "type": "number",
          "description": "Instead of `start` and `end`: makes the task a milestone, drawn as a mark at this point with no length."
        },
        "actor": {
          "type": "string",
          "description": "Who does it — free text, drawn as the row label's lead, so the names line up in a column. A task with an actor may not put a newline in `text`."
        },
        "done": {
          "type": "number",
          "description": "How much of the task is complete, 0 to 100: drawn as a solid band inside the bar from its start, MS Project's progress line. Not on a milestone."
        },
        "events": {
          "type": "array",
          "description": "Moments on the task's own row — a delivery, a release, a review — each a diamond on the bar where it falls, its words under the bar. Unlike a milestone task they take no row of their own, so several fall on one row. Within the task's `start` to `end`; not on a milestone.",
          "items": {
            "$ref": "#/$defs/task-event"
          }
        },
        "iterations": {
          "type": "array",
          "description": "Cycles the work goes round: each an arc over the bar from an iteration's `end` back to its `start`, the return a life cycle draws. Within the task's `start` to `end`, in order and not overlapping; not on a milestone.",
          "items": {
            "$ref": "#/$defs/iteration"
          }
        },
        "role": {
          "type": "string",
          "description": "`step` (the default bar), `strong` (on the critical path: drawn heavier, the word its dependencies take), `emphasis` (the task the diagram is about) or `note` (outside the plan, drawn lighter).",
          "enum": [
            "step",
            "strong",
            "emphasis",
            "note"
          ]
        }
      },
      "required": [
        "id",
        "text"
      ],
      "additionalProperties": false
    },
    "task-event": {
      "type": "object",
      "properties": {
        "at": {
          "type": "number",
          "description": "Where on the axis, inside the task's interval."
        },
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        }
      },
      "required": [
        "at"
      ],
      "additionalProperties": false
    },
    "transition": {
      "type": "object",
      "properties": {
        "from": {
          "type": "string",
          "description": "The state the machine leaves — or a group, for a transition that leaves the composite from whichever state inside it is current."
        },
        "to": {
          "type": "string",
          "description": "The state the machine enters — or a group, which is entered at its own `initial`. The same id as `from` draws a self-loop."
        },
        "event": {
          "type": "string",
          "description": "What happens that moves the machine. Omit for a completion transition, taken as soon as the state's work is done."
        },
        "guard": {
          "type": "string",
          "description": "The condition that must hold for the event to move the machine. Written plainly; drawspec adds the brackets."
        },
        "action": {
          "type": "string",
          "description": "What the machine does on the way. Written plainly; drawspec adds the slash. The label reads `event [guard] / action`, each part optional."
        },
        "role": {
          "type": "string",
          "description": "The semantic role, which the theme resolves to an appearance. Defaults to 'flow'.",
          "enum": [
            "flow",
            "strong",
            "weak"
          ]
        }
      },
      "required": [
        "from",
        "to"
      ],
      "additionalProperties": false
    },
    "treemap-group": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique among the groups; what a part's `group` names."
        },
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        }
      },
      "required": [
        "id",
        "text"
      ],
      "additionalProperties": false
    },
    "treemap-part": {
      "type": "object",
      "properties": {
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "amount": {
          "type": "number",
          "description": "How much of the total this part is, in the treemap's `unit`: its area is in proportion. A number you already know, more than 0.",
          "exclusiveMinimum": 0
        },
        "group": {
          "type": "string",
          "description": "The id of one of the treemap's `groups`: the part is laid out with the group's other parts inside its captioned frame. Omit it to sit beside the groups."
        },
        "role": {
          "type": "string",
          "description": "`step` (the default), `emphasis` (the part the diagram is about — not automatically the largest: a heavier outline, its words bold) or `note` (the remainder, `Everything else`: a light dashed outline, laid out last).",
          "enum": [
            "step",
            "emphasis",
            "note"
          ]
        }
      },
      "required": [
        "text",
        "amount"
      ],
      "additionalProperties": false
    },
    "venn-set": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique among the sets; what a region's `in` names."
        },
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "role": {
          "type": "string",
          "description": "`step` (the default) or `emphasis` (the set the diagram is about), drawn as a heavier outline.",
          "enum": [
            "step",
            "emphasis"
          ]
        }
      },
      "required": [
        "id",
        "text"
      ],
      "additionalProperties": false
    },
    "waterfall-axis": {
      "type": "object",
      "properties": {
        "label": {
          "type": "string",
          "description": "What the numbers are, with their unit — `Borrowing, £ billion`. Set beside the vertical axis; required, as on every chart."
        }
      },
      "required": [
        "label"
      ],
      "additionalProperties": false
    },
    "waterfall-bar": {
      "type": "object",
      "properties": {
        "text": {
          "type": "string",
          "description": "The words themselves. May carry inline spans — `code` for the monospace role and **bold** for emphasis — because those are semantic, not typographic. A newline says this label is a lead and a detail rather than one sentence; the theme's `[box] lead` decides what the first paragraph looks like. Prefer it to punctuating the two apart inside one line."
        },
        "total": {
          "type": "number",
          "description": "A total: the bar stands on zero and runs to it. The first bar is one and so is the last; one in between is a subtotal. Every total after the first is checked: it must be the running sum. Not with `amount`."
        },
        "amount": {
          "type": "number",
          "description": "A signed step, not 0: the bar floats from the running sum to the running sum plus this, and is written `+6.1` or `−9.4`. Not with `total`."
        },
        "role": {
          "type": "string",
          "description": "`step` (the default) or `emphasis` (the bar the chart is about: a heavier outline, its number bold).",
          "enum": [
            "step",
            "emphasis"
          ]
        }
      },
      "required": [
        "text"
      ],
      "additionalProperties": false
    },
    "waypoint": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Optional, and only needed to measure from this point: a span names the two waypoints it runs between. Unique within the document."
        },
        "text": {
          "type": "string",
          "description": "What to call this point. Omit for a point that only shapes the curve."
        },
        "across": {
          "type": "number",
          "description": "Where this sits on the horizontal axis. Data, not a coordinate."
        },
        "up": {
          "type": "number",
          "description": "Where this sits on the vertical axis. Data, not a coordinate."
        }
      },
      "required": [
        "across",
        "up"
      ],
      "additionalProperties": false
    }
  }
}
