diagram-design-editorial
Generate editorial-quality HTML+SVG diagrams (13 types) for blog posts and documentation using Claude Code, with brand-matched styling and no external dependencies.
How do I install this agent skill?
npx skills add https://github.com/reason-machines/trending-skills --skill diagram-design-editorialIs this agent skill safe to install?
- Gen Agent Trust Hubpass
The skill is generally safe but contains an indirect prompt injection surface through its brand onboarding feature, which fetches and processes untrusted content from external websites.
- Socketpass
No alerts
- Snykwarn
Risk: MEDIUM · 1 issue
What does this agent skill do?
Diagram Design — Editorial HTML+SVG Diagrams
Skill by 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
git clone git@github.com:cathrynlavery/diagram-design.git ~/.claude/skills/diagram-design
# restart Claude Code — skill registers as `diagram-design`
Or symlink from another location:
git clone git@github.com:cathrynlavery/diagram-design.git ~/code/diagram-design
ln -s ~/code/diagram-design ~/.claude/skills/diagram-design
Browse all 13 types locally:
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:
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:
- Fetch your homepage
- Extract dominant palette + font stack
- Map values to semantic roles:
paper,ink,muted,accent,link - Run WCAG AA contrast checks (auto-adjusts failures)
- 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:
| 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)
<!-- 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)
<!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 -->
<line x1="320" y1="128" x2="140" y2="196"
stroke="var(--muted)" stroke-width="1"/>
<line x1="320" y1="128" x2="500" y2="196"
stroke="var(--muted)" stroke-width="1"/>
<line x1="320" y1="128" x2="320" y2="312"
stroke="var(--muted)" stroke-width="1" stroke-dasharray="4 3"/>
<!-- Arrow markers -->
<defs>
<marker id="arrow" markerWidth="6" markerHeight="6"
refX="5" refY="3" orient="auto">
<path d="M0,0 L6,3 L0,6 Z" fill="var(--muted)"/>
</marker>
</defs>
</svg>
</body>
</html>
Quadrant Diagram
<svg width="520" height="520" viewBox="0 0 520 520"
xmlns="http://www.w3.org/2000/svg"
font-family="Geist, system-ui, sans-serif">
<rect width="520" height="520" fill="var(--paper)"/>
<!-- Axes -->
<line x1="64" y1="456" x2="456" y2="456"
stroke="var(--ink)" stroke-width="1"/> <!-- x-axis -->
<line x1="64" y1="64" x2="64" y2="456"
stroke="var(--ink)" stroke-width="1"/> <!-- y-axis -->
<!-- Quadrant dividers -->
<line x1="260" y1="64" x2="260" y2="456"
stroke="var(--muted)" stroke-width="1" stroke-dasharray="4 3"/>
<line x1="64" y1="260" x2="456" y2="260"
stroke="var(--muted)" stroke-width="1" stroke-dasharray="4 3"/>
<!-- Axis labels -->
<text x="260" y="488" text-anchor="middle" font-size="11"
fill="var(--muted)">← Low Effort · High Effort →</text>
<text x="20" y="260" text-anchor="middle" font-size="11"
fill="var(--muted)" transform="rotate(-90, 20, 260)">
← Low Impact · High Impact →
</text>
<!-- Quadrant labels -->
<text x="162" y="88" text-anchor="middle" font-size="10"
font-weight="600" fill="var(--muted)" letter-spacing="0.05em">QUICK WINS</text>
<text x="358" y="88" text-anchor="middle" font-size="10"
font-weight="600" fill="var(--muted)" letter-spacing="0.05em">MAJOR PROJECTS</text>
<text x="162" y="448" text-anchor="middle" font-size="10"
font-weight="600" fill="var(--muted)" letter-spacing="0.05em">FILL-INS</text>
<text x="358" y="448" text-anchor="middle" font-size="10"
font-weight="600" fill="var(--muted)" letter-spacing="0.05em">THANKLESS TASKS</text>
<!-- Focal item (accent) -->
<circle cx="148" cy="148" r="28" fill="var(--accent)" opacity="0.9"/>
<text x="148" y="144" text-anchor="middle" font-size="10"
font-weight="600" fill="var(--accent-fg)">Auth</text>
<text x="148" y="158" text-anchor="middle" font-size="9"
fill="var(--accent-fg)" opacity="0.85">redesign</text>
<!-- Standard items -->
<circle cx="200" cy="200" r="22" fill="var(--paper-2)"
stroke="var(--ink)" stroke-width="1"/>
<text x="200" y="196" text-anchor="middle" font-size="9"
fill="var(--ink)">Dark</text>
<text x="200" y="208" text-anchor="middle" font-size="9"
fill="var(--ink)">mode</text>
<circle cx="340" cy="160" r="26" fill="var(--paper-2)"
stroke="var(--ink)" stroke-width="1"/>
<text x="340" y="156" text-anchor="middle" font-size="9"
fill="var(--ink)">API v2</text>
<text x="340" y="168" text-anchor="middle" font-size="9"
fill="var(--ink)">migration</text>
</svg>
Sequence Diagram
<svg width="600" height="360" viewBox="0 0 600 360"
xmlns="http://www.w3.org/2000/svg"
font-family="Geist, system-ui, sans-serif">
<rect width="600" height="360" fill="var(--paper)"/>
<!-- Actor boxes -->
<rect x="40" y="40" width="100" height="36" rx="6"
fill="var(--accent)"/>
<text x="90" y="63" text-anchor="middle" font-size="12"
font-weight="600" fill="var(--accent-fg)">Browser</text>
<rect x="248" y="40" width="100" height="36" rx="6"
fill="var(--paper-2)" stroke="var(--ink)" stroke-width="1"/>
<text x="298" y="63" text-anchor="middle" font-size="12"
font-weight="600" fill="var(--ink)">Auth Server</text>
<rect x="456" y="40" width="100" height="36" rx="6"
fill="var(--paper-2)" stroke="var(--ink)" stroke-width="1"/>
<text x="506" y="63" text-anchor="middle" font-size="12"
font-weight="600" fill="var(--ink)">API</text>
<!-- Lifelines -->
<line x1="90" y1="76" x2="90" y2="340"
stroke="var(--muted)" stroke-width="1" stroke-dasharray="4 3"/>
<line x1="298" y1="76" x2="298" y2="340"
stroke="var(--muted)" stroke-width="1" stroke-dasharray="4 3"/>
<line x1="506" y1="76" x2="506" y2="340"
stroke="var(--muted)" stroke-width="1" stroke-dasharray="4 3"/>
<!-- Messages -->
<defs>
<marker id="seq-arrow" markerWidth="6" markerHeight="6"
refX="5" refY="3" orient="auto">
<path d="M0,0 L6,3 L0,6 Z" fill="var(--ink)"/>
</marker>
</defs>
<!-- 1: redirect to auth -->
<line x1="90" y1="120" x2="292" y2="120"
stroke="var(--ink)" stroke-width="1"
marker-end="url(#seq-arrow)"/>
<text x="194" y="114" text-anchor="middle" font-size="10"
fill="var(--muted)">GET /authorize</text>
<!-- 2: login page -->
<line x1="298" y1="152" x2="96" y2="152"
stroke="var(--ink)" stroke-width="1" stroke-dasharray="4 3"
marker-end="url(#seq-arrow)"/>
<text x="194" y="146" text-anchor="middle" font-size="10"
fill="var(--muted)">302 → login page</text>
<!-- 3: credentials -->
<line x1="90" y1="188" x2="292" y2="188"
stroke="var(--ink)" stroke-width="1"
marker-end="url(#seq-arrow)"/>
<text x="194" y="182" text-anchor="middle" font-size="10"
fill="var(--muted)">POST credentials</text>
<!-- 4: code -->
<line x1="298" y1="220" x2="96" y2="220"
stroke="var(--ink)" stroke-width="1" stroke-dasharray="4 3"
marker-end="url(#seq-arrow)"/>
<text x="194" y="214" text-anchor="middle" font-size="10"
fill="var(--muted)">302 + code</text>
<!-- 5: exchange code -->
<line x1="90" y1="260" x2="500" y2="260"
stroke="var(--ink)" stroke-width="1"
marker-end="url(#seq-arrow)"/>
<text x="295" y="254" text-anchor="middle" font-size="10"
fill="var(--muted)">GET /resource + Bearer token</text>
<!-- 6: response -->
<line x1="506" y1="292" x2="96" y2="292"
stroke="var(--ink)" stroke-width="1" stroke-dasharray="4 3"
marker-end="url(#seq-arrow)"/>
<text x="295" y="286" text-anchor="middle" font-size="10"
fill="var(--muted)">200 OK + data</text>
</svg>
Primitives
Annotation Callout
Italic Instrument Serif + dashed Bézier leader for editorial asides in diagram margins:
<!-- Editorial annotation callout -->
<defs>
<style>
.callout-text {
font-family: 'Instrument Serif', Georgia, serif;
font-style: italic;
font-size: 12px;
fill: var(--muted);
}
</style>
</defs>
<!-- Bézier leader line (dashed, 1px) -->
<path d="M 180,200 C 200,180 220,160 260,148"
stroke="var(--muted)" stroke-width="1"
stroke-dasharray="3 3" fill="none"/>
<!-- Callout text — sits in margin -->
<text x="80" y="204" class="callout-text">only runs on cold start</text>
Sketchy Filter (hand-drawn variant)
For essays and informal posts — not technical docs:
<defs>
<filter id="sketchy" x="-5%" y="-5%" width="110%" height="110%">
<feTurbulence type="fractalNoise" baseFrequency="0.04"
numOctaves="3" seed="2" result="noise"/>
<feDisplacementMap in="SourceGraphic" in2="noise"
scale="2.5" xChannelSelector="R"
yChannelSelector="G"/>
</filter>
</defs>
<!-- Apply to any element -->
<rect x="100" y="100" width="160" height="48" rx="6"
fill="var(--paper-2)" stroke="var(--ink)" stroke-width="1.5"
filter="url(#sketchy)"/>
File Structure
diagram-design/
├── SKILL.md # type selection guide, design rules
├── references/
│ ├── style-guide.md # color + font tokens (edit for your brand)
│ ├── onboarding.md # URL-to-tokens extraction spec
│ ├── type-architecture.md
│ ├── type-flowchart.md
│ ├── type-sequence.md
│ ├── type-state.md
│ ├── type-er.md
│ ├── type-timeline.md
│ ├── type-swimlane.md
│ ├── type-quadrant.md
│ ├── type-nested.md
│ ├── type-tree.md
│ ├── type-layers.md
│ ├── type-venn.md
│ ├── type-pyramid.md
│ ├── primitive-annotation.md
│ └── primitive-sketchy.md
├── assets/
│ ├── index.html # live gallery, all 13 types, 3 variants each
│ ├── template.html # minimal light scaffold
│ ├── template-full.html # editorial with summary cards
│ └── example-<type>.html # 39 files: 3 variants × 13 types
└── docs/screenshots/
Context loading (what Claude reads per request):
| Request | Files loaded |
|---|---|
| Any specific type | SKILL.md + references/type-<name>.md |
| Onboarding | SKILL.md + onboarding.md + style-guide.md |
| Add annotation | SKILL.md + primitive-annotation.md |
| Hand-drawn variant | SKILL.md + primitive-sketchy.md |
Only the relevant reference file loads — keeps context tight regardless of how many types exist.
Common Patterns
Choosing the right type
# Decision logic with yes/no branches → flowchart
"Should I use X?" branching → flowchart
# Time-ordered messages between actors → sequence
OAuth, webhooks, API calls → sequence
# Lifecycle with transitions → state machine
Order status, auth state, connection state → state machine
# Two-axis comparison → quadrant
Impact vs effort, risk vs value → quadrant
# Ranked importance → pyramid
Priority tiers, conversion funnel → pyramid
# System components and how they connect → architecture
Services, databases, queues → architecture
Controlling focal emphasis
# Accent = 1–2 nodes only — the main point of the diagram
# If everything is accent, nothing is accent
# Wrong: 5 accent nodes in a 7-node diagram
# Right: 1 accent node (the bottleneck / the thing that matters)
Density calibration
# Target: 4/10 density
# 5 nodes is usually enough
# 8 nodes is usually too many
# 12 nodes → split into two diagrams or use layers/nested
# Eliminate any node the reader doesn't need to understand the point
Troubleshooting
Diagrams look generic / AI-generated
- Check all coordinates are divisible by 4 — misaligned grids are the tell
- Reduce node count; every node must earn its place
- Confirm only 1–2 nodes use
var(--accent); the rest should bevar(--paper-2)
Colors don't match my site
- Run onboarding:
"onboard diagram-design to https://yoursite.com" - Or edit
references/style-guide.mddirectly with your hex values
Fonts not loading
- Diagrams use system fallbacks by default — Geist and Instrument Serif only load if available
- Add Google Fonts or Bunny Fonts link in
<head>for exact rendering:
<link rel="preconnect" href="https://fonts.bunny.net">
<link href="https://fonts.bunny.net/css?family=instrument-serif:400,400i|geist:400,600&display=swap"
rel="stylesheet">
WCAG contrast failing on my brand colors
- Onboarding runs contrast checks automatically and proposes adjustments
- Manual fix: darken
inkor lightenpaperuntil ratio ≥ 4.5:1 at 12px
Diagram too dense / cluttered
- Delete nodes until it hurts, then delete one more
- Split into two diagrams: overview + detail
- Use a nested or layers type if you need to show hierarchy without individual connections
Wrong type chosen
- Override explicitly:
"Make this a swimlane, not a flowchart — rows for Design, Eng, PM"
When NOT to use this skill
- Quick ASCII/unicode diagrams for terminal or tweets → use wiretext
- Before/after comparisons → use a table
- Simple lists → use bullets
- Single-shape "diagrams" (one box, one label) → write the sentence instead
How can the creator link this skill?
Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.
<a href="https://skillzs.dev/skills/reason-machines/trending-skills/diagram-design-editorial">View diagram-design-editorial on skillZs</a>