Home · Skills · Operations
Workflow Diagram Creator
Create FigJam/Miro-style workflow diagrams as high-quality PNG images from plain-text workflow descriptions.
How to use it
- Hit Copy SKILL.md — or use the Claude Code line below to get every file.
- Claude: ⋯ → Download .md, then Customize → Skills → Add → Upload skill.
ChatGPT: make a Project and paste it into Instructions.
Neither? Paste it at the top of a new chat — it works for that chat. - Describe your job in plain words. The AI follows the skill from there.
npx degit gooseworks-ai/goose-skills/skills/design/capabilities/create-workflow-diagram#main ~/.claude/skills/create-workflow-diagramFor one project only, change the path to .claude/skills/create-workflow-diagram. This skill also uses STYLE_PRESETS.md, screenshot-diagram.js — copying SKILL.md alone won't be enough. See the folder on GitHub.
Not working?
- Check which app you pasted it into — the steps above name the right one.
- Some skills need the paid tier of Claude or ChatGPT.
Paste into Claude, ChatGPT or Cursor.
Show the full text619 lines
Workflow Diagram Creator
Create FigJam/Miro-style workflow diagrams as PNG images. This skill takes a plain-text workflow description and generates a styled HTML diagram with connected nodes, directional arrows, and labels — then automatically screenshots it for sharing in docs, Slack, LinkedIn, or presentations.
Core Philosophy
- Visual Clarity — Each step is a distinct node with clear connections
- FigJam/Miro Aesthetic — Colorful, rounded, friendly diagram style
- Automated Export — Generate HTML → Screenshot → PNG ready to share
- Smart Layout — Automatically arranges nodes in logical flow patterns
- One-Command — Describe workflow in plain text, get a polished diagram
Output Specs
Format: PNG image
- Default size: 1920×1080px (landscape, presentation-friendly)
- Alternative sizes: 1080×1080px (square, LinkedIn), 1200×630px (blog/social)
- File format: PNG
- File size: Under 5MB
When to Use This Skill
Use for workflow/process diagrams like:
- "Find leads on Apollo → Enrich with Clay → Qualify with Claude → Send to Smartlead"
- "User signs up → Onboarding email → Trial → Upgrade prompt → Paid"
- "PR opened → CI runs → Review → Approve → Merge → Deploy"
- "Scrape data → Clean → Enrich → Score → Route to CRM"
NOT for:
- Org charts or hierarchy diagrams (use a tree layout tool)
- Complex flowcharts with many branches (use draw.io)
- Data architecture diagrams (use Mermaid or similar)
- Simple text lists (just use bullet points)
Workflow Overview
1. Content Input → User describes the workflow in plain text
2. Parse Steps → Extract nodes, connections, and labels
3. Style Selection → Choose visual style
4. HTML Generation → Create positioned diagram with SVG arrows
5. Screenshot → Auto-capture as PNG
6. Delivery → PNG file ready to share
Phase 1: Content Discovery
Step 1.1: Get Workflow Description
Ask the user:
Question 1: What's the workflow?
- Header: "Workflow"
- Question: "Describe the workflow steps. Use arrows (→) or numbers to show the flow."
- (Free text input)
- Examples:
- "1. Find leads on Apollo → 2. Enrich with Clay → 3. Qualify with Claude → 4. Send to Smartlead"
- "Scrape Reddit → Filter relevant posts → Draft comments → Send to Slack for review → Post"
Question 2: Layout Direction
- Header: "Layout"
- Question: "How should the diagram flow?"
- Options:
- "Left to Right" — Horizontal flow (default, best for 4-8 steps)
- "Top to Bottom" — Vertical flow (best for 3-5 steps)
- "Snake/Zigzag" — Wraps to next row (best for 6+ steps)
Question 3: Diagram Size
- Header: "Size"
- Question: "What size works best for your use case?"
- Options:
- "Landscape (1920×1080)" — Presentations, docs, Slack (default)
- "Square (1080×1080)" — LinkedIn, social media
- "Wide (1200×630)" — Blog headers, social cards
Step 1.2: Parse the Workflow
Extract structured data from the user's description:
Input: "1. Find leads on Apollo → 2. Enrich with Clay → 3. Qualify with Claude → 4. Send to Smartlead via API"
Parsed:
nodes:
- id: 1, label: "Find leads", detail: "Apollo", icon: "🔍"
- id: 2, label: "Enrich leads", detail: "Clay", icon: "✨"
- id: 3, label: "Qualify leads", detail: "Claude", icon: "🤖"
- id: 4, label: "Send to Smartlead", detail: "via API", icon: "📤"
connections:
- from: 1, to: 2
- from: 2, to: 3
- from: 3, to: 4
Parsing rules:
- Split on
→,->,>, numbered lists, or line breaks - Extract the primary action (label) and the tool/platform (detail)
- Auto-assign relevant emoji icons based on the action
- Detect branching if words like "if", "or", "else" appear
Icon assignment heuristics:
| Action keyword | Icon |
|---|---|
| find, search, discover | 🔍 |
| enrich, enhance, augment | ✨ |
| qualify, score, filter | 🎯 |
| send, email, outreach | 📤 |
| scrape, crawl, extract | 🕷️ |
| analyze, research | 📊 |
| review, approve | ✅ |
| deploy, ship, launch | 🚀 |
| store, save, database | 💾 |
| AI, Claude, GPT | 🤖 |
| alert, notify, Slack | 🔔 |
| clean, transform | 🧹 |
| merge, combine | 🔗 |
| schedule, automate | ⏰ |
Phase 2: Style Selection
Style Options
Question: Pick a Style
- Header: "Style"
- Question: "Which visual style?"
- Options:
- "FigJam Classic" — Colorful sticky-note nodes on dotted canvas (default)
- "Blueprint" — Technical dark theme with grid lines
- "Minimal White" — Clean white with thin borders and subtle shadows
- "Neon Flow" — Dark background with glowing neon connections
- "Pastel Board" — Soft pastel nodes on light background
See STYLE_PRESETS.md for full details on each style.
Phase 3: Generate HTML Diagram
File Structure
skills/create-workflow-diagram/[diagram-name]/
├── diagram.html # Full diagram page
└── exports/
└── diagram.png # Screenshot (generated in Phase 4)
HTML Architecture
The diagram is built with pure HTML/CSS using absolute positioning for nodes and SVG for arrows.
CRITICAL: Use absolute positioning for precise node placement. Use SVG overlay for arrows/connections.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Workflow Diagram</title>
<!-- Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
/* ===========================================
WORKFLOW DIAGRAM
=========================================== */
:root {
--diagram-width: 1920px;
--diagram-height: 1080px;
/* Colors (from chosen preset) */
--bg-primary: #f5f5f0;
--bg-dot-color: #d4d4d0;
--node-shadow: 0 4px 12px rgba(0,0,0,0.08);
--arrow-color: #666;
--text-primary: #1a1a1a;
--text-secondary: #666;
/* Node colors (cycle through for each node) */
--node-1: #FFE066; /* Yellow */
--node-2: #A8D8EA; /* Blue */
--node-3: #C3F0CA; /* Green */
--node-4: #F0B4D4; /* Pink */
--node-5: #D4BAFF; /* Purple */
--node-6: #FFB366; /* Orange */
/* Typography */
--font-family: 'Inter', -apple-system, sans-serif;
--node-title-size: 22px;
--node-detail-size: 15px;
--node-icon-size: 36px;
/* Node dimensions */
--node-width: 220px;
--node-min-height: 120px;
--node-padding: 24px;
--node-radius: 16px;
--node-gap: 80px; /* gap between nodes for arrows */
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body {
width: var(--diagram-width);
height: var(--diagram-height);
overflow: hidden;
}
body {
font-family: var(--font-family);
background: var(--bg-primary);
position: relative;
}
/* Dotted grid background (FigJam-style) */
.canvas-bg {
position: absolute;
width: 100%;
height: 100%;
background-image: radial-gradient(circle, var(--bg-dot-color) 1.2px, transparent 1.2px);
background-size: 24px 24px;
z-index: 0;
}
/* Diagram container */
.diagram {
position: absolute;
width: 100%;
height: 100%;
z-index: 1;
}
/* SVG arrow layer */
.arrows-layer {
position: absolute;
width: 100%;
height: 100%;
z-index: 1;
pointer-events: none;
}
/* Workflow node */
.node {
position: absolute;
width: var(--node-width);
min-height: var(--node-min-height);
padding: var(--node-padding);
border-radius: var(--node-radius);
box-shadow: var(--node-shadow);
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
gap: 8px;
z-index: 2;
border: 2px solid rgba(0,0,0,0.06);
}
.node-icon {
font-size: var(--node-icon-size);
line-height: 1;
}
.node-label {
font-size: var(--node-title-size);
font-weight: 700;
color: var(--text-primary);
line-height: 1.2;
}
.node-detail {
font-size: var(--node-detail-size);
font-weight: 500;
color: var(--text-secondary);
opacity: 0.8;
}
.node-step {
position: absolute;
top: -12px;
left: -12px;
width: 32px;
height: 32px;
border-radius: 50%;
background: var(--text-primary);
color: white;
font-size: 14px;
font-weight: 700;
display: flex;
align-items: center;
justify-content: center;
}
/* Title overlay */
.diagram-title {
position: absolute;
top: 40px;
left: 50%;
transform: translateX(-50%);
font-size: 32px;
font-weight: 700;
color: var(--text-primary);
z-index: 3;
text-align: center;
}
.diagram-subtitle {
position: absolute;
top: 82px;
left: 50%;
transform: translateX(-50%);
font-size: 18px;
font-weight: 400;
color: var(--text-secondary);
z-index: 3;
}
</style>
</head>
<body>
<div class="canvas-bg"></div>
<!-- Optional title -->
<div class="diagram-title">Lead Generation Pipeline</div>
<div class="diagram-subtitle">Apollo → Clay → Claude → Smartlead</div>
<div class="diagram">
<!-- SVG arrows connecting nodes -->
<svg class="arrows-layer" viewBox="0 0 1920 1080" xmlns="http://www.w3.org/2000/svg">
<!-- Arrow from node 1 to node 2 -->
<defs>
<marker id="arrowhead" markerWidth="12" markerHeight="8" refX="10" refY="4" orient="auto">
<path d="M 0 0 L 12 4 L 0 8 Z" fill="var(--arrow-color)" />
</marker>
</defs>
<!-- Connection lines drawn between node centers -->
<line x1="380" y1="490" x2="520" y2="490"
stroke="var(--arrow-color)" stroke-width="3"
stroke-dasharray="8,6" marker-end="url(#arrowhead)" />
<!-- Repeat for each connection -->
</svg>
<!-- Nodes -->
<div class="node" style="left: 160px; top: 420px; background: var(--node-1);">
<span class="node-step">1</span>
<span class="node-icon">🔍</span>
<span class="node-label">Find Leads</span>
<span class="node-detail">Apollo</span>
</div>
<div class="node" style="left: 560px; top: 420px; background: var(--node-2);">
<span class="node-step">2</span>
<span class="node-icon">✨</span>
<span class="node-label">Enrich Leads</span>
<span class="node-detail">Clay</span>
</div>
<!-- ... more nodes ... -->
</div>
</body>
</html>
Layout Algorithms
Left-to-Right (default for 4-8 steps):
Position each node evenly across the width:
- totalWidth = diagramWidth - (2 * margin)
- nodeSpacing = totalWidth / (nodeCount - 1)
- node[i].x = margin + (i * nodeSpacing) - (nodeWidth / 2)
- node[i].y = (diagramHeight / 2) - (nodeHeight / 2)
For the default 1920×1080 with 4 nodes:
- margin = 200px
- spacing = ~507px
- y = ~460px (vertically centered)
Top-to-Bottom (3-5 steps):
- totalHeight = diagramHeight - (2 * margin)
- nodeSpacing = totalHeight / (nodeCount - 1)
- node[i].y = margin + (i * nodeSpacing) - (nodeHeight / 2)
- node[i].x = (diagramWidth / 2) - (nodeWidth / 2)
Snake/Zigzag (6+ steps):
- maxPerRow = 4
- rowHeight = 250px
- For each row, alternate left-to-right and right-to-left
- Row 0: nodes flow →
- Row 1: nodes flow ←
- Row 2: nodes flow →
- Connect last node of row to first node of next row with vertical arrow
Arrow Drawing
Arrows are drawn as SVG lines between node edges:
// Calculate arrow coordinates between two nodes
function getArrowCoords(fromNode, toNode, direction) {
if (direction === 'horizontal') {
// Arrow from right edge of fromNode to left edge of toNode
const x1 = fromNode.x + fromNode.width;
const y1 = fromNode.y + fromNode.height / 2;
const x2 = toNode.x;
const y2 = toNode.y + toNode.height / 2;
return { x1, y1, x2, y2 };
}
if (direction === 'vertical') {
// Arrow from bottom of fromNode to top of toNode
const x1 = fromNode.x + fromNode.width / 2;
const y1 = fromNode.y + fromNode.height;
const x2 = toNode.x + toNode.width / 2;
const y2 = toNode.y;
return { x1, y1, x2, y2 };
}
}
For curved arrows (more FigJam-like), use SVG <path> with cubic bezier:
<path d="M 380,490 C 430,490 470,490 520,490"
stroke="var(--arrow-color)" stroke-width="3"
fill="none" stroke-dasharray="8,6"
marker-end="url(#arrowhead)" />
For snake layout vertical connectors between rows:
<!-- Vertical connector from end of row 1 to start of row 2 -->
<path d="M 1500,550 C 1500,620 200,620 200,690"
stroke="var(--arrow-color)" stroke-width="3"
fill="none" stroke-dasharray="8,6"
marker-end="url(#arrowhead)" />
Branching (Optional)
If the workflow has conditional branches:
Step 3: Qualify leads
├── Yes → Step 4a: Send to Smartlead
└── No → Step 4b: Add to nurture sequence
Render as:
- Main node for step 3
- Two arrows diverging from step 3
- Label on each arrow ("Qualified" / "Not Qualified")
- Two destination nodes
<!-- Branch label on arrow -->
<text x="650" y="400" font-size="14" fill="var(--text-secondary)"
font-family="Inter" font-weight="600">Qualified</text>
Phase 4: Screenshot Generation
After generating HTML, automatically capture a screenshot.
Using Playwright
cd /path/to/skills/create-workflow-diagram
node screenshot-diagram.js <diagram-name>
This will:
- Open the diagram HTML in a headless browser
- Set viewport to the diagram dimensions (e.g., 1920×1080)
- Wait for fonts to load
- Capture PNG screenshot at 2x resolution
- Save to the diagram's
exports/directory
Installation
First time setup:
cd /path/to/skills/create-workflow-diagram
npm install
Phase 5: Delivery
After the screenshot is generated, present to user:
Your workflow diagram is ready!
HTML source: skills/create-workflow-diagram/[name]/diagram.html
PNG export: skills/create-workflow-diagram/[name]/exports/diagram.png
Preview: Open diagram.html in a browser to see the full diagram.
Diagram details:
- 4 workflow steps connected with arrows
- Style: FigJam Classic
- Size: 1920×1080px (landscape)
- File size: ~350 KB
Want to make any changes?
Node Sizing Rules
Keep nodes consistent and readable:
| Element | Size |
|---|---|
| Node width | 200-240px |
| Node min-height | 110-140px |
| Node padding | 20-28px |
| Icon | 32-40px |
| Label font | 20-24px, weight 700 |
| Detail font | 14-16px, weight 500 |
| Step badge | 28-34px circle |
| Arrow stroke | 2-3px |
| Arrow gap | 60-100px between nodes |
Content Rules
Each node should have:
- Step number — Badge in top-left corner
- Icon — Relevant emoji (auto-assigned from keyword)
- Label — Action in 2-4 words (e.g., "Find Leads")
- Detail — Tool/platform name (e.g., "Apollo") — optional
If a label is too long, truncate or split across lines. Max 2 lines for label.
Troubleshooting
Nodes Overlap
Solution: Increase --node-gap or switch to snake layout for many nodes.
Arrows Misaligned
Solution: Recalculate arrow start/end points based on actual node positions. Use the center of the node edge closest to the target.
Fonts Not Loading
Solution: Add await page.waitForLoadState('networkidle') before screenshot. Increase timeout to 1000ms.
Diagram Too Crowded
Solution: Reduce node count by combining steps, switch to a larger canvas size, or use snake layout.
Style Quick Reference
| Preset | Best For | Vibe |
|---|---|---|
| FigJam Classic | General workflows | Friendly, colorful |
| Blueprint | Technical processes | Professional, dark |
| Minimal White | Documentation | Clean, corporate |
| Neon Flow | Tech/AI workflows | Futuristic, bold |
| Pastel Board | Presentations | Soft, approachable |
See STYLE_PRESETS.md for complete styling details.
Related Skills
- create-html-carousel — For multi-slide LinkedIn carousels
- frontend-slides — For full HTML presentations
Example Session Flow
- User: "Create a diagram for: Find leads on Apollo → Enrich with Clay → Qualify with Claude → Send to Smartlead"
- Skill asks: layout direction, size, style
- User picks defaults (left-to-right, landscape, FigJam Classic)
- Skill parses 4 nodes with auto-icons
- Skill generates HTML diagram with positioned nodes and SVG arrows
- Skill runs screenshot script
- Skill delivers PNG file
- User shares in Slack/docs/LinkedIn
Total time: 2-5 minutes from description to exported diagram.
| 1 | |
| 2 | name create-workflow-diagram |
| 3 | description Create FigJam/Miro-style workflow diagrams as high-quality PNG images from plain-text workflow descriptions. Renders beautiful HTML diagrams with connected nodes, arrows, and labels, then screenshots them for sharing. |
| 4 | |
| 5 | |
| 6 | # Workflow Diagram Creator |
| 7 | |
| 8 | Create FigJam/Miro-style workflow diagrams as PNG images. This skill takes a plain-text workflow description and generates a styled HTML diagram with connected nodes, directional arrows, and labels — then automatically screenshots it for sharing in docs, Slack, LinkedIn, or presentations. |
| 9 | |
| 10 | ## Core Philosophy |
| 11 | |
| 12 | **Visual Clarity** — Each step is a distinct node with clear connections |
| 13 | **FigJam/Miro Aesthetic** — Colorful, rounded, friendly diagram style |
| 14 | **Automated Export** — Generate HTML → Screenshot → PNG ready to share |
| 15 | **Smart Layout** — Automatically arranges nodes in logical flow patterns |
| 16 | **One-Command** — Describe workflow in plain text, get a polished diagram |
| 17 | |
| 18 | |
| 19 | |
| 20 | ## Output Specs |
| 21 | |
| 22 | **Format:** PNG image |
| 23 | **Default size:** 1920×1080px (landscape, presentation-friendly) |
| 24 | **Alternative sizes:** 1080×1080px (square, LinkedIn), 1200×630px (blog/social) |
| 25 | **File format:** PNG |
| 26 | **File size:** Under 5MB |
| 27 | |
| 28 | |
| 29 | |
| 30 | ## When to Use This Skill |
| 31 | |
| 32 | Use for workflow/process diagrams like: |
| 33 | "Find leads on Apollo → Enrich with Clay → Qualify with Claude → Send to Smartlead" |
| 34 | "User signs up → Onboarding email → Trial → Upgrade prompt → Paid" |
| 35 | "PR opened → CI runs → Review → Approve → Merge → Deploy" |
| 36 | "Scrape data → Clean → Enrich → Score → Route to CRM" |
| 37 | |
| 38 | **NOT for:** |
| 39 | Org charts or hierarchy diagrams (use a tree layout tool) |
| 40 | Complex flowcharts with many branches (use draw.io) |
| 41 | Data architecture diagrams (use Mermaid or similar) |
| 42 | Simple text lists (just use bullet points) |
| 43 | |
| 44 | |
| 45 | |
| 46 | ## Workflow Overview |
| 47 | |
| 48 | |
| 49 | 1. Content Input → User describes the workflow in plain text |
| 50 | 2. Parse Steps → Extract nodes, connections, and labels |
| 51 | 3. Style Selection → Choose visual style |
| 52 | 4. HTML Generation → Create positioned diagram with SVG arrows |
| 53 | 5. Screenshot → Auto-capture as PNG |
| 54 | 6. Delivery → PNG file ready to share |
| 55 | |
| 56 | |
| 57 | |
| 58 | |
| 59 | ## Phase 1: Content Discovery |
| 60 | |
| 61 | ### Step 1.1: Get Workflow Description |
| 62 | |
| 63 | Ask the user: |
| 64 | |
| 65 | **Question 1: What's the workflow?** |
| 66 | Header: "Workflow" |
| 67 | Question: "Describe the workflow steps. Use arrows (→) or numbers to show the flow." |
| 68 | (Free text input) |
| 69 | Examples: |
| 70 | "1. Find leads on Apollo → 2. Enrich with Clay → 3. Qualify with Claude → 4. Send to Smartlead" |
| 71 | "Scrape Reddit → Filter relevant posts → Draft comments → Send to Slack for review → Post" |
| 72 | |
| 73 | **Question 2: Layout Direction** |
| 74 | Header: "Layout" |
| 75 | Question: "How should the diagram flow?" |
| 76 | Options: |
| 77 | "Left to Right" — Horizontal flow (default, best for 4-8 steps) |
| 78 | "Top to Bottom" — Vertical flow (best for 3-5 steps) |
| 79 | "Snake/Zigzag" — Wraps to next row (best for 6+ steps) |
| 80 | |
| 81 | **Question 3: Diagram Size** |
| 82 | Header: "Size" |
| 83 | Question: "What size works best for your use case?" |
| 84 | Options: |
| 85 | "Landscape (1920×1080)" — Presentations, docs, Slack (default) |
| 86 | "Square (1080×1080)" — LinkedIn, social media |
| 87 | "Wide (1200×630)" — Blog headers, social cards |
| 88 | |
| 89 | ### Step 1.2: Parse the Workflow |
| 90 | |
| 91 | Extract structured data from the user's description: |
| 92 | |
| 93 | |
| 94 | Input: "1. Find leads on Apollo → 2. Enrich with Clay → 3. Qualify with Claude → 4. Send to Smartlead via API" |
| 95 | |
| 96 | Parsed: |
| 97 | nodes: |
| 98 | - id: 1, label: "Find leads", detail: "Apollo", icon: "🔍" |
| 99 | - id: 2, label: "Enrich leads", detail: "Clay", icon: "✨" |
| 100 | - id: 3, label: "Qualify leads", detail: "Claude", icon: "🤖" |
| 101 | - id: 4, label: "Send to Smartlead", detail: "via API", icon: "📤" |
| 102 | |
| 103 | connections: |
| 104 | - from: 1, to: 2 |
| 105 | - from: 2, to: 3 |
| 106 | - from: 3, to: 4 |
| 107 | |
| 108 | |
| 109 | **Parsing rules:** |
| 110 | Split on `→`, `->`, `>`, numbered lists, or line breaks |
| 111 | Extract the primary action (label) and the tool/platform (detail) |
| 112 | Auto-assign relevant emoji icons based on the action |
| 113 | Detect branching if words like "if", "or", "else" appear |
| 114 | |
| 115 | **Icon assignment heuristics:** |
| 116 | | Action keyword | Icon | |
| 117 | |---------------|------| |
| 118 | | find, search, discover | 🔍 | |
| 119 | | enrich, enhance, augment | ✨ | |
| 120 | | qualify, score, filter | 🎯 | |
| 121 | | send, email, outreach | 📤 | |
| 122 | | scrape, crawl, extract | 🕷️ | |
| 123 | | analyze, research | 📊 | |
| 124 | | review, approve | ✅ | |
| 125 | | deploy, ship, launch | 🚀 | |
| 126 | | store, save, database | 💾 | |
| 127 | | AI, Claude, GPT | 🤖 | |
| 128 | | alert, notify, Slack | 🔔 | |
| 129 | | clean, transform | 🧹 | |
| 130 | | merge, combine | 🔗 | |
| 131 | | schedule, automate | ⏰ | |
| 132 | |
| 133 | |
| 134 | |
| 135 | ## Phase 2: Style Selection |
| 136 | |
| 137 | ### Style Options |
| 138 | |
| 139 | **Question: Pick a Style** |
| 140 | Header: "Style" |
| 141 | Question: "Which visual style?" |
| 142 | Options: |
| 143 | "FigJam Classic" — Colorful sticky-note nodes on dotted canvas (default) |
| 144 | "Blueprint" — Technical dark theme with grid lines |
| 145 | "Minimal White" — Clean white with thin borders and subtle shadows |
| 146 | "Neon Flow" — Dark background with glowing neon connections |
| 147 | "Pastel Board" — Soft pastel nodes on light background |
| 148 | |
| 149 | See STYLE_PRESETS.md for full details on each style. |
| 150 | |
| 151 | |
| 152 | |
| 153 | ## Phase 3: Generate HTML Diagram |
| 154 | |
| 155 | ### File Structure |
| 156 | |
| 157 | |
| 158 | skills/create-workflow-diagram/[diagram-name]/ |
| 159 | ├── diagram.html # Full diagram page |
| 160 | └── exports/ |
| 161 | └── diagram.png # Screenshot (generated in Phase 4) |
| 162 | |
| 163 | |
| 164 | ### HTML Architecture |
| 165 | |
| 166 | The diagram is built with pure HTML/CSS using absolute positioning for nodes and SVG for arrows. |
| 167 | |
| 168 | **CRITICAL: Use absolute positioning for precise node placement. Use SVG overlay for arrows/connections.** |
| 169 | |
| 170 | |
| 171 | <!DOCTYPE html> |
| 172 | <html lang="en"> |
| 173 | <head> |
| 174 | <meta charset="UTF-8"> |
| 175 | <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| 176 | <title>Workflow Diagram</title> |
| 177 | |
| 178 | <!-- Fonts --> |
| 179 | <link rel="preconnect" href="https://fonts.googleapis.com"> |
| 180 | <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> |
| 181 | <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet"> |
| 182 | |
| 183 | <style> |
| 184 | /* =========================================== |
| 185 | WORKFLOW DIAGRAM |
| 186 | =========================================== */ |
| 187 | :root { |
| 188 | --diagram-width: 1920px; |
| 189 | --diagram-height: 1080px; |
| 190 | |
| 191 | /* Colors (from chosen preset) */ |
| 192 | --bg-primary: #f5f5f0; |
| 193 | --bg-dot-color: #d4d4d0; |
| 194 | --node-shadow: 0 4px 12px rgba(0,0,0,0.08); |
| 195 | --arrow-color: #666; |
| 196 | --text-primary: #1a1a1a; |
| 197 | --text-secondary: #666; |
| 198 | |
| 199 | /* Node colors (cycle through for each node) */ |
| 200 | --node-1: #FFE066; /* Yellow */ |
| 201 | --node-2: #A8D8EA; /* Blue */ |
| 202 | --node-3: #C3F0CA; /* Green */ |
| 203 | --node-4: #F0B4D4; /* Pink */ |
| 204 | --node-5: #D4BAFF; /* Purple */ |
| 205 | --node-6: #FFB366; /* Orange */ |
| 206 | |
| 207 | /* Typography */ |
| 208 | --font-family: 'Inter', -apple-system, sans-serif; |
| 209 | --node-title-size: 22px; |
| 210 | --node-detail-size: 15px; |
| 211 | --node-icon-size: 36px; |
| 212 | |
| 213 | /* Node dimensions */ |
| 214 | --node-width: 220px; |
| 215 | --node-min-height: 120px; |
| 216 | --node-padding: 24px; |
| 217 | --node-radius: 16px; |
| 218 | --node-gap: 80px; /* gap between nodes for arrows */ |
| 219 | } |
| 220 | |
| 221 | * { |
| 222 | margin: 0; |
| 223 | padding: 0; |
| 224 | box-sizing: border-box; |
| 225 | } |
| 226 | |
| 227 | html, body { |
| 228 | width: var(--diagram-width); |
| 229 | height: var(--diagram-height); |
| 230 | overflow: hidden; |
| 231 | } |
| 232 | |
| 233 | body { |
| 234 | font-family: var(--font-family); |
| 235 | background: var(--bg-primary); |
| 236 | position: relative; |
| 237 | } |
| 238 | |
| 239 | /* Dotted grid background (FigJam-style) */ |
| 240 | .canvas-bg { |
| 241 | position: absolute; |
| 242 | width: 100%; |
| 243 | height: 100%; |
| 244 | background-image: radial-gradient(circle, var(--bg-dot-color) 1.2px, transparent 1.2px); |
| 245 | background-size: 24px 24px; |
| 246 | z-index: 0; |
| 247 | } |
| 248 | |
| 249 | /* Diagram container */ |
| 250 | .diagram { |
| 251 | position: absolute; |
| 252 | width: 100%; |
| 253 | height: 100%; |
| 254 | z-index: 1; |
| 255 | } |
| 256 | |
| 257 | /* SVG arrow layer */ |
| 258 | .arrows-layer { |
| 259 | position: absolute; |
| 260 | width: 100%; |
| 261 | height: 100%; |
| 262 | z-index: 1; |
| 263 | pointer-events: none; |
| 264 | } |
| 265 | |
| 266 | /* Workflow node */ |
| 267 | .node { |
| 268 | position: absolute; |
| 269 | width: var(--node-width); |
| 270 | min-height: var(--node-min-height); |
| 271 | padding: var(--node-padding); |
| 272 | border-radius: var(--node-radius); |
| 273 | box-shadow: var(--node-shadow); |
| 274 | display: flex; |
| 275 | flex-direction: column; |
| 276 | align-items: center; |
| 277 | text-align: center; |
| 278 | gap: 8px; |
| 279 | z-index: 2; |
| 280 | border: 2px solid rgba(0,0,0,0.06); |
| 281 | } |
| 282 | |
| 283 | .node-icon { |
| 284 | font-size: var(--node-icon-size); |
| 285 | line-height: 1; |
| 286 | } |
| 287 | |
| 288 | .node-label { |
| 289 | font-size: var(--node-title-size); |
| 290 | font-weight: 700; |
| 291 | color: var(--text-primary); |
| 292 | line-height: 1.2; |
| 293 | } |
| 294 | |
| 295 | .node-detail { |
| 296 | font-size: var(--node-detail-size); |
| 297 | font-weight: 500; |
| 298 | color: var(--text-secondary); |
| 299 | opacity: 0.8; |
| 300 | } |
| 301 | |
| 302 | .node-step { |
| 303 | position: absolute; |
| 304 | top: -12px; |
| 305 | left: -12px; |
| 306 | width: 32px; |
| 307 | height: 32px; |
| 308 | border-radius: 50%; |
| 309 | background: var(--text-primary); |
| 310 | color: white; |
| 311 | font-size: 14px; |
| 312 | font-weight: 700; |
| 313 | display: flex; |
| 314 | align-items: center; |
| 315 | justify-content: center; |
| 316 | } |
| 317 | |
| 318 | /* Title overlay */ |
| 319 | .diagram-title { |
| 320 | position: absolute; |
| 321 | top: 40px; |
| 322 | left: 50%; |
| 323 | transform: translateX(-50%); |
| 324 | font-size: 32px; |
| 325 | font-weight: 700; |
| 326 | color: var(--text-primary); |
| 327 | z-index: 3; |
| 328 | text-align: center; |
| 329 | } |
| 330 | |
| 331 | .diagram-subtitle { |
| 332 | position: absolute; |
| 333 | top: 82px; |
| 334 | left: 50%; |
| 335 | transform: translateX(-50%); |
| 336 | font-size: 18px; |
| 337 | font-weight: 400; |
| 338 | color: var(--text-secondary); |
| 339 | z-index: 3; |
| 340 | } |
| 341 | </style> |
| 342 | </head> |
| 343 | <body> |
| 344 | <div class="canvas-bg"></div> |
| 345 | |
| 346 | <!-- Optional title --> |
| 347 | <div class="diagram-title">Lead Generation Pipeline</div> |
| 348 | <div class="diagram-subtitle">Apollo → Clay → Claude → Smartlead</div> |
| 349 | |
| 350 | <div class="diagram"> |
| 351 | <!-- SVG arrows connecting nodes --> |
| 352 | <svg class="arrows-layer" viewBox="0 0 1920 1080" xmlns="http://www.w3.org/2000/svg"> |
| 353 | <!-- Arrow from node 1 to node 2 --> |
| 354 | <defs> |
| 355 | <marker id="arrowhead" markerWidth="12" markerHeight="8" refX="10" refY="4" orient="auto"> |
| 356 | <path d="M 0 0 L 12 4 L 0 8 Z" fill="var(--arrow-color)" /> |
| 357 | </marker> |
| 358 | </defs> |
| 359 | <!-- Connection lines drawn between node centers --> |
| 360 | <line x1="380" y1="490" x2="520" y2="490" |
| 361 | stroke="var(--arrow-color)" stroke-width="3" |
| 362 | stroke-dasharray="8,6" marker-end="url(#arrowhead)" /> |
| 363 | <!-- Repeat for each connection --> |
| 364 | </svg> |
| 365 | |
| 366 | <!-- Nodes --> |
| 367 | <div class="node" style="left: 160px; top: 420px; background: var(--node-1);"> |
| 368 | <span class="node-step">1</span> |
| 369 | <span class="node-icon">🔍</span> |
| 370 | <span class="node-label">Find Leads</span> |
| 371 | <span class="node-detail">Apollo</span> |
| 372 | </div> |
| 373 | |
| 374 | <div class="node" style="left: 560px; top: 420px; background: var(--node-2);"> |
| 375 | <span class="node-step">2</span> |
| 376 | <span class="node-icon">✨</span> |
| 377 | <span class="node-label">Enrich Leads</span> |
| 378 | <span class="node-detail">Clay</span> |
| 379 | </div> |
| 380 | |
| 381 | <!-- ... more nodes ... --> |
| 382 | </div> |
| 383 | </body> |
| 384 | </html> |
| 385 | |
| 386 | |
| 387 | ### Layout Algorithms |
| 388 | |
| 389 | **Left-to-Right (default for 4-8 steps):** |
| 390 | |
| 391 | Position each node evenly across the width: |
| 392 | - totalWidth = diagramWidth - (2 * margin) |
| 393 | - nodeSpacing = totalWidth / (nodeCount - 1) |
| 394 | - node[i].x = margin + (i * nodeSpacing) - (nodeWidth / 2) |
| 395 | - node[i].y = (diagramHeight / 2) - (nodeHeight / 2) |
| 396 | |
| 397 | For the default 1920×1080 with 4 nodes: |
| 398 | - margin = 200px |
| 399 | - spacing = ~507px |
| 400 | - y = ~460px (vertically centered) |
| 401 | |
| 402 | |
| 403 | **Top-to-Bottom (3-5 steps):** |
| 404 | |
| 405 | - totalHeight = diagramHeight - (2 * margin) |
| 406 | - nodeSpacing = totalHeight / (nodeCount - 1) |
| 407 | - node[i].y = margin + (i * nodeSpacing) - (nodeHeight / 2) |
| 408 | - node[i].x = (diagramWidth / 2) - (nodeWidth / 2) |
| 409 | |
| 410 | |
| 411 | **Snake/Zigzag (6+ steps):** |
| 412 | |
| 413 | - maxPerRow = 4 |
| 414 | - rowHeight = 250px |
| 415 | - For each row, alternate left-to-right and right-to-left |
| 416 | - Row 0: nodes flow → |
| 417 | - Row 1: nodes flow ← |
| 418 | - Row 2: nodes flow → |
| 419 | - Connect last node of row to first node of next row with vertical arrow |
| 420 | |
| 421 | |
| 422 | ### Arrow Drawing |
| 423 | |
| 424 | Arrows are drawn as SVG lines between node edges: |
| 425 | |
| 426 | |
| 427 | // Calculate arrow coordinates between two nodes |
| 428 | function getArrowCoords(fromNode, toNode, direction) { |
| 429 | if (direction === 'horizontal') { |
| 430 | // Arrow from right edge of fromNode to left edge of toNode |
| 431 | const x1 = fromNode.x + fromNode.width; |
| 432 | const y1 = fromNode.y + fromNode.height / 2; |
| 433 | const x2 = toNode.x; |
| 434 | const y2 = toNode.y + toNode.height / 2; |
| 435 | return { x1, y1, x2, y2 }; |
| 436 | } |
| 437 | if (direction === 'vertical') { |
| 438 | // Arrow from bottom of fromNode to top of toNode |
| 439 | const x1 = fromNode.x + fromNode.width / 2; |
| 440 | const y1 = fromNode.y + fromNode.height; |
| 441 | const x2 = toNode.x + toNode.width / 2; |
| 442 | const y2 = toNode.y; |
| 443 | return { x1, y1, x2, y2 }; |
| 444 | } |
| 445 | } |
| 446 | |
| 447 | |
| 448 | For **curved arrows** (more FigJam-like), use SVG `<path>` with cubic bezier: |
| 449 | |
| 450 | |
| 451 | <path d="M 380,490 C 430,490 470,490 520,490" |
| 452 | stroke="var(--arrow-color)" stroke-width="3" |
| 453 | fill="none" stroke-dasharray="8,6" |
| 454 | marker-end="url(#arrowhead)" /> |
| 455 | |
| 456 | |
| 457 | For **snake layout** vertical connectors between rows: |
| 458 | |
| 459 | |
| 460 | <!-- Vertical connector from end of row 1 to start of row 2 --> |
| 461 | <path d="M 1500,550 C 1500,620 200,620 200,690" |
| 462 | stroke="var(--arrow-color)" stroke-width="3" |
| 463 | fill="none" stroke-dasharray="8,6" |
| 464 | marker-end="url(#arrowhead)" /> |
| 465 | |
| 466 | |
| 467 | ### Branching (Optional) |
| 468 | |
| 469 | If the workflow has conditional branches: |
| 470 | |
| 471 | |
| 472 | Step 3: Qualify leads |
| 473 | ├── Yes → Step 4a: Send to Smartlead |
| 474 | └── No → Step 4b: Add to nurture sequence |
| 475 | |
| 476 | |
| 477 | Render as: |
| 478 | Main node for step 3 |
| 479 | Two arrows diverging from step 3 |
| 480 | Label on each arrow ("Qualified" / "Not Qualified") |
| 481 | Two destination nodes |
| 482 | |
| 483 | |
| 484 | <!-- Branch label on arrow --> |
| 485 | <text x="650" y="400" font-size="14" fill="var(--text-secondary)" |
| 486 | font-family="Inter" font-weight="600">Qualified</text> |
| 487 | |
| 488 | |
| 489 | |
| 490 | |
| 491 | ## Phase 4: Screenshot Generation |
| 492 | |
| 493 | After generating HTML, automatically capture a screenshot. |
| 494 | |
| 495 | ### Using Playwright |
| 496 | |
| 497 | |
| 498 | cd /path/to/skills/create-workflow-diagram |
| 499 | node screenshot-diagram.js <diagram-name> |
| 500 | |
| 501 | |
| 502 | This will: |
| 503 | Open the diagram HTML in a headless browser |
| 504 | Set viewport to the diagram dimensions (e.g., 1920×1080) |
| 505 | Wait for fonts to load |
| 506 | Capture PNG screenshot at 2x resolution |
| 507 | Save to the diagram's `exports/` directory |
| 508 | |
| 509 | ### Installation |
| 510 | |
| 511 | First time setup: |
| 512 | |
| 513 | cd /path/to/skills/create-workflow-diagram |
| 514 | npm install |
| 515 | |
| 516 | |
| 517 | |
| 518 | |
| 519 | ## Phase 5: Delivery |
| 520 | |
| 521 | After the screenshot is generated, present to user: |
| 522 | |
| 523 | |
| 524 | Your workflow diagram is ready! |
| 525 | |
| 526 | HTML source: skills/create-workflow-diagram/[name]/diagram.html |
| 527 | PNG export: skills/create-workflow-diagram/[name]/exports/diagram.png |
| 528 | |
| 529 | Preview: Open diagram.html in a browser to see the full diagram. |
| 530 | |
| 531 | Diagram details: |
| 532 | - 4 workflow steps connected with arrows |
| 533 | - Style: FigJam Classic |
| 534 | - Size: 1920×1080px (landscape) |
| 535 | - File size: ~350 KB |
| 536 | |
| 537 | Want to make any changes? |
| 538 | |
| 539 | |
| 540 | |
| 541 | |
| 542 | ## Node Sizing Rules |
| 543 | |
| 544 | Keep nodes consistent and readable: |
| 545 | |
| 546 | | Element | Size | |
| 547 | |---------|------| |
| 548 | | Node width | 200-240px | |
| 549 | | Node min-height | 110-140px | |
| 550 | | Node padding | 20-28px | |
| 551 | | Icon | 32-40px | |
| 552 | | Label font | 20-24px, weight 700 | |
| 553 | | Detail font | 14-16px, weight 500 | |
| 554 | | Step badge | 28-34px circle | |
| 555 | | Arrow stroke | 2-3px | |
| 556 | | Arrow gap | 60-100px between nodes | |
| 557 | |
| 558 | ### Content Rules |
| 559 | |
| 560 | Each node should have: |
| 561 | **Step number** — Badge in top-left corner |
| 562 | **Icon** — Relevant emoji (auto-assigned from keyword) |
| 563 | **Label** — Action in 2-4 words (e.g., "Find Leads") |
| 564 | **Detail** — Tool/platform name (e.g., "Apollo") — optional |
| 565 | |
| 566 | If a label is too long, truncate or split across lines. Max 2 lines for label. |
| 567 | |
| 568 | |
| 569 | |
| 570 | ## Troubleshooting |
| 571 | |
| 572 | ### Nodes Overlap |
| 573 | **Solution:** Increase `--node-gap` or switch to snake layout for many nodes. |
| 574 | |
| 575 | ### Arrows Misaligned |
| 576 | **Solution:** Recalculate arrow start/end points based on actual node positions. Use the center of the node edge closest to the target. |
| 577 | |
| 578 | ### Fonts Not Loading |
| 579 | **Solution:** Add `await page.waitForLoadState('networkidle')` before screenshot. Increase timeout to 1000ms. |
| 580 | |
| 581 | ### Diagram Too Crowded |
| 582 | **Solution:** Reduce node count by combining steps, switch to a larger canvas size, or use snake layout. |
| 583 | |
| 584 | |
| 585 | |
| 586 | ## Style Quick Reference |
| 587 | |
| 588 | | Preset | Best For | Vibe | |
| 589 | |--------|----------|------| |
| 590 | | FigJam Classic | General workflows | Friendly, colorful | |
| 591 | | Blueprint | Technical processes | Professional, dark | |
| 592 | | Minimal White | Documentation | Clean, corporate | |
| 593 | | Neon Flow | Tech/AI workflows | Futuristic, bold | |
| 594 | | Pastel Board | Presentations | Soft, approachable | |
| 595 | |
| 596 | See STYLE_PRESETS.md for complete styling details. |
| 597 | |
| 598 | |
| 599 | |
| 600 | ## Related Skills |
| 601 | |
| 602 | **create-html-carousel** — For multi-slide LinkedIn carousels |
| 603 | **frontend-slides** — For full HTML presentations |
| 604 | |
| 605 | |
| 606 | |
| 607 | ## Example Session Flow |
| 608 | |
| 609 | User: "Create a diagram for: Find leads on Apollo → Enrich with Clay → Qualify with Claude → Send to Smartlead" |
| 610 | Skill asks: layout direction, size, style |
| 611 | User picks defaults (left-to-right, landscape, FigJam Classic) |
| 612 | Skill parses 4 nodes with auto-icons |
| 613 | Skill generates HTML diagram with positioned nodes and SVG arrows |
| 614 | Skill runs screenshot script |
| 615 | Skill delivers PNG file |
| 616 | User shares in Slack/docs/LinkedIn |
| 617 | |
| 618 | Total time: 2-5 minutes from description to exported diagram. |
| 619 |