Generative UI Skill
Design system and guidelines for Claude's built-in generative UI — the show_widget tool that renders interactive HTML/SVG widgets inline in claude.ai conversations.
How to use it
Claude Code
- Run the line below. It pulls the whole folder into
~/.claude/skills/generative-ui, including the files SKILL.md points to. - Describe your job in plain words. Claude Code follows the skill from there.
npx degit himself65/finance-skills/plugins/ui-tools/skills/generative-ui#main ~/.claude/skills/generative-uiFor one project only, change the path to .claude/skills/generative-ui. This skill also uses Chart.js, esm.sh — copying SKILL.md alone won't be enough. See the folder on GitHub.
Claude (web or desktop app)
- On this page open ⋯ → Download .md.
- Save it as SKILL.md in a folder, zip the folder, then Customize → Skills → + → Create skill → Upload a skill.
- Pick the file and Save. Claude shows the name and description and runs a security scan.
- Check the skill is switched on.
- Start a new chat and describe your job in plain words. The AI follows the skill from there.
ChatGPT or another app
- ChatGPT: make a Project and paste it into Instructions.
- Neither? Paste it at the top of a new chat — it works for that chat.
Not working?
- Check which app you pasted it into — the steps above name the right one.
- Some skills need the paid tier of Claude or ChatGPT.
Paste into Claude, ChatGPT or Cursor.
Source of Generative UI Skill
Show the full text290 lines
| name | description |
|---|---|
| generative-ui | > Design system and guidelines for Claude's built-in generative UI — the show_widget tool that renders interactive HTML/SVG widgets inline in claude.ai conversations. This skill provides the complete Anthropic "Imagine" design system so Claude produces high-quality widgets without needing to call read_me first. Use this skill whenever the user asks to visualize data, create an interactive chart, build a dashboard, render a diagram, draw a flowchart, show a mockup, create an interactive explainer, or produce any visual content beyond plain text or markdown. Triggers include: "show me", "visualize", draw", "chart", "dashboard", "diagram", "flowchart", "widget", "interactive", "mockup", "illustrate", explain how X works" (with visual), or any request for visual/interactive output. Also triggers when the user wants to display financial data visually, create comparison grids, or build tools with sliders, toggles, or live-updating displays. |
Generative UI Skill
This skill contains the complete design system for Claude's built-in show_widget tool — the generative UI feature that renders interactive HTML/SVG widgets inline in claude.ai conversations. The guidelines below are the actual Anthropic "Imagine — Visual Creation Suite" design rules, extracted so you can produce high-quality widgets directly without needing the read_me setup call.
How it works: On claude.ai, Claude has access to the show_widget tool which renders raw HTML/SVG fragments inline in the conversation. This skill provides the design system, templates, and patterns to use it well.
Step 1: Pick the Right Visual Type
Route on the verb, not the noun. Same subject, different visual depending on what was asked:
| User says | Type | Format |
|---|---|---|
| "how does X work" | Illustrative diagram | SVG |
| "X architecture" | Structural diagram | SVG |
| "what are the steps" | Flowchart | SVG |
| "explain compound interest" | Interactive explainer | HTML |
| "compare these options" | Comparison grid | HTML |
| "show revenue chart" | Chart.js chart | HTML |
| "create a contact card" | Data record | HTML |
| "draw a sunset" | Art/illustration | SVG |
Step 2: Build the Widget
Structure (strict order)
<style> → HTML content → <script>
Output streams token-by-token. Styles must exist before the elements they target, and scripts must run after the DOM is ready.
Philosophy
- Seamless: Users shouldn't notice where the host UI ends and your widget begins
- Flat: No gradients, mesh backgrounds, noise textures, or decorative effects. Clean flat surfaces
- Compact: Show the essential inline. Explain the rest in text
- Text goes in your response, visuals go in the tool — all explanatory text, descriptions, and summaries must be written as normal response text OUTSIDE the tool call. The tool output should contain ONLY the visual element
Core Rules
- No
<!-- comments -->or/* comments */(waste tokens, break streaming) - No font-size below 11px
- No emoji — use CSS shapes or SVG paths
- No gradients, drop shadows, blur, glow, or neon effects
- No dark/colored backgrounds on outer containers (transparent only — host provides the bg)
- Typography: two weights only: 400 regular, 500 medium. Never use 600 or 700. Headings: h1=22px, h2=18px, h3=16px — all font-weight 500. Body text=16px, weight 400, line-height 1.7
- Sentence case always. Never Title Case, never ALL CAPS
- No mid-sentence bolding — entity names go in
code stylenot bold - No
<!DOCTYPE>,<html>,<head>, or<body>— just content fragments - No
position: fixed— use normal-flow layouts - No tabs, carousels, or
display: nonesections during streaming - No nested scrolling — auto-fit height
- Corners:
border-radius: var(--border-radius-lg)for cards,var(--border-radius-md)for elements - No rounded corners on single-sided borders (border-left, border-top)
- Round every displayed number — use
Math.round(),.toFixed(n), orIntl.NumberFormat
CDN Allowlist (CSP-enforced)
External resources may ONLY load from:
cdnjs.cloudflare.comcdn.jsdelivr.netunpkg.comesm.sh
All other origins are blocked — the request silently fails.
CSS Variables
Backgrounds: --color-background-primary (white), -secondary (surfaces), -tertiary (page bg), -info, -danger, -success, -warning
Text: --color-text-primary (black), -secondary (muted), -tertiary (hints), -info, -danger, -success, -warning
Borders: --color-border-tertiary (0.15α, default), -secondary (0.3α, hover), -primary (0.4α), semantic -info/-danger/-success/-warning
Typography: --font-sans, --font-serif, --font-mono
Layout: --border-radius-md (8px), --border-radius-lg (12px), --border-radius-xl (16px)
All auto-adapt to light/dark mode.
Dark mode is mandatory — every color must work in both modes:
- In HTML: always use CSS variables for text. Never hardcode colors like
color: #333 - In SVG: use pre-built color classes (
c-blue,c-teal, etc.) — they handle light/dark automatically - Mental test: if the background were near-black, would every text element still be readable?
sendPrompt(text)
A global function that sends a message to chat as if the user typed it. Use it when the user's next step benefits from Claude thinking. Handle filtering, sorting, toggling, and calculations in JS instead.
Step 3: Render with show_widget
The show_widget tool is built into claude.ai — no activation needed. Pass your widget code directly:
{
"title": "snake_case_widget_name",
"widget_code": "<style>...</style>\n<div>...</div>\n<script>...</script>"
}
| Parameter | Type | Required | Description |
|---|---|---|---|
title |
string | Yes | Snake_case identifier for the widget |
widget_code |
string | Yes | HTML or SVG code. For SVG: start with <svg>. For HTML: content fragment |
For SVG output: start widget_code with <svg — it will be auto-detected and wrapped appropriately.
Step 4: Chart.js Template
For charts, use onload callback pattern to handle script load ordering:
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px;">
<div style="background: var(--color-background-secondary); border-radius: var(--border-radius-md); padding: 1rem;">
<div style="font-size: 13px; color: var(--color-text-secondary);">Label</div>
<div style="font-size: 24px; font-weight: 500;" id="stat1">—</div>
</div>
</div>
<div style="position: relative; width: 100%; height: 300px; margin-top: 1rem;">
<canvas id="myChart"></canvas>
</div>
<div style="display: flex; align-items: center; gap: 12px; margin-top: 1rem;">
<label style="font-size: 14px; color: var(--color-text-secondary);">Parameter</label>
<input type="range" min="0" max="100" value="50" id="param" step="1" style="flex: 1;" />
<span style="font-size: 14px; font-weight: 500; min-width: 32px;" id="param-out">50</span>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.5.1/chart.umd.js" onload="initChart()"></script>
<script>
function initChart() {
const slider = document.getElementById('param');
const out = document.getElementById('param-out');
let chart = null;
function update() {
const val = parseFloat(slider.value);
out.textContent = val;
document.getElementById('stat1').textContent = val.toFixed(1);
const labels = [], data = [];
for (let x = 0; x <= 100; x++) {
labels.push(x);
data.push(x * val / 100);
}
if (chart) chart.destroy();
chart = new Chart(document.getElementById('myChart'), {
type: 'line',
data: { labels, datasets: [{ data, borderColor: '#7F77DD', borderWidth: 2, pointRadius: 0, fill: false }] },
options: {
responsive: true,
maintainAspectRatio: false,
plugins: { legend: { display: false } },
scales: { x: { grid: { display: false } } }
}
});
}
slider.addEventListener('input', update);
update();
}
if (window.Chart) initChart();
</script>
Chart.js rules:
- Canvas cannot resolve CSS variables — use hardcoded hex
- Set height ONLY on the wrapper div, never on canvas itself
- Always
responsive: true, maintainAspectRatio: false - Always disable default legend, build custom HTML legends
- Number formatting:
-$5Mnot$-5M(negative sign before currency symbol) - Use
onload="initChart()"on CDN script tag +if (window.Chart) initChart();as fallback
Step 5: SVG Diagram Template
For flowcharts and diagrams, use SVG with pre-built classes:
<svg width="100%" viewBox="0 0 680 H">
<defs>
<marker id="arrow" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M2 1L8 5L2 9" fill="none" stroke="context-stroke" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</marker>
</defs>
<!-- Single-line node (44px tall) -->
<g class="node c-blue" onclick="sendPrompt('Tell me more about this')">
<rect x="250" y="40" width="180" height="44" rx="8" stroke-width="0.5"/>
<text class="th" x="340" y="62" text-anchor="middle" dominant-baseline="central">Step one</text>
</g>
<!-- Connector arrow -->
<line x1="340" y1="84" x2="340" y2="120" class="arr" marker-end="url(#arrow)"/>
<!-- Two-line node (56px tall) -->
<g class="node c-teal" onclick="sendPrompt('Explain this step')">
<rect x="230" y="120" width="220" height="56" rx="8" stroke-width="0.5"/>
<text class="th" x="340" y="140" text-anchor="middle" dominant-baseline="central">Step two</text>
<text class="ts" x="340" y="158" text-anchor="middle" dominant-baseline="central">Processes the input</text>
</g>
</svg>
SVG rules:
- ViewBox always 680px wide (
viewBox="0 0 680 H"). Set H to fit content + 40px padding - Safe area: x=40 to x=640, y=40 to y=(H-40)
- Pre-built classes:
t(14px),ts(12px secondary),th(14px medium 500),box,node,arr,c-{color} - Every
<text>element must carry a class (t,ts, orth) - Use
dominant-baseline="central"for vertical text centering in boxes - Connector paths need
fill="none"(SVG defaults tofill: black) - Stroke width: 0.5px for borders and edges
- Make all nodes clickable:
onclick="sendPrompt('...')"
Step 6: Interactive Explainer Template
For interactive explainers (sliders, live calculations, inline SVG):
<div style="display: flex; align-items: center; gap: 12px; margin: 0 0 1.5rem;">
<label style="font-size: 14px; color: var(--color-text-secondary);">Years</label>
<input type="range" min="1" max="40" value="20" id="years" style="flex: 1;" />
<span style="font-size: 14px; font-weight: 500; min-width: 24px;" id="years-out">20</span>
</div>
<div style="display: flex; align-items: baseline; gap: 8px; margin: 0 0 1.5rem;">
<span style="font-size: 14px; color: var(--color-text-secondary);">$1,000 →</span>
<span style="font-size: 24px; font-weight: 500;" id="result">$3,870</span>
</div>
<div style="margin: 2rem 0; position: relative; height: 240px;">
<canvas id="chart"></canvas>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.5.1/chart.umd.js" onload="initChart()"></script>
<script>
function initChart() {
// slider logic, chart rendering, sendPrompt() for follow-ups
}
if (window.Chart) initChart();
</script>
Use sendPrompt() to let users ask follow-ups: sendPrompt('What if I increase the rate to 10%?')
Step 7: Respond to the User
After rendering the widget, briefly explain:
- What the widget shows
- How to interact with it (which controls do what)
- One key insight from the data
Keep it concise — the widget speaks for itself.
Reference Files
references/design_system.md— Complete color palette (9 ramps × 7 stops), CSS variables, UI component patterns, metric cards, layout rulesreferences/svg_and_diagrams.md— SVG viewBox setup, font calibration, pre-built classes, flowchart/structural/illustrative diagram patterns with examplesreferences/chart_js.md— Chart.js configuration, script load ordering, canvas sizing, legend patterns, dashboard layout
Read the relevant reference file when you need specific design tokens, SVG coordinate math, or Chart.js configuration details.
| 1 | |
| 2 | name generative-ui |
| 3 | description > |
| 4 | Design system and guidelines for Claude's built-in generative UI — the show_widget tool that renders |
| 5 | interactive HTML/SVG widgets inline in claude.ai conversations. This skill provides the complete |
| 6 | Anthropic "Imagine" design system so Claude produces high-quality widgets without needing to call |
| 7 | read_me first. Use this skill whenever the user asks to visualize data, create an interactive chart, |
| 8 | build a dashboard, render a diagram, draw a flowchart, show a mockup, create an interactive explainer, |
| 9 | or produce any visual content beyond plain text or markdown. Triggers include: "show me", "visualize", |
| 10 | "draw", "chart", "dashboard", "diagram", "flowchart", "widget", "interactive", "mockup", "illustrate", |
| 11 | "explain how X works" (with visual), or any request for visual/interactive output. Also triggers |
| 12 | when the user wants to display financial data visually, create comparison grids, or build tools |
| 13 | with sliders, toggles, or live-updating displays. |
| 14 | |
| 15 | |
| 16 | # Generative UI Skill |
| 17 | |
| 18 | This skill contains the complete design system for Claude's built-in `show_widget` tool — the generative UI feature that renders interactive HTML/SVG widgets inline in claude.ai conversations. The guidelines below are the actual Anthropic "Imagine — Visual Creation Suite" design rules, extracted so you can produce high-quality widgets directly without needing the `read_me` setup call. |
| 19 | |
| 20 | **How it works**: On claude.ai, Claude has access to the `show_widget` tool which renders raw HTML/SVG fragments inline in the conversation. This skill provides the design system, templates, and patterns to use it well. |
| 21 | |
| 22 | |
| 23 | |
| 24 | ## Step 1: Pick the Right Visual Type |
| 25 | |
| 26 | Route on the **verb**, not the noun. Same subject, different visual depending on what was asked: |
| 27 | |
| 28 | | User says | Type | Format | |
| 29 | |---|---|---| |
| 30 | | "how does X work" | Illustrative diagram | SVG | |
| 31 | | "X architecture" | Structural diagram | SVG | |
| 32 | | "what are the steps" | Flowchart | SVG | |
| 33 | | "explain compound interest" | Interactive explainer | HTML | |
| 34 | | "compare these options" | Comparison grid | HTML | |
| 35 | | "show revenue chart" | Chart.js chart | HTML | |
| 36 | | "create a contact card" | Data record | HTML | |
| 37 | | "draw a sunset" | Art/illustration | SVG | |
| 38 | |
| 39 | |
| 40 | |
| 41 | ## Step 2: Build the Widget |
| 42 | |
| 43 | ### Structure (strict order) |
| 44 | |
| 45 | |
| 46 | <style> → HTML content → <script> |
| 47 | |
| 48 | |
| 49 | Output streams token-by-token. Styles must exist before the elements they target, and scripts must run after the DOM is ready. |
| 50 | |
| 51 | ### Philosophy |
| 52 | |
| 53 | **Seamless**: Users shouldn't notice where the host UI ends and your widget begins |
| 54 | **Flat**: No gradients, mesh backgrounds, noise textures, or decorative effects. Clean flat surfaces |
| 55 | **Compact**: Show the essential inline. Explain the rest in text |
| 56 | **Text goes in your response, visuals go in the tool** — all explanatory text, descriptions, and summaries must be written as normal response text OUTSIDE the tool call. The tool output should contain ONLY the visual element |
| 57 | |
| 58 | ### Core Rules |
| 59 | |
| 60 | No `<!-- comments -->` or `/* comments */` (waste tokens, break streaming) |
| 61 | No font-size below 11px |
| 62 | No emoji — use CSS shapes or SVG paths |
| 63 | No gradients, drop shadows, blur, glow, or neon effects |
| 64 | No dark/colored backgrounds on outer containers (transparent only — host provides the bg) |
| 65 | **Typography**: two weights only: 400 regular, 500 medium. Never use 600 or 700. Headings: h1=22px, h2=18px, h3=16px — all font-weight 500. Body text=16px, weight 400, line-height 1.7 |
| 66 | **Sentence case** always. Never Title Case, never ALL CAPS |
| 67 | No mid-sentence bolding — entity names go in `code style` not **bold** |
| 68 | No `<!DOCTYPE>`, `<html>`, `<head>`, or `<body>` — just content fragments |
| 69 | No `position: fixed` — use normal-flow layouts |
| 70 | No tabs, carousels, or `display: none` sections during streaming |
| 71 | No nested scrolling — auto-fit height |
| 72 | Corners: `border-radius: var(--border-radius-lg)` for cards, `var(--border-radius-md)` for elements |
| 73 | No rounded corners on single-sided borders (border-left, border-top) |
| 74 | **Round every displayed number** — use `Math.round()`, `.toFixed(n)`, or `Intl.NumberFormat` |
| 75 | |
| 76 | ### CDN Allowlist (CSP-enforced) |
| 77 | |
| 78 | External resources may ONLY load from: |
| 79 | `cdnjs.cloudflare.com` |
| 80 | `cdn.jsdelivr.net` |
| 81 | `unpkg.com` |
| 82 | `esm.sh` |
| 83 | |
| 84 | All other origins are blocked — the request silently fails. |
| 85 | |
| 86 | ### CSS Variables |
| 87 | |
| 88 | **Backgrounds**: `--color-background-primary` (white), `-secondary` (surfaces), `-tertiary` (page bg), `-info`, `-danger`, `-success`, `-warning` |
| 89 | **Text**: `--color-text-primary` (black), `-secondary` (muted), `-tertiary` (hints), `-info`, `-danger`, `-success`, `-warning` |
| 90 | **Borders**: `--color-border-tertiary` (0.15α, default), `-secondary` (0.3α, hover), `-primary` (0.4α), semantic `-info/-danger/-success/-warning` |
| 91 | **Typography**: `--font-sans`, `--font-serif`, `--font-mono` |
| 92 | **Layout**: `--border-radius-md` (8px), `--border-radius-lg` (12px), `--border-radius-xl` (16px) |
| 93 | |
| 94 | All auto-adapt to light/dark mode. |
| 95 | |
| 96 | **Dark mode is mandatory** — every color must work in both modes: |
| 97 | In HTML: always use CSS variables for text. Never hardcode colors like `color: #333` |
| 98 | In SVG: use pre-built color classes (`c-blue`, `c-teal`, etc.) — they handle light/dark automatically |
| 99 | Mental test: if the background were near-black, would every text element still be readable? |
| 100 | |
| 101 | ### `sendPrompt(text)` |
| 102 | |
| 103 | A global function that sends a message to chat as if the user typed it. Use it when the user's next step benefits from Claude thinking. Handle filtering, sorting, toggling, and calculations in JS instead. |
| 104 | |
| 105 | |
| 106 | |
| 107 | ## Step 3: Render with `show_widget` |
| 108 | |
| 109 | The `show_widget` tool is built into claude.ai — no activation needed. Pass your widget code directly: |
| 110 | |
| 111 | |
| 112 | { |
| 113 | "title": "snake_case_widget_name", |
| 114 | "widget_code": "<style>...</style>\n<div>...</div>\n<script>...</script>" |
| 115 | } |
| 116 | |
| 117 | |
| 118 | | Parameter | Type | Required | Description | |
| 119 | |---|---|---|---| |
| 120 | | `title` | string | Yes | Snake_case identifier for the widget | |
| 121 | | `widget_code` | string | Yes | HTML or SVG code. For SVG: start with `<svg>`. For HTML: content fragment | |
| 122 | |
| 123 | For SVG output: start `widget_code` with `<svg` — it will be auto-detected and wrapped appropriately. |
| 124 | |
| 125 | |
| 126 | |
| 127 | ## Step 4: Chart.js Template |
| 128 | |
| 129 | For charts, use `onload` callback pattern to handle script load ordering: |
| 130 | |
| 131 | |
| 132 | <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px;"> |
| 133 | <div style="background: var(--color-background-secondary); border-radius: var(--border-radius-md); padding: 1rem;"> |
| 134 | <div style="font-size: 13px; color: var(--color-text-secondary);">Label</div> |
| 135 | <div style="font-size: 24px; font-weight: 500;" id="stat1">—</div> |
| 136 | </div> |
| 137 | </div> |
| 138 | |
| 139 | <div style="position: relative; width: 100%; height: 300px; margin-top: 1rem;"> |
| 140 | <canvas id="myChart"></canvas> |
| 141 | </div> |
| 142 | |
| 143 | <div style="display: flex; align-items: center; gap: 12px; margin-top: 1rem;"> |
| 144 | <label style="font-size: 14px; color: var(--color-text-secondary);">Parameter</label> |
| 145 | <input type="range" min="0" max="100" value="50" id="param" step="1" style="flex: 1;" /> |
| 146 | <span style="font-size: 14px; font-weight: 500; min-width: 32px;" id="param-out">50</span> |
| 147 | </div> |
| 148 | |
| 149 | <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.5.1/chart.umd.js" onload="initChart()"></script> |
| 150 | <script> |
| 151 | function initChart() { |
| 152 | const slider = document.getElementById('param'); |
| 153 | const out = document.getElementById('param-out'); |
| 154 | let chart = null; |
| 155 | |
| 156 | function update() { |
| 157 | const val = parseFloat(slider.value); |
| 158 | out.textContent = val; |
| 159 | document.getElementById('stat1').textContent = val.toFixed(1); |
| 160 | |
| 161 | const labels = [], data = []; |
| 162 | for (let x = 0; x <= 100; x++) { |
| 163 | labels.push(x); |
| 164 | data.push(x * val / 100); |
| 165 | } |
| 166 | |
| 167 | if (chart) chart.destroy(); |
| 168 | chart = new Chart(document.getElementById('myChart'), { |
| 169 | type: 'line', |
| 170 | data: { labels, datasets: [{ data, borderColor: '#7F77DD', borderWidth: 2, pointRadius: 0, fill: false }] }, |
| 171 | options: { |
| 172 | responsive: true, |
| 173 | maintainAspectRatio: false, |
| 174 | plugins: { legend: { display: false } }, |
| 175 | scales: { x: { grid: { display: false } } } |
| 176 | } |
| 177 | }); |
| 178 | } |
| 179 | |
| 180 | slider.addEventListener('input', update); |
| 181 | update(); |
| 182 | } |
| 183 | if (window.Chart) initChart(); |
| 184 | </script> |
| 185 | |
| 186 | |
| 187 | **Chart.js rules:** |
| 188 | Canvas cannot resolve CSS variables — use hardcoded hex |
| 189 | Set height ONLY on the wrapper div, never on canvas itself |
| 190 | Always `responsive: true, maintainAspectRatio: false` |
| 191 | Always disable default legend, build custom HTML legends |
| 192 | Number formatting: `-$5M` not `$-5M` (negative sign before currency symbol) |
| 193 | Use `onload="initChart()"` on CDN script tag + `if (window.Chart) initChart();` as fallback |
| 194 | |
| 195 | |
| 196 | |
| 197 | ## Step 5: SVG Diagram Template |
| 198 | |
| 199 | For flowcharts and diagrams, use SVG with pre-built classes: |
| 200 | |
| 201 | |
| 202 | <svg width="100%" viewBox="0 0 680 H"> |
| 203 | <defs> |
| 204 | <marker id="arrow" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse"> |
| 205 | <path d="M2 1L8 5L2 9" fill="none" stroke="context-stroke" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> |
| 206 | </marker> |
| 207 | </defs> |
| 208 | |
| 209 | <!-- Single-line node (44px tall) --> |
| 210 | <g class="node c-blue" onclick="sendPrompt('Tell me more about this')"> |
| 211 | <rect x="250" y="40" width="180" height="44" rx="8" stroke-width="0.5"/> |
| 212 | <text class="th" x="340" y="62" text-anchor="middle" dominant-baseline="central">Step one</text> |
| 213 | </g> |
| 214 | |
| 215 | <!-- Connector arrow --> |
| 216 | <line x1="340" y1="84" x2="340" y2="120" class="arr" marker-end="url(#arrow)"/> |
| 217 | |
| 218 | <!-- Two-line node (56px tall) --> |
| 219 | <g class="node c-teal" onclick="sendPrompt('Explain this step')"> |
| 220 | <rect x="230" y="120" width="220" height="56" rx="8" stroke-width="0.5"/> |
| 221 | <text class="th" x="340" y="140" text-anchor="middle" dominant-baseline="central">Step two</text> |
| 222 | <text class="ts" x="340" y="158" text-anchor="middle" dominant-baseline="central">Processes the input</text> |
| 223 | </g> |
| 224 | </svg> |
| 225 | |
| 226 | |
| 227 | **SVG rules:** |
| 228 | ViewBox always 680px wide (`viewBox="0 0 680 H"`). Set H to fit content + 40px padding |
| 229 | Safe area: x=40 to x=640, y=40 to y=(H-40) |
| 230 | Pre-built classes: `t` (14px), `ts` (12px secondary), `th` (14px medium 500), `box`, `node`, `arr`, `c-{color}` |
| 231 | Every `<text>` element must carry a class (`t`, `ts`, or `th`) |
| 232 | Use `dominant-baseline="central"` for vertical text centering in boxes |
| 233 | Connector paths need `fill="none"` (SVG defaults to `fill: black`) |
| 234 | Stroke width: 0.5px for borders and edges |
| 235 | Make all nodes clickable: `onclick="sendPrompt('...')"` |
| 236 | |
| 237 | |
| 238 | |
| 239 | ## Step 6: Interactive Explainer Template |
| 240 | |
| 241 | For interactive explainers (sliders, live calculations, inline SVG): |
| 242 | |
| 243 | |
| 244 | <div style="display: flex; align-items: center; gap: 12px; margin: 0 0 1.5rem;"> |
| 245 | <label style="font-size: 14px; color: var(--color-text-secondary);">Years</label> |
| 246 | <input type="range" min="1" max="40" value="20" id="years" style="flex: 1;" /> |
| 247 | <span style="font-size: 14px; font-weight: 500; min-width: 24px;" id="years-out">20</span> |
| 248 | </div> |
| 249 | |
| 250 | <div style="display: flex; align-items: baseline; gap: 8px; margin: 0 0 1.5rem;"> |
| 251 | <span style="font-size: 14px; color: var(--color-text-secondary);">$1,000 →</span> |
| 252 | <span style="font-size: 24px; font-weight: 500;" id="result">$3,870</span> |
| 253 | </div> |
| 254 | |
| 255 | <div style="margin: 2rem 0; position: relative; height: 240px;"> |
| 256 | <canvas id="chart"></canvas> |
| 257 | </div> |
| 258 | |
| 259 | <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.5.1/chart.umd.js" onload="initChart()"></script> |
| 260 | <script> |
| 261 | function initChart() { |
| 262 | // slider logic, chart rendering, sendPrompt() for follow-ups |
| 263 | } |
| 264 | if (window.Chart) initChart(); |
| 265 | </script> |
| 266 | |
| 267 | |
| 268 | Use `sendPrompt()` to let users ask follow-ups: `sendPrompt('What if I increase the rate to 10%?')` |
| 269 | |
| 270 | |
| 271 | |
| 272 | ## Step 7: Respond to the User |
| 273 | |
| 274 | After rendering the widget, briefly explain: |
| 275 | What the widget shows |
| 276 | How to interact with it (which controls do what) |
| 277 | One key insight from the data |
| 278 | |
| 279 | Keep it concise — the widget speaks for itself. |
| 280 | |
| 281 | |
| 282 | |
| 283 | ## Reference Files |
| 284 | |
| 285 | `references/design_system.md` — Complete color palette (9 ramps × 7 stops), CSS variables, UI component patterns, metric cards, layout rules |
| 286 | `references/svg_and_diagrams.md` — SVG viewBox setup, font calibration, pre-built classes, flowchart/structural/illustrative diagram patterns with examples |
| 287 | `references/chart_js.md` — Chart.js configuration, script load ordering, canvas sizing, legend patterns, dashboard layout |
| 288 | |
| 289 | Read the relevant reference file when you need specific design tokens, SVG coordinate math, or Chart.js configuration details. |
| 290 |
Discussion
Browse more free Claude skills or everything in Design.