# yUML DSL Reference (v1) yUML is a text-based diagramming language. Each diagram type has its own syntax. Metadata lines (`@heading`, `@caption`, `@legend`, `@direction`, `@style`) can appear anywhere in any diagram type. This file is the **canonical source of truth** for the AI-friendly DSL reference. It is read by: - `/dsl/v1/spec` and `/dsl/v1/spec.txt` (public docs endpoint on app.yuml.me) - `Ai::FixDsl` service (Fix-with-AI system prompt in the Rails web app) - The MCP server's `render_diagram` / `render_story` tool descriptions Formal grammars live in `renderer/src/*.pegjs` and are the ultimate authority on what parses. This file is the human-and-LLM-friendly narrative — keep it in sync when grammar changes. Public URL: https://app.yuml.me/dsl/v1/spec.txt ## Styles Available styles: `clean`, `plain`, `boring`, `sketch`, `scruffy`, `napkin`, `midnight`, `blueprint`. Set via `@style ` in stories or as a render option. ## Layout direction Most diagram types lay out top-to-bottom by default. The **use case** diagram is the exception — it goes left-to-right. Override with `@direction` in the DSL: ``` @direction LR — left-to-right @direction TB — top-to-bottom (alias: TD, DOWN) [A]->[B] [B]->[C] ``` Accepted values (case-insensitive): `LR` / `RIGHT`, `TB` / `TD` / `DOWN`. Direction has no effect on types whose layout is intrinsic to the type — sequence, journey flow, timeline, roadmap, and the chart family (bar, column, line, pie). When rendering via the URL API you can also pass direction as a modifier on the style segment instead of editing the DSL: ``` /diagram/v1/class/clean;dir=LR/[A]->[B],[B]->[C].svg ``` `@direction` and `;dir=…` are equivalent. If both are present, the URL modifier wins. ## Forced line breaks A literal `\n` (backslash + the letter n) in the DSL becomes a forced line break in the rendered text. Soft-wrapping still applies to each segment, so `\n` is a *guaranteed* break, not a substitute for wrapping. Supported in: - `@heading` and `@caption` (any diagram type) - **Notes on every diagram type that has them** — class, activity, state, use case, and sequence: `[note: First line\nSecond line]`, `(note: First line\nSecond line)` - Class-diagram labels - Canvas titles, sub-titles, `>` help text, prose, and bullets Example: ``` @heading Quarterly Review\nSWOT [note: Recalculated\non every change]-[Order] (note: Validate within\n24 hours)-(Receive Order) ``` ## Colouring nodes To colour a node, use `{bg:name}` (a named colour or `#hex`) and `{!}` for the theme accent. **Placement is per family — get it wrong and it either doesn't parse or is ignored, so follow the rule for the type:** - **Class, C4, use case, activity, state, sequence, timeline, roadmap** — INSIDE the brackets, after the name/last field: `[Order{bg:blue}|date]`, `[Platform|System|Core{bg:blue}]`, `[Card Title{bg:green}]`, `(Review{bg:blue})`, `[Draft{bg:blue}]`. Use case colours actors and use cases alike: `[Actor{bg:blue}]`, `(Use Case{bg:green})`. Placing it after the closing `]`/`)` is a parse error, not a style. - **Charts** (bar/column/line/pie) — AFTER the value, on the value side of the colon: `Q3: 140{bg:blue}` or `Q3: 140{!}`. Putting it on the label (`Q3{!}: 140`) is ignored. - **Mind map** — a trailing decorator on the node line: ` Risks {bg:red}`. - **Canvas** — after the region heading: `# Region {bg: cream}` or `# Region {!}`. - **Class/C4 notes** — inside the note: `[note: text{bg:wheat}]`. `{!}` works anywhere `{bg}` does, painting the theme accent. **Colour is NOT supported on** journey maps, journey flow, or causal-loop diagrams — they ignore `{bg}`/`{!}` (and a journey map will render the token as literal text). Do not add colour to these; convey feeling with their emotion tokens (`:happy:`, `:frustrated:`, …) instead. If a diagram type is not listed above as supporting colour, do not add `{bg}` or `{!}` to it. ## Class Diagrams ``` [ClassName] — class [ClassName|attr1;attr2] — with attributes [ClassName|attr1;attr2|method()] — with methods [<>;Name] — stereotype [ClassName{bg:blue}] — coloured class (fill INSIDE the brackets) [ClassName{bg:blue}|attr|method()] — colour with attributes/methods [note: text{bg:wheat}] — note [A]->[B] — directed association [A]<->[B] — bidirectional [Parent]^[Child] — inheritance — the side adjacent to ^ is the PARENT [A]<>[B] — aggregation [A]++->[B] — composition [A]-.->[B] — dependency (dashed) [A]^-.-[B] — implements (dashed inheritance) [A]label->[B] — labelled [A]1-0..*>[B] — cardinality // comment ``` Example: ``` [Customer|name;email]-orders>*[Order|date;total] [Order]->*[LineItem|qty;price] [LineItem]->[Product|name;sku;price] ``` Colour — `{bg:name}` (named colour or `#hex`) goes **inside** the brackets, right after the class name: `[Order{bg:blue}|date;total]`. Placing it after the closing `]` (`[Order|date]{bg:blue}`) is a parse error, not a style. Same rule as C4 elements. Inheritance direction — the parent is on the **left** of `^`. So `[Animal]^[Duck]` means Duck inherits from Animal. Mirror this when translating from Mermaid (`Animal <|-- Duck` becomes `[Animal]^[Duck]`) or PlantUML (`Animal <|-- Duck` becomes `[Animal]^[Duck]`). ``` [Animal|age;gender|isMammal();mate()] [Animal]^[Duck|beakColor|swim();quack()] [Animal]^[Fish|sizeInFeet|canEat()] [Animal]^[Zebra|isWild|run()] ``` ## Sequence Diagrams ``` [Object] — participant (box) — on its own line declares; in a message it references (Actor) — participant (stick figure) — on its own line declares; in a message it references [A]message->[B] — sync message [A]message-->[B] — return message (dashed) [A]message->>[B] — async message {alt condition} ... {else} ... {end} — alt fragment {loop condition} ... {end} — loop fragment {opt condition} ... {end} — optional fragment [note: text]-[A] — note on participant (plain `-`, no arrow) ``` Example: ``` (User)Login->[Auth] [Auth]validate->[Auth] [Auth]checkCredentials->[DB] [DB]result-->[Auth] {alt valid} [Auth]token-->(User) {else} [Auth]error-->(User) {end} ``` ## Activity Diagrams ``` (Activity Name) — activity (rounded box) (start) — start node (end) — end node — decision diamond |Fork| — fork/join bar (A)->(B) — flow (A)label->(B) — labelled flow (A)[guard]->(B) — guarded flow (note: text)-(Activity) — note attached to an activity ``` Notes use `( )` like activities, but with a leading `note:`. Attach a note to the node it explains with a plain `-` connector (no arrow) — the note renders as a folded-corner callout beside that node. A bare `(note: text)` with nothing to attach it to has no anchor, so always connect it: `(note: Orders must be validated within 24 hours)-(Validate)`. Use `\n` inside the text for a forced line break. A decision diamond can carry a name (``), but it is **not rendered** — the diamond shows empty. The branch guards are what the reader sees, so make them descriptive: prefer `[Passes test]` / `[Fails test]` over `[yes]` / `[no]`. The name is still worth keeping in the DSL as an identifier that ties the branches together and documents intent. Example: ``` (start)->(Receive Order) (Receive Order)-> [Order is valid]->(Process) [Missing details]->(Reject) (Process)->(end) (Reject)->(end) (note: Must clear fraud check\nbefore processing)-(Process) ``` ## Use Case Diagrams ``` [Actor Name] — actor (stick figure) (Use Case Name) — use case (ellipse) [Actor{bg:blue}] — coloured actor (fill inside the brackets) (Use Case{bg:green}) — coloured use case (fill inside the parens) [A]-(B) — association (A)<(B) — extends (A)>(B) — includes (A)^(B) — inheritance ``` Colour goes **inside** the `[ ]` or `( )`, right after the name — same rule as class and C4. After the closing bracket it won't apply. Example: ``` [Customer]-(Place Order{bg:green}) [Customer]-(Track Order) (Place Order)>(Validate Payment) (Track Order)<(Cancel Order) [Admin{bg:blue}]-(Manage Inventory) ``` ## State Diagrams ``` [State Name] — state (rounded rect) (start) — initial state (end) — final state — choice diamond [A]->[B] — transition [A]-event->[B] — event transition [A]-event[guard]->[B] — guarded transition [A]-event[guard]/action->[B] — with action [note: text]-[State] — note attached to a state ``` Attach a note to the state it explains with a plain `-` connector (no arrow), the same way class-diagram notes attach. `\n` forces a line break inside the text. Example: ``` (start)->[Idle] [Idle]-login->[Active] [Active]-logout->[Idle] [Active]-timeout[inactive > 30m]->[Expired] [Expired]->[Idle] [note: Cleared after 30 min\nof inactivity]-[Expired] ``` ## C4 Architecture Diagrams A single `c4` diagram type covers Context, Container, Component and System Landscape views — they use the same notation. ``` [Name|Type|Description] — element with type + description [Name|Type] — element with type, no description [Name] — untyped element ``` Recognised element types (case-insensitive, with common aliases): - `Person` — also `User`, `Actor`, `Role`, `Customer`, `Admin` - `System` — also `Software System`, `Platform` - `Container` — also `Application`, `Web App`, `Service`, `Microservice`, `API`, `Database`, `Queue`, `Message Bus`, `Worker`, `Function` - `Component` — also `Module`, `Package`, `Library`, `Subsystem` - `External` — also `External System`, `External Service`, `Third Party`, `Vendor`, `SaaS` Edges: ``` [A]->[B] — solid arrow [A]-.->[B] — dashed arrow (any `.` in the dash run → dashed) [A]-Uses->[B] — middle label (solid) [A]-Sends mail via-.->[B] — middle label (dashed) [A]<->[B] — bidirectional [A]->[B] : Uses — colon label (alternative) ``` Boundaries group elements inside a dashed frame: ``` {Banking System [Web App|Container|Browser UI] [API|Container|REST endpoints] [DB|Container|Data store :database:] } ``` Decorator shortcodes inside descriptions trigger strip visuals on the card (database cylinder, browser chrome, mobile status bar, etc.): `:database:`, `:browser:`, `:mobile:`, `:queue:`, `:folder:`, `:document:`, `:console:`. Colour and highlight — the modifier goes **inside** the brackets, right after the last field (never after the closing `]`): ``` [Platform|System|Core system{bg:blue}] — coloured card fill [Account DB|Container|Stores accounts{!}] — theme accent highlight [Customer{bg:#e0f2ff}] — untyped card, hex fill ``` `{bg:name}` accepts a named colour or `#hex`; `{!}` paints the card in the theme accent. Both sit before the closing `]` — `[...]{bg:blue}` (outside) does not parse as a style. Metadata: ``` @heading My Banking Architecture @caption System Context view @legend true @direction LR ``` Example: ``` @heading Banking System Context @legend true [Customer|Person|A user of the bank] [Banking System|System|Core system for accounts and payments] [Email Service|External|Third-party transactional email] [Customer]-Uses->[Banking System] [Banking System]-Sends mail via-.->[Email Service] ``` ## Journey Map Diagrams Type `journey`. A line-oriented map of one actor's experience across stages, with an emotion per step. Distinct from **journey flow** (below), which uses activity syntax — pick `journey` for the classic stages-and-emotions map, `journeyflow` for a flow of emotive steps. ``` journey: Title — map title actor: Persona name — whose journey (optional) scenario: One-line context — optional expects: Thing one, Thing two — comma-separated expectations (optional) section Stage Name — a stage/column header Action text: :emotion: — a step with emotion Action text: :emotion: "Quote" — step with a spoken quote Action text — step, no emotion ``` Emotions accept shortcodes or raw emoji. Shortcodes (high → low): `:elated:` `:excited:` `:happy:` `:relieved:` `:calm:` `:neutral:` `:thinking:` `:uncertain:` `:worried:` `:frustrated:` `:stressed:` `:angry:` `:furious:`. Example: ``` journey: Switching Mobile Plans actor: Jumping Jamie expects: Clear online info, Easy plan comparison section Define Review current plan: :neutral: "I wonder if I can pay less" Define parameters: :neutral: section Compare Watches commercial: :happy: "This seems like a better deal" Compares tariffs: :uncertain: "Too many options" section Switch Completes signup: :elated: "That was painless" ``` ## Journey Flow Diagrams Uses activity diagram syntax with emotions for customer journey mapping. ``` (Phase Name) — journey phase/section header [:emotion: Action text] — step with emotion [:emotion: "Quote text"] — speech bubble with emotion [Action text] — step without emotion -> — flow arrow (optional) ``` Emotions: `:elated:` `:happy:` `:relieved:` `:neutral:` `:uncertain:` `:frustrated:` `:angry:` Example: ``` (Discover)-> [:happy: Finds product online]-> [:happy: "This looks promising"]-> (Evaluate)-> [:neutral: Reads reviews]-> [:uncertain: "Is it worth the price?"]-> (Purchase)-> [:frustrated: Complex checkout form]-> [:elated: Order confirmed] ``` ## Timeline Diagrams Uses activity diagram syntax for milestones. ``` (Title|Subtitle|Details) — major milestone (3 parts) (Title|Subtitle) — major milestone (2 parts) (Title) — major milestone (title only) [Event text] — minor milestone -> — flow arrow (optional) ``` Example: ``` (Q1|Research|Interviewed 50 users)-> [Team assembled]-> (Q2|Beta launch)-> [First paying customer]-> (Q3|Public release) ``` ## Roadmap Diagrams ``` (Horizon Name) — horizon/column header [Card Title|Description] — feature card [Card Title] — card without description [Card{bg:color}] — coloured card ``` Example: ``` (Now) [Search improvements|Full-text search] [Bug fixes|Top 10 issues] (Next) [Mobile app|iOS and Android] [API v2|REST and GraphQL] (Future) [AI features{bg:green}] [Enterprise SSO] ``` ## Canvas Diagrams Canvases are structured 2D thinking grids — Strategy Choice Cascade, SWOT, retros, OKRs, post-mortems, or any custom frame. The DSL is markdown- flavoured. ``` @type canvas — required type metadata @cols N — top-level grid width (optional) # Region Title — top-level region ## Sub Region — sub-region of the most recent # > Custom help text — blockquote overrides canonical help Prose body… — body lines (prose or bullets) - bullet — `* ` or `- ` starts a bullet # Region {cols: 2} — sub-grid layout override # Region {span: 2} — width weight within its row # Region {bg: cream} — fill that cell # Region {!} — accent: tint title + body ``` A `#` section with at least one `##` child renders as a group containing sub-boxes; otherwise it renders as a single box with its body content. Bullets are content, not regions. Decorators chain with `;` — `{cols: 2; bg: cream; !}`. A literal `\n` forces a break inside any title, sub-title, `>` help line, prose paragraph, or bullet — see [Forced line breaks](#forced-line-breaks). ### Auto-detected templates When section names match a known framework, the renderer applies the template automatically: canonical help text appears under each heading (muted subtitle), missing canonical sections are inserted as dashed- inset placeholders, and the layout shape is hinted (e.g. SWOT → 2×2). Detection is fuzzy and case-insensitive. Aliases: ``` Strategy Choice Cascade — vertical stack of regions Aspiration / Winning Aspiration Where to Play — 4 sub-regions: Geography Customer / Customer Segments Channels Offering / Products How to Win Capabilities / Must-Have Capabilities Management Systems / Systems SWOT Analysis — 2×2 quadrant Strengths Weaknesses Opportunities Threats ``` ### Layout - `@cols N` (canvas-level): how many top-level cells per row. Default 1 (vertical stack), or template default, or heuristic (even-and-≥4 → N/2). - `{cols: N}` (on a heading with sub-regions): sub-grid width inside that group. - `{span: N}` (on any heading): weight within its row. Default 1; `{span: 2}` is twice as wide as a default sibling. - Empty cells (no body, no children) render as dashed-inset placeholders — same treatment whether auto-inserted or written empty by the user. ### Examples Strategy Choice Cascade — auto-detected, canonical help text supplied: ``` @type canvas # Aspiration Launch a successful startup that helps people build their face-to-face network and relationships without compromising privacy. # Where to Play ## Geography Initially focus on saturating specific events in a single town, then global product. ## Customer Anyone doing networking — hobbyist artists to business folks. ## Channels Organic makes most sense. ## Offering Privacy-first way of sharing always-up-to-date contact details at networking events. # How to Win ??? # Capabilities - Privacy-by-design contact format - Event partnerships # Management Systems - KPI: subscription revenue to £30K ARR - KPI: k-factor for card shares - KPI: after-event conversations ``` SWOT — 2×2 layout from the template: ``` @type canvas # Strengths Deep ML expertise; existing customer base of 200 SMBs. # Weaknesses - Limited marketing budget - Single-region presence # Opportunities > Where could we grow? (overrides canonical help) Enterprise demand for privacy-first tools is accelerating. # Threats Big-tech entrants with bundled offerings. ``` Custom canvas without a template — author supplies help via blockquote: ``` @type canvas @cols 2 # What worked > Highlights from this sprint - Shipped onboarding redesign - Cut p95 latency by 40% # What didn't > Rough edges - Demo broke in staging twice - Search relevance regression # Surprises - 3 enterprise leads from a tweet # Next sprint - Re-run onboarding A/B - Latency budgets per service ``` Guidelines for AI canvas generation: - Prefer canonical section names so templates auto-apply (Aspiration, Where to Play, Strengths, etc.) — gets help text and layout for free. - Use `>` blockquote help text only for *non-template* sections, or to override the canonical when a domain-specific framing is needed. - Reach for `{bg}` sparingly — it draws the eye; one or two cells max. - Use `{!}` to mark a single most-important region. - Leave a region empty (just heading + optional `>` help) when the user is mid-thinking — the dashed placeholder invites filling-in. ## Causal Loop Diagrams Causal loop diagrams (CLDs) show how variables in a system reinforce or balance one another. Polarity lives in the arrow. ``` @type causal-loop — required type metadata A -+> B — A increases B (positive / same-direction) A --> B — A increases B's *opposite* (negative) A -+> B --> C — chain: two links sharing node B Name (bad) — flag an undesirable variable Name (good) — default; rarely needed explicitly {Zone Name — group related variables Member 1 Member 2 } // comment ``` Conventions: - **Spaces around the operator are required**: write `A -+> B`, not `A-+>B`. Multi-word names with internal hyphens (`Tech-debt`) stay unambiguous because of the surrounding whitespace. - **`-+>` vs `-->`**: `-+>` means "as A goes up, B goes up" (or both down). `-->` means "as A goes up, B goes *down*". Never use a bare `->` — that is a syntax error. - **Value tags** `(good)` / `(bad)` are optional after any node name. `(good)` is the implicit default — only flag `(bad)` when a variable represents something undesirable (Burnout, Bugs shipped, Tech debt). - **Bare lines** declare or retag a variable without creating a link: `Churn (bad)` on its own line just marks Churn as bad. - **Zones** are visual groupings; a zone is opened with `{Name` on its own line and closed with `}`. Members listed on their own lines (or declared via links inside the zone) become part of it. - **Loop type is derived** at layout time from the parity of negative links around a cycle and any `(bad)` tags — you don't tag loops as reinforcing/balancing yourself. Example — burnout cycle: ``` @type causal-loop @heading Burnout cycle {People Burnout (bad) Decision quality Hours worked } {Output Bugs shipped (bad) Customer complaints (bad) } Hours worked -+> Burnout --> Decision quality --> Bugs shipped -+> Customer complaints -+> Hours worked ``` Example — SaaS referral with saturation: ``` @type causal-loop Happy customers -+> Referrals -+> New signups -+> Happy customers New signups -+> Market saturation --> New signups ``` Guidelines for AI causal-loop generation: - Aim for 4–8 variables and 1–3 loops. CLDs become unreadable past ~10 variables. - Name variables as nouns or short noun phrases ("Customer complaints", not "Customers complain"). - Mark only the genuinely undesirable variables with `(bad)`. Don't tag everything. - Use chains (`A -+> B --> C`) to keep loops on one line — easier to read than three separate `A -+> B` / `B --> C` / `C -+> A` lines. - Use zones when the user describes distinct sub-systems (People vs Output, Customer vs Internal, etc.). ## Mind Map Diagrams Mind maps capture a single central idea and its branching sub-topics. Structure comes from **indentation**, not connectors. ```yuml @type mindmap — required type metadata @style sketch — optional; ink/hand-drawn suits mind maps @layout radial — optional; radial (default) or tree Mind Mapping — the single root (first flush-left line) Work — a branch (indented under the root) Structure — a leaf (indented under the branch) Plan Definition Thinking Advantages Memory Creative ``` Rules: - **Exactly one root** — the first non-blank line, flush left. A second flush-left line is an error (a mind map has one centre). - **Indentation is the hierarchy** — indent deeper for a child, dedent to return to an ancestor. Tabs or any consistent number of spaces work. - **The label is the rest of the line** — URLs, colons and punctuation are fine. Only a line starting with `//` is a comment. - **Colour nodes with trailing decorators** — `{bg:green}` fills a node (named palette colour or hex), `{!}` paints it in the theme accent. Same syntax as the other diagram types. Example: ` Risks {bg:red}` or ` Launch {!}`. - **Choose a layout with `@layout`** — `radial` (default) fans the branches around the centre on local rings, each leaf tucked in beside its parent, for the classic organic, hand-drawn look. `tree` is the balanced horizontal tree used by dedicated mind-map tools: root centred, branches split left and right, siblings stacked in tidy aligned columns — best for dense or deep maps where you want every level lined up. Mind maps ignore `@direction`. Guidelines for AI mind-map generation: - Use a mind map when the user wants to brainstorm, outline, or break one topic into sub-topics — not for processes (use activity) or relationships (use class). - Keep the root to 2–4 words. Aim for 3–6 branches, each with 2–5 children. - Two levels of depth read best; go to three only when genuinely nested. - Phrase nodes as short noun phrases, not sentences. ## Chart Diagrams Charts render numeric data as visualisations. Five types share the same syntax shape: `bar`, `column`, `line`, `pie`, and `chart` (auto-pick — the renderer picks the best fit from the data). ``` @heading — optional title @caption <subtitle> — optional caption Label: value — value can be number, tally, or percentage Label: 100 — number Label: ||||| — tally marks (count = number of bars) Label: 72% — percentage Label: value{!} — accent / highlight (modifier AFTER the value) Label: value{bg:wheat} — custom bar background tint // comment ``` Charts ignore `@direction` — bar is horizontal, column is vertical, line is left-to-right time series, pie is radial. ### Bar — horizontal bars Best for tally counts, survey responses, votes. Tally marks (`|||`) or numbers both work. Tally marks render as a count of glyphs. ``` @heading Fruit bowl census Apples: ||||| Pears: ||||||| Bananas: ||| Plums: |||||||||| ``` ### Column — vertical bars Best for category comparisons (quarters, months, products). ``` @heading Quarterly revenue Q1: 100 Q2: 120 Q3: 140{!} Q4: 160 ``` ### Line — time series Best for trends over time. Labels typically dates or sequential periods; values are numbers. ``` @heading Monthly active users 2025-01: 120 2025-02: 135 2025-03: 128 2025-04: 142 2025-05: 155 2025-06: 170 ``` ### Pie — proportions Best for parts-of-a-whole. Values can be percentages (must sum to ~100) or raw numbers (renderer normalises). ``` @heading Sprint status Done: 72% In progress: 18% Blocked: 10% ``` ### Chart — auto-picked type When the diagram type isn't specified, the renderer picks from the data shape: dated labels → line, percentages → pie, short numeric labels (Q1, Jan) → column, tally marks → bar. ``` // no @type — yUML picks bar/column/line/pie from the data shape Q1: 100 Q2: 120 Q3: 140 Q4: 160 ``` Guidelines for AI chart generation: - Pick a specific type (`bar`/`column`/`line`/`pie`) when the user's intent is clear; reach for `chart` only when ambiguous. - Tally marks suit small whole-number counts (≤ 12-ish). Use numbers for larger values. - Percentages should sum to ~100 in pies. If the user gives raw counts, leave them — the renderer handles the maths. - Use `{!}` on a single most-important bar/column to draw attention. ## Story Format Stories are markdown documents with embedded yUML diagrams. ```` @style blueprint — global style (applies to all diagrams) @direction LR — global direction # Slide Title — starts a section Prose text in **markdown**. — rendered as styled text ```yuml class — diagram block (type after "yuml") @heading Diagram Title — optional heading @caption Description — optional caption [A]->[B] ``` --- — slide separator # Next Slide ... ```` Valid fence types (the word after `yuml`): `class` · `activity` · `usecase` · `sequence` · `state` · `c4` · `journey` · `journeyflow` · `timeline` · `roadmap` · `canvas` · `causal-loop` · `mindmap` · `chart` · `bar` · `column` · `pie` · `line` Use the type's exact spelling, including the hyphen in `causal-loop`. The fence type and an in-body `@type` must agree; if both are present the in-body `@type` wins. Guidelines for AI story generation: - Start with a high-level overview, then progressively reveal detail - Each slide should have a heading, 1-2 sentences of prose, and one diagram - Use different diagram types to show different perspectives (class for structure, sequence for behaviour, journey for UX, c4 for systems) - Keep individual diagrams focused — 3-7 elements each, not comprehensive - Use `@heading` on diagrams to label what aspect they show ## Common mistakes to avoid - Missing closing `]` or `)` on the last element - Unbalanced `{ }` boundary braces - Wrong arrow for the diagram type — respect the target type's arrow set - Extra or missing pipes in `[Name|Type|Desc]` (c4) or `[Name|attrs|methods]` (class) - Quoting names that don't need quotes — the grammar is liberal about names