Claude Skill

generative-ui

Design system and templates for interactive HTML/SVG visuals in Claude and Codex, using an available inline renderer or a standalone HTML file. Use this skill whenever the user wants visual or interactive output rather than plain text or markdown: charts and dashboards, diagrams,

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Download himself65-finance-skills-plugins_ui-tools_skills_generative-ui-73d554d.zip · 17 KB

Install

skills CLI npx skills add https://github.com/himself65/finance-skills/tree/main/plugins/ui-tools/skills/generative-ui
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install himself65-finance-skills@llmmart
Git git clone https://github.com/himself65/finance-skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole himself65/finance-skills collection as a plugin from our marketplace. Git is the plain clone.

README

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.

What it does

Provides the complete Anthropic "Imagine" design system so Claude produces high-quality widgets without needing to call read_me first. Covers:

  • Charts — Chart.js line, bar, area charts with interactive controls
  • Diagrams — SVG flowcharts, structural diagrams, illustrative diagrams
  • Dashboards — metric cards, comparison grids, data displays
  • Interactive explainers — sliders, toggles, live-updating calculations
  • Design tokens — CSS variables, color palette (light/dark), typography, spacing

Key design principles

  • Seamless — widgets blend with the host UI
  • Flat — no gradients, shadows, or decorative effects
  • Compact — show the essential inline, explain in text
  • Dark mode mandatory — all colors work in both light and dark mode via CSS variables

Triggers

  • "show me", "visualize", "draw", "chart", "dashboard"
  • "diagram", "flowchart", "widget", "interactive", "mockup"
  • "explain how X works" (with visual), "illustrate"
  • Any request for visual/interactive output beyond plain text or markdown

Platform

Works on Claude.ai with its built-in show_widget tool, and OpenAI Codex with an available visualization tool or a standalone HTML file. Standalone output includes its own styles and chart dependencies; chat-only sendPrompt actions are omitted when no bridge is available.

Setup

# Choose finance-ui-tools when prompted.
npx plugins add himself65/finance-skills

# Or install just this skill
npx skills add himself65/finance-skills --skill generative-ui

See the main README for more installation options.

Reference files

  • references/design_system.md — Complete color palette, CSS variables, UI component patterns, metric cards, layout rules
  • references/svg_and_diagrams.md — SVG viewBox setup, font calibration, pre-built classes, diagram patterns with examples
  • references/chart_js.md — Chart.js configuration, script load ordering, canvas sizing, legend patterns, dashboard layout

Skill manifest

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.

Codex and other hosts: First check the available tools. Use the host's documented visualization interface when provided; otherwise save a complete HTML document in the workspace and return a clickable file link. For standalone output, the fragment-only rule below does not apply: include a document wrapper and viewport metadata, define the CSS variables and SVG classes used by the templates (including dark-mode colors), and load chart dependencies explicitly. The host-specific CDN allowlist and injected styles below describe Claude's renderer; they are not Codex capabilities. Remove chat follow-up buttons and sendPrompt handlers when that bridge is unavailable; keep local sliders and calculations functional. Verify the saved output in a browser when available.


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
  • No stock "AI design" defaults: skip cream or off-white panels, italic accent words in headings, numbered "01 / 02 / 03" section labels, monospace labels outside code, and pill-shaped buttons — they read as generic and clash with the host UI
  • Text goes in your response, visuals go in the tool — write explanatory text, descriptions, and summaries as normal response text outside the tool call; the widget holds 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 the Available Host

When the host exposes show_widget, pass your widget code directly as below. In Codex without that tool, follow the standalone HTML path above; do not invent a show_widget call.

{
  "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.

Files (finance-skills)
  • references
    • chart_js.md 5.2 KB
      Loading…
    • design_system.md 6.6 KB
      Loading…
    • svg_and_diagrams.md 10.9 KB
      Loading…
  • README.md 2.2 KB
    # 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.
    
    ## What it does
    
    Provides the complete Anthropic "Imagine" design system so Claude produces high-quality widgets without needing to call `read_me` first. Covers:
    
    - **Charts** — Chart.js line, bar, area charts with interactive controls
    - **Diagrams** — SVG flowcharts, structural diagrams, illustrative diagrams
    - **Dashboards** — metric cards, comparison grids, data displays
    - **Interactive explainers** — sliders, toggles, live-updating calculations
    - **Design tokens** — CSS variables, color palette (light/dark), typography, spacing
    
    ## Key design principles
    
    - **Seamless** — widgets blend with the host UI
    - **Flat** — no gradients, shadows, or decorative effects
    - **Compact** — show the essential inline, explain in text
    - **Dark mode mandatory** — all colors work in both light and dark mode via CSS variables
    
    ## Triggers
    
    - "show me", "visualize", "draw", "chart", "dashboard"
    - "diagram", "flowchart", "widget", "interactive", "mockup"
    - "explain how X works" (with visual), "illustrate"
    - Any request for visual/interactive output beyond plain text or markdown
    
    ## Platform
    
    Works on **Claude.ai** with its built-in `show_widget` tool, and **OpenAI Codex** with an available visualization tool or a standalone HTML file. Standalone output includes its own styles and chart dependencies; chat-only `sendPrompt` actions are omitted when no bridge is available.
    
    ## Setup
    
    ```bash
    # Choose finance-ui-tools when prompted.
    npx plugins add himself65/finance-skills
    
    # Or install just this skill
    npx skills add himself65/finance-skills --skill generative-ui
    ```
    
    See the [main README](../../../../README.md) for more installation options.
    
    ## Reference files
    
    - `references/design_system.md` — Complete color palette, CSS variables, UI component patterns, metric cards, layout rules
    - `references/svg_and_diagrams.md` — SVG viewBox setup, font calibration, pre-built classes, diagram patterns with examples
    - `references/chart_js.md` — Chart.js configuration, script load ordering, canvas sizing, legend patterns, dashboard layout
    
  • SKILL.md 13 KB
    ---
    name: generative-ui
    description: >
      Design system and templates for interactive HTML/SVG visuals in Claude and Codex,
      using an available inline renderer or a standalone HTML file.
      Use this skill whenever the user wants visual or interactive output rather than
      plain text or markdown: charts and dashboards, diagrams, flowcharts and
      architecture drawings, mockups, comparison grids, illustrations, interactive
      explainers ("explain how X works" with a visual), or tools with sliders, toggles,
      and live-updating displays — including financial data shown visually and requests
      phrased as "show me", "visualize", "draw", or "chart this".
    ---
    
    # 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.
    
    **Codex and other hosts**: First check the available tools. Use the host's documented visualization interface when provided; otherwise save a complete HTML document in the workspace and return a clickable file link. For standalone output, the fragment-only rule below does not apply: include a document wrapper and viewport metadata, define the CSS variables and SVG classes used by the templates (including dark-mode colors), and load chart dependencies explicitly. The host-specific CDN allowlist and injected styles below describe Claude's renderer; they are not Codex capabilities. Remove chat follow-up buttons and `sendPrompt` handlers when that bridge is unavailable; keep local sliders and calculations functional. Verify the saved output in a browser when available.
    
    ---
    
    ## 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
    - **No stock "AI design" defaults**: skip cream or off-white panels, italic accent words in headings, numbered "01 / 02 / 03" section labels, monospace labels outside code, and pill-shaped buttons — they read as generic and clash with the host UI
    - **Text goes in your response, visuals go in the tool** — write explanatory text, descriptions, and summaries as normal response text outside the tool call; the widget holds 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 the Available Host
    
    When the host exposes `show_widget`, pass your widget code directly as below. In Codex without that tool, follow the standalone HTML path above; do not invent a `show_widget` call.
    
    ```json
    {
      "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:
    
    ```html
    <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
    <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):
    
    ```html
    <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.
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.