Svg infographic
Practical, portable skills for agentic coding workflows — clearer diagrams, checked claims, safer GitHub releases, natural EN↔KO writing.
npx -y skills add kyungseo/skillstead --skill svg-infographicAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 29 days oldThe repository was created 29 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
What its author says it does
Copied from the file, not written here
Author technical/structured SVG infographics and diagrams, then render them to crisp PNG with a headless browser. Best for architecture diagrams, topology maps, flows, before/after comparisons, nested/onion layer models, roadmaps, decision matrices, and social-ready technical one-pagers. Prefers clean line icons in soft tinted circles. First-class Korean/CJK text. Includes an opt-in "tidy hand-drawn" sketch preset (paper background, Korean handwriting font, rough strokes, highlighter). Not for photo-heavy or illustration-heavy graphics, statistical charts, or mascot/character illustration.
The file declares its own license as LICENSE.txt. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
21.5 KB, as published. Nobody here has run it
svg-infographic
Use this skill when the user wants a technical or structured infographic/diagram from a description, or asks to export an SVG to PNG.
Good for: architecture diagrams, cloud/network topology, component/layer diagrams, before/after, process/data flow, nested "onion" models, roadmap/risk maps, decision matrices, social-ready technical one-pagers.
Do not use for: photo/illustration-heavy marketing graphics; data-accurate statistical charts (bar/line/scatter/heatmap — use a chart tool); mascots or character illustration; custom logo design or bespoke icon design.
Nuances: a simple qualitative 2×2/3×3 matrix or a status-count badge is fine (it's structure, not a data-accurate chart). Using the built-in line-icon set is expected and encouraged — the non-goal is designing new brand marks, not using icons. A hand-drawn / sketchnote feel is supported as the opt-in sketch preset (references/sketch.md) — "tidy hand-drawn": hand-drawn surface, computed layout; mascots and scene illustration stay out of scope.
Package map — this skill ships as a directory; load the parts on demand:
| File | When to read |
|---|---|
references/archetypes.md | Always, before the layout pass — the chosen archetype's layout skeleton, premium recipe, and per-type checks |
references/authoring.md | Always, before writing SVG — detailed geometry/connector/panel/emphasis/color rules and the full icon set; also the manual render fallback |
references/sketch.md | Only when the user asks for a hand-drawn / sketchnote / 손글씨 feel — the opt-in sketch preset (paper, handwriting font, rough filters, highlighter) |
scripts/render.mjs | Canonical renderer (Node 18+, stdlib only) — lint gate → browser discovery → 2× render → exact IHDR verification in one entrypoint; works from any shell incl. Windows CMD/PowerShell without Git Bash |
scripts/render.sh | Thin POSIX/Git-Bash wrapper that delegates to render.mjs (adds only the no-Node diagnostics) |
scripts/check-svg.mjs | Source lint gate (Node 18+, standard library only; no npm install) — the renderer runs it automatically; run it directly while iterating on the SVG source |
0. Preflight — confirm, then offer to change
Before drawing, confirm visual intent, audience, output ratio, and language. Then state the defaults (§6) and note the user can change any of them. Propose an output directory inside the current project and confirm before writing files.
Before promising automated lint or using the bundled render.sh, check whether node --version reports Node.js
18 or newer.
Node is not required to install or discover this skill, or to author an editable SVG. It is required for the
bundled source lint and therefore for a machine-linted handoff.
If Node 18+ is missing:
- Detect the operating system and an available trusted package manager. Confirm that its candidate package provides Node 18+ before showing the exact install command and asking in the conversation language: "Would you like me to install Node.js 18+ and continue with automated validation?"
- Install only after the user explicitly approves that system change. Use the detected package manager; do not
substitute a remote
curl | shinstaller. If the command needs elevated privileges, surface that approval rather than hiding it. - Verify
node --versionafter installation, then resume the source lint and render workflow. If installation fails or still provides an older version, report that result and do not retry through a different source without another approval. - If the user declines, or no safe package-manager route is available, keep the pre-v0.7.1 quality floor:
complete every item in the manual source checklist, do not invoke
render.sh, and use the Node-free Chromium path inreferences/authoring.md§8 to render a 2× PNG. Verify its dimensions and complete the §7 visual QA. State: "Automated source lint was not run because Node.js 18+ was unavailable. The manual source checklist and PNG render/visual QA passed." Never label this fallback as machine-linted. - Only if a Chromium-based browser is also unavailable, deliver an SVG-only draft and state that neither automated source lint nor PNG visual verification ran.
Classify the input mode first (it sets how much to ask before drawing):
- brief-first — only a topic/goal is given → ask up to ~3 focused questions (audience, key message, ratio), then propose the structure.
- source-first — a doc, notes, or paste is provided → summarize the source and agree the key message before drawing; don't transcribe it box-for-box.
- research-first — "just draft it" → state your assumptions (and any missing data) up front; external lookup may be unavailable, so proceed from the given material plus explicit assumptions.
Lead with the conclusion. Prefer a conclusion-style title over a topic label — "Phased Migration Cuts Cutover Risk" beats "Migration Plan". Sketch the one-to-two-sentence story spine (context → tension → resolution) before placing boxes. Exception: for a named pattern or archetype showcase, a concise topic/pattern title is fine as long as the subtitle or <desc> carries the conclusion.
1. Pick an archetype (shape first)
Pick from the content signal, then read that archetype's section in references/archetypes.md — it has the layout skeleton, the premium recipe, and the checks that prevent that type's common failures.
| Content signal | Archetype |
|---|---|
| systems/components and their links | Topology / component |
| ordered steps or handoffs | Flow (swimlane variant for parallel rails) |
| approval / gate on a simple request path | Approval / sequence-lite |
| options, trade-offs, qualitative scoring | Decision / risk matrix, or Cards |
| old vs new | Before / after |
| layered capability or containment | Layer stack, or Nested / onion |
| time, phases, milestones | Roadmap / timeline |
| a few headline items or numbers | Cards / KPI stat grid (not a chart) |
2. Layout pass — numbers before SVG (required)
This step is the main defense against render-fix loops. Do the arithmetic first; never place a box at an eyeballed coordinate. Produce a short numeric plan (a scratch table of coordinates is enough), then author the SVG from those numbers.
- Canvas. Pick a preset: compact doc 680w · wide architecture 1400×900 · 16:9 slide 1600×900 · social portrait 1080×1350 (4:5). Height is flexible for the doc width. Fix outer margins (≥ 40px wide canvases, ≥ 24px at 680w).
- Regions. Split the canvas top→bottom: header (title + subtitle), one band per section, optional footer row. Assign each region a
yrange and keep 32–48px between bands. - Grid arithmetic. For each row of n cards inside a region: choose
cardWandgap(gutter 24–32px), then verify the last edge before drawing:start + (n−1)·(cardW+gap) + cardW ≤ region_right − padding. Same check vertically for columns/stacks. If it doesn't fit: shrinkcardW/gap, wrap to a second row, or widen the canvas — decide now, not after a render. - Text budget. For each box, set lines × chars/line from the box width: ~28–36 Latin chars per line at body size, Korean ≈ 60% of that; 2–3 lines max per box. Edit the copy to fit the budget before writing SVG — abbreviate long tokens now. SVG has no auto-wrap; every line you plan here becomes one
<tspan>. - Type scale — unified across the diagram (never vary per box):
- 1080-wide social: H1 46 / section 24 / card title 25 / body 19 / caption 16
- 1400–1600 wide: H1 40–44 / section 22 / card title 20–22 / body 16–17 / caption 13–14
- 680-wide docs: title 22 / box label 14 / caption 11
- Icons. Derive every icon-circle center from card geometry (e.g.
cy = card_y + card_h/2), never a hand-tuned per-language offset. EN and KO variants must share the same formulas. - Connector corridors. Budget connectors like cards:
corridor = target_visual_left − source_visual_right, and subtract the marker's real footprint (markerUnits="strokeWidth"multiplies it by the stroke width — formulas inauthoring.md§3). If no readable shaft survives, choose a compact arrow, a transition glyph, or a reflow now, not after a render.
3. Author the SVG — core rules
Read references/authoring.md for the detailed rules and the reusable icon set. The render-critical core:
- Root:
<svg xmlns viewBox="0 0 W H" width=W height=H role="img" style="font-family:Pretendard,'Apple SD Gothic Neo','Malgun Gothic','Noto Sans KR',sans-serif">with<title>/<desc>. The stack covers Korean/CJK on macOS/Windows/Linux; on Linux installfonts-noto-cjkif Korean renders as tofu (□). - Color tokens in one
<style>block — recolor the whole diagram by editing only this block. Colors encode role, not decoration:
<style>
svg{ --bg:#FFFFFF; --ink:#1F2733; --muted:#5B6675; --hair:#D6E0EC; --primary:#1F6FB2;
--edge-fill:#E8F1FB; --edge-line:#1F6FB2; --edge-ink:#124267; /* entry / network */
--api-fill:#ECEBFB; --api-line:#534AB7; --api-ink:#3C3489; /* app / accent */
--k8s-fill:#E7F5EF; --k8s-line:#0F7A5F; --k8s-ink:#085041; /* compute / ok */
--data-fill:#F1F1EE; --data-line:#7A8398; --data-ink:#3F4453; /* data / neutral */
--card:#F7FAFD; }
.on-accent{ fill:#FFFFFF }
</style>
- Boxes: rounded rect
rx="8"(wide bandsrx="12–22"), hairline borderstroke-width:1. Each box = tinted fill + same-family border + same-family text (one semantic color family per box). - Vertical centering: center text with
dominant-baseline="central"andyat the box's vertical center. Two lines straddle the center: title atcenter−11, sub atcenter+10, bothcentral. Never rely on the default alphabetic baseline for box labels — it sits high. - Wrapping: one planned line = one
<tspan x=.. dy=..>; keep to the §2 text budget. - Arrows: define one
<marker>arrowhead, usemarker-end. Solid = sync/request, dashed (stroke-dasharray="5 4") = async/batch/private. The default head is an open-V stroked marker sized by visible geometry:visible ≈ markerWidth × 8/12, aim visible ≈3× the shaft →markerWidth ≈ 4.5 × shaft(sizing table inauthoring.md§3) — filled triangles only as a deliberate choice with the same visible-extent arithmetic.markerUnits="userSpaceOnUse"is mandatory on every referenced marker and the lint gate enforces it — the defaultmarkerUnits="strokeWidth"multiplies the head by the stroke width. SetrefXso the tip lands on the path endpoint; leave an 8–12px gap between tip and target box and keep a visible shaft behind the head; pick each connector's form (standard / compact / curved / transition glyph / reflow) from the corridor budget, and prefer the gentle single-bend curve recipe when boxes sit at different heights (authoring.md§3). - On-accent text is light: any label on a saturated fill uses
class="on-accent"(white/near-white) — never dark text on a mid/dark accent, and never rely on a blankettext{fill}rule to sort it out. - Emphasis toolkit: stroke + soft shadow + a number/status badge + a corner label + a filled icon badge. No top accent bar on cards (corner-smear and badge-collision failure modes — details and narrow exception in
authoring.md). - Icon-first (default on): a line icon in a soft tinted circle (
r≈34–38, tint#E3EEF8) per card/node, icon ~40px via<use>, recolor withstyle="color:#…". Number badge only when sequence or cross-reference matters — never icon + redundant number.
4. Pre-render checklist (source-level — run before every render)
Run the lint gate first for a verified handoff — it machine-checks the deterministic subset of this list (ids/references, root viewBox, marker units and footprint, high-confidence Latin/CJK text overflow) with file/line, measured values, and a suggested fix per finding. If Node 18+ is unavailable, follow the §0 approval/fallback branch; the manual fallback does not count as a machine-linted handoff.
node scripts/check-svg.mjs diagram.svg # render.sh runs this again as a hard gate
Hard errors must be fixed before rendering (render.sh refuses at exit 5). Warnings are low-confidence estimates — disposition each one deliberately (fix it, or verify it in the §7 PNG pass); never treat a warning as a pass. Then walk the rest of the checklist — layout arithmetic and design judgement stay yours:
- Containment re-check: the §2 last-edge/bottom-edge arithmetic still holds for what you actually wrote (cards, arrows, badges, labels — including any element you added while authoring). Judge visual bounds, not just the fill rect — half the stroke width, shadow spread, and children drawn outside the base rect count; in a padded panel, an edge that merely touches the parent is a fail, not a pass (formula in
authoring.md§1). - Text budget: no
<text>/<tspan>line exceeds its planned chars/line; box labels usedominant-baseline="central"with computedy. Pill/badge fit: every pill/badge background covers its actual label width plus ≥ 14–16px padding per side, and EN/KO shared geometry fits the wider language's label (formula inauthoring.md§2). - References resolve: every
<use href="#id">matches a defined<symbol id>; everymarker-endreferences a defined<marker>; no danglingurl(#…). - Contrast classes: every label on a saturated fill carries
class="on-accent"; no blankettext{fill}rule that overrides on-accent labels via inheritance. - Corner clearance: badges / status labels / corner icons in the same card corner region have ≥ 20–24px between bounding boxes.
- EN/KO parity: if generating both, the two variants share identical geometry formulas — only text (and text budget) differs.
- Root sanity:
viewBoxmatches the intended W×H;<title>/<desc>present; font stack on the root. - Connector budget: every connector's corridor and marker footprint are computed (§2.7); each standard arrow keeps a visible shaft (≥ 12–16px, not hidden under a card/panel by paint order) plus the 8–12px tip gap — a head-only arrow is a fail even when the gap is right; tight corridors carry a deliberate form choice (compact arrow, transition glyph, or reflow —
authoring.md§3); EN/KO share connector geometry and semantics.
5. Render to PNG (2×)
The canonical renderer is render.mjs (Node 18+ stdlib): it runs the §4 source lint as a hard gate (exit 5 =
lint errors), discovers a Chromium-based browser (PATH plus the documented known paths), discloses the exact
executable/version, renders at 2×, and verifies the PNG IHDR dimensions exactly. It needs no shell beyond Node —
on Windows run it directly from CMD or PowerShell, verbatim, with no PowerShell scripting and no Git Bash. Use the
path of the skills root this package is actually installed under.
Claude Code install (.claude\skills):
node .claude\skills\svg-infographic\scripts\render.mjs out\diagram.svg
Codex install (.agents\skills):
node .agents\skills\svg-infographic\scripts\render.mjs out\diagram.svg
On POSIX/Git-Bash environments the familiar wrapper delegates to the same core (exit 6 = Node 18+ missing — return to the §0 approval/fallback branch rather than bypassing the gate):
bash scripts/render.sh diagram.svg # → diagram.png (2×)
bash scripts/render.sh diagram.svg out.png --transparent
SVG_INFOGRAPHIC_BROWSER=<executable> overrides discovery for owner-approved retries — it must still point at a
Chromium-based browser.
Keep wrapper/intermediate files in the session scratchpad, not the repo. In native PowerShell/CMD the canonical path is still node scripts/render.mjs (above) — the manual fallback in references/authoring.md §8 exists only for the §0 no-Node branch. If no Chromium-based browser is available at all, deliver the SVG only and state the limitation.
The documented Chromium path is the canonical renderer. Non-negotiables:
- Record the exact browser executable/version (render.mjs prints a
renderer:line — include it in the handoff) and the render command. - On Windows the canonical
node render.mjspath needs neither PowerShell scripting nor Git Bash and probes the four Program Files known paths itself; do not conclude "no browser" from a shell probe alone — run the canonical entrypoint, and only its exit-2 candidate report counts as a discovery failure. - If the browser launch is denied by a sandbox boundary, render.mjs stops and prints the exact same render command — hand it to the owner for approved outside-sandbox execution; do not silently switch renderer.
- Never substitute ImageMagick, resvg, an app visualization helper, or any other renderer and label the result as a Chromium render; never post-process PNG pixels. If the canonical render remains unavailable, stop with the editable SVG and an explicit unverified-PNG/SVG-only limitation.
6. Defaults to state (and let the user change)
- Style: muted technical · light background · icons = soft circular bg + line icon. Opt-in alternative: sketch preset (tidy hand-drawn — paper, Korean handwriting font, rough strokes; see
references/sketch.md) when the user asks for that feel - Font stack: Pretendard, Apple SD Gothic Neo, Malgun Gothic, Noto Sans KR, sans-serif (covers macOS/Windows/Linux CJK)
- Changeable: brand color, ratio (docs vs 4:5 social), dark mode (override the same CSS vars under
@media (prefers-color-scheme:dark); PNG renders light unless forced), icon style, Korean/English, SVG-only vs SVG+PNG - Optional attribution/footer layer: off by default. On request, add a small footer strip (source, author, or date) as its own bottom layer — a labeled footer, not a watermark laid over the content.
7. Verify the PNG (quality bar)
The pre-render checklist covered the source; now check what only the pixels show:
- Rendering: no text overflow or clipped glyphs; text vertically centered in its box; correct Korean/CJK rendering (no tofu); PNG is exactly 2× the viewBox (render.sh reports this); icons visible (no blank circles); labels on accent fills read clearly (AA-like separation).
- Containment (visual): every child sits inside its container plus inner padding — scan the PNG for anything touching or crossing a panel edge; an element can spill without touching any text.
- Connectors: every arrow reads as shaft + head — no head-only arrows and no head buried under a panel or card; the head joins its shaft cleanly and neither touches the target border nor floats detached; head/shaft proportion reads natural — a visible head ≈4× its shaft width or more is a fail for newly authored diagrams, and a visible head below ≈2.5× reads weak (aim ≈3×; the lint computes the visible ratio from the marker's glyph extent —
authoring.md§3). Pre-contract legacy examples keep their approved visuals under an explicitdata-lint-allow="marker-footprint"exception — never add that attribute to silence a new diagram. A curve keeps one readable bend (an accidental S-shape is a fail); a transition glyph reads as flow, not as an icon or play button. - Two-pass inspection (required): first view the PNG at fit-to-page scale — every major stage connector must be immediately recognizable as an arrow (not a hairline or a tiny decorative glyph), and the reading order must survive the zoom-out; then inspect close-up for connector/text detail. A lint warning that maps to a hard visual rule (head proportion, containment) is never accepted just because the artifact is otherwise attractive.
- Explicit fail examples (each has shipped as a defect at least once): an edge label crossed by its own path or ambiguous about which route it labels; icon/text overlap or a feedback loop crowded against cards; a major-flow connector that disappears at fit-to-page scale; a rendered EN/KO pair whose CJK glyphs break or whose connectors differ between languages.
- Message: the archetype fits the content; one clear reading order; the title states a conclusion, not just a topic; text density stays low per box; any matrix/labels read unambiguously; depth and language fit the stated audience.
- The SVG stays editable — tokens in one
<style>block, no flattened or rasterized text. The source SVG is authoritative: never patch or redraw a connector only in the PNG.
If a check fails: fix the SVG source, re-run §4, re-render. Track which §4 item would have caught it — if none, the checklist is missing a rule.
8. Output & handoff
Save both the SVG (editable source of truth) and the PNG (2× export for slides/docs/social). The renderer uses locally installed fonts, so Korean/CJK falls back to the platform default (Apple SD Gothic Neo on macOS, Malgun Gothic on Windows, Noto Sans KR on Linux) — verify no tofu in the PNG.