From finma-course-tools
Review a hand-crafted SVG diagram for common visual issues — label/arrow overlaps, fan symmetry, consistent arrow-to-box clearances, box row/column alignment, legend/colour consistency, and semantic arrow direction. Invoke after creating or editing any SVG under `**/assets/*.svg` (the PostToolUse hook will remind you).
How this skill is triggered — by the user, by Claude, or both
Slash command
/finma-course-tools:svg-reviewThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Catch clutter and asymmetry **before** the user has to point them out. Every item in this checklist is something a previous iteration got wrong; adding checks here is how we learn.
Catch clutter and asymmetry before the user has to point them out. Every item in this checklist is something a previous iteration got wrong; adding checks here is how we learn.
**/assets/*.svg (the hook nudges you).Before any geometry math, render the SVG to a PNG and actually look at it. The checklist below approximates bounding boxes by hand; a raster lets you see the real layout and catch overlaps, clipping, and imbalance the math misses.
rsvg-convert -o /tmp/svg-review.png path/to/diagram.svg
Then Read /tmp/svg-review.png to view it. Form a first impression — what looks
crowded, crooked, or off — then use the checklist below to confirm and to quantify
each issue with coordinates.
rsvg-convert (from librsvg2-bin) is installed by the course devcontainer. If
it's missing (command -v rsvg-convert returns nothing), fall back in order:
resvg diagram.svg /tmp/svg-review.png, cairosvg diagram.svg -o /tmp/svg-review.png,
or inkscape --export-type=png -o /tmp/svg-review.png diagram.svg. If none are
available, say you're reviewing analytically (no raster) and proceed with the
bounding-box math alone.
text-anchor is start (default), middle, or end, and whether dominant-baseline is set (middle/central centres on y).font-size="N", width ≈ 0.55 * N per character (italic slightly narrower, bold slightly wider); height ≈ N. If dominant-baseline is unset, the baseline sits at y and text extends ≈ 0.75N above and 0.25N below.For each <text> whose position is near any <line>, <polyline>, or <path>:
x, y, text-anchor, dominant-baseline, and character count.(x1,y1) to (x2,y2), compute x(t) = x1 + t*(x2-x1), y(t) = y1 + t*(y2-y1) for t ∈ [0,1].y-range; check whether the resulting x values fall inside the label's x-range. If they do — the line crosses the label.A fan is a group of 2+ connectors that share a common endpoint (convergent) or common origin (divergent). M3→M5 and M4→M5 form a convergent fan; M5→M6 and M5→M7 a divergent one.
x).|dx| and |dy| of each arrow in the fan must match, so the fan is mirror-symmetric.x.For every connector whose endpoint lands on or near a box:
y) and column (same x or same x + width/2).y (rows) or centre x (columns), and the same width/height.If the diagram includes a legend describing colour meanings:
fill or stroke on shapes.For each labelled arrow:
Eyeball-level checks:
python3 -c "import xml.etree.ElementTree as ET; ET.parse('<path>'); print('OK')"Report each finding as:
If everything passes, say so in one line. Do not fabricate issues.
Every time the user flags a visual issue that this checklist missed, add a new check here. The checklist is meant to grow with the pattern library of real problems, not with imagined edge cases.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub howesrichard/finma-course-tools --plugin finma-course-tools