Produce a visual that reads as designed: one takeaway, specific elements,
one highlighter, in the active design system. Free-hand SVG from a language model collides once
it has more than a handful of elements, and the popular "no Mermaid slop"
skills turn out to have the model hand-place every coordinate — so here the
model does not write geometry. It writes a JSON spec and a compiler
places it: build_svg.py puts cards (flow, stack, hub, grid,
compare, timeline, matrix) on a fixed grid with capacity checks;
arch_svg.py lets Graphviz lay out an architecture diagram (groups,
cards with outline icons, pill tags, sticky notes, orthogonal connectors,
numbered step badges plus a legend) and paints it. Both read the design
system (--design-system, $DIAGRAM_DESIGN_SYSTEM, ./design-system.md,
else the built-in Studio look; see diagram-design-system) and tag every
element with data-step, so diagram-animate can turn the result into a GIF.
The render is still inspected, because fonts vary by machine. This skill runs
inside one fixed budget.
When NOT to use
- The destination is a README, docs page, or PR →
mermaid-draw. - The idea has no format yet →
diagram-brief(it routes here when the destination is a feed, article, or slide). - The takeaway depends on labeled, directed edges between more than three
entities — the archetypes cannot express them (see "What an archetype can
say" in
references/style-rules.md) →mermaid-drawor a handoff. - Reviewing or fixing an existing image →
diagram-review. - App icons →
icon-draw(icon-designer-skills); decks, charts, characters, brand scenes → the handoffs indiagram-brief.
Budget (the whole skill runs inside it)
- Three mutations of the spec per request — a capacity fix, a lint fix, and a regeneration by the drawer all count.
- One review pass, plus at most one re-check after its FIX or REDRAW.
- Every mutation is followed by compile, lint, and render before anything is delivered. At the cap, deliver with residual findings; do not loop.
Workflow
-
Brief. Use the brief path you were given. Without one, read
diagram-design/brief.mdonly if its takeaway matches the request; otherwise write a 5-line quick brief (takeaway, audience, destination, entities, archetype) todiagram-design/<slug>/brief.md. Never draw without a stated takeaway. -
Choose the archetype by the relation in the takeaway, not its nouns —
flow(strict order),cycle(it loops back),before_after(a change of state),decision(if/otherwise),tree(breaks down into),swimlane(hand-offs between actors),layers(contains / runs inside),stack(tiers),hub(one center),compare(2–3 options),matrix(groups × items, a ruled table),grid(exactly 2×2),quadrant(3–10 items placed on two axes),timeline(dated milestones),metrics(the numbers are the point: KPI tiles, ranked bars) — seereferences/spec-options.md. A type none of these draws goes tomermaid-drawor diagram-design (routing indiagram-brief), never into a near archetype. Or an architecture spec when the takeaway needs systems, boundaries and an ordered flow between them (arch_svg.py --sampleprints a working one). Pick the canvas (social1200×627 for LinkedIn/X/OG,square1080×1080,wide1920×1080 for slides — or--canvasto override;{"w","h"}for a wide panorama to camera-pan;arch_svg.py/pipeline_svg.py --canvasfit a finished diagram and warn under 12 px). Figures are always inline: the title is the SVG<title>/alt text, never drawn. Pick aniconper card fromicons.py --list(35 outline icons, line or isometric-line by the design system). Readreferences/style-rules.mdonce per session; it is what the drawer and the reviewer both follow. If the brief's required entities exceed the archetype's capacity, split the brief or route tomermaid-draw— dropping a required entity is a fidelity failure, not a fix. -
Get the spec from a drawer — an in-harness subagent, or a separate session through
acpx(an installed Claude Code or Codex; useful for a different model or another harness). The acpx path, every permission denied, run from an empty temp directory so no project context is loaded:python3 "${CLAUDE_SKILL_DIR}/scripts/spawn_drawer.py" --brief diagram-design/<slug>/brief.md \ --out-dir diagram-design/<slug> --name <slug> --agent claude # or --agent codexIt writes
<slug>.prompt.md,<slug>.spec.json, and compiles<slug>.svg. Exit 3 meansacpxis not installed: give the prompt file to a subagent (or answer it yourself), save the JSON as<slug>.spec.json, then compile:python3 "${CLAUDE_SKILL_DIR}/scripts/build_svg.py" diagram-design/<slug>/<slug>.spec.json --out diagram-design/<slug>/<slug>.svgArchitecture specs compile with
arch_svg.py SPEC.json --out X.svg(needs Graphvizdot). Add--design-system PATHto either compiler to restyle. How a system works, step by step (question → model → answers → query → spec → rendered result), is a pipeline explainer:pipeline_svg.py SPEC.json --out X.svglays columns of labelled code/JSON panels (with bracket callouts to coloured notes), tall processor boxes with latency captions, a rendered mini-dashboard and a timing bar left to right —pipeline_svg.py --sampleprints one; animate it withdiagram-animate --preset pipeline. Lint it with--diagram --max-words 400(it is read over time). A capacity ERROR ("does not fit", "needs 2-6 items") means shorten labels or remove elements the takeaway does not need; never shrink text. -
Lint and render with the sibling review scripts (install with
npx skills add Paldom/diagram-skills --skill diagram-reviewif missing):python3 "${CLAUDE_SKILL_DIR}/../diagram-review/scripts/svg_lint.py" diagram-design/<slug>/<slug>.svg # --diagram for architecture python3 "${CLAUDE_SKILL_DIR}/../diagram-review/scripts/render.py" diagram-design/<slug>/<slug>.svgRead both PNGs (delivery size and half size). Fix by editing the spec and recompiling — never the SVG — counting each fix against the budget.
-
Review. Invoke
diagram-reviewwith the SVG, the PNGs, and the brief path. On FIX edit the spec, on REDRAW change archetype or cut content and return to step 3; either way recompile, lint, render, then one re-check at most. -
Deliver (and offer
diagram-animatefor a GIF/MP4) the SVG and the delivery-size PNG paths (feeds want PNG; LinkedIn and X do not accept SVG), the spec, the verdict, and anything left out of the brief. Never commit or push.
Output spec
diagram-design/<slug>/<slug>.svg— one file,viewBoxat a preset size, rootfont-family,<title>and<desc>, passessvg_lint.pywith 0 errors.diagram-design/<slug>/renders/<slug>/<slug>-<w>.pngat two widths.diagram-design/<slug>/<slug>.spec.json— the editable source of truth.- The review verdict and residual warnings, in one short block.
Spec options and generated visuals
Card anatomy, every optional spec key (eyebrow, numbered, takeaway,
item chips, the hub bus layout, tiered compare with S/M/L badges and a
complexity scale, the matrix archetype) and the Gemini icon/hero workflow
(scripts/gemini_icon.py, needs GEMINI_API_KEY and --allow-network) are in
references/spec-options.md — read it when the brief needs one of them.
Gotchas
- The spec is the artifact. Editing the SVG by hand reintroduces the failure the compiler removed; regenerate from the spec.
- Capacity errors usually mean the brief carries more than one point. Split into two cards when cutting would drop something the takeaway needs.
acpxglobal flags go before the agent name (acpx --deny-all ... claude exec);spawn_drawer.pyalready does this and uses--cwdon an empty directory. The adapters must be installed and logged in; nothing is downloaded here. What leaves the machine: the prompt file plus whatever the adapter attaches on its own (session metadata) — to that agent's provider.- The drawer prompt asks for content, not compliance — rules live in the compiler
and the lint, because format-restricted prompts measurably degrade reasoning
(reference in
references/style-rules.md). - The neumorph lift is the one filter allowed (
<filter data-ds="neumorph">); the accent is a fill behind ink — the lint errors if it becomes text or a line. - Fonts are a system stack declared on the root; no CDN fonts, so text metrics differ slightly between machines. The lint's fitting is approximate; the half-size render is the check that counts.
- Drawing the spec yourself is fine — the compiler and the reviewer, not the drawer's identity, are the gate.