SVG Design System Integration Requires Raw HSL Extraction, Not CSS Classes
The Assumption That Breaks
When you build a data visualization in React with d3 or Canvas, you expect to use the same design tokens as the rest of your app. The oompa-landing component graph uses Tailwind utilities everywhere else —bg-factory-gold-500, text-factory-chocolate-700 — so the natural instinct is to apply the same pattern to SVG node colors:
Why It Fails
1. SVG Scope Isolation
SVG elements exist in their own paint server context. They don’t inherit CSS styles the way HTML elements do. Tailwind’s utility classes generate CSS rules, but SVG presentation attributes (fill, stroke, opacity) are not CSS properties — they’re XML attributes with their own resolution rules.
2. Presentation Attributes vs CSS Properties
| Attribute | Type | Styling Method |
|---|---|---|
fill="red" | Presentation attribute | Inline value only |
style="color: red" | Inline style | CSS property |
class="text-red-500" | Tailwind utility | CSS rule in stylesheet |
fill-factory-gold-500 class generates:
3. CSS Custom Properties in SVG Context
Even if you try to use CSS custom properties directly:- The SVG namespace has stricter rules about variable resolution
- Some browsers resolve
var(--factory-gold-500)as a string literal, not a computed value - The computed value is
hsl(38 92% 50%), but the attribute receives the literal string"var(--factory-gold-500)"
The Solution: Extract Raw HSL Strings
Instead of relying on Tailwind utilities, extract the underlying HSL values and use them as inline attributes:Maintenance Cost
This approach requires an extra maintenance step:- Design system owner updates
globals.css:--factory-gold-500: 38 92% 50%→38 92% 48% - Frontend engineer must manually update the
getCategoryColormap - No automation to sync the values
Lessons for Future Data Visualization Work
- Don’t assume CSS utilities work in SVG. Test early with a prototype.
- Extract tokens at the component level. Create a
getToken()function that returns raw values. - Document the mapping. Include source line numbers or token names in comments.
- Plan for dark mode. If your design system has light + dark variants, extract both at module load time.
- Use Tailwind for non-SVG markup only. Reserve CSS utilities for HTML elements where they reliably work.
Platform Impact
This pattern should be documented as a required doctrine for any future data visualization components (dashboards, analytics, network graphs, timelines). Including it in the codebase review checklist will prevent repeated rediscovery of this CSS-in-SVG footgun.Related session: Command graph redesign (oompa.tools/commands) — 31 slash commands visualized as chocolate/gold pill-shaped nodes with full-name labels. The design system integration challenge revealed this pattern.