Generative UI Skill This skill contains the complete design system for Claude's built-in 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 setup call. How it works : On claude.ai, Claude has access to the 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:…

+ Math.abs(v) + 'M'\n```\n\n---\n\n## Legends\n\nAlways disable Chart.js default and build custom HTML:\n\n```js\nplugins: { legend: { display: false } }\n```\n\n```html\n\u003cdiv style=\"display: flex; flex-wrap: wrap; gap: 16px; margin-bottom: 8px; font-size: 12px; color: var(--color-text-secondary);\">\n \u003cspan style=\"display: flex; align-items: center; gap: 4px;\">\n \u003cspan style=\"width: 10px; height: 10px; border-radius: 2px; background: #3266ad;\">\u003c/span>Chrome 65%\n \u003c/span>\n \u003cspan style=\"display: flex; align-items: center; gap: 4px;\">\n \u003cspan style=\"width: 10px; height: 10px; border-radius: 2px; background: #73726c;\">\u003c/span>Safari 18%\n \u003c/span>\n\u003c/div>\n```\n\nInclude the value/percentage in each label when the data is categorical (pie, donut, single-series bar). Position the legend above the chart (`margin-bottom`) or below (`margin-top`) — not inside the canvas.\n\n---\n\n## Dashboard Layout\n\nWrap summary numbers in metric cards above the chart:\n\n```html\n\u003cdiv style=\"display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; margin-bottom: 1rem;\">\n \u003cdiv style=\"background: var(--color-background-secondary); border-radius: var(--border-radius-md); padding: 1rem;\">\n \u003cdiv style=\"font-size: 13px; color: var(--color-text-secondary);\">Revenue\u003c/div>\n \u003cdiv style=\"font-size: 24px; font-weight: 500;\">$2.4M\u003c/div>\n \u003c/div>\n \u003cdiv style=\"background: var(--color-background-secondary); border-radius: var(--border-radius-md); padding: 1rem;\">\n \u003cdiv style=\"font-size: 13px; color: var(--color-text-secondary);\">Growth\u003c/div>\n \u003cdiv style=\"font-size: 24px; font-weight: 500; color: var(--color-text-success);\">+12%\u003c/div>\n \u003c/div>\n\u003c/div>\n\n\u003cdiv style=\"position: relative; width: 100%; height: 300px;\">\n \u003ccanvas id=\"revenueChart\">\u003c/canvas>\n\u003c/div>\n```\n\nChart canvas flows below without a card wrapper. Use `sendPrompt()` for drill-down: `sendPrompt('Break down Q4 by region')`.\n\n---\n\n## ERD / Database Schemas (mermaid.js)\n\nUse mermaid.js `erDiagram`, not Chart.js or SVG:\n\n```html\n\u003cstyle>\n#erd svg.erDiagram .row-rect-odd path,\n#erd svg.erDiagram .row-rect-odd rect,\n#erd svg.erDiagram .row-rect-even path,\n#erd svg.erDiagram .row-rect-even rect { stroke: none !important; }\n\u003c/style>\n\u003cdiv id=\"erd\">\u003c/div>\n\u003cscript type=\"module\">\nimport mermaid from 'https://esm.sh/mermaid@11/dist/mermaid.esm.min.mjs';\nconst dark = matchMedia('(prefers-color-scheme: dark)').matches;\nawait document.fonts.ready;\nmermaid.initialize({\n startOnLoad: false,\n theme: 'base',\n themeVariables: {\n darkMode: dark,\n fontSize: '13px',\n lineColor: dark ? '#9c9a92' : '#73726c',\n textColor: dark ? '#c2c0b6' : '#3d3d3a',\n },\n});\nconst { svg } = await mermaid.render('erd-svg', `erDiagram\n USERS ||--o{ POSTS : writes\n POSTS ||--o{ COMMENTS : has`);\ndocument.getElementById('erd').innerHTML = svg;\n\u003c/script>\n```\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":5276,"content_sha256":"dbc95a4a02bc7bf1a672c34fcc6b4a8fd4edb8e25e8e89ec25bb029bc7f3c268"},{"filename":"references/design_system.md","content":"# Generative UI Design System\n\nExtracted from Claude's actual `visualize:read_me` guidelines (Imagine — Visual Creation Suite).\n\n---\n\n## Color Palette\n\n9 color ramps, each with 7 stops from lightest to darkest. 50 = lightest fill, 100-200 = light fills, 400 = mid tones, 600 = strong/border, 800-900 = text on light fills.\n\n| Class | Ramp | 50 | 100 | 200 | 400 | 600 | 800 | 900 |\n|---|---|---|---|---|---|---|---|---|\n| `c-purple` | Purple | #EEEDFE | #CECBF6 | #AFA9EC | #7F77DD | #534AB7 | #3C3489 | #26215C |\n| `c-teal` | Teal | #E1F5EE | #9FE1CB | #5DCAA5 | #1D9E75 | #0F6E56 | #085041 | #04342C |\n| `c-coral` | Coral | #FAECE7 | #F5C4B3 | #F0997B | #D85A30 | #993C1D | #712B13 | #4A1B0C |\n| `c-pink` | Pink | #FBEAF0 | #F4C0D1 | #ED93B1 | #D4537E | #993556 | #72243E | #4B1528 |\n| `c-gray` | Gray | #F1EFE8 | #D3D1C7 | #B4B2A9 | #888780 | #5F5E5A | #444441 | #2C2C2A |\n| `c-blue` | Blue | #E6F1FB | #B5D4F4 | #85B7EB | #378ADD | #185FA5 | #0C447C | #042C53 |\n| `c-green` | Green | #EAF3DE | #C0DD97 | #97C459 | #639922 | #3B6D11 | #27500A | #173404 |\n| `c-amber` | Amber | #FAEEDA | #FAC775 | #EF9F27 | #BA7517 | #854F0B | #633806 | #412402 |\n| `c-red` | Red | #FCEBEB | #F7C1C1 | #F09595 | #E24B4A | #A32D2D | #791F1F | #501313 |\n\n### How to Assign Colors\n\nColor encodes **meaning**, not sequence. Don't cycle through colors like a rainbow.\n\n- Group nodes by **category** — all nodes of the same type share one color\n- Use **gray for neutral/structural** nodes (start, end, generic steps)\n- Use **2-3 colors per diagram**, not 6+. More = more visual noise\n- **Prefer purple, teal, coral, pink** for general categories. Reserve blue, green, amber, red for semantic meaning (info, success, warning, error)\n\n### Text on Colored Backgrounds\n\nAlways use the 800 or 900 stop from the same ramp as the fill. Never use black, gray, or `--color-text-primary` on colored fills.\n\nWhen a box has both a title and a subtitle, use two different stops:\n- **Light mode**: 50 fill + 600 stroke + 800 title / 600 subtitle\n- **Dark mode**: 800 fill + 200 stroke + 100 title / 200 subtitle\n\nExample: text on Blue 50 (#E6F1FB) must use Blue 800 (#0C447C) or 900 (#042C53), not black.\n\n---\n\n## CSS Variables\n\n**Backgrounds**: `--color-background-primary` (white), `-secondary` (surfaces), `-tertiary` (page bg), `-info`, `-danger`, `-success`, `-warning`\n\n**Text**: `--color-text-primary` (black), `-secondary` (muted), `-tertiary` (hints), `-info`, `-danger`, `-success`, `-warning`\n\n**Borders**: `--color-border-tertiary` (0.15α, default), `-secondary` (0.3α, hover), `-primary` (0.4α), semantic `-info/-danger/-success/-warning`\n\n**Typography**: `--font-sans`, `--font-serif`, `--font-mono`\n\n**Layout**: `--border-radius-md` (8px), `--border-radius-lg` (12px — preferred for most components), `--border-radius-xl` (16px)\n\nAll auto-adapt to light/dark mode. For custom colors in HTML, use CSS variables. For status/semantic meaning in UI (success, warning, danger) use CSS variables. For categorical coloring in both diagrams and UI, use the color ramps.\n\n---\n\n## UI Component Patterns\n\n### Aesthetic\n\nFlat, clean, white surfaces. Minimal 0.5px borders. Generous whitespace. No gradients, no shadows (except functional focus rings). Everything should feel native to the host UI.\n\n### Tokens\n\n- Borders: always `0.5px solid var(--color-border-tertiary)` (or `-secondary` for emphasis)\n- Corner radius: `var(--border-radius-md)` for most elements, `var(--border-radius-lg)` for cards\n- Cards: white bg (`var(--color-background-primary)`), 0.5px border, radius-lg, padding 1rem 1.25rem\n- Form elements (input, select, textarea, button, range slider) are pre-styled — write bare tags\n- Buttons: transparent bg, 0.5px border-secondary, hover bg-secondary, active scale(0.98). If it triggers `sendPrompt`, append a ↗ arrow\n- Spacing: use rem for vertical rhythm (1rem, 1.5rem, 2rem), px for component-internal gaps (8px, 12px, 16px)\n- Box-shadows: none, except `box-shadow: 0 0 0 Npx` focus rings on inputs\n\n### Metric Cards\n\nFor summary numbers (revenue, count, percentage):\n\n```html\n\u003cdiv style=\"background: var(--color-background-secondary); border-radius: var(--border-radius-md); padding: 1rem;\">\n \u003cdiv style=\"font-size: 13px; color: var(--color-text-secondary);\">Label\u003c/div>\n \u003cdiv style=\"font-size: 24px; font-weight: 500;\">$1,234\u003c/div>\n\u003c/div>\n```\n\nUse in grids of 2-4 with `gap: 12px`. Distinct from raised cards (which have white bg + border).\n\n### Layout Patterns\n\n- **Editorial** (explanatory content): no card wrapper, prose flows naturally\n- **Card** (bounded objects like a contact record, receipt): single raised card wraps the whole thing\n- Don't put tables in widgets — output them as markdown in your response text\n\n**Grid overflow**: `grid-template-columns: 1fr` has `min-width: auto` by default. Use `minmax(0, 1fr)` to clamp.\n\n### Interactive Explainer\n\nSliders, buttons, live state displays, charts. Keep prose explanations in your response text. No card wrapper. Whitespace is the container.\n\n```html\n\u003cdiv style=\"display: flex; align-items: center; gap: 12px; margin: 0 0 1.5rem;\">\n \u003clabel style=\"font-size: 14px; color: var(--color-text-secondary);\">Years\u003c/label>\n \u003cinput type=\"range\" min=\"1\" max=\"40\" value=\"20\" id=\"years\" style=\"flex: 1;\" />\n \u003cspan style=\"font-size: 14px; font-weight: 500; min-width: 24px;\" id=\"years-out\">20\u003c/span>\n\u003c/div>\n```\n\n### Comparison Grid\n\nSide-by-side card grid. Highlight differences with semantic colors. Use `repeat(auto-fit, minmax(160px, 1fr))` for responsive columns. When one option is recommended, accent its card with `border: 2px solid var(--color-border-info)` (the only exception to the 0.5px rule).\n\n### Data Record\n\nWrap in a single raised card. Example:\n\n```html\n\u003cdiv style=\"background: var(--color-background-primary); border-radius: var(--border-radius-lg); border: 0.5px solid var(--color-border-tertiary); padding: 1rem 1.25rem;\">\n \u003cdiv style=\"display: flex; align-items: center; gap: 12px; margin-bottom: 16px;\">\n \u003cdiv style=\"width: 44px; height: 44px; border-radius: 50%; background: var(--color-background-info); display: flex; align-items: center; justify-content: center; font-weight: 500; font-size: 14px; color: var(--color-text-info);\">MR\u003c/div>\n \u003cdiv>\n \u003cp style=\"font-weight: 500; font-size: 15px; margin: 0;\">Maya Rodriguez\u003c/p>\n \u003cp style=\"font-size: 13px; color: var(--color-text-secondary); margin: 0;\">VP of Engineering\u003c/p>\n \u003c/div>\n \u003c/div>\n\u003c/div>\n```\n\n---\n\n## Complexity Budget (Hard Limits)\n\n- Box subtitles: ≤5 words\n- Colors: ≤2 ramps per diagram\n- Horizontal tier: ≤4 boxes at full width (~140px each). 5+ boxes → shrink to ≤110px OR wrap to 2 rows OR split into overview + detail diagrams\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":6709,"content_sha256":"8f3016cf3485203e5f2e80fded01891873cf8fe52c8208fddff9f6473ea1ab7a"},{"filename":"references/svg_and_diagrams.md","content":"# SVG Setup and Diagram Patterns\n\nExtracted from Claude's actual `visualize:read_me` guidelines.\n\n---\n\n## SVG Setup\n\n**ViewBox**: `\u003csvg width=\"100%\" viewBox=\"0 0 680 H\">` — 680px wide, flexible height. Set H to fit content tightly (last element's bottom edge + 40px padding). Safe area: x=40 to x=640, y=40 to y=(H-40). Background transparent.\n\n**The 680 in viewBox is load-bearing — do not change it.** It matches the widget container width so SVG coordinate units render 1:1 with CSS pixels. If your diagram content is naturally narrow, keep viewBox width at 680 and center the content — do not shrink the viewBox.\n\n**Do not wrap the SVG in a container `\u003cdiv>` with a background color** — the widget host provides the card container and background. Output the raw `\u003csvg>` element directly.\n\n### ViewBox Safety Checklist\n\nBefore finalizing any SVG, verify:\n1. Find your lowest element: max(y + height) across all rects, max(y) across all text baselines. Set viewBox height = that value + 40px buffer\n2. Find your rightmost element: max(x + width) across all rects. All content must stay within x=0 to x=680\n3. For text with `text-anchor=\"end\"`, the text extends LEFT from x. If x=118 and text is 200px wide, it starts at x=-82 — outside the viewBox\n4. Never use negative x or y coordinates. The viewBox starts at 0,0\n5. For every pair of boxes in the same row, check that left box's (x + width) \u003c right box's x by at least 20px\n\n### Font Size Calibration\n\n| Text | Chars | Weight | Size | Rendered Width |\n|---|---|---|---|---|\n| Authentication Service | 22 | 500 | 14px | 167px |\n| Background Job Processor | 24 | 500 | 14px | 201px |\n| Detects and validates incoming tokens | 37 | 400 | 14px | 279px |\n| forwards request to | 19 | 400 | 12px | 123px |\n\nBefore placing text in a box: does (text width + 2×padding) fit the container? Box width formula: `rect_width = max(title_chars × 8, subtitle_chars × 7) + 24`.\n\nSVG `\u003ctext>` never auto-wraps. Every line break needs an explicit `\u003ctspan x=\"...\" dy=\"1.2em\">`.\n\n### Pre-built Classes\n\nAlready loaded in SVG widget context:\n\n- `class=\"t\"` = sans 14px primary text\n- `class=\"ts\"` = sans 12px secondary text\n- `class=\"th\"` = sans 14px medium (500) heading text\n- `class=\"box\"` = neutral rect (bg-secondary fill, border stroke)\n- `class=\"node\"` = clickable group with hover effect (cursor pointer, slight dim on hover)\n- `class=\"arr\"` = arrow line (1.5px, open chevron head)\n- `class=\"leader\"` = dashed leader line (tertiary stroke, 0.5px, dashed)\n- `class=\"c-{ramp}\"` = colored node. Apply to `\u003cg>` or shape element (rect/circle/ellipse), NOT to paths. Sets fill+stroke on shapes, auto-adjusts child text classes, dark mode automatic\n- Short aliases: `var(--p)`, `var(--s)`, `var(--t)`, `var(--bg2)`, `var(--b)`\n\n**`c-{ramp}` nesting**: These classes use direct-child selectors. Nest a `\u003cg>` inside a `\u003cg class=\"c-blue\">` and inner shapes become grandchildren — they lose the fill and render BLACK. Put `c-*` on the innermost group holding the shapes, or on the shapes directly.\n\n### Arrow Marker (always include)\n\n```svg\n\u003cdefs>\n \u003cmarker id=\"arrow\" viewBox=\"0 0 10 10\" refX=\"8\" refY=\"5\" markerWidth=\"6\" markerHeight=\"6\" orient=\"auto-start-reverse\">\n \u003cpath d=\"M2 1L8 5L2 9\" fill=\"none\" stroke=\"context-stroke\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n \u003c/marker>\n\u003c/defs>\n```\n\nUse `marker-end=\"url(#arrow)\"` on lines. The head uses `context-stroke` — inherits the color of whichever line it sits on.\n\n### Style Rules\n\n- Every `\u003ctext>` element must carry one of: `t`, `ts`, `th`\n- Use only two font sizes: 14px (node labels) and 12px (subtitles, descriptions, arrow labels)\n- No decorative step numbers or oversized headings\n- No icons or illustrations inside boxes — text only\n- Sentence case on all labels\n- Stroke width: 0.5px for diagram borders and edges\n- Connector paths need `fill=\"none\"` (SVG defaults to `fill: black`)\n- `rx=\"4\"` for subtle corners, `rx=\"8\"` max for emphasized rounding\n- One SVG per tool call — never leave an abandoned or partial SVG\n\n---\n\n## Diagram Types\n\n### Flowchart\n\nFor sequential processes, cause-and-effect, decision trees.\n\n**Planning**: Size boxes to fit text generously. At 14px, each character is ~8px wide. A label like \"Load Balancer\" (13 chars) needs at least 140px wide rect.\n\n**Spacing**: 60px minimum between boxes, 24px padding inside boxes, 12px between text and edges. Leave 10px gap between arrowheads and box edges. Two-line boxes need at least 56px height with 22px between lines.\n\n**Vertical text placement**: Every `\u003ctext>` inside a box needs `dominant-baseline=\"central\"`, with y set to the center of its slot. Formula: for text centered in a rect at (x, y, w, h), use `\u003ctext x={x+w/2} y={y+h/2} text-anchor=\"middle\" dominant-baseline=\"central\">`.\n\n**Layout**: Prefer single-direction flows. Max 4-5 nodes per diagram. The widget is narrow (~680px).\n\n**Single-line node** (44px tall):\n```svg\n\u003cg class=\"node c-blue\" onclick=\"sendPrompt('Tell me more about T-cells')\">\n \u003crect x=\"100\" y=\"20\" width=\"180\" height=\"44\" rx=\"8\" stroke-width=\"0.5\"/>\n \u003ctext class=\"th\" x=\"190\" y=\"42\" text-anchor=\"middle\" dominant-baseline=\"central\">T-cells\u003c/text>\n\u003c/g>\n```\n\n**Two-line node** (56px tall):\n```svg\n\u003cg class=\"node c-blue\" onclick=\"sendPrompt('Tell me more about dendritic cells')\">\n \u003crect x=\"100\" y=\"20\" width=\"200\" height=\"56\" rx=\"8\" stroke-width=\"0.5\"/>\n \u003ctext class=\"th\" x=\"200\" y=\"38\" text-anchor=\"middle\" dominant-baseline=\"central\">Dendritic cells\u003c/text>\n \u003ctext class=\"ts\" x=\"200\" y=\"56\" text-anchor=\"middle\" dominant-baseline=\"central\">Detect foreign antigens\u003c/text>\n\u003c/g>\n```\n\n**Connector** (no label):\n```svg\n\u003cline x1=\"200\" y1=\"76\" x2=\"200\" y2=\"120\" class=\"arr\" marker-end=\"url(#arrow)\"/>\n```\n\n**Arrows**: Must not cross any other box or label. If the direct path crosses something, route around with an L-bend: `\u003cpath d=\"M x1 y1 L x1 ymid L x2 ymid L x2 y2\"/>`.\n\n**Cycles**: Don't draw as rings. Build a stepper in HTML instead: one panel per stage, dots showing position (● ○ ○), Next wraps from last stage to first.\n\n**Over budget prompts**: If user lists 6+ components, decompose into a stripped overview + one diagram per interesting sub-flow, each with 3-4 nodes.\n\n### Structural Diagram\n\nFor concepts where physical or logical containment matters.\n\n**Container rules**:\n- Outermost: large rounded rect, rx=20-24, lightest fill (50 stop), 0.5px stroke (600 stop). Label at top-left, 14px bold\n- Inner regions: medium rounded rects, rx=8-12, next shade fill (100-200 stop). Different color ramp if semantically different\n- 20px minimum padding inside every container\n- Max 2-3 nesting levels\n\n**Example** (horizontal layout with two inner regions):\n```svg\n\u003cdefs>\n \u003cmarker id=\"arrow\" viewBox=\"0 0 10 10\" refX=\"8\" refY=\"5\" markerWidth=\"6\" markerHeight=\"6\" orient=\"auto-start-reverse\">\n \u003cpath d=\"M2 1L8 5L2 9\" fill=\"none\" stroke=\"context-stroke\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n \u003c/marker>\n\u003c/defs>\n\u003cg class=\"c-green\">\n \u003crect x=\"120\" y=\"30\" width=\"560\" height=\"260\" rx=\"20\" stroke-width=\"0.5\"/>\n \u003ctext class=\"th\" x=\"400\" y=\"62\" text-anchor=\"middle\">Library branch\u003c/text>\n \u003ctext class=\"ts\" x=\"400\" y=\"80\" text-anchor=\"middle\">Main floor\u003c/text>\n\u003c/g>\n\u003cg class=\"c-teal\">\n \u003crect x=\"150\" y=\"100\" width=\"220\" height=\"160\" rx=\"12\" stroke-width=\"0.5\"/>\n \u003ctext class=\"th\" x=\"260\" y=\"130\" text-anchor=\"middle\">Circulation desk\u003c/text>\n \u003ctext class=\"ts\" x=\"260\" y=\"148\" text-anchor=\"middle\">Checkouts, returns\u003c/text>\n\u003c/g>\n\u003cg class=\"c-amber\">\n \u003crect x=\"450\" y=\"100\" width=\"210\" height=\"160\" rx=\"12\" stroke-width=\"0.5\"/>\n \u003ctext class=\"th\" x=\"555\" y=\"130\" text-anchor=\"middle\">Reading room\u003c/text>\n \u003ctext class=\"ts\" x=\"555\" y=\"148\" text-anchor=\"middle\">Seating, reference\u003c/text>\n\u003c/g>\n\u003ctext class=\"ts\" x=\"410\" y=\"175\" text-anchor=\"middle\">Books\u003c/text>\n\u003cline x1=\"370\" y1=\"185\" x2=\"448\" y2=\"185\" class=\"arr\" marker-end=\"url(#arrow)\"/>\n```\n\n**Color in structural diagrams**: Nested regions need distinct ramps. Same class on parent and child gives identical fills and flattens the hierarchy. Pick a related ramp for inner structures and a contrasting ramp for functionally different regions.\n\n**Database schemas / ERDs**: Use mermaid.js, not SVG.\n\n### Illustrative Diagram\n\nFor building *intuition*. Draw the mechanism, not a diagram *about* the mechanism.\n\n**Two flavors**:\n- **Physical subjects**: simplified cross-sections, cutaways, schematics (a water heater is a tank with a burner)\n- **Abstract subjects**: spatial metaphors (a transformer is stacked slabs with attention threads, a hash function is a funnel scattering into buckets)\n\n**What changes from flowchart rules**:\n- Shapes are freeform: `\u003cpath>`, `\u003cellipse>`, `\u003ccircle>`, `\u003cpolygon>`, curved lines\n- Layout follows the subject's geometry, not a grid\n- Color encodes intensity, not category (warm = active/high-weight, cool = dormant)\n- Layering and overlap are encouraged for shapes (but never let a stroke cross text)\n- Small shape-based indicators are allowed (triangles for flames, circles for bubbles)\n- One gradient per diagram is permitted — only for continuous physical properties\n- CSS `@keyframes` animation permitted (only `transform` and `opacity`, wrap in `@media (prefers-reduced-motion: no-preference)`)\n\n**Prefer interactive over static**: if the real-world system has a control, give the diagram that control. Use `show_widget` with inline SVG + HTML controls.\n\n**Label placement**: Place labels outside the drawn object with thin leader lines (0.5px dashed). Reserve at least 140px of horizontal margin on the label side.\n\n**Composition approach**:\n1. Main object's silhouette — largest shape, centered\n2. Internal structure: chambers, pipes, membranes\n3. External connections: pipes, arrows, input/output labels\n4. State indicators last: color fills, small animated elements\n5. Leave generous whitespace around the object for labels\n\n### Routing Decisions\n\n| User says | Type | What to draw |\n|---|---|---|\n| \"how do LLMs work\" | Illustrative | Token row, stacked layers, attention threads |\n| \"transformer architecture\" | Structural | Labelled boxes: embedding, attention, FFN |\n| \"how does attention work\" | Illustrative | One query token, fan of lines to every key |\n| \"what are the training steps\" | Flowchart | Forward → loss → backward → update |\n| \"explain the Krebs cycle\" | HTML stepper | Click through stages. Never a ring |\n| \"draw the database schema\" | mermaid.js | `erDiagram` syntax |\n\nThe illustrative route is the default for \"how does X work\" — don't default to a flowchart because it feels safer.\n\n---\n\n## Art and Illustration\n\nFor \"draw me a sunset\" / \"create a geometric pattern\":\n\n- Fill the canvas — art should feel rich, not sparse\n- Bold colors: mix `--color-text-*` categories for variety\n- Art is the one place custom `\u003cstyle>` color blocks are fine — freestyle colors\n- Layer overlapping opaque shapes for depth\n- Organic forms with `\u003cpath>` curves, `\u003cellipse>`, `\u003ccircle>`\n- Texture via repetition (parallel lines, dots, hatching) not raster effects\n- Geometric patterns with `\u003cg transform=\"rotate()\">` for radial symmetry\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":11143,"content_sha256":"e8b62160d7aaa182020a04f9e8368e5eb56ee3ca6e1d986bca3a9539d8bdfcac"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Generative UI Skill","type":"text"}]},{"type":"paragraph","content":[{"text":"This skill contains the complete design system for Claude's built-in ","type":"text"},{"text":"show_widget","type":"text","marks":[{"type":"code_inline"}]},{"text":" 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 ","type":"text"},{"text":"read_me","type":"text","marks":[{"type":"code_inline"}]},{"text":" setup call.","type":"text"}]},{"type":"paragraph","content":[{"text":"How it works","type":"text","marks":[{"type":"strong"}]},{"text":": On claude.ai, Claude has access to the ","type":"text"},{"text":"show_widget","type":"text","marks":[{"type":"code_inline"}]},{"text":" tool which renders raw HTML/SVG fragments inline in the conversation. This skill provides the design system, templates, and patterns to use it well.","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Step 1: Pick the Right Visual Type","type":"text"}]},{"type":"paragraph","content":[{"text":"Route on the ","type":"text"},{"text":"verb","type":"text","marks":[{"type":"strong"}]},{"text":", not the noun. Same subject, different visual depending on what was asked:","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"User says","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Type","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Format","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\"how does X work\"","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Illustrative diagram","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"SVG","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\"X architecture\"","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Structural diagram","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"SVG","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\"what are the steps\"","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Flowchart","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"SVG","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\"explain compound interest\"","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Interactive explainer","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"HTML","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\"compare these options\"","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Comparison grid","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"HTML","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\"show revenue chart\"","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Chart.js chart","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"HTML","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\"create a contact card\"","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Data record","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"HTML","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\"draw a sunset\"","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Art/illustration","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"SVG","type":"text"}]}]}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Step 2: Build the Widget","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Structure (strict order)","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"\u003cstyle> → HTML content → \u003cscript>","type":"text"}]},{"type":"paragraph","content":[{"text":"Output streams token-by-token. Styles must exist before the elements they target, and scripts must run after the DOM is ready.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Philosophy","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Seamless","type":"text","marks":[{"type":"strong"}]},{"text":": Users shouldn't notice where the host UI ends and your widget begins","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Flat","type":"text","marks":[{"type":"strong"}]},{"text":": No gradients, mesh backgrounds, noise textures, or decorative effects. Clean flat surfaces","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Compact","type":"text","marks":[{"type":"strong"}]},{"text":": Show the essential inline. Explain the rest in text","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Text goes in your response, visuals go in the tool","type":"text","marks":[{"type":"strong"}]},{"text":" — 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","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Core Rules","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"No ","type":"text"},{"text":"\u003c!-- comments -->","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"/* comments */","type":"text","marks":[{"type":"code_inline"}]},{"text":" (waste tokens, break streaming)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"No font-size below 11px","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"No emoji — use CSS shapes or SVG paths","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"No gradients, drop shadows, blur, glow, or neon effects","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"No dark/colored backgrounds on outer containers (transparent only — host provides the bg)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Typography","type":"text","marks":[{"type":"strong"}]},{"text":": 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","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Sentence case","type":"text","marks":[{"type":"strong"}]},{"text":" always. Never Title Case, never ALL CAPS","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"No mid-sentence bolding — entity names go in ","type":"text"},{"text":"code style","type":"text","marks":[{"type":"code_inline"}]},{"text":" not ","type":"text"},{"text":"bold","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"No ","type":"text"},{"text":"\u003c!DOCTYPE>","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"\u003chtml>","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"\u003chead>","type":"text","marks":[{"type":"code_inline"}]},{"text":", or ","type":"text"},{"text":"\u003cbody>","type":"text","marks":[{"type":"code_inline"}]},{"text":" — just content fragments","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"No ","type":"text"},{"text":"position: fixed","type":"text","marks":[{"type":"code_inline"}]},{"text":" — use normal-flow layouts","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"No tabs, carousels, or ","type":"text"},{"text":"display: none","type":"text","marks":[{"type":"code_inline"}]},{"text":" sections during streaming","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"No nested scrolling — auto-fit height","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Corners: ","type":"text"},{"text":"border-radius: var(--border-radius-lg)","type":"text","marks":[{"type":"code_inline"}]},{"text":" for cards, ","type":"text"},{"text":"var(--border-radius-md)","type":"text","marks":[{"type":"code_inline"}]},{"text":" for elements","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"No rounded corners on single-sided borders (border-left, border-top)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Round every displayed number","type":"text","marks":[{"type":"strong"}]},{"text":" — use ","type":"text"},{"text":"Math.round()","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":".toFixed(n)","type":"text","marks":[{"type":"code_inline"}]},{"text":", or ","type":"text"},{"text":"Intl.NumberFormat","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"CDN Allowlist (CSP-enforced)","type":"text"}]},{"type":"paragraph","content":[{"text":"External resources may ONLY load from:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"cdnjs.cloudflare.com","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"cdn.jsdelivr.net","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"unpkg.com","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"esm.sh","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"paragraph","content":[{"text":"All other origins are blocked — the request silently fails.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"CSS Variables","type":"text"}]},{"type":"paragraph","content":[{"text":"Backgrounds","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"--color-background-primary","type":"text","marks":[{"type":"code_inline"}]},{"text":" (white), ","type":"text"},{"text":"-secondary","type":"text","marks":[{"type":"code_inline"}]},{"text":" (surfaces), ","type":"text"},{"text":"-tertiary","type":"text","marks":[{"type":"code_inline"}]},{"text":" (page bg), ","type":"text"},{"text":"-info","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"-danger","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"-success","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"-warning","type":"text","marks":[{"type":"code_inline"}]},{"text":" ","type":"text"},{"text":"Text","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"--color-text-primary","type":"text","marks":[{"type":"code_inline"}]},{"text":" (black), ","type":"text"},{"text":"-secondary","type":"text","marks":[{"type":"code_inline"}]},{"text":" (muted), ","type":"text"},{"text":"-tertiary","type":"text","marks":[{"type":"code_inline"}]},{"text":" (hints), ","type":"text"},{"text":"-info","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"-danger","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"-success","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"-warning","type":"text","marks":[{"type":"code_inline"}]},{"text":" ","type":"text"},{"text":"Borders","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"--color-border-tertiary","type":"text","marks":[{"type":"code_inline"}]},{"text":" (0.15α, default), ","type":"text"},{"text":"-secondary","type":"text","marks":[{"type":"code_inline"}]},{"text":" (0.3α, hover), ","type":"text"},{"text":"-primary","type":"text","marks":[{"type":"code_inline"}]},{"text":" (0.4α), semantic ","type":"text"},{"text":"-info/-danger/-success/-warning","type":"text","marks":[{"type":"code_inline"}]},{"text":" ","type":"text"},{"text":"Typography","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"--font-sans","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"--font-serif","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"--font-mono","type":"text","marks":[{"type":"code_inline"}]},{"text":" ","type":"text"},{"text":"Layout","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"--border-radius-md","type":"text","marks":[{"type":"code_inline"}]},{"text":" (8px), ","type":"text"},{"text":"--border-radius-lg","type":"text","marks":[{"type":"code_inline"}]},{"text":" (12px), ","type":"text"},{"text":"--border-radius-xl","type":"text","marks":[{"type":"code_inline"}]},{"text":" (16px)","type":"text"}]},{"type":"paragraph","content":[{"text":"All auto-adapt to light/dark mode.","type":"text"}]},{"type":"paragraph","content":[{"text":"Dark mode is mandatory","type":"text","marks":[{"type":"strong"}]},{"text":" — every color must work in both modes:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"In HTML: always use CSS variables for text. Never hardcode colors like ","type":"text"},{"text":"color: #333","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"In SVG: use pre-built color classes (","type":"text"},{"text":"c-blue","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"c-teal","type":"text","marks":[{"type":"code_inline"}]},{"text":", etc.) — they handle light/dark automatically","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Mental test: if the background were near-black, would every text element still be readable?","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"sendPrompt(text)","type":"text","marks":[{"type":"code_inline"}]}]},{"type":"paragraph","content":[{"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.","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Step 3: Render with ","type":"text"},{"text":"show_widget","type":"text","marks":[{"type":"code_inline"}]}]},{"type":"paragraph","content":[{"text":"The ","type":"text"},{"text":"show_widget","type":"text","marks":[{"type":"code_inline"}]},{"text":" tool is built into claude.ai — no activation needed. Pass your widget code directly:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"json"},"content":[{"text":"{\n \"title\": \"snake_case_widget_name\",\n \"widget_code\": \"\u003cstyle>...\u003c/style>\\n\u003cdiv>...\u003c/div>\\n\u003cscript>...\u003c/script>\"\n}","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Parameter","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Type","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Required","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"title","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"string","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Yes","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Snake_case identifier for the widget","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"widget_code","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"string","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Yes","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"HTML or SVG code. For SVG: start with ","type":"text"},{"text":"\u003csvg>","type":"text","marks":[{"type":"code_inline"}]},{"text":". For HTML: content fragment","type":"text"}]}]}]}]},{"type":"paragraph","content":[{"text":"For SVG output: start ","type":"text"},{"text":"widget_code","type":"text","marks":[{"type":"code_inline"}]},{"text":" with ","type":"text"},{"text":"\u003csvg","type":"text","marks":[{"type":"code_inline"}]},{"text":" — it will be auto-detected and wrapped appropriately.","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Step 4: Chart.js Template","type":"text"}]},{"type":"paragraph","content":[{"text":"For charts, use ","type":"text"},{"text":"onload","type":"text","marks":[{"type":"code_inline"}]},{"text":" callback pattern to handle script load ordering:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"html"},"content":[{"text":"\u003cdiv style=\"display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px;\">\n \u003cdiv style=\"background: var(--color-background-secondary); border-radius: var(--border-radius-md); padding: 1rem;\">\n \u003cdiv style=\"font-size: 13px; color: var(--color-text-secondary);\">Label\u003c/div>\n \u003cdiv style=\"font-size: 24px; font-weight: 500;\" id=\"stat1\">—\u003c/div>\n \u003c/div>\n\u003c/div>\n\n\u003cdiv style=\"position: relative; width: 100%; height: 300px; margin-top: 1rem;\">\n \u003ccanvas id=\"myChart\">\u003c/canvas>\n\u003c/div>\n\n\u003cdiv style=\"display: flex; align-items: center; gap: 12px; margin-top: 1rem;\">\n \u003clabel style=\"font-size: 14px; color: var(--color-text-secondary);\">Parameter\u003c/label>\n \u003cinput type=\"range\" min=\"0\" max=\"100\" value=\"50\" id=\"param\" step=\"1\" style=\"flex: 1;\" />\n \u003cspan style=\"font-size: 14px; font-weight: 500; min-width: 32px;\" id=\"param-out\">50\u003c/span>\n\u003c/div>\n\n\u003cscript src=\"https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.js\" onload=\"initChart()\">\u003c/script>\n\u003cscript>\nfunction initChart() {\n const slider = document.getElementById('param');\n const out = document.getElementById('param-out');\n let chart = null;\n\n function update() {\n const val = parseFloat(slider.value);\n out.textContent = val;\n document.getElementById('stat1').textContent = val.toFixed(1);\n\n const labels = [], data = [];\n for (let x = 0; x \u003c= 100; x++) {\n labels.push(x);\n data.push(x * val / 100);\n }\n\n if (chart) chart.destroy();\n chart = new Chart(document.getElementById('myChart'), {\n type: 'line',\n data: { labels, datasets: [{ data, borderColor: '#7F77DD', borderWidth: 2, pointRadius: 0, fill: false }] },\n options: {\n responsive: true,\n maintainAspectRatio: false,\n plugins: { legend: { display: false } },\n scales: { x: { grid: { display: false } } }\n }\n });\n }\n\n slider.addEventListener('input', update);\n update();\n}\nif (window.Chart) initChart();\n\u003c/script>","type":"text"}]},{"type":"paragraph","content":[{"text":"Chart.js rules:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Canvas cannot resolve CSS variables — use hardcoded hex","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Set height ONLY on the wrapper div, never on canvas itself","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Always ","type":"text"},{"text":"responsive: true, maintainAspectRatio: false","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Always disable default legend, build custom HTML legends","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Number formatting: ","type":"text"},{"text":"-$5M","type":"text","marks":[{"type":"code_inline"}]},{"text":" not ","type":"text"},{"text":"$-5M","type":"text","marks":[{"type":"code_inline"}]},{"text":" (negative sign before currency symbol)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"onload=\"initChart()\"","type":"text","marks":[{"type":"code_inline"}]},{"text":" on CDN script tag + ","type":"text"},{"text":"if (window.Chart) initChart();","type":"text","marks":[{"type":"code_inline"}]},{"text":" as fallback","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Step 5: SVG Diagram Template","type":"text"}]},{"type":"paragraph","content":[{"text":"For flowcharts and diagrams, use SVG with pre-built classes:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"svg"},"content":[{"text":"\u003csvg width=\"100%\" viewBox=\"0 0 680 H\">\n \u003cdefs>\n \u003cmarker id=\"arrow\" viewBox=\"0 0 10 10\" refX=\"8\" refY=\"5\" markerWidth=\"6\" markerHeight=\"6\" orient=\"auto-start-reverse\">\n \u003cpath d=\"M2 1L8 5L2 9\" fill=\"none\" stroke=\"context-stroke\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n \u003c/marker>\n \u003c/defs>\n\n \u003c!-- Single-line node (44px tall) -->\n \u003cg class=\"node c-blue\" onclick=\"sendPrompt('Tell me more about this')\">\n \u003crect x=\"250\" y=\"40\" width=\"180\" height=\"44\" rx=\"8\" stroke-width=\"0.5\"/>\n \u003ctext class=\"th\" x=\"340\" y=\"62\" text-anchor=\"middle\" dominant-baseline=\"central\">Step one\u003c/text>\n \u003c/g>\n\n \u003c!-- Connector arrow -->\n \u003cline x1=\"340\" y1=\"84\" x2=\"340\" y2=\"120\" class=\"arr\" marker-end=\"url(#arrow)\"/>\n\n \u003c!-- Two-line node (56px tall) -->\n \u003cg class=\"node c-teal\" onclick=\"sendPrompt('Explain this step')\">\n \u003crect x=\"230\" y=\"120\" width=\"220\" height=\"56\" rx=\"8\" stroke-width=\"0.5\"/>\n \u003ctext class=\"th\" x=\"340\" y=\"140\" text-anchor=\"middle\" dominant-baseline=\"central\">Step two\u003c/text>\n \u003ctext class=\"ts\" x=\"340\" y=\"158\" text-anchor=\"middle\" dominant-baseline=\"central\">Processes the input\u003c/text>\n \u003c/g>\n\u003c/svg>","type":"text"}]},{"type":"paragraph","content":[{"text":"SVG rules:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"ViewBox always 680px wide (","type":"text"},{"text":"viewBox=\"0 0 680 H\"","type":"text","marks":[{"type":"code_inline"}]},{"text":"). Set H to fit content + 40px padding","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Safe area: x=40 to x=640, y=40 to y=(H-40)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Pre-built classes: ","type":"text"},{"text":"t","type":"text","marks":[{"type":"code_inline"}]},{"text":" (14px), ","type":"text"},{"text":"ts","type":"text","marks":[{"type":"code_inline"}]},{"text":" (12px secondary), ","type":"text"},{"text":"th","type":"text","marks":[{"type":"code_inline"}]},{"text":" (14px medium 500), ","type":"text"},{"text":"box","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"node","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"arr","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"c-{color}","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Every ","type":"text"},{"text":"\u003ctext>","type":"text","marks":[{"type":"code_inline"}]},{"text":" element must carry a class (","type":"text"},{"text":"t","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"ts","type":"text","marks":[{"type":"code_inline"}]},{"text":", or ","type":"text"},{"text":"th","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"dominant-baseline=\"central\"","type":"text","marks":[{"type":"code_inline"}]},{"text":" for vertical text centering in boxes","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Connector paths need ","type":"text"},{"text":"fill=\"none\"","type":"text","marks":[{"type":"code_inline"}]},{"text":" (SVG defaults to ","type":"text"},{"text":"fill: black","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Stroke width: 0.5px for borders and edges","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Make all nodes clickable: ","type":"text"},{"text":"onclick=\"sendPrompt('...')\"","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Step 6: Interactive Explainer Template","type":"text"}]},{"type":"paragraph","content":[{"text":"For interactive explainers (sliders, live calculations, inline SVG):","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"html"},"content":[{"text":"\u003cdiv style=\"display: flex; align-items: center; gap: 12px; margin: 0 0 1.5rem;\">\n \u003clabel style=\"font-size: 14px; color: var(--color-text-secondary);\">Years\u003c/label>\n \u003cinput type=\"range\" min=\"1\" max=\"40\" value=\"20\" id=\"years\" style=\"flex: 1;\" />\n \u003cspan style=\"font-size: 14px; font-weight: 500; min-width: 24px;\" id=\"years-out\">20\u003c/span>\n\u003c/div>\n\n\u003cdiv style=\"display: flex; align-items: baseline; gap: 8px; margin: 0 0 1.5rem;\">\n \u003cspan style=\"font-size: 14px; color: var(--color-text-secondary);\">$1,000 →\u003c/span>\n \u003cspan style=\"font-size: 24px; font-weight: 500;\" id=\"result\">$3,870\u003c/span>\n\u003c/div>\n\n\u003cdiv style=\"margin: 2rem 0; position: relative; height: 240px;\">\n \u003ccanvas id=\"chart\">\u003c/canvas>\n\u003c/div>\n\n\u003cscript src=\"https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.js\" onload=\"initChart()\">\u003c/script>\n\u003cscript>\nfunction initChart() {\n // slider logic, chart rendering, sendPrompt() for follow-ups\n}\nif (window.Chart) initChart();\n\u003c/script>","type":"text"}]},{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"sendPrompt()","type":"text","marks":[{"type":"code_inline"}]},{"text":" to let users ask follow-ups: ","type":"text"},{"text":"sendPrompt('What if I increase the rate to 10%?')","type":"text","marks":[{"type":"code_inline"}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Step 7: Respond to the User","type":"text"}]},{"type":"paragraph","content":[{"text":"After rendering the widget, briefly explain:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"What the widget shows","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"How to interact with it (which controls do what)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"One key insight from the data","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Keep it concise — the widget speaks for itself.","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Reference Files","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/design_system.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" — Complete color palette (9 ramps × 7 stops), CSS variables, UI component patterns, metric cards, layout rules","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/svg_and_diagrams.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" — SVG viewBox setup, font calibration, pre-built classes, flowchart/structural/illustrative diagram patterns with examples","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/chart_js.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" — Chart.js configuration, script load ordering, canvas sizing, legend patterns, dashboard layout","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Read the relevant reference file when you need specific design tokens, SVG coordinate math, or Chart.js configuration details.","type":"text"}]}]},"metadata":{"date":"2026-06-05","name":"generative-ui","author":"@skillopedia","source":{"stars":2651,"repo_name":"finance-skills","origin_url":"https://github.com/himself65/finance-skills/blob/HEAD/plugins/ui-tools/skills/generative-ui/SKILL.md","repo_owner":"himself65","body_sha256":"611fc9c0a20c08d3160c7dc9bd2a09253762c687ff8df3ed2c23b9e8f873ce25","cluster_key":"308e5903fcf1069bfb424c692fbcf81bc91f58b616324fbdbd4c762563e5869b","clean_bundle":{"format":"clean-skill-bundle-v1","source":"himself65/finance-skills/plugins/ui-tools/skills/generative-ui/SKILL.md","attachments":[{"id":"c588e5b7-4091-5703-a00b-161308ba7b63","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/c588e5b7-4091-5703-a00b-161308ba7b63/attachment.md","path":"README.md","size":2057,"sha256":"b22b4f08828be02e5392e5bd97c06de8b11e0226f64bf4b875744dfaf473ea95","contentType":"text/markdown; charset=utf-8"},{"id":"aa44bdf5-e9ee-5e24-9a05-7b9a50997460","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/aa44bdf5-e9ee-5e24-9a05-7b9a50997460/attachment.md","path":"references/chart_js.md","size":5276,"sha256":"dbc95a4a02bc7bf1a672c34fcc6b4a8fd4edb8e25e8e89ec25bb029bc7f3c268","contentType":"text/markdown; charset=utf-8"},{"id":"d1fa72c7-5b4c-51d7-b7af-1f612ef154a7","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/d1fa72c7-5b4c-51d7-b7af-1f612ef154a7/attachment.md","path":"references/design_system.md","size":6709,"sha256":"8f3016cf3485203e5f2e80fded01891873cf8fe52c8208fddff9f6473ea1ab7a","contentType":"text/markdown; charset=utf-8"},{"id":"726a4955-9abe-554e-b14c-48f157b94e96","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/726a4955-9abe-554e-b14c-48f157b94e96/attachment.md","path":"references/svg_and_diagrams.md","size":11143,"sha256":"e8b62160d7aaa182020a04f9e8368e5eb56ee3ca6e1d986bca3a9539d8bdfcac","contentType":"text/markdown; charset=utf-8"}],"bundle_sha256":"5ddb4f5bcbafd2b392e8d6a36b6a86e6f10321f4ff1ce4921abcb468b01a8508","attachment_count":4,"text_attachments":4,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"plugins/ui-tools/skills/generative-ui/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"web-development","category_label":"Web"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"web-development","import_tag":"clean-skills-v1","description":"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.\n"}},"renderedAt":1782979663501}

Generative UI Skill This skill contains the complete design system for Claude's built-in 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 setup call. How it works : On claude.ai, Claude has access to the 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:…