Initial release: diagram-design v1.0

Thirteen editorial diagram types (architecture, flowchart, sequence,
state, ER, timeline, swimlane, quadrant, nested, tree, layers, venn,
pyramid) as self-contained HTML files with inline SVG.

Progressive disclosure: lean SKILL.md points to per-type references.
Neutral stone+rust default skin, first-run gate that prompts users
to customize the style guide from their own website, URL-based
onboarding, annotation-callout primitive, sketchy filter variant,
live gallery at assets/index.html.
This commit is contained in:
Cathryn Lavery
2026-04-16 13:30:53 -05:00
commit 53bd8dde0f
75 changed files with 8186 additions and 0 deletions
+139
View File
@@ -0,0 +1,139 @@
# Onboarding — generate your skin from a website
**Goal:** point the skill at a site you like (your own, a competitor, a reference), and have it extract the palette + typography, then rewrite `style-guide.md` so every future diagram inherits that skin.
Takes about 60 seconds.
---
## The flow
```
URL you provide
↓
[1] fetch homepage (headless browser or HTTP)
↓
[2] extract dominant colors + fonts
↓
[3] map to semantic roles (paper, ink, muted, accent, …)
↓
[4] propose a style-guide.md diff
↓
[5] write the diff (with your approval)
↓
future diagrams use your tokens
```
---
## Invocation
Ask the skill:
> *"Onboard diagram-design to my site — `https://example.com`"*
Or run it with an explicit URL and the skill reads this file and executes the steps below.
---
## Step 1 — fetch the page
Use `agent-browser` (preferred) or a plain `fetch`. If the site has multiple pages worth sampling (landing + blog + product), fetch 2–3 and merge the palette signals.
```bash
agent-browser navigate https://example.com --screenshot out.png --html out.html
```
---
## Step 2 — extract colors and fonts
### Colors
Parse the rendered CSS and screenshot:
- **Background color** of `<body>` or the dominant large region → `paper`
- **Primary text color** (body text) → `ink`
- **Secondary text color** (captions, meta) → `muted`
- **Most-used brand color** (CTA button, link, heading accent) → `accent`
- **Container / card background** slightly darker than paper → `paper-2`
- **Border / hairline color** → `rule` (convert to rgba of ink at ~0.12 opacity)
Prefer CSS custom properties when the site exposes them (`:root { --accent: …; }`). Otherwise pull via rendered `getComputedStyle` samples or a color-histogram pass over the screenshot.
### Fonts
Read the rendered `font-family` stack of:
- `<h1>` → `title` family
- `<body>` → `node-name` family
- `<code>`, `<pre>`, or any mono-styled element → `sublabel` family
If the site has only one family, keep the diagram-design defaults for the missing roles (Instrument Serif for title, Geist Mono for mono). Don't force-pick a mono font that isn't on the site.
---
## Step 3 — map to semantic roles
Propose a diff by filling this table:
| Role | Detected | Confidence |
|---|---|---|
| paper | `#f8f6f0` | high |
| ink | `#111111` | high |
| muted | `#6b6b68` | medium |
| accent | `#c73a2b` | high |
| … | … | … |
Flag low-confidence guesses so the user can correct before applying.
### Constraint checks
Before writing, validate:
- **AA contrast**: `ink` on `paper` ≥ 4.5:1. `muted` on `paper` ≥ 4.5:1 for body text.
- **Accent is the most saturated color**: not muted-ish, not near-grey.
- **paper ≠ pure white**: if the site uses `#ffffff`, fall back to `#fafaf7` to preserve diagram-design's warm-neutral feel — or ask the user to confirm pure-white is intentional.
If any check fails, propose an adjusted value and explain why.
---
## Step 4 — preview the diff
Show the user what will change in `style-guide.md`. Only the tokens table — everything else stays the same.
```diff
-| `paper` | `#f5f4ed` | `#1c1a17` |
-| `ink` | `#0b0d0b` | `#f1efe7` |
-| `accent` | `#f7591f` | `#ff6a30` |
+| `paper` | `#f8f6f0` | `#1a1815` |
+| `ink` | `#111111` | `#efeee7` |
+| `accent` | `#c73a2b` | `#e05440` |
```
Also regenerate the dark variant via the inversion rule (`rgba(11,13,11, X)` → `rgba(ink-rgb, X)`).
---
## Step 5 — apply
Write the new tokens to `style-guide.md`. Suggest running the `/regenerate-examples` flow (if it exists) or rebuilding one example to verify the new skin reads cleanly.
After onboarding, the user should:
1. Open `assets/index.html` (gallery) and confirm the new palette feels coherent across all 13 types.
2. If any type looks off, they usually need to tune `muted` (often too dark or too light against the new `paper`).
---
## When onboarding fails
- **Site uses webfonts you can't replicate** (custom-hosted, paid): keep the diagram-design defaults for typography and skin only the colors.
- **Brand has 6+ colors** and you can't identify a clear hierarchy: pick one as `accent`, demote the rest to `muted` variants or ignore them. The diagram grammar only uses 5–7 roles.
- **Site is dark-mode first**: flip the inversion — treat their dark paper as the default `paper`, and generate a light variant via inversion.
- **Homepage is all imagery, no text**: ask for a blog or docs URL instead — text-heavy pages expose the type hierarchy.
---
## Future: per-project skins
If the user wants multiple skins (one per project), duplicate `style-guide.md` as `style-guides/<project>.md` and add a header comment pointing the build to the active one. That's a v1.1 feature — for now, one skin per skill install.
+36
View File
@@ -0,0 +1,36 @@
# Annotation Callout (italic-serif aside)
Use for editorial asides — the "italic pointer" that marks a detail without competing with the primary diagram grammar. Think marginalia: *"structure IS the index"*, *"no imports, no configuration"*.
## Grammar
```svg
<!-- 1. Italic Instrument Serif text -->
<text x="904" y="36" fill="#0b0d0b" font-size="14" font-style="italic"
font-family="'Instrument Serif', serif" text-anchor="end">no imports, no configuration</text>
<!-- 2. Dashed Bézier leader -->
<path d="M 820 44 Q 700 84 520 216" fill="none"
stroke="rgba(11,13,11,0.40)" stroke-width="1" stroke-dasharray="4,3"/>
<!-- 3. Landing dot -->
<circle cx="520" cy="216" r="2" fill="#0b0d0b"/>
```
## Rules
- Italic + serif together signal "editorial voice" against the diagram's sans/mono body. Don't substitute italic sans or italic mono — the combination is load-bearing.
- Dashed path (`stroke-dasharray="4,3"`) distinguishes the callout leader from primary arrows (which are solid).
- Place callouts in margins (top-right, bottom-left). Never inside the active diagram area.
- Max 2 callouts per diagram. More becomes commentary, not signal.
## Colors
| Intent | Text | Leader |
|---|---|---|
| Neutral aside | ink `#0b0d0b` | `rgba(11,13,11,0.40)` |
| Focal / accent | coral `#f7591f` | `rgba(247,89,31,0.50)` |
| Tertiary (muted) | muted `#52534e` | `rgba(11,13,11,0.30)` |
## Anti-patterns
- Solid arrow leader (reads as a flow arrow).
- Italic sans or italic mono — the serif is load-bearing.
- Callouts crossing primary arrows / lifelines — offset to a clear margin.
- Using a callout to label something the diagram should label directly — put the label on the element.
+43
View File
@@ -0,0 +1,43 @@
# Sketchy Filter (hand-drawn variant)
Optional displacement filter that wobbles every stroke and edge slightly — turns any minimal variant into a hand-drawn "editorial" register without changing layout. Use when the diagram accompanies an essay rather than technical docs.
## Grammar
```svg
<defs>
<filter id="sketchy" x="-2%" y="-2%" width="104%" height="104%">
<feTurbulence type="fractalNoise" baseFrequency="0.02" numOctaves="2" seed="4"/>
<feDisplacementMap in="SourceGraphic" scale="1.5"/>
</filter>
</defs>
<!-- Apply to a group wrapping shapes — NOT text -->
<g filter="url(#sketchy)">
<!-- rects, paths, circles, lines go here -->
</g>
<!-- Text sits OUTSIDE the filtered group — legibility stays crisp -->
<text ...>Labels go here</text>
```
## Tuning
| Parameter | Range | Effect |
|---|---|---|
| `baseFrequency` | 0.01–0.04 | Lower = lazy wavy lines; higher = jittery. 0.02 default. |
| `numOctaves` | 1–3 | More = more noise detail. 2 is plenty. |
| `scale` | 1–6 | 1 barely-there, 1.5 default, 2 visible, 4+ cartoon. |
| `seed` | integer | Swap for a different random pattern. |
## Critical rule
Filter shapes, NOT text. Displacement-mapped text becomes illegible. Structure your SVG so text is in a sibling group outside the filtered group.
## When to use
- Essay / blog post / newsletter where the diagram is the hero of a narrative page.
- "Working sketch" register — showing something is mid-thought, not final architecture.
## When not to use
- Technical documentation (precision matters).
- Diagrams with dense labels or tight alignments (filter reads as noise).
- Dark variants — wobble reads as artifact on dark backgrounds. Test first.
+104
View File
@@ -0,0 +1,104 @@
# Style Guide
**The single source of truth for colors, typography, and tokens.** Every diagram draws from this — not from hex values inlined in other reference files. If you want to change the visual skin of diagram-design, change this file.
Default skin is a neutral editorial palette — warm stone paper, deep charcoal ink, rust accent. It's designed to look good out of the box for any open-source user without matching any specific brand. Swap these values (or run [`onboarding.md`](onboarding.md)) and every new diagram inherits the new skin without touching any type-specific logic.
To generate your own from a website URL, see [`onboarding.md`](onboarding.md).
---
## Tokens
### Semantic roles
Every token is referred to by **semantic role**, not by its hex value. Type references (`type-*.md`) and SKILL.md say `accent`, not `#f7591f`.
| Role | Purpose | Default (light) | Default (dark) |
|---|---|---|---|
| `paper` | Page background, default node fill | `#faf7f2` | `#1c1917` |
| `paper-2` | Diagram container bg, secondary fill | `#f2ede4` | `#292524` |
| `ink` | Primary text, primary stroke | `#1c1917` | `#faf7f2` |
| `muted` | Secondary text, default arrow stroke | `#57534e` | `#a8a29e` |
| `soft` | Sublabels, boundary labels | `#78716c` | `#8e8680` |
| `rule` | Hairline borders | `rgba(28,25,23,0.12)` | `rgba(250,247,242,0.12)` |
| `rule-solid` | Stronger borders, baselines | `rgba(120,113,108,0.25)` | `rgba(168,162,158,0.25)` |
| `accent` | Focal / 1–2 max per diagram | `#b5523a` | `#d6724a` |
| `accent-tint` | Fill for accent-bordered boxes | `rgba(181,82,58,0.08)` | `rgba(214,114,74,0.10)` |
| `link` | HTTP/API calls, external arrows | `#2563eb` | `#60a5fa` |
> **Note:** The pre-baked example HTML files in `assets/` were built under an earlier skin. Regenerating them against the current `style-guide.md` is a v1.1 task. New diagrams the skill produces will use the tokens above.
### Inversion rule (light → dark)
Any `rgba(28,25,23, X)` in light becomes `rgba(250,247,242, X)` in dark. Same opacities, RGB flipped. The accent gets a slight hue-shift brighter to read on dark paper.
---
## Typography
| Role | Family | Size | Weight | Usage |
|---|---|---|---|---|
| `title` | Instrument Serif | 1.75rem | 400 | Page H1 |
| `node-name` | Geist (sans) | 12px | 600 | Human-readable labels |
| `sublabel` | Geist Mono | 9px | 400 | Port, protocol, URL, field type |
| `eyebrow` | Geist Mono | 7–8px | 500, tracked 0.18em, uppercase | Type tags, axis labels |
| `arrow-label` | Geist Mono | 8px | 400, tracked 0.06em | Arrow annotations |
| `callout` | Instrument Serif *italic* | 14px | 400 | Editorial asides only |
### Font stack
```html
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500;600&display=swap" rel="stylesheet">
```
**Load-bearing rule:** Mono is for *technical* content (ports, commands, URLs, field types). Names go in Geist sans. Page title is Instrument Serif. Italic Instrument Serif is reserved for annotation callouts (see [primitive-annotation.md](primitive-annotation.md)). **Never JetBrains Mono** as a blanket "dev" font.
---
## Stroke, radius, spacing
| Token | Value | Use |
|---|---|---|
| `stroke-thin` | `0.8` | Tag-box outlines, leaf nodes |
| `stroke-default` | `1` | Most strokes |
| `stroke-strong` | `1.2` | Emphasis strokes |
| `radius-sm` | `4` | Small tags |
| `radius-md` | `6` | Node boxes |
| `radius-lg` | `8` | Containers, rings |
| `grid` | `4` | Every coord, size, and gap is divisible by 4 (hard rule) |
---
## Node type → treatment
Semantic role combinations — reference these by name in type specs.
| Type | Fill | Stroke |
|---|---|---|
| `focal` (1–2 max) | `accent-tint` | `accent` |
| `backend` | `#ffffff` (white) | `ink` |
| `store` | `ink @ 0.05` | `muted` |
| `external` | `ink @ 0.03` | `ink @ 0.30` |
| `input` | `muted @ 0.10` | `soft` |
| `optional` | `ink @ 0.02` | `ink @ 0.20` dashed `4,3` |
| `security` | `accent @ 0.05` | `accent @ 0.50` dashed `4,4` |
---
## Customizing the skin
Three options:
1. **Run onboarding** — see [`onboarding.md`](onboarding.md). Drop a URL; the skill extracts the palette + fonts and rewrites this file.
2. **Edit by hand** — change the hex values in the tables above. Run the pre-output taste gate afterward to verify the accent still reads as "focal" against the new paper color.
3. **Brand handoff** — paste your existing design-token JSON into a new section here and map its tokens to the semantic roles above.
### Constraints (don't break these)
- **Contrast**: `ink` must hit WCAG AA on `paper`. `muted` must hit AA on `paper` for 11px+ text.
- **One accent**: pick one color for `accent`. Two accents erases the focal signal.
- **No rainbow palette**: if your brand ships 8 colors, pick 3 (paper, ink, accent). The rest become `muted` variants.
- **Serif + sans + mono**: three families, not more. If brand typography is all sans, keep Instrument Serif for `title` and `callout` anyway — the contrast is load-bearing.
- **Paper is warm-neutral, not pure white**: pure white turns the design sterile. Pick a cream, bone, or light grey with a hint of warmth.
- **Dot pattern survives**: the 22×22 dot pattern on the diagram background needs to sit at ~10% opacity of `ink` on `paper` — verify it's visible but quiet after a skin change.
+20
View File
@@ -0,0 +1,20 @@
# Architecture
**Best for:** system overviews, data-flow diagrams, integration maps, infra topology.
## Layout conventions
- Group components by tier or trust boundary (frontend → backend → data; public → private).
- Primary flow runs left→right or top→down. Pick one and hold it.
- Draw arrows before boxes so z-order puts connections behind components.
- 1–2 coral focal nodes: the primary integration point, the primary data store, or the key decision node.
- Dashed boundary rectangles mark regions (VPC, security group, trust zone); labels sit on a paper-colored mask over the boundary line.
## Anti-patterns
- Every box in coral ("this is important too") — hierarchy collapses.
- Bidirectional arrow when one direction is obvious from context.
- Legend floating inside the diagram area.
## Examples
- `assets/example-architecture.html` — minimal light
- `assets/example-architecture-dark.html` — minimal dark
- `assets/example-architecture-full.html` — full editorial
+23
View File
@@ -0,0 +1,23 @@
# ER / Data Model
**Best for:** database schemas, API resource relationships, domain models.
## Layout conventions
- Each entity is a two-section box:
- **Header**: type tag (`ENTITY`) + entity name in Geist.
- **Body**: field list in Geist Mono, one per line. PK prefixed with `#`, FK prefixed with `→`.
- Relationships: lines between entities with cardinality at each end:
- `1`, `N`, `0..1`, `1..*` in Geist Mono, 8px, placed 10–12px from the entity edge.
- Optional relationship label ("has", "belongs to") centered on the line.
- Group related entities close; lay out so most relationships are straight lines, not tangles.
- Coral on the aggregate root or central entity of the model.
## Anti-patterns
- Drawing an arrow for every FK on a model with dozens — lay out by cluster instead.
- Inconsistent cardinality notation between ends of the same relationship.
- Fields padded to equal-height boxes — natural height by content is fine.
## Examples
- `assets/example-er.html` — minimal light
- `assets/example-er-dark.html` — minimal dark
- `assets/example-er-full.html` — full editorial
+23
View File
@@ -0,0 +1,23 @@
# Flowchart
**Best for:** decision logic, algorithms, user-facing branching flows ("Should I…?"), onboarding routing, support-triage trees.
## Layout conventions
- Shape carries type, not color:
- **Oval** (`rx=20`) — start / end
- **Rectangle** (`rx=6`) — step / action
- **Diamond** — decision (≤3 exits)
- **Small filled ink dot** (`r=4`) — merge point where branches rejoin
- Flow runs top→down. From a diamond, conventional exits: Yes to the right, No below — but label every outgoing arrow regardless.
- Use coral on the happy path *or* on the single most consequential decision — never on every decision.
- If two arrows must cross, use a small arc jump on one so the crossing is readable.
## Anti-patterns
- Using fill color to signal node type (shape does that).
- Decision diamond with 4+ exits — refactor into nested diamonds.
- Unlabeled decision branches.
## Examples
- `assets/example-flowchart.html` — minimal light
- `assets/example-flowchart-dark.html` — minimal dark
- `assets/example-flowchart-full.html` — full editorial
+26
View File
@@ -0,0 +1,26 @@
# Layer Stack
**Best for:** OSI model, CSS cascade, context hierarchy, tech stack, abstraction layers, memory hierarchy.
## Layout conventions
- Horizontal bands stacked vertically. Each layer is a full-width rectangle (same x, same width). 4–6 layers total.
- Layer height 56–72px, width typically 800–880px inside a 1000px viewBox.
- Each row contains (left→right):
1. **Index tag** on the far left (`L3`, `07`, `APPLICATION`) — Geist Mono 8–9px eyebrow.
2. **Layer name** slightly right of center-left — Geist 14–16px 600.
3. **Sublabel / note** on the far right — Geist Mono 9–10px muted.
- Border between layers: 1px hairline `rgba(11,13,11,0.12)`. Outer silhouette 1px ink or muted.
- Fills: either alternating subtle shades (paper / paper-2) OR all paper with hairline dividers. Pick one and hold it.
- Direction indicator on the LEFT margin (outside the stack): small up/down arrow + Geist Mono label (`abstraction ↑`, `packets ↓`).
- Coral on **one** focal layer (stroke + subtle tint fill) — the bottleneck, the pay-rent layer, the one under discussion.
## Anti-patterns
- Layers that aren't actually hierarchical (use swimlane or architecture).
- Skipped numbering (missing L4 between L3 and L5 without explanation).
- Every layer a different color — hierarchy invisible.
- Inconsistent layer heights without reason.
## Examples
- `assets/example-layers.html` — minimal light
- `assets/example-layers-dark.html` — minimal dark
- `assets/example-layers-full.html` — full editorial
+22
View File
@@ -0,0 +1,22 @@
# Nested Containment
**Best for:** hierarchy through containment — scope boundaries, CLAUDE.md cascade, trust zones, folder nesting, blast radius. Outer = broader, inner = more specific.
## Layout conventions
- 3–5 rounded rectangles (`rx=8`), nested with consistent inset padding (24–32px horizontal, 32–36px vertical recommended).
- Each level labeled at the top-left in Geist Mono eyebrow style (7–8px, letter-spacing 0.14em). Labels sit on a paper-colored mask rect over the ring's top border.
- Stroke hierarchy: outer rings faint (`rgba(..,0.30–0.45)`), progressing to muted, to ink, to coral at the innermost focal.
- Fills step up in opacity from outer to inner: `rgba(..,0.015)` → `rgba(..,0.025)` → accent-tint on the innermost.
- Optional file-icon glyph (folded-corner rect) inside each level hints at scope content.
- Italic Instrument Serif callouts (see `references/primitive-annotation.md`) — 1–2 max.
## Anti-patterns
- More than 6 levels (information disappears inward).
- Irregular padding between levels — unaligned nesting looks accidental.
- Content inside rings that isn't part of the hierarchy — use a sibling diagram.
- Coral on multiple levels — hierarchy collapses.
## Examples
- `assets/example-nested.html` — minimal light
- `assets/example-nested-dark.html` — minimal dark
- `assets/example-nested-full.html` — full editorial
+33
View File
@@ -0,0 +1,33 @@
# Pyramid / Funnel
**Best for:** hierarchy of needs, prioritization ranks, value pyramids, conversion funnels, content importance stacks.
## Two orientations — pick one
- **Pyramid** (point up) — narrow apex = most important / rarest / most valuable. Base is broadest / foundational.
- **Funnel** (point down) — narrow end = conversion (smallest group). Top is widest / audience.
Don't mix orientations on one diagram.
## Layout conventions
- 4–6 layers. Each layer is a trapezoid built from an SVG `<polygon>` with 4 points.
- Consistent layer height (56–72px).
- Widths decrease linearly from base to apex (pyramid) or top to bottom (funnel). When showing real funnel data, widths must be honest (proportional to count/percentage).
- Each layer has:
- **Name label** centered inside the trapezoid — Geist 12–14px 600.
- **Sublabel** below or beside the name — Geist Mono 9–10px.
- **Side annotation** (right or left) — optional. For funnels: drop-off percentage here (`−40%`).
- Fill: subtle graded tints OR all paper-2 with hairline dividers (cleaner). Pick one.
- Stroke: 1px hairline between layers; outer silhouette 1px muted or ink.
- **Coral on ONE layer only**: apex of pyramid, conversion layer of funnel, or critical bottleneck.
- Optional left-margin axis arrow + Geist Mono label (`rarer ↑`, `drop-off ↓`).
## Anti-patterns
- 7+ layers (illegible — compress or split).
- Pyramid for non-hierarchical data (use a tree or bar chart).
- Dishonest widths (fake equal spacing when drops are unequal).
- Coral on the base layer (dilutes the "apex = rare" signal).
## Examples
- `assets/example-pyramid.html` — minimal light
- `assets/example-pyramid-dark.html` — minimal dark
- `assets/example-pyramid-full.html` — full editorial
+20
View File
@@ -0,0 +1,20 @@
# Quadrant
**Best for:** prioritization (Impact × Effort), positioning (Reach × Frequency), portfolio maps, 2×2 decision frames.
## Layout conventions
- 2×2 grid. Axis lines: 1px ink cross through the center.
- Axis labels at the *ends* of each axis (e.g., `HIGH IMPACT →` on the right, `LOW IMPACT ←` on the left — Geist Mono eyebrow). Never label at the midpoint.
- Items: small labeled dots (`r=4`) positioned in the quadrants. Labels 8–10px away; don't let labels cross axis lines.
- Coral on the "do first" item (typically top-right).
- Limit to ~12 items; cluster or split beyond that.
## Anti-patterns
- Four filled quadrants in different colors — position + label does the work; color noise weakens it.
- Items placed on axis lines (ambiguous quadrant).
- Missing axis names.
## Examples
- `assets/example-quadrant.html` — minimal light
- `assets/example-quadrant-dark.html` — minimal dark
- `assets/example-quadrant-full.html` — full editorial
+35
View File
@@ -0,0 +1,35 @@
# Sequence
**Best for:** request/response flows, protocol exchanges, multi-actor interactions over time, API call traces, incident reconstructions.
## Layout conventions
- Actors as boxes in a horizontal row at the top.
- **Lifelines**: dashed vertical lines descending from each actor to the bottom.
- Messages: horizontal arrows between lifelines; time flows top→down.
- **Activation bar**: narrow rectangle (`w=8`, muted fill, 0.8 hairline stroke) on a lifeline spanning the interval that actor holds control. Stack for nested calls.
- Self-messages: short U-shaped loop returning to the same lifeline; label right of the loop.
- Return messages: dashed line in the same color as the originating call.
- Coral on the primary success response or headline message — one, maybe two.
## Anti-patterns
- Message arrow pointing *upward* (reverses time — never).
- Activation bars that never close.
- Labels sitting over another lifeline — shorten or shift y into a gap.
- Swimlane-style lanes instead of lifelines (different grammar).
## Lifeline primitive
```svg
<line x1="CX" y1="TOP" x2="CX" y2="BOTTOM"
stroke="rgba(11,13,11,0.20)" stroke-width="1" stroke-dasharray="3,3"/>
```
## Activation bar primitive
```svg
<rect x="CX-4" y="TOP" width="8" height="H"
fill="rgba(11,13,11,0.06)" stroke="#52534e" stroke-width="0.8"/>
```
## Examples
- `assets/example-sequence.html` — minimal light
- `assets/example-sequence-dark.html` — minimal dark
- `assets/example-sequence-full.html` — full editorial
+21
View File
@@ -0,0 +1,21 @@
# State Machine
**Best for:** finite state logic — order status, auth state, connection lifecycle, form wizard, job queue status.
## Layout conventions
- States are rounded rectangles (`rx=8`), labeled in Geist.
- **Start**: filled ink dot (`r=6`). **End**: ringed dot (outer `r=8` outline, inner filled `r=5`).
- Transitions: curved arrows labeled in Geist Mono as `event [guard] / action` (omit sections you don't need).
- Self-loops curve above the state.
- Orient along the dominant flow direction (left→right or top→down); rearrange before crossing transitions.
- Coral on the state the reader should notice — typically the error state, or "happy completion".
## Anti-patterns
- More transitions than states × 2 → likely two state machines.
- "From any state" transitions drawn from every state — use a single annotation (`* → Error on timeout`) instead.
- Unlabeled transitions (the whole point is *what triggers this*).
## Examples
- `assets/example-state.html` — minimal light
- `assets/example-state-dark.html` — minimal dark
- `assets/example-state-full.html` — full editorial
+20
View File
@@ -0,0 +1,20 @@
# Swimlane
**Best for:** cross-functional processes, RACI-style flows, vendor handoffs, multi-team shipping workflows.
## Layout conventions
- Horizontal lanes (or vertical columns) — one per actor/team. Label each lane in the left margin (or top) with a Geist Mono eyebrow.
- Lane dividers: 1px hairlines.
- Process steps are rectangles placed inside the lane of the actor performing them; arrows show flow.
- Handoffs (arrows crossing lane boundaries) are the most important edges — consider coral on the handoff that introduces the most coupling or latency.
- Don't force equal step count per lane; a lane with one step is fine.
## Anti-patterns
- Lanes without labels.
- A step drawn across two lanes (pick one owner).
- Arrows that snake back and forth — reorder steps so the flow is mostly straight.
## Examples
- `assets/example-swimlane.html` — minimal light
- `assets/example-swimlane-dark.html` — minimal dark
- `assets/example-swimlane-full.html` — full editorial
+20
View File
@@ -0,0 +1,20 @@
# Timeline
**Best for:** release history, project milestones, incident timelines, roadmaps, changelog visualizations.
## Layout conventions
- Horizontal hairline baseline across the middle (`stroke-width=1`).
- Tick marks at time boundaries (quarters, months, sprints) with date labels below in Geist Mono.
- Events: small filled circles (`r=4`) on the baseline. Labels alternate above and below to prevent collision, connected to the circle with a 1px hairline drop.
- Major milestones: coral circle (`r=6`) + bold Geist label.
- Time scale must be honest: if intervals are non-equal, space the circles non-equally. Don't fake linear spacing for aesthetics. Break the axis visibly if a region is too dense.
## Anti-patterns
- Equal-spacing events that aren't equally spaced in time.
- Missing axis labels ("what unit is this?").
- Crowded labels without vertical offset — illegible.
## Examples
- `assets/example-timeline.html` — minimal light
- `assets/example-timeline-dark.html` — minimal dark
- `assets/example-timeline-full.html` — full editorial
+24
View File
@@ -0,0 +1,24 @@
# Tree / Hierarchy
**Best for:** org charts, dependency trees, taxonomy, file trees, decision breakdowns, skill trees.
## Layout conventions
- Root at top, children fan out below (or root at left, children to right).
- Nodes are small labeled rectangles (`rx=6`), Geist 12px 600 name + optional Geist Mono 9px sublabel. Width 120–180px, height 40–52px.
- **Connectors are orthogonal (elbow-style), never diagonal.** Parent drops a short vertical line, then a horizontal bus connects siblings, then each child has a short vertical drop into its top edge. 1px muted stroke.
- Leaf indicator: thinner stroke (0.8) or different fill — OR let terminal position do the work.
- Max depth: 4 (root + 3 tiers). Max breadth per level: 5.
- Coral on **one** node: root OR critical leaf. Not both.
- Draw connectors before nodes.
## Anti-patterns
- Tree 5+ levels deep on a single page (illegible — split).
- Nodes of wildly varying widths — pick 2 widths max.
- Diagonal connector lines.
- Skipped levels (parent connected to grandchild with no middle).
- Coral on root AND a leaf.
## Examples
- `assets/example-tree.html` — minimal light
- `assets/example-tree-dark.html` — minimal dark
- `assets/example-tree-full.html` — full editorial
+26
View File
@@ -0,0 +1,26 @@
# Venn / Set Overlap
**Best for:** intersection of concepts/domains, shared attributes between categories, "where A meets B", ikigai-style frames (desirable × feasible × viable).
## Layout conventions
- **Prefer 2 or 3 circles.** Avoid 4+ (unreadable — use a matrix instead).
- Circle stroke: 1px hairline, color per-set (ink, muted, soft).
- Circle fill: very low-opacity tint — `rgba(11,13,11,0.04)` for ink set, `rgba(82,83,78,0.05)` for muted. Tints compound naturally in overlap regions.
- Radii: equal when sets are comparable in size; proportional when sets are meaningfully different. Don't fake equal sizes for aesthetics.
- **Set labels** placed outside the circle, NEVER crossing the stroke. Geist 12–14px 600 for the set name, optional Geist Mono 9px sublabel.
- **Intersection labels** placed inside the overlap region, Geist 12px 600, centered. For small overlaps, use a leader line to a label in clear space.
- **Coral accent** on the ONE focal intersection — the "sweet spot". Either coral label stroke OR clipPath-bounded coral fill tint (`rgba(247,89,31,0.10)`).
- Circle centers and radii divisible by 4.
## Anti-patterns
- Unlabeled regions — reader can't tell which set is which.
- Circles that don't overlap when overlap is the point.
- Equal-sized circles when sets are obviously different (dishonest).
- Coral on multiple overlap regions (focal signal dies).
- Labels sitting on top of circle strokes (illegible).
- 4+ circles where 2–3 would do.
## Examples
- `assets/example-venn.html` — minimal light
- `assets/example-venn-dark.html` — minimal dark
- `assets/example-venn-full.html` — full editorial