diagram-design

Installation
SKILL.md

Diagram Design

Create visual diagrams as self-contained HTML files with inline SVG and CSS, following an opinionated editorial design system.

Thirteen diagram types. One shared design system, complexity budget, and taste gate. Type-specific conventions live in references/ and are loaded only when you pick a type.


0. First-time setup — style guide gate

Before generating your first diagram in a new project, verify the style guide has been customized.

Open references/style-guide.md and check the default tokens. If they're still the shipped defaults (paper #faf7f2, ink #1c1917, accent #b5523a rust), pause and ask the user:

"This is your first diagram in this project. The style guide is still at the default (neutral stone + rust). Do you want to customize it to match your brand first? Options: (a) run onboarding — I'll pull colors and fonts from your website, (b) paste your tokens manually, (c) proceed with the default for now."

Then branch:

  • (a) → follow references/onboarding.md to fetch the site, extract palette + fonts, propose a diff, and write style-guide.md.
  • (b) → accept the user's tokens and write them into style-guide.md under a new "Custom tokens" section.
  • (c) → proceed; optionally remind the user they can run onboarding later.

Once the style guide has been customized (or the user explicitly opted for default), skip this gate on subsequent runs. A simple way to detect customization: if the accent value in style-guide.md differs from #b5523a, assume custom.

Don't silently ship default-skinned diagrams into a branded project — that's the failure mode this gate exists to prevent.


1. Philosophy

The highest-quality move is usually deletion.

From .impeccable.md: "Confident restraint. Earn every element. One color accent, two families, a small spacing vocabulary. If removing it wouldn't hurt the page, remove it."

Applied to diagrams:

  • Every node represents a distinct idea. Two nodes that always travel together are one node.
  • Every connection carries information. If the relationship is obvious from layout, remove the line.
  • Coral is editorial, not a flag. 1–2 focal nodes per diagram. Using it on 5 nodes erases the signal.
  • The diagram isn't done when everything is added. It's done when nothing can be removed.

Target density: 4/10. Enough to be technically complete. Not so dense it needs a guide. Above 9 nodes, it's probably two diagrams.


2. When to Use

Use for any of the 13 diagram types (§3) when a reader will learn more from a visual than from prose, a table, or a bulleted list.

Don't use for:

  • Quick unicode diagrams → use wiretext.
  • Lists of things → table or bullets.
  • Simple before/after → table.
  • One-shape "diagrams" → just write the sentence.

Before drawing, ask: Would the reader learn more from this than from a well-written paragraph? If no, don't draw.


3. Diagram Types

Selection guide

If you're showing… Use Reference
Components + connections in a system Architecture type-architecture.md
Decision logic with branches Flowchart type-flowchart.md
Time-ordered messages between actors Sequence type-sequence.md
States + transitions + guards State machine type-state.md
Entities + fields + relationships ER / data model type-er.md
Events positioned in time Timeline type-timeline.md
Cross-functional process with handoffs Swimlane type-swimlane.md
Two-axis positioning / prioritization Quadrant type-quadrant.md
Hierarchy through containment / scope Nested type-nested.md
Parent → children relationships Tree type-tree.md
Stacked abstraction levels Layer stack type-layers.md
Overlap between sets Venn type-venn.md
Ranked hierarchy or conversion drop-off Pyramid / funnel type-pyramid.md

Rules of thumb:

  • If a 3-column table communicates the same thing, pick the table.
  • If you're combining two types, pick the dominant axis — don't hybridize grammars.
  • If you're past the complexity budget (§7), split into an overview + detail.

Always load the relevant references/type-*.md before drawing — it contains layout conventions, anti-patterns, and example files for that type.


4. Universal Anti-patterns

These mark "AI slop" diagrams of any type:

Anti-pattern Why it fails
Dark mode + cyan/purple glow Looks "technical" without design decisions
JetBrains Mono as blanket "dev" font Mono is for technical content — ports, commands, URLs. Names go in Geist sans.
Identical boxes for every node Erases hierarchy
Legend floating inside the diagram area Collides with nodes
Arrow labels with no masking rect Bleeds through the line
Vertical writing-mode text on arrows Unreadable
3 equal-width summary cards as default Generic grid — vary widths
Shadow on any element Shadows are out. Borders are in.
rounded-2xl on boxes Max radius 6–10px or none
Coral on every "important" node Coral is 1–2 editorial accents, not a signaling system

Type-specific anti-patterns live in each references/type-*.md.


5. Design System

The design system is skinnable. All colors, typography, and tokens live in a single source of truth — references/style-guide.md. This file describes semantic roles (paper, ink, muted, accent, link, …). The default skin is littlemight.com (warm paper, ink, coral); to apply your own brand, either edit style-guide.md directly or run the URL-based flow described in references/onboarding.md.

When specs below or in type references mention "ink", "accent", "muted", etc., look up the current hex value in style-guide.md.

Semantic roles (at a glance)

Role Purpose
paper, paper-2 Page bg and container bg
ink Primary text / stroke
muted, soft Secondary text, default arrows, sublabels
rule, rule-solid Hairline borders
accent, accent-tint 1–2 focal elements per diagram
link HTTP/API calls, external arrows

Focal rule: accent goes on 1–2 elements max. Everything else is ink / muted / soft. If you're tempted to accent 4 things, you haven't decided what's focal yet.

Node type → treatment

Type Fill Stroke
Focal (1–2 max) accent-tint accent
Backend / API / Step white ink
Store / State ink @ 0.05 muted
External / Cloud ink @ 0.03 ink @ 0.30
Input / User muted @ 0.10 soft
Optional / Async ink @ 0.02 ink @ 0.20 dashed 4,3
Security / Boundary accent @ 0.05 accent @ 0.50 dashed 4,4

Typography (summary — full spec in style-guide.md)

  • Title — Instrument Serif, 1.75rem, 400 — H1 only
  • Node name — Geist (sans), 12px, 600 — human-readable labels
  • Sublabel — Geist Mono, 9px — ports, URLs, field types
  • Eyebrow / tag — Geist Mono, 7–8px, uppercase, tracked — type tags, axis labels
  • Arrow label — Geist Mono, 8px — annotation on arrows
  • Editorial aside — Instrument Serif italic, 14px — callouts only

Mono is for technical content. Names are Geist sans. Page title is Instrument Serif. Italic Instrument Serif is reserved for annotation callouts. Never JetBrains Mono as a blanket "dev" font.

<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">

6. Core SVG Primitives

Universal building blocks. Type-specialized primitives (lifeline, activation bar, region) live in the relevant references/type-*.md. Optional primitives:

Background

<defs>
  <pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
    <circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
  </pattern>
</defs>
<rect width="100%" height="100%" fill="#f5f4ed"/>
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.6"/>

Arrow markers (define all three, always)

<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto">
  <polygon points="0 0, 8 3, 0 6" fill="#52534e"/>
</marker>
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto">
  <polygon points="0 0, 8 3, 0 6" fill="#f7591f"/>
</marker>
<marker id="arrow-link" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto">
  <polygon points="0 0, 8 3, 0 6" fill="#1a70c7"/>
</marker>
Arrow Stroke When
Default muted #52534e Internal, generic
Accent coral #f7591f Primary / highlighted / headline
Link-blue #1a70c7 HTTP/API calls, external systems
Dashed stroke-dasharray="5,4" + any color Optional, passive, return, async

Draw arrows before boxes so z-order puts lines behind nodes.

Node box — full pattern

<!-- 1. Opaque paper mask — prevents arrows bleeding through transparent fills -->
<rect x="X" y="Y" width="W" height="H" rx="6" fill="#f5f4ed"/>
<!-- 2. Styled box -->
<rect x="X" y="Y" width="W" height="H" rx="6" fill="FILL" stroke="STROKE" stroke-width="1"/>
<!-- 3. Rectangular type tag (rx=2, NOT a pill) -->
<rect x="X+8" y="Y+6" width="28" height="12" rx="2" fill="transparent" stroke="STROKE@0.40" stroke-width="0.8"/>
<text x="X+22" y="Y+15" fill="STROKE@0.8" font-size="7" font-family="'Geist Mono', monospace"
      text-anchor="middle" letter-spacing="0.08em">API</text>
<!-- 4. Node name (Geist sans — human-readable) -->
<text x="CX" y="CY+2" fill="#0b0d0b" font-size="12" font-weight="600"
      font-family="'Geist', sans-serif" text-anchor="middle">Node Name</text>
<!-- 5. Technical sublabel (Geist Mono) -->
<text x="CX" y="CY+18" fill="#52534e" font-size="9"
      font-family="'Geist Mono', monospace" text-anchor="middle">tech:port</text>

Arrow labels — always mask

Every arrow label needs an opaque rect behind it. Without one it bleeds through the line.

<rect x="MID_X-18" y="ARROW_Y-12" width="36" height="12" rx="2" fill="#f5f4ed"/>
<text x="MID_X" y="ARROW_Y-3" fill="#65655c" font-size="8"
      font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.06em">WRITE</text>

Rules: ≤14 characters, all-caps, centered on segment midpoint, 8–10px above line. Never writing-mode vertical.

Legend — horizontal strip at the bottom

Never put the legend inside the diagram area. Place as a horizontal strip after all nodes, with a hairline separator:

<line x1="30" y1="LEGEND_Y-8" x2="VIEWBOX_W-30" y2="LEGEND_Y-8"
      stroke="rgba(11,13,11,0.10)" stroke-width="0.8"/>
<text x="30" y="LEGEND_Y+8" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace"
      letter-spacing="0.14em">LEGEND</text>
<!-- Items — horizontal row, ~160px apart -->

Expand SVG viewBox height by ~60px.


7. Layout & Spacing

4px grid

All values — font sizes, padding, node dimensions, gaps, x/y coords — divisible by 4. Non-negotiable.

Category Allowed values
Font sizes 8, 12, 16, 20, 24, 28, 32, 40
Node width / height 80, 96, 112, 120, 128, 140, 144, 160, 180, 200, 240, 320
x / y coordinates multiples of 4
Gap between nodes 20, 24, 32, 40, 48
Padding inside boxes 8, 12, 16
Border radius 4, 6, 8

Exempt: stroke widths (0.8, 1, 1.2), opacity values, and the 22×22 dot-pattern.

Quick check: if a coordinate ends in 1, 2, 3, 5, 6, 7, 9 — fix it.

Complexity budget (per diagram)

Limit Rule
Max nodes 9
Max arrows / transitions 12
Max coral elements 2
Max lifelines (sequence) 5
Max lanes (swimlane) 5
Max items (quadrant) 12
Max entities (ER) 8
Max nesting levels (nested) 6
Max tree depth 4
Max layers (layer stack) 6
Max circles (venn) 3
Max layers (pyramid) 6
Max annotation callouts 2

If you exceed, split into two diagrams (overview + detail).

Page layout

  1. Header — eyebrow (Geist Mono), title (Instrument Serif), optional subtitle (Geist muted).
  2. Diagram container#efeee5 bg, 1px rgba(11,13,11,0.12) border, 8px radius, overflow-x: auto.
  3. Summary cards — 2–3 col grid with varied widths (e.g., 1.1fr 1fr 0.9fr).
  4. Footer — colophon in Geist Mono, muted, hairline top border.

8. Summary Card Pattern

Don't use 3 identical generic cards. Vary the treatment:

<div class="card">
  <p class="eyebrow">SECTION LABEL</p>
  <div class="card-header">
    <span class="card-dot coral"></span>
    <h3>Card Title</h3>
  </div>
  <ul><li>Item</li></ul>
</div>

Rules:

  • background: #ffffff (not paper — slight lift without shadow)
  • border: 1px solid rgba(11,13,11,0.12)
  • border-radius: 6px, padding: 1.25rem
  • No box-shadow
  • Card dots: 7px, border-radius: 50% — ink / muted / coral / link / soft variants

9. Pre-Output Checklist (Taste Gate)

Run before producing any diagram.

Type fit:

  • Right type for what I'm showing? (§3 selection guide)
  • Would a table / paragraph do the same job? (If yes — don't draw.)
  • Loaded the matching references/type-*.md?

Remove test:

  • Can I remove any node? (Would a reader still understand?)
  • Can I merge any two nodes? (Do they always travel together?)
  • Can I remove any arrow? (Is the relationship obvious from layout?)
  • Can I remove any label? (Does color or shape already signal it?)

Signal:

  • Coral used on ≤2 elements? If more, which actually deserve focal status?
  • Legend covers every type used — and nothing extra?
  • Within the type's complexity budget (§7)?

Technical:

  • Arrows drawn before boxes?
  • Every arrow label has an opaque fill="#f5f4ed" rect behind it?
  • Legend is a horizontal bottom strip, not floating?
  • No vertical writing-mode text?
  • viewBox expanded for the legend strip (~60px)?
  • Every font size, coord, width, height, gap divisible by 4?

Typography:

  • Human-readable names in Geist sans, not Geist Mono?
  • Technical sublabels (ports, commands, URLs) in Geist Mono?
  • Page title in Instrument Serif?
  • Annotation callouts (if any) in italic Instrument Serif? (see primitive-annotation.md)
  • No JetBrains Mono anywhere?

10. Templates & Variants

Every diagram ships in three variants (see assets/):

Variant File pattern When to use
Minimal light (default) template.html, example-<type>.html Screenshot-ready. Diagram + title. Warm paper.
Minimal dark template-dark.html, example-<type>-dark.html Dark mode sites, slides, high-contrast posts.
Full editorial template-full.html, example-<type>-full.html Long-form posts where the diagram is the hero.

Sketchy variant (optional, applied to any of the above) — see primitive-sketchy.md. SVG turbulence filter wobbles strokes for a hand-drawn feel. Good for essays, not for technical docs.

To create a new diagram

  1. Copy the variant closest to what you want (template.html for minimal, template-full.html for cards).
  2. Load the matching references/type-<name>.md for layout conventions.
  3. Replace the eyebrow, h1, and SVG body.
  4. Run the §9 taste gate.

11. Output

Always produce a single self-contained .html file:

  • Embedded CSS (no external except Google Fonts)
  • Inline SVG (no external images)
  • No JavaScript required

Renders correctly in any modern browser.

Related skills

More from alfredolopez80/multi-agent-ralph-loop

Installs
1
GitHub Stars
108
First Seen
5 days ago