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
  1. Run the line below. It pulls the whole folder into ~/.claude/skills/generative-ui, including the files SKILL.md points to.
  2. Describe your job in plain words. Claude Code follows the skill from there.
Claude Code — installs the whole folder, not just SKILL.md
npx degit himself65/finance-skills/plugins/ui-tools/skills/generative-ui#main ~/.claude/skills/generative-ui

For 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)
  1. On this page open ⋯ → Download .md.
  2. Save it as SKILL.md in a folder, zip the folder, then Customize → Skills → + → Create skill → Upload a skill.
  3. Pick the file and Save. Claude shows the name and description and runs a security scan.
  4. Check the skill is switched on.
  5. Start a new chat and describe your job in plain words. The AI follows the skill from there.
ChatGPT or another app
  1. ChatGPT: make a Project and paste it into Instructions.
  2. 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.
Step-by-step guide with screenshots · Ask in the forum

Paste into Claude, ChatGPT or Cursor.

Source of Generative UI Skill

Show the full text290 lines
namedescription
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 style not bold
  • No <!DOCTYPE>, <html>, <head>, or <body> — just content fragments
  • No position: fixed — use normal-flow layouts
  • No tabs, carousels, or display: none sections 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), or Intl.NumberFormat
CDN Allowlist (CSP-enforced)

External resources may ONLY load from:

  • cdnjs.cloudflare.com
  • cdn.jsdelivr.net
  • unpkg.com
  • esm.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: -$5M not $-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, or th)
  • Use dominant-baseline="central" for vertical text centering in boxes
  • Connector paths need fill="none" (SVG defaults to fill: 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:

  1. What the widget shows
  2. How to interact with it (which controls do what)
  3. 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 rules
  • references/svg_and_diagrams.md — SVG viewBox setup, font calibration, pre-built classes, flowchart/structural/illustrative diagram patterns with examples
  • references/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---
2name: generative-ui
3description: >
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 
18This 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 
26Route 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 
49Output 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 
78External resources may ONLY load from:
79- `cdnjs.cloudflare.com`
80- `cdn.jsdelivr.net`
81- `unpkg.com`
82- `esm.sh`
83 
84All 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 
94All 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 
103A 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 
109The `show_widget` tool is built into claude.ai — no activation needed. Pass your widget code directly:
110 
111```json
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 
123For 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 
129For charts, use `onload` callback pattern to handle script load ordering:
130 
131```html
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>
151function 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}
183if (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 
199For flowcharts and diagrams, use SVG with pre-built classes:
200 
201```svg
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 
241For interactive explainers (sliders, live calculations, inline SVG):
242 
243```html
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>
261function initChart() {
262 // slider logic, chart rendering, sendPrompt() for follow-ups
263}
264if (window.Chart) initChart();
265</script>
266```
267 
268Use `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 
274After rendering the widget, briefly explain:
2751. What the widget shows
2762. How to interact with it (which controls do what)
2773. One key insight from the data
278 
279Keep 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 
289Read the relevant reference file when you need specific design tokens, SVG coordinate math, or Chart.js configuration details.
290 

Discussion

Alternatives

Also in Interface designSee all 106 in Design →
Frontend designGuidance for distinctive, intentional visual design when building new UI or reshaping an existing one. Helps with aesthetic direction, typography, and making choices that don't read as templated defaults.Design & UI · Apache-2.0ImpeccableUse when the user wants to design, redesign, shape, critique, audit, polish, clarify, distill, harden, optimize, adapt, animate, colorize, extract, or otherwise improve a frontend interface. Covers websites, landing pages, dashboards, product UI, app shells, components, forms, settings, onboarding, and empty states. Handles UX review, visual hierarchy, information architecture, cognitive load, accessibility, performance, responsive behavior, theming, anti-patterns, typography, fonts, spacing, layout, alignment, color, motion, micro-interactions, UX copy, error states, edge cases, i18n, and reusable design systems or tokens. Also use for bland designs that need to become bolder or more delightful, loud designs that should become quieter, live browser iteration on UI elements, or ambitious visual effects that should feel technically extraordinary. Not for backend-only or non-UI tasks.Design & UI · Apache-2.0Apple designApple's approach to interface design and fluid, physical motion, translated for the web. Use when building or reviewing gesture-driven UI, spring animations, drag/swipe/sheet interactions, momentum and interruptible transitions, translucent materials and depth, typography (optical sizing, tracking, leading), reduced-motion, or the design foundations (feedback, spatial consistency, restraint) behind Apple-style interfaces.Design & UI · MITBuilding AnimationsBuild an animation from scratch, making the decisions in the order that determines whether it feels right — should it animate at all, what purpose, which tool, which properties, which curve and duration, how it interrupts, how it exits. Writes the implementation. Use when asked to animate something, add motion, make a component feel alive, or build a transition. For critiquing existing motion use review-animations; for auditing a whole codebase use improve-animations.Design & UI · MIT