Claude
Skills
Sign in
Back

diagram-design-editorial

Included with Lifetime
$97 forever

Generate editorial-quality HTML+SVG diagrams (13 types) for blog posts and documentation using Claude Code, with brand-matched styling and no external dependencies.

Ads & Marketing

What this skill does


# Diagram Design — Editorial HTML+SVG Diagrams

> Skill by [ara.so](https://ara.so) — Daily 2026 Skills collection.

Editorial-quality diagrams for blog posts and documentation. 13 types, self-contained HTML+SVG, no build step, no Mermaid, no shadows. Brand-matched in 60 seconds by reading your website.

---

## Installation

```bash
git clone [email protected]:cathrynlavery/diagram-design.git ~/.claude/skills/diagram-design
# restart Claude Code — skill registers as `diagram-design`
```

Or symlink from another location:

```bash
git clone [email protected]:cathrynlavery/diagram-design.git ~/code/diagram-design
ln -s ~/code/diagram-design ~/.claude/skills/diagram-design
```

Browse all 13 types locally:

```bash
open ~/.claude/skills/diagram-design/assets/index.html
```

---

## The 13 Diagram Types

| Type | Use when… |
|---|---|
| **Architecture** | Components + connections (services, APIs, infra) |
| **Flowchart** | Decision logic, yes/no branches |
| **Sequence** | Messages over time (OAuth, API calls, user flows) |
| **State machine** | States + transitions (order lifecycle, auth states) |
| **ER / data model** | Entities + fields + relationships |
| **Timeline** | Events on a horizontal or vertical axis |
| **Swimlane** | Cross-functional flows (who does what, when) |
| **Quadrant** | Two-axis positioning (impact vs effort, risk vs value) |
| **Nested** | Hierarchy by containment (layers inside layers) |
| **Tree** | Parent → children (org chart, file tree, decision tree) |
| **Layer stack** | Stacked abstractions (OSI model, tech stack) |
| **Venn** | Set overlap (2–3 circles) |
| **Pyramid / funnel** | Ranked hierarchy or conversion drop-off |

**Selection rule:** ask "would a reader learn more from this than from a well-written paragraph?" If no, don't draw. Default to deletion over addition.

---

## Quickstart

```
# In Claude Code — just describe what you need:
"Make me an architecture diagram: frontend, backend, Postgres, Redis cache."
"I need a quadrant of Q2 projects by impact vs effort."
"Give me a sequence diagram of the OAuth 2.0 handshake."
"Draw a state machine for an e-commerce order: pending → paid → shipped → delivered."
"Timeline of the Roman Empire's key turning points."
```

Claude picks the right type, builds HTML, saves the file. To use a template directly:

```bash
cp assets/template.html my-diagram.html        # minimal light
cp assets/template-full.html my-diagram.html   # editorial with summary cards
```

---

## Brand Onboarding (60 seconds)

Without onboarding, diagrams render in neutral stone + rust (warm off-white paper, charcoal ink, rust-orange accent). Run onboarding to match your site:

```
"onboard diagram-design to https://yoursite.com"
```

Claude will:
1. Fetch your homepage
2. Extract dominant palette + font stack
3. Map values to semantic roles: `paper`, `ink`, `muted`, `accent`, `link`
4. Run WCAG AA contrast checks (auto-adjusts failures)
5. Show a proposed diff → write tokens to `references/style-guide.md`

### What gets extracted

| Detected from your site | Becomes |
|---|---|
| `<body>` background | `paper` token |
| Primary text color | `ink` token |
| Secondary / caption text | `muted` token |
| Cards or containers | `paper-2` token |
| Most-used brand color (CTA, link, heading) | `accent` token |
| `<h1>` font family | `title` font |
| `<body>` font family | `node-name` font |
| `<code>` / `<pre>` font | `sublabel` font |

### Manual token override

Edit `references/style-guide.md` directly:

```markdown
| Token      | Value     | Role                          |
|------------|-----------|-------------------------------|
| paper      | #F8F5F0   | diagram background            |
| ink        | #1A1A1A   | primary text, borders         |
| muted      | #6B6560   | secondary labels, grid lines  |
| paper-2    | #EEEAE4   | card fills, lane backgrounds  |
| accent     | #B5523A   | focal nodes, 1–2 per diagram  |
| accent-fg  | #FFFFFF   | text on accent-colored nodes  |
```

**First-run gate:** on first use in a new project, if `style-guide.md` is still at default, Claude pauses and asks: *"Run onboarding, paste tokens manually, or proceed with default?"*

---

## Design System Rules

Every diagram generated by this skill follows these non-negotiable constraints:

### Grid
- All coordinates, widths, gaps divisible by **4px** — prevents the AI-generated jitter
- No shadows anywhere
- Max border-radius: **10px**
- Borders: **1px hairline** only

### Typography (three families, three roles)
```
Instrument Serif  → titles, italic editorial callouts
Geist Sans        → node names, labels (primary UI text)
Geist Mono        → technical sublabels (ports, URLs, field types, IDs)
```
Mono is for technical content specifically — not a blanket "dev aesthetic."

### Color discipline
- **One accent color** per diagram
- Accent reserved for **1–2 focal nodes** — the things the reader looks at first
- Everything else: `ink`, `muted`, `paper-2`
- Target visual density: **4/10** — ruthlessly sparse

### Focal nodes (coral tint)
```html
<!-- Accent node — use sparingly, 1–2 per diagram -->
<rect width="160" height="48" rx="6" fill="var(--accent)"/>
<text fill="var(--accent-fg)" font-family="Geist, sans-serif" font-size="13">
  Primary Component
</text>

<!-- Standard node -->
<rect width="160" height="48" rx="6" fill="var(--paper-2)" stroke="var(--ink)" stroke-width="1"/>
<text fill="var(--ink)" font-family="Geist, sans-serif" font-size="13">
  Secondary Component
</text>
```

---

## Code Examples

### Architecture Diagram (minimal structure)

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <style>
    :root {
      --paper:    #F8F5F0;
      --ink:      #1A1A1A;
      --muted:    #6B6560;
      --paper-2:  #EEEAE4;
      --accent:   #B5523A;
      --accent-fg:#FFFFFF;
    }
    body { background: var(--paper); margin: 0; padding: 40px; }
    svg  { display: block; }
  </style>
</head>
<body>
<svg width="640" height="400" viewBox="0 0 640 400"
     xmlns="http://www.w3.org/2000/svg"
     font-family="Geist, system-ui, sans-serif">

  <!-- Background -->
  <rect width="640" height="400" fill="var(--paper)"/>

  <!-- Title -->
  <text x="32" y="40" font-size="15" font-weight="600" fill="var(--ink)">
    Application Architecture
  </text>

  <!-- Focal node: API Gateway (accent) -->
  <rect x="240" y="80" width="160" height="48" rx="6" fill="var(--accent)"/>
  <text x="320" y="100" text-anchor="middle" font-size="12"
        font-weight="600" fill="var(--accent-fg)">API Gateway</text>
  <text x="320" y="116" text-anchor="middle" font-size="10"
        fill="var(--accent-fg)" opacity="0.8">:443</text>

  <!-- Standard node: Frontend -->
  <rect x="60" y="196" width="160" height="48" rx="6"
        fill="var(--paper-2)" stroke="var(--ink)" stroke-width="1"/>
  <text x="140" y="216" text-anchor="middle" font-size="12"
        font-weight="600" fill="var(--ink)">Frontend</text>
  <text x="140" y="232" text-anchor="middle" font-size="10"
        font-family="'Geist Mono', monospace" fill="var(--muted)">Next.js</text>

  <!-- Standard node: Auth Service -->
  <rect x="420" y="196" width="160" height="48" rx="6"
        fill="var(--paper-2)" stroke="var(--ink)" stroke-width="1"/>
  <text x="500" y="216" text-anchor="middle" font-size="12"
        font-weight="600" fill="var(--ink)">Auth Service</text>
  <text x="500" y="232" text-anchor="middle" font-size="10"
        font-family="'Geist Mono', monospace" fill="var(--muted)">JWT / OAuth</text>

  <!-- Standard node: Database -->
  <rect x="240" y="312" width="160" height="48" rx="6"
        fill="var(--paper-2)" stroke="var(--ink)" stroke-width="1"/>
  <text x="320" y="332" text-anchor="middle" font-size="12"
        font-weight="600" fill="var(--ink)">Postgres</text>
  <text x="320" y="348" text-anchor="middle" font-size="10"
        font-family="'Geist Mono', monospace" fill="var(--muted)">:5432</text>

  <!-- Connections — 1px hairline, muted -->
 

Related in Ads & Marketing