# How Diagram Design Separates Semantic Patterns from Visual Types

> Learn how Diagram Design separates semantic patterns from visual types. Discover a workflow that prioritizes function over form for clearer system understanding.

- Repository: [Cathryn Lavery/diagram-design](https://github.com/cathrynlavery/diagram-design)
- Tags: deep-dive
- Published: 2026-08-23

---

**TLDR:** Diagram Design separates semantic patterns (what a system does) from visual types (how it's laid out) by requiring semantic selection first in the SKILL.md workflow, mapping patterns to visual types through a routing table, and building a semantic model during import that discards all visual decoration.

The [cathrynlavery/diagram-design](https://github.com/cathrynlavery/diagram-design) repository implements a two-layer architecture for creating technical diagrams. Its core innovation is that **semantic patterns** encode the meaning of a system — behavior, state, enforcement, or risk — while **visual types** provide pure layout grammar for SVG rendering. This separation ensures that a diagram's semantics remain independent from its appearance, making diagrams both machine-validatable and visually consistent. In this article, we'll trace exactly how this separation is enforced across the repository's master skill file, reference guides, and Python validation script.

## The Two-Layer Architecture: Semantic Patterns vs. Visual Types

The repository's architecture rests on a clean distinction between what a diagram means (**semantic patterns**) and how that meaning gets drawn (**visual types**). Both layers are fully documented in the `references/` directory of the skill.

### What Are Semantic Patterns?

**Semantic patterns** are defined in [[`references/semantic-patterns.md`](https://github.com/cathrynlavery/diagram-design/blob/main/references/semantic-patterns.md)](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/semantic-patterns.md). Each pattern defines the behavior, state, enforcement, or risk that the diagram must convey. Examples include:

- **Stage framework with semantic slots** — for showing sequential process stages with typed placeholders
- **Secure paved road** — for illustrating a path where certain nodes enforce security constraints
- **Monitored loop** — for depicting feedback cycles with runtime validation

Each pattern entry includes a routing action that points to its **nearest visual type** (the layout grammar that will render the pattern). The routing table is a central mechanism: it ensures that for every semantic concept you want to express, there's a concrete structural template to express it.

### What Are Visual Types?

**Visual types** are the 27 static layout grammars defined in the various `type-*.md` files. Examples include:

- [[`type-process.md`](https://github.com/cathrynlavery/diagram-design/blob/main/type-process.md)](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/type-process.md) — for sequential step-by-step flows
- [[`type-data-flow.md`](https://github.com/cathrynlavery/diagram-design/blob/main/type-data-flow.md)](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/type-data-flow.md) — for pipelines showing how data moves between stages

The visual types dictate the SVG node shapes, connector syntax, spacing rules, and size limits for the diagram. Significantly, a visual type carries **no intrinsic meaning** — a "square" is just a shape until the semantic model assigns it a semantic role. The meaning comes entirely from the semantic pattern that selected the visual type.

## How the Separation Is Enforced: The Orchestration Workflow

The separation is not just a design concept — the repository enforces it through coded workflow steps and automated validation.

### Selection Order Enforced by SKILL.md

The master skill file [[`SKILL.md`](https://github.com/cathrynlavery/diagram-design/blob/main/SKILL.md)](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/SKILL.md) enforces the correct sequence in section 3:

```markdown

## 3. Selection: semantic pattern, then visual type

When behavior, state, enforcement, or risk carries the meaning, first load
`references/semantic-patterns.md` and choose one primary pattern.
Then choose the nearest visual type for layout.

```

This is the load-bearing rule of the entire project: **semantic first, visual second**. The user (or AI agent executing this skill) must pick a semantic pattern before selecting a visual type, so diagrams that are just visuals without meaning can never be generated.

### Validating the Routing with verify-semantic-motion.py

The script [[`scripts/verify-semantic-motion.py`](https://github.com/cathrynlavery/diagram-design/blob/main/scripts/verify-semantic-motion.py)](https://github.com/cathrynlavery/diagram-design/blob/main/scripts/verify-semantic-motion.py) programmatically checks that [`SKILL.md`](https://github.com/cathrynlavery/diagram-design/blob/main/SKILL.md) respects this ordering. It asserts:

```python
if "Selection: semantic pattern, then visual type" not in skill:
    errors.append("SKILL.md must choose semantic pattern before visual type")
router_position = skill.find("semantic-patterns.md")
if router_position == -1:
    errors.append("SKILL.md must link to semantic-patterns.md")

# ensure the router appears before the visual‑type guide

if router_position > skill.find("type-"):
    errors.append("semantic-pattern router must precede the visual‑type guide")

```

This script runs as a check in the repository's QCS, guaranteeing that edits to the skill doc don't break the core separation invariant.

### Building the Semantic Model on Import

When a diagram is imported from Mermaid or Draw.io, the pipeline builds the **semantic model** first. As stated in [[`import-mermaid.md`](https://github.com/cathrynlavery/diagram-design/blob/main/import-mermaid.md)](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/import-mermaid.md), a Mermaid cylinder shape becomes a semantic "Store/State" node, and a rhombus stays a decision only in a flowchart context. The imported diagram's visual syntax is translated into semantic terms:

```markdown

## Step 4 — Build the semantic model

- Use semantic treatments from the chosen type.
- A Mermaid cylinder becomes Store/State; a rhombus stays a decision only in a flowchart.

```

Similarly, [[`import-drawio.md`](https://github.com/cathrynlavery/diagram-design/blob/main/import-drawio.md)](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/import-drawio.md) explicitly **discards source colors** and maps them to semantic roles:

```markdown

## Step 4 — Build the semantic model

- **Discard source colors.** Map them to semantic roles instead:
  e.g., a red fill becomes the semantic role `accent` (security concern).

```

### Semantic Roles in the Style Guide

The semantic roles referenced above — "paper", "ink", "accent" — are defined in [[`style-guide.md`](https://github.com/cathrynlavery/diagram-design/blob/main/style-guide.md)](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/style-guide.md). Instead of hardcoded colors or formatting, diagrams are built using semantic roles that can be swapped out based on context (dark mode, brand style, etc.). The visual type only knows about structural layout; the semantic role provides the meaning.

### Output and Animation: Semantics Stay Independent

The final HTML/SVG output contains **semantic markup**: labels, `data-step` attributes, and ARIA labels that are independent of the visual type. When motion is requested, the [[`animation.md`](https://github.com/cathrynlavery/diagram-design/blob/main/animation.md)](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/animation.md) contract states that the motion animates the **semantic steps** — it never changes the underlying semantic model. This allows a diagram to be replayed, restyled, or re-rendered without altering its meaning.

## Key Files at a Glance

| Purpose | File | Link |
|---|---|---|
| Master skill definition & orchestration workflow | [`SKILL.md`](https://github.com/cathrynlavery/diagram-design/blob/main/SKILL.md) | [View](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/SKILL.md) |
| List of semantic patterns & routing table | [`semantic-patterns.md`](https://github.com/cathrynlavery/diagram-design/blob/main/semantic-patterns.md) | [View](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/semantic-patterns.md) |
| Visual-type specification (Process) | [`type-process.md`](https://github.com/cathrynlavery/diagram-design/blob/main/type-process.md) | [View](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/type-process.md) |
| Validation of semantic-pattern routing | [`verify-semantic-motion.py`](https://github.com/cathrynlavery/diagram-design/blob/main/verify-semantic-motion.py) | [View](https://github.com/cathrynlavery/diagram-design/blob/main/scripts/verify-semantic-motion.py) |
| Mermaid import pipeline (semantic IR) | [`import-mermaid.md`](https://github.com/cathrynlavery/diagram-design/blob/main/import-mermaid.md) | [View](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/import-mermaid.md) |
| Draw.io import pipeline (semantic IR) | [`import-drawio.md`](https://github.com/cathrynlavery/diagram-design/blob/main/import-drawio.md) | [View](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/import-drawio.md) |
| Semantic role definitions | [`style-guide.md`](https://github.com/cathrynlavery/diagram-design/blob/main/style-guide.md) | [View](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/style-guide.md) |
| Animation contract for semantic steps | [`animation.md`](https://github.com/cathrynlavery/diagram-design/blob/main/animation.md) | [View](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/animation.md) |

## Summary

- **Semantic patterns** encode meaning (behavior, state, enforcement, risk) and are listed in [`semantic-patterns.md`](https://github.com/cathrynlavery/diagram-design/blob/main/semantic-patterns.md) with a routing table to layout.
- **Visual types** provide 27 static SVG layout grammars with no intrinsic semantics — meaning only gets assigned via a semantic model.
- **[`SKILL.md`](https://github.com/cathrynlavery/diagram-design/blob/main/SKILL.md)** enforces the workflow "semantic pattern first, then visual type," and **[`verify-semantic-motion.py`](https://github.com/cathrynlavery/diagram-design/blob/main/verify-semantic-motion.py)** validates this ordering programmatically.
- **Import pipelines** ([`import-mermaid.md`](https://github.com/cathrynlavery/diagram-design/blob/main/import-mermaid.md), [`import-drawio.md`](https://github.com/cathrynlavery/diagram-design/blob/main/import-drawio.md)) discard colors and icons, replacing them with semantic roles like "accent" for security nodes.
- **Final output** contains semantic markup (labels, ARIA, data-step) that is independent of the chosen visual type, enabling re-theming and animated replay without changing the diagram's meaning.

## Frequently Asked Questions

### Why does diagram-design separate semantics and visuals?

The separation enables three things: diagrams are validated against the semantic model (see [`verify-semantic-motion.py`](https://github.com/cathrynlavery/diagram-design/blob/main/verify-semantic-motion.py)), styles can be swapped without editing the content, and animations/replays highlight semantic steps rather than changing the meaning. In other words, the meaning stays stable while the presentation is flexible.

### Which layer defines the shape of nodes?

The **visual type** defines node shapes, connectors, and spacing constraints. The **semantic pattern** decides which visual type to use and labels the nodes with meaning. As the repository's docs state, a "visual type carries no intrinsic meaning" — a square only becomes a state once the semantic model says it is one.

### What happens to source colors during import?

Source colors are **discarded** during import. Instead, the semantic model maps fill colors to semantic roles from [`style-guide.md`](https://github.com/cathrynlavery/diagram-design/blob/main/style-guide.md) (e.g., red becomes a security `accent` role). This lets colors be re-themed later without altering the semantic content.

### Which script enforces the separation invariant?

The script at [`scripts/verify-semantic-motion.py`](https://github.com/cathrynlavery/diagram-design/blob/main/scripts/verify-semantic-motion.py) checks that [`SKILL.md`](https://github.com/cathrynlavery/diagram-design/blob/main/SKILL.md) selects a semantic pattern **before** the visual-type guide, that the semantic-pattern file is linked, and that the router appears before any `type-*` guide. If any of these conditions fail, the script reports errors, acting as a continuous integration guard.