look-before-you-leap/skills/svg-art/SKILL.md
Generate distinctive, production-quality SVG artwork inline in code — decorative backgrounds, abstract illustrations, generative patterns, filter effects, section dividers, brand marks, data visualizations, and animated elements. Pure hand-coded SVG with no external image assets or libraries. Use this skill whenever the user asks for: SVG illustrations, decorative SVG backgrounds, SVG patterns, SVG textures, grain/noise effects, generative art, abstract shapes, blob shapes, topographic patterns, mesh gradients, hero illustrations, SVG icons, section dividers, SVG filters, duotone effects, glow effects, SVG data visualization, sparklines, inline charts, or any request where visual art should be created as SVG code rather than imported as an image. Also trigger when frontend-design produces a design that calls for decorative artwork, custom illustrations, or textured backgrounds. Do NOT use for: GSAP-driven SVG animation (use immersive-frontend), raster image editing, CSS-only effects that don't need SVG, or simple geometric shapes that don't require artistic direction.
npx skillsauth add miospotdevteam/claude-control svg-artInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Generate SVG artwork directly in code — no external assets, no image
editors, no libraries. Everything from grain textures to abstract
illustrations to generative compositions, written as inline <svg>
elements or embedded in CSS.
Announce at start: "I'm using the svg-art skill to create this artwork."
This skill operates within the conductor's execution phases:
If frontend-design ran first: inherit its design direction (color
palette, temperature, creative seed). The SVG art should reinforce
the page's aesthetic, not compete with it.
If brainstorming ran first: use its visual direction from design.md.
If the design includes a Creative Brief, read its Intent and Visual
Direction sections before the decision tree below. Let the brief's mood,
conceptual thread, and craftsmanship standard guide which techniques you
choose — don't pick techniques first and retrofit intent afterward.
Answer these questions to determine which references to read:
What kind of SVG art is needed?
│
├── Background texture or pattern?
│ ├── Grain / noise / paper texture → Read: references/filter-recipes.md (§ Texture Filters)
│ ├── Geometric tile pattern (dots, lines, crosses, chevrons) → Read: references/decorative-backgrounds.md (§ Tile Patterns)
│ ├── Organic background (blobs, waves, topographic) → Read: references/decorative-backgrounds.md (§ Organic Backgrounds)
│ └── Mesh gradient or color field → Read: references/decorative-backgrounds.md (§ Gradient Techniques)
│
├── Illustration or decorative element?
│ ├── Hero section artwork → Read: references/illustration-techniques.md (§ Hero Art)
│ ├── Section dividers / separators → Read: references/illustration-techniques.md (§ Section Dividers)
│ ├── Abstract composition → Read: references/illustration-techniques.md (§ Abstract Compositions)
│ ├── Brand mark / logo shape → Read: references/illustration-techniques.md (§ Brand Marks)
│ ├── Icon system → Read: references/illustration-techniques.md (§ Icon Systems)
│ ├── Trust badges / security seals → Read: references/illustration-techniques.md (§ Trust Badges)
│ └── Micro-animations (pulsing, floating, drawing-on) → Read: references/micro-animations.md
│
├── Generative / algorithmic art?
│ ├── Mathematical curves (Lissajous, spirograph, sine composites) → Read: references/generative-patterns.md (§ Curves)
│ ├── Grid-based generative composition → Read: references/generative-patterns.md (§ Grid Art)
│ ├── Organic blobs / fluid shapes → Read: references/generative-patterns.md (§ Organic Shapes)
│ └── Particle fields / dot distributions → Read: references/generative-patterns.md (§ Distributions)
│
├── Filter effect or color treatment?
│ ├── Glow / neon → Read: references/filter-recipes.md (§ Glow)
│ ├── Emboss / metallic / 3D lighting → Read: references/filter-recipes.md (§ Lighting)
│ ├── Duotone / color matrix → Read: references/filter-recipes.md (§ Color)
│ ├── Displacement / distortion → Read: references/filter-recipes.md (§ Displacement)
│ └── Composite effect (layered filters) → Read: references/filter-recipes.md (§ Composites)
│
└── Data visualization?
├── Sparkline / inline chart → Read: references/illustration-techniques.md (§ Data Viz)
└── Decorative data (abstract representation) → Read: references/generative-patterns.md (§ Data-Driven)
Always read: references/svg-gotchas.md before writing any SVG —
it covers viewBox, performance, accessibility, and browser quirks that
cause the most bugs.
These principles apply to ALL SVG art regardless of category. They're what separates professional artwork from random shapes on a canvas.
Not every pixel needs to be filled. The empty areas are as important as the drawn areas — they direct the eye, create breathing room, and establish visual hierarchy. A composition with 40% negative space usually reads better than one with 10%.
Constrain colors deliberately:
If frontend-design set the page palette, pull SVG colors from those
CSS custom properties. The SVG should feel like part of the page, not
pasted on top of it:
<circle fill="var(--primary)" opacity="0.15"/>
<path stroke="var(--accent)" stroke-width="1.5"/>
Pick 1-2 stroke widths for the entire composition and stick to them. Mixing 4 different stroke widths without reason looks sloppy. If you need hierarchy, use opacity or color — not stroke width variation.
Exception: intentional weight contrast (a thick border with thin interior detail) is a valid compositional choice, but it should be a conscious design decision.
When generating paths programmatically, use cubic beziers (C) or
quadratic beziers (Q) instead of sequences of L (line-to) commands.
The difference between a smooth organic blob and a jagged polygon is
curve interpolation.
For computed points, convert to smooth curves:
BAD: M 0,50 L 10,45 L 20,52 L 30,48 L 40,55 ...
GOOD: M 0,50 C 5,47 15,43 20,52 S 35,46 40,55 ...
A single flat shape is rarely interesting. Build depth by layering:
Design for the container, not for a fixed size. Use viewBox to define
the coordinate space, and let the SVG scale to its container. Think about
what happens at different aspect ratios — a hero illustration needs to
work on both 16:9 desktop and 9:16 mobile.
Every element should earn its place. Ask: "Does this shape serve the composition, or am I adding it because the canvas feels empty?" If the answer is the latter, try making existing elements larger or adjusting spacing instead of adding more.
Every SVG should follow this structure:
<svg
viewBox="0 0 800 600"
xmlns="http://www.w3.org/2000/svg"
role="img" <!-- or aria-hidden="true" for decorative -->
aria-labelledby="title desc"
>
<title id="title">Short title</title>
<desc id="desc">Longer description for screen readers</desc>
<defs>
<!-- Gradients, patterns, filters, clip paths -->
</defs>
<!-- Artwork layers, back to front -->
</svg>
For purely decorative SVGs (backgrounds, textures), use:
<svg viewBox="0 0 800 600" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
| Use inline <svg> when | Use CSS background when |
|---|---|
| The SVG is part of page content | It's a repeating pattern |
| It needs to be accessible | It's purely decorative texture |
| It interacts with page layout | It tiles or covers a section |
| It uses page CSS custom properties | It's a static background fill |
CSS background approach:
.textured {
background-image: url("data:image/svg+xml,...");
/* or */
background-image: url("data:image/svg+xml;base64,...");
}
When the page uses CSS custom properties (from frontend-design or
color-palettes.md), reference them in SVG:
<!-- Inline SVG can use CSS custom properties directly -->
<rect fill="var(--surface-1)" />
<circle fill="var(--primary)" opacity="0.2" />
<path stroke="var(--border)" />
For CSS background SVGs (data URIs), bake the actual color values in since CSS variables don't work inside data URIs.
| Element | Budget | Why | |---|---|---| | Path nodes | < 500 per SVG | DOM rendering cost | | Filter primitives | 2-3 per chain | Rasterization is expensive | | Nested filters | Avoid | Compounds the cost exponentially | | Animated elements | < 20 | Each triggers repaints | | Total SVGs on page | < 10 complex ones | Memory + rendering |
If you need more complexity, consider:
<use> for repeated shapesfilter: blur(), opacity()) instead of SVG
filters where possibleWhen the page includes multiple sections (hero, badges, categories, data viz), elements should reveal on scroll rather than appearing all at once on load. This creates a curated, editorial feel — each section earns the user's attention as they scroll to it.
GSAP + ScrollTrigger is the right tool for this when JavaScript is available. Load via CDN:
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/ScrollTrigger.min.js"></script>
gsap.registerPlugin(ScrollTrigger);
// Staggered card entrance (badges, categories, features)
gsap.utils.toArray('.badge-card').forEach((card, i) => {
gsap.from(card, {
y: 40,
opacity: 0,
duration: 0.8,
delay: i * 0.15,
ease: 'power2.out',
scrollTrigger: {
trigger: card,
start: 'top 85%',
toggleActions: 'play none none none'
}
});
});
// Section title fade-in
gsap.utils.toArray('.section-title').forEach(title => {
gsap.from(title, {
y: 20,
opacity: 0,
duration: 0.6,
ease: 'power2.out',
scrollTrigger: { trigger: title, start: 'top 85%' }
});
});
Animate chart elements when they enter the viewport — bars grow to their final width, donut charts draw their arcs, sparklines trace their paths:
// Bar chart: animate width from 0
gsap.utils.toArray('.bar-fill').forEach(bar => {
const targetWidth = bar.style.width;
bar.style.width = '0%';
gsap.to(bar, {
width: targetWidth,
duration: 1.2,
ease: 'power2.out',
scrollTrigger: { trigger: bar, start: 'top 85%' }
});
});
// Donut chart: animate stroke-dashoffset
gsap.from('.donut-value', {
strokeDashoffset: circumference,
duration: 1.5,
ease: 'power2.out',
scrollTrigger: { trigger: '.donut-chart', start: 'top 80%' }
});
This is different from immersive-frontend. Scroll entrance animations are simple reveals (fade + slide, staggered timing). They don't need Three.js, WebGL, or complex scroll choreography. Use GSAP+ScrollTrigger directly in svg-art pages when the design benefits from progressive disclosure on scroll.
Also read references/anti-slop.md for the shared cross-skill banlist
covering typography, color, layout, animation, illustration, and copy.
These produce amateur-looking SVG art — avoid them:
| Anti-pattern | Why it's bad | Do instead | |---|---|---| | Random colors without palette | Looks chaotic, clashes with page | Use 2-4 colors from page tokens | | Perfect symmetry everywhere | Feels mechanical, robotic | Introduce slight asymmetry | | Clipart basic shapes | Circle + rectangle ≠ illustration | Combine shapes, use masks/clips, add curves | | feTurbulence on everything | Visual clutter, not sophistication | Use noise purposefully, mask to areas | | 5+ stacked SVG filters | Performance tanks, muddy results | Limit to 2-3 filter primitives | | Inconsistent stroke widths | Looks sloppy and unintentional | Pick 1-2 weights, stick to them | | No viewBox attribute | Breaks responsive scaling | Always define viewBox | | Ignoring accessibility | Decorative SVGs pollute screen readers | aria-hidden="true" or role="img" + title/desc | | Gradient as the only technique | Browser inconsistency, boring | Combine with shapes, texture, transparency | | Too many competing elements | Eye fatigue, no focal point | 3-5 visual layers max, embrace whitespace | | Line segments for curves | Jagged edges on organic shapes | Use C/Q bezier commands | | Fixed width/height without viewBox | Doesn't scale, breaks on mobile | Use viewBox, let CSS control sizing |
| Skill | Relationship |
|---|---|
| frontend-design | Provides design direction (palette, temperature, creative seed). SVG art inherits these decisions. frontend-design may invoke svg-art when a design needs illustration. |
| immersive-frontend | Handles GSAP-driven SVG animation (MorphSVG, DrawSVG, motion paths). svg-art creates the artwork; immersive-frontend animates it. |
| color-palettes.md | SVG art should pull colors from the page's palette, not invent its own. |
| Situation | Read |
|---|---|
| Noise, grain, glow, emboss, duotone, displacement | references/filter-recipes.md |
| Mathematical curves, grids, blobs, distributions | references/generative-patterns.md |
| Tile patterns, organic backgrounds, gradients | references/decorative-backgrounds.md |
| Hero art, dividers, compositions, icons, badges, data viz | references/illustration-techniques.md |
| Pulsing, floating, drawing-on, orbital, hover animations | references/micro-animations.md |
| viewBox, performance, accessibility, browser quirks | references/svg-gotchas.md |
development
Use after discovery to write implementation plans with TDD-granularity steps. Produces plan.json (immutable definition, frozen after approval), progress.json (mutable execution state), and masterPlan.md (user-facing proposal for Orbit review). Every step is one component/feature; TDD rhythm (test, verify fail, implement, verify pass, commit) lives in its progress items. Consumes discovery.md from exploration phase. Make sure to use this skill whenever the user says discovery is done, exploration is finished, discovery.md is ready, or asks to write/create/draft the implementation plan — even if they don't mention plan.json or masterPlan.md by name. Also use when the user references completed exploration findings, blast radius analysis, or consumer mappings and wants them converted into actionable steps. Do NOT use when: the user says 'just do it' or 'no plan', resuming or executing an existing plan, during exploration or brainstorming (discovery not yet complete), debugging, or code review.
tools
End-to-end webapp testing with Playwright MCP integration. Use when: writing Playwright tests, E2E testing, browser testing, webapp testing, visual regression testing, accessibility testing with axe-core, testing user flows through a web UI, verifying frontend behavior in a real browser. Integrates with test-driven-development skill for test-first browser tests and engineering-discipline for verification. Do NOT use when: unit tests only (no browser UI involved), API tests without UI, mobile native testing (use react-native-mobile), testing CLI tools, or writing backend-only integration tests.
development
Test-Driven Development workflow enforcing red-green-refactor cycles. Use when writing new features, adding behavior, or implementing functions where tests should drive design. Requires explicit test-first prompting because Claude naturally writes implementation first. Integrates with writing-plans (TDD rhythm in Progress items) and engineering-discipline (verification). Do NOT use when: fixing a bug in existing tested code (use systematic-debugging), writing tests for existing untested code (characterization tests are a different workflow), refactoring without behavior change (use refactoring), or the project has no test infrastructure.
development
Use when encountering any bug, test failure, or unexpected behavior. Enforces root cause investigation before fixes. Four phases: investigate, analyze patterns, form hypotheses, implement. Prevents guess-and-check thrashing. Use ESPECIALLY when under pressure or when 'just one quick fix' seems obvious. Do NOT use for: learning unfamiliar APIs (use exploration), performance optimization without a specific regression, or code review without a reported bug.