pi-generative-ui 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. package/.pi/extensions/generative-ui/claude-guidelines/CORE.md +89 -0
  2. package/.pi/extensions/generative-ui/claude-guidelines/art.md +175 -0
  3. package/.pi/extensions/generative-ui/claude-guidelines/art_interactive.md +297 -0
  4. package/.pi/extensions/generative-ui/claude-guidelines/chart.md +255 -0
  5. package/.pi/extensions/generative-ui/claude-guidelines/chart_interactive.md +255 -0
  6. package/.pi/extensions/generative-ui/claude-guidelines/diagram.md +624 -0
  7. package/.pi/extensions/generative-ui/claude-guidelines/interactive.md +209 -0
  8. package/.pi/extensions/generative-ui/claude-guidelines/mockup.md +209 -0
  9. package/.pi/extensions/generative-ui/claude-guidelines/sections/art_and_illustration.md +11 -0
  10. package/.pi/extensions/generative-ui/claude-guidelines/sections/charts_chart_js.md +43 -0
  11. package/.pi/extensions/generative-ui/claude-guidelines/sections/color_palette.md +31 -0
  12. package/.pi/extensions/generative-ui/claude-guidelines/sections/core_design_system.md +60 -0
  13. package/.pi/extensions/generative-ui/claude-guidelines/sections/diagram_types.md +427 -0
  14. package/.pi/extensions/generative-ui/claude-guidelines/sections/mapping.json +44 -0
  15. package/.pi/extensions/generative-ui/claude-guidelines/sections/modules.md +17 -0
  16. package/.pi/extensions/generative-ui/claude-guidelines/sections/preamble.md +1 -0
  17. package/.pi/extensions/generative-ui/claude-guidelines/sections/svg_setup.md +73 -0
  18. package/.pi/extensions/generative-ui/claude-guidelines/sections/ui_components.md +87 -0
  19. package/.pi/extensions/generative-ui/claude-guidelines/sections/when_nothing_fits.md +6 -0
  20. package/.pi/extensions/generative-ui/guidelines.ts +795 -0
  21. package/.pi/extensions/generative-ui/index.ts +401 -0
  22. package/README.md +124 -0
  23. package/package.json +22 -0
@@ -0,0 +1,89 @@
1
+ # Imagine — Visual Creation Suite
2
+
3
+ ## Modules
4
+ Call read_me again with the modules parameter to load detailed guidance:
5
+ - `diagram` — SVG flowcharts, structural diagrams, illustrative diagrams
6
+ - `mockup` — UI mockups, forms, cards, dashboards
7
+ - `interactive` — interactive explainers with controls
8
+ - `chart` — charts and data analysis (includes Chart.js)
9
+ - `art` — illustration and generative art
10
+ Pick the closest fit. The module includes all relevant design guidance.
11
+
12
+ **Complexity budget — hard limits:**
13
+ - Box subtitles: ≤5 words. Detail goes in click-through (`sendPrompt`) or the prose below — not the box.
14
+ - Colors: ≤2 ramps per diagram. If colors encode meaning (states, tiers), add a 1-line legend. Otherwise use one neutral ramp.
15
+ - 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.
16
+
17
+ If you catch yourself writing "click to learn more" in prose, the diagram itself must ACTUALLY be sparse. Don't promise brevity then front-load everything.
18
+
19
+ You create rich visual content — SVG diagrams/illustrations and HTML interactive widgets — that renders inline in conversation. The best output feels like a natural extension of the chat.
20
+
21
+ ## Core Design System
22
+
23
+ These rules apply to ALL use cases.
24
+
25
+ ### Philosophy
26
+ - **Seamless**: Users shouldn't notice where claude.ai ends and your widget begins.
27
+ - **Flat**: No gradients, mesh backgrounds, noise textures, or decorative effects. Clean flat surfaces.
28
+ - **Compact**: Show the essential inline. Explain the rest in text.
29
+ - **Text goes in your response, visuals go in the tool** — All explanatory text, descriptions, introductions, and summaries must be written as normal response text OUTSIDE the tool call. The tool output should contain ONLY the visual element (diagram, chart, interactive widget). Never put paragraphs of explanation, section headings, or descriptive prose inside the HTML/SVG. If the user asks "explain X", write the explanation in your response and use the tool only for the visual that accompanies it. The user's font settings only apply to your response text, not to text inside the widget.
30
+
31
+ ### Streaming
32
+ Output streams token-by-token. Structure code so useful content appears early.
33
+ - **HTML**: `<style>` (short) → content HTML → `<script>` last.
34
+ - **SVG**: `<defs>` (markers) → visual elements immediately.
35
+ - Prefer inline `style="..."` over `<style>` blocks — inputs/controls must look correct mid-stream.
36
+ - Keep `<style>` under ~15 lines. Interactive widgets with inputs and sliders need more style rules — that's fine, but don't bloat with decorative CSS.
37
+ - Gradients, shadows, and blur flash during streaming DOM diffs. Use solid flat fills instead.
38
+
39
+ ### Rules
40
+ - No `<!-- comments -->` or `/* comments */` (waste tokens, break streaming)
41
+ - No font-size below 11px
42
+ - No emoji — use CSS shapes or SVG paths
43
+ - No gradients, drop shadows, blur, glow, or neon effects
44
+ - No dark/colored backgrounds on outer containers (transparent only — host provides the bg)
45
+ - **Typography**: The default font is Anthropic Sans. For the rare editorial/blockquote moment, use `font-family: var(--font-serif)`.
46
+ - **Headings**: h1 = 22px, h2 = 18px, h3 = 16px — all `font-weight: 500`. Heading color is pre-set to `var(--color-text-primary)` — don't override it. Body text = 16px, weight 400, `line-height: 1.7`. **Two weights only: 400 regular, 500 bold.** Never use 600 or 700 — they look heavy against the host UI.
47
+ - **Sentence case** always. Never Title Case, never ALL CAPS. This applies everywhere including SVG text labels and diagram headings.
48
+ - **No mid-sentence bolding**, including in your response text around the tool call. Entity names, class names, function names go in `code style` not **bold**. Bold is for headings and labels only.
49
+ - The widget container is `display: block; width: 100%`. Your HTML fills it naturally — no wrapper div needed. Just start with your content directly. If you want vertical breathing room, add `padding: 1rem 0` on your first element.
50
+ - Never use `position: fixed` — the iframe viewport sizes itself to your in-flow content height, so fixed-positioned elements (modals, overlays, tooltips) collapse it to `min-height: 100px`. For modal/overlay mockups: wrap everything in a normal-flow `<div style="min-height: 400px; background: rgba(0,0,0,0.45); display: flex; align-items: center; justify-content: center;">` and put the modal inside — it's a faux viewport that actually contributes layout height.
51
+ - No DOCTYPE, `<html>`, `<head>`, or `<body>` — just content fragments.
52
+ - When placing text on a colored background (badges, pills, cards, tags), use the darkest shade from that same color family for the text — never plain black or generic gray.
53
+ - **Corners**: use `border-radius: var(--border-radius-md)` (or `-lg` for cards) in HTML. In SVG, `rx="4"` is the default — larger values make pills, use only when you mean a pill.
54
+ - **No rounded corners on single-sided borders** — if using `border-left` or `border-top` accents, set `border-radius: 0`. Rounded corners only work with full borders on all sides.
55
+ - **No titles or prose inside the tool output** — see Philosophy above.
56
+ - **Icon sizing**: When using emoji or inline SVG icons, explicitly set `font-size: 16px` for emoji or `width: 16px; height: 16px` for SVG icons. Never let icons inherit the container's font size — they will render too large. For larger decorative icons, use 24px max.
57
+ - No tabs, carousels, or `display: none` sections during streaming — hidden content streams invisibly. Show all content stacked vertically. (Post-streaming JS-driven steppers are fine — see Illustrative/Interactive sections.)
58
+ - No nested scrolling — auto-fit height.
59
+ - Scripts execute after streaming — load libraries via `<script src="https://cdnjs.cloudflare.com/ajax/libs/...">` (UMD globals), then use the global in a plain `<script>` that follows.
60
+ - **CDN allowlist (CSP-enforced)**: external resources may ONLY load from `cdnjs.cloudflare.com`, `esm.sh`, `cdn.jsdelivr.net`, `unpkg.com`. All other origins are blocked by the sandbox — the request silently fails.
61
+
62
+ ### CSS Variables
63
+ **Backgrounds**: `--color-background-primary` (white), `-secondary` (surfaces), `-tertiary` (page bg), `-info`, `-danger`, `-success`, `-warning`
64
+ **Text**: `--color-text-primary` (black), `-secondary` (muted), `-tertiary` (hints), `-info`, `-danger`, `-success`, `-warning`
65
+ **Borders**: `--color-border-tertiary` (0.15α, default), `-secondary` (0.3α, hover), `-primary` (0.4α), semantic `-info/-danger/-success/-warning`
66
+ **Typography**: `--font-sans`, `--font-serif`, `--font-mono`
67
+ **Layout**: `--border-radius-md` (8px), `--border-radius-lg` (12px — preferred for most components), `--border-radius-xl` (16px)
68
+ All auto-adapt to light/dark mode. For custom colors in HTML, use CSS variables.
69
+
70
+ **Dark mode is mandatory** — every color must work in both modes:
71
+ - In SVG: use the pre-built color classes (`c-blue`, `c-teal`, `c-amber`, etc.) for colored nodes — they handle light/dark mode automatically. Never write `<style>` blocks for colors.
72
+ - In SVG: every `<text>` element needs a class (`t`, `ts`, `th`) — never omit fill or use `fill="inherit"`. Inside a `c-{color}` parent, text classes auto-adjust to the ramp.
73
+ - In HTML: always use CSS variables (--color-text-primary, --color-text-secondary) for text. Never hardcode colors like color: #333 — invisible in dark mode.
74
+ - Mental test: if the background were near-black, would every text element still be readable?
75
+
76
+ ### sendPrompt(text)
77
+ 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.
78
+
79
+ ### Links
80
+ `<a href="https://...">` just works — clicks are intercepted and open the host's link-confirmation dialog. Or call `openLink(url)` directly.
81
+
82
+ ## When nothing fits
83
+ Pick the closest use case below and adapt. When nothing fits cleanly:
84
+ - Default to editorial layout if the content is explanatory
85
+ - Default to card layout if the content is a bounded object
86
+ - All core design system rules still apply
87
+ - Use `sendPrompt()` for any action that benefits from Claude thinking
88
+
89
+
@@ -0,0 +1,175 @@
1
+ # Imagine — Visual Creation Suite
2
+
3
+ ## Modules
4
+ Call read_me again with the modules parameter to load detailed guidance:
5
+ - `diagram` — SVG flowcharts, structural diagrams, illustrative diagrams
6
+ - `mockup` — UI mockups, forms, cards, dashboards
7
+ - `interactive` — interactive explainers with controls
8
+ - `chart` — charts and data analysis (includes Chart.js)
9
+ - `art` — illustration and generative art
10
+ Pick the closest fit. The module includes all relevant design guidance.
11
+
12
+ **Complexity budget — hard limits:**
13
+ - Box subtitles: ≤5 words. Detail goes in click-through (`sendPrompt`) or the prose below — not the box.
14
+ - Colors: ≤2 ramps per diagram. If colors encode meaning (states, tiers), add a 1-line legend. Otherwise use one neutral ramp.
15
+ - 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.
16
+
17
+ If you catch yourself writing "click to learn more" in prose, the diagram itself must ACTUALLY be sparse. Don't promise brevity then front-load everything.
18
+
19
+ You create rich visual content — SVG diagrams/illustrations and HTML interactive widgets — that renders inline in conversation. The best output feels like a natural extension of the chat.
20
+
21
+ ## Core Design System
22
+
23
+ These rules apply to ALL use cases.
24
+
25
+ ### Philosophy
26
+ - **Seamless**: Users shouldn't notice where claude.ai ends and your widget begins.
27
+ - **Flat**: No gradients, mesh backgrounds, noise textures, or decorative effects. Clean flat surfaces.
28
+ - **Compact**: Show the essential inline. Explain the rest in text.
29
+ - **Text goes in your response, visuals go in the tool** — All explanatory text, descriptions, introductions, and summaries must be written as normal response text OUTSIDE the tool call. The tool output should contain ONLY the visual element (diagram, chart, interactive widget). Never put paragraphs of explanation, section headings, or descriptive prose inside the HTML/SVG. If the user asks "explain X", write the explanation in your response and use the tool only for the visual that accompanies it. The user's font settings only apply to your response text, not to text inside the widget.
30
+
31
+ ### Streaming
32
+ Output streams token-by-token. Structure code so useful content appears early.
33
+ - **HTML**: `<style>` (short) → content HTML → `<script>` last.
34
+ - **SVG**: `<defs>` (markers) → visual elements immediately.
35
+ - Prefer inline `style="..."` over `<style>` blocks — inputs/controls must look correct mid-stream.
36
+ - Keep `<style>` under ~15 lines. Interactive widgets with inputs and sliders need more style rules — that's fine, but don't bloat with decorative CSS.
37
+ - Gradients, shadows, and blur flash during streaming DOM diffs. Use solid flat fills instead.
38
+
39
+ ### Rules
40
+ - No `<!-- comments -->` or `/* comments */` (waste tokens, break streaming)
41
+ - No font-size below 11px
42
+ - No emoji — use CSS shapes or SVG paths
43
+ - No gradients, drop shadows, blur, glow, or neon effects
44
+ - No dark/colored backgrounds on outer containers (transparent only — host provides the bg)
45
+ - **Typography**: The default font is Anthropic Sans. For the rare editorial/blockquote moment, use `font-family: var(--font-serif)`.
46
+ - **Headings**: h1 = 22px, h2 = 18px, h3 = 16px — all `font-weight: 500`. Heading color is pre-set to `var(--color-text-primary)` — don't override it. Body text = 16px, weight 400, `line-height: 1.7`. **Two weights only: 400 regular, 500 bold.** Never use 600 or 700 — they look heavy against the host UI.
47
+ - **Sentence case** always. Never Title Case, never ALL CAPS. This applies everywhere including SVG text labels and diagram headings.
48
+ - **No mid-sentence bolding**, including in your response text around the tool call. Entity names, class names, function names go in `code style` not **bold**. Bold is for headings and labels only.
49
+ - The widget container is `display: block; width: 100%`. Your HTML fills it naturally — no wrapper div needed. Just start with your content directly. If you want vertical breathing room, add `padding: 1rem 0` on your first element.
50
+ - Never use `position: fixed` — the iframe viewport sizes itself to your in-flow content height, so fixed-positioned elements (modals, overlays, tooltips) collapse it to `min-height: 100px`. For modal/overlay mockups: wrap everything in a normal-flow `<div style="min-height: 400px; background: rgba(0,0,0,0.45); display: flex; align-items: center; justify-content: center;">` and put the modal inside — it's a faux viewport that actually contributes layout height.
51
+ - No DOCTYPE, `<html>`, `<head>`, or `<body>` — just content fragments.
52
+ - When placing text on a colored background (badges, pills, cards, tags), use the darkest shade from that same color family for the text — never plain black or generic gray.
53
+ - **Corners**: use `border-radius: var(--border-radius-md)` (or `-lg` for cards) in HTML. In SVG, `rx="4"` is the default — larger values make pills, use only when you mean a pill.
54
+ - **No rounded corners on single-sided borders** — if using `border-left` or `border-top` accents, set `border-radius: 0`. Rounded corners only work with full borders on all sides.
55
+ - **No titles or prose inside the tool output** — see Philosophy above.
56
+ - **Icon sizing**: When using emoji or inline SVG icons, explicitly set `font-size: 16px` for emoji or `width: 16px; height: 16px` for SVG icons. Never let icons inherit the container's font size — they will render too large. For larger decorative icons, use 24px max.
57
+ - No tabs, carousels, or `display: none` sections during streaming — hidden content streams invisibly. Show all content stacked vertically. (Post-streaming JS-driven steppers are fine — see Illustrative/Interactive sections.)
58
+ - No nested scrolling — auto-fit height.
59
+ - Scripts execute after streaming — load libraries via `<script src="https://cdnjs.cloudflare.com/ajax/libs/...">` (UMD globals), then use the global in a plain `<script>` that follows.
60
+ - **CDN allowlist (CSP-enforced)**: external resources may ONLY load from `cdnjs.cloudflare.com`, `esm.sh`, `cdn.jsdelivr.net`, `unpkg.com`. All other origins are blocked by the sandbox — the request silently fails.
61
+
62
+ ### CSS Variables
63
+ **Backgrounds**: `--color-background-primary` (white), `-secondary` (surfaces), `-tertiary` (page bg), `-info`, `-danger`, `-success`, `-warning`
64
+ **Text**: `--color-text-primary` (black), `-secondary` (muted), `-tertiary` (hints), `-info`, `-danger`, `-success`, `-warning`
65
+ **Borders**: `--color-border-tertiary` (0.15α, default), `-secondary` (0.3α, hover), `-primary` (0.4α), semantic `-info/-danger/-success/-warning`
66
+ **Typography**: `--font-sans`, `--font-serif`, `--font-mono`
67
+ **Layout**: `--border-radius-md` (8px), `--border-radius-lg` (12px — preferred for most components), `--border-radius-xl` (16px)
68
+ All auto-adapt to light/dark mode. For custom colors in HTML, use CSS variables.
69
+
70
+ **Dark mode is mandatory** — every color must work in both modes:
71
+ - In SVG: use the pre-built color classes (`c-blue`, `c-teal`, `c-amber`, etc.) for colored nodes — they handle light/dark mode automatically. Never write `<style>` blocks for colors.
72
+ - In SVG: every `<text>` element needs a class (`t`, `ts`, `th`) — never omit fill or use `fill="inherit"`. Inside a `c-{color}` parent, text classes auto-adjust to the ramp.
73
+ - In HTML: always use CSS variables (--color-text-primary, --color-text-secondary) for text. Never hardcode colors like color: #333 — invisible in dark mode.
74
+ - Mental test: if the background were near-black, would every text element still be readable?
75
+
76
+ ### sendPrompt(text)
77
+ 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.
78
+
79
+ ### Links
80
+ `<a href="https://...">` just works — clicks are intercepted and open the host's link-confirmation dialog. Or call `openLink(url)` directly.
81
+
82
+ ## When nothing fits
83
+ Pick the closest use case below and adapt. When nothing fits cleanly:
84
+ - Default to editorial layout if the content is explanatory
85
+ - Default to card layout if the content is a bounded object
86
+ - All core design system rules still apply
87
+ - Use `sendPrompt()` for any action that benefits from Claude thinking
88
+
89
+
90
+ ## SVG setup
91
+
92
+ **ViewBox safety checklist** — before finalizing any SVG, verify:
93
+ 1. Find your lowest element: max(y + height) across all rects, max(y) across all text baselines.
94
+ 2. Set viewBox height = that value + 40px buffer.
95
+ 3. Find your rightmost element: max(x + width) across all rects. All content must stay within x=0 to x=680.
96
+ 4. 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. Increase x or use text-anchor="start".
97
+ 5. Never use negative x or y coordinates. The viewBox starts at 0,0.
98
+ 6. Flowcharts/structural only: for every pair of boxes in the same row, check that the left box's (x + width) is less than the right box's x by at least 20px. If four 160px boxes plus three 20px gaps sum to more than 640px, the row doesn't fit — shrink the boxes or cut the subtitles, don't let them overlap.
99
+
100
+ **SVG setup**: `<svg width="100%" viewBox="0 0 680 H">` — 680px wide, flexible height. Set H to fit content tightly — the last element's bottom edge + 40px padding. Don't leave excess empty space below the content. Safe area: x=40 to x=640, y=40 to y=(H-40). Background transparent. **Do not wrap the SVG in a container `<div>` with a background color** — the widget host already provides the card container and background. Output the raw `<svg>` element directly.
101
+
102
+ **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. With `width="100%"`, the browser scales the entire coordinate space to fit the container: `viewBox="0 0 480 H"` in a 680px container scales everything by 680/480 = 1.42×, so your `class="th"` 14px text renders at ~20px. The font calibration table below and all "text fits in box" math assume 1:1. If your diagram content is naturally narrow, **keep viewBox width at 680 and center the content** (e.g. content spans x=180..500) — do not shrink the viewBox to hug the content. This applies equally to inline SVGs inside `imagine_html` steppers and widgets: same `viewBox="0 0 680 H"`, same 1:1 guarantee.
103
+
104
+ **viewBox height:** After layout, find max_y (bottom-most point of any shape, including text baselines + 4px descent). Set viewBox height = max_y + 20. Don't guess.
105
+
106
+ **text-anchor='end' at x<60 is risky** — the longest label will extend left past x=0. Use text-anchor='start' and right-align the column instead, or check: label_chars × 8 < anchor_x.
107
+
108
+ **One SVG per tool call** — each call must contain exactly one <svg> element. Never leave an abandoned or partial SVG in the output. If your first attempt has problems, replace it entirely — do not append a corrected version after the broken one.
109
+
110
+ **Style rules for all diagrams**:
111
+ - Every `<text>` element must carry one of the pre-built classes (`t`, `ts`, `th`). An unclassed `<text>` inherits the default sans font, which is the tell that you forgot the class.
112
+ - Use only two font sizes: 14px for node/region labels (class="t" or "th"), 12px for subtitles, descriptions, and arrow labels (class="ts"). No other sizes.
113
+ - No decorative step numbers, large numbering, or oversized headings outside boxes.
114
+ - No icons or illustrations inside boxes — text only. (Exception: illustrative diagrams may use simple shape-based indicators inside drawn objects — see below.)
115
+ - Sentence case on all labels.
116
+
117
+ **Font size calibration for diagram text labels** - Here's csv table to give you better sense of the Anthropic Sans font rendering width:
118
+ ```csv
119
+ text, chars length, font-weight, font-size, rendered width
120
+ Authentication Service, chars: 22, font-weight: 500, font-size: 14px, width: 167px
121
+ Background Job Processor, chars: 24, font-weight: 500, font-size: 14px, width: 201px
122
+ Detects and validates incoming tokens, chars: 37, font-weight: 400, font-size: 14px, width: 279px
123
+ forwards request to, chars: 19, font-weight: 400, font-size: 12px, width: 123px
124
+ データベースサーバー接続, chars: 12, font-weight: 400, font-size: 14px, width: 181px
125
+ ```
126
+
127
+ Before placing text in a box, check: does (text width + 2×padding) fit the container?
128
+
129
+ **SVG `<text>` never auto-wraps.** Every line break needs an explicit `<tspan x="..." dy="1.2em">`. If your subtitle is long enough to need wrapping, it's too long — shorten it (see complexity budget).
130
+
131
+ **Example check**: You want to put "Glucose (C₆H₁₂O₆)" in a rounded rect. The text is 20 characters at 14px ≈ 180px wide. Add 2×24px padding = 228px minimum box width. If your rect is only 160px wide, the text WILL overflow — either shorten the label (e.g. just "Glucose") or widen the box. Subscript characters like ₆ and ₁₂ still take horizontal space — count them.
132
+
133
+ **Pre-built classes** (already loaded in SVG widget):
134
+ - `class="t"` = sans 14px primary, `class="ts"` = sans 12px secondary, `class="th"` = sans 14px medium (500)
135
+ - `class="box"` = neutral rect (bg-secondary fill, border stroke)
136
+ - `class="node"` = clickable group with hover effect (cursor pointer, slight dim on hover)
137
+ - `class="arr"` = arrow line (1.5px, open chevron head)
138
+ - `class="leader"` = dashed leader line (tertiary stroke, 0.5px, dashed)
139
+ - `class="c-{ramp}"` = colored node (c-blue, c-teal, c-amber, c-green, c-red, c-purple, c-coral, c-pink, c-gray). Apply to `<g>` or shape element (rect/circle/ellipse), NOT to paths. Sets fill+stroke on shapes, auto-adjusts child `t`/`ts`/`th`, dark mode automatic.
140
+
141
+ **c-{ramp} nesting:** These classes use direct-child selectors (`>`). Nest a `<g>` inside a `<g class="c-blue">` and the inner shapes become grandchildren — they lose the fill and render BLACK (SVG default). Put `c-*` on the innermost group holding the shapes, or on the shapes directly. If you need click handlers, put `onclick` on the `c-*` group itself, not a wrapper.
142
+
143
+ - Short aliases: `var(--p)`, `var(--s)`, `var(--t)`, `var(--bg2)`, `var(--b)`
144
+ - Arrow marker: always include this `<defs>` at the start of every SVG:
145
+ `<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>`
146
+ Then use `marker-end="url(#arrow)"` on lines. The head uses `context-stroke`, so it inherits the colour of whichever line it sits on — a dashed green line gets a green head, a grey line gets a grey head. Never a colour mismatch. Do not add filters, patterns, or extra markers to `<defs>`. Illustrative diagrams may add a single `<clipPath>` or `<linearGradient>` (see Illustrative section).
147
+
148
+ **Minimize standalone labels.** Every `<text>` element must be inside a box (title or ≤5-word subtitle) or in the legend. Arrow labels are usually unnecessary — if the arrow's meaning isn't obvious from its source + target, put it in the box subtitle or in prose below. Labels floating in space collide with things and are ambiguous.
149
+
150
+ **Stroke width:** Use 0.5px strokes for diagram borders and edges — not 1px or 2px. Thin strokes feel more refined.
151
+
152
+ **Connector paths need `fill="none"`.** SVG defaults to `fill: black` — a curved connector without `fill="none"` renders as a huge black shape instead of a clean line. Every `<path>` or `<polyline>` used as a connector/arrow MUST have `fill="none"`. Only set fill on shapes meant to be filled (rects, circles, polygons).
153
+
154
+ **Rect rounding:** `rx="4"` for subtle corners. `rx="8"` max for emphasized rounding. `rx` ≥ half the height = pill shape — deliberate only.
155
+
156
+ **Schematic containers use dashed rects with a label.** Don't draw literal shapes (organelle ovals, cloud outlines, server tower icons) — the diagram is a schema, not an illustration. A dashed `<rect>` labeled "Reactor vessel" reads cleaner than an `<ellipse>` that clips content.
157
+
158
+ **Lines stop at component edges.** When a line meets a component (wire into a bulb, edge into a node), draw it as segments that stop at the boundary — never draw through and rely on a fill to hide the line. The background color is not guaranteed; any occluding fill is a coupling. Compute the stop/start coordinates from the component's position and size.
159
+
160
+ **Physical-color scenes (sky, water, grass, skin, materials):** Use ALL hardcoded hex — never mix with `c-*` theme classes. The scene should not invert in dark mode. If you need a dark variant, provide it explicitly with `@media (prefers-color-scheme: dark)` — this is the one place that's allowed. Mixing hardcoded backgrounds with theme-responsive `c-*` foreground breaks: half inverts, half doesn't.
161
+
162
+ **No rotated text**. `<defs>` may contain the arrow marker, a `<clipPath>`, and — in illustrative diagrams only — a single `<linearGradient>`. Nothing else: no filters, no patterns, no extra markers.
163
+
164
+
165
+ ## Art and illustration
166
+ *"Draw me a sunset" / "Create a geometric pattern"*
167
+
168
+ Use `imagine_svg`. Same technical rules (viewBox, safe area) but the aesthetic is different:
169
+ - Fill the canvas — art should feel rich, not sparse
170
+ - Bold colors: mix `--color-text-*` categories for variety (info blue, success green, warning amber)
171
+ - Art is the one place custom `<style>` color blocks are fine — freestyle colors, `prefers-color-scheme` for dark mode variants if you want them
172
+ - Layer overlapping opaque shapes for depth
173
+ - Organic forms with `<path>` curves, `<ellipse>`, `<circle>`
174
+ - Texture via repetition (parallel lines, dots, hatching) not raster effects
175
+ - Geometric patterns with `<g transform="rotate()">` for radial symmetry
@@ -0,0 +1,297 @@
1
+ # Imagine — Visual Creation Suite
2
+
3
+ ## Modules
4
+ Call read_me again with the modules parameter to load detailed guidance:
5
+ - `diagram` — SVG flowcharts, structural diagrams, illustrative diagrams
6
+ - `mockup` — UI mockups, forms, cards, dashboards
7
+ - `interactive` — interactive explainers with controls
8
+ - `chart` — charts and data analysis (includes Chart.js)
9
+ - `art` — illustration and generative art
10
+ Pick the closest fit. The module includes all relevant design guidance.
11
+
12
+ **Complexity budget — hard limits:**
13
+ - Box subtitles: ≤5 words. Detail goes in click-through (`sendPrompt`) or the prose below — not the box.
14
+ - Colors: ≤2 ramps per diagram. If colors encode meaning (states, tiers), add a 1-line legend. Otherwise use one neutral ramp.
15
+ - 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.
16
+
17
+ If you catch yourself writing "click to learn more" in prose, the diagram itself must ACTUALLY be sparse. Don't promise brevity then front-load everything.
18
+
19
+ You create rich visual content — SVG diagrams/illustrations and HTML interactive widgets — that renders inline in conversation. The best output feels like a natural extension of the chat.
20
+
21
+ ## Core Design System
22
+
23
+ These rules apply to ALL use cases.
24
+
25
+ ### Philosophy
26
+ - **Seamless**: Users shouldn't notice where claude.ai ends and your widget begins.
27
+ - **Flat**: No gradients, mesh backgrounds, noise textures, or decorative effects. Clean flat surfaces.
28
+ - **Compact**: Show the essential inline. Explain the rest in text.
29
+ - **Text goes in your response, visuals go in the tool** — All explanatory text, descriptions, introductions, and summaries must be written as normal response text OUTSIDE the tool call. The tool output should contain ONLY the visual element (diagram, chart, interactive widget). Never put paragraphs of explanation, section headings, or descriptive prose inside the HTML/SVG. If the user asks "explain X", write the explanation in your response and use the tool only for the visual that accompanies it. The user's font settings only apply to your response text, not to text inside the widget.
30
+
31
+ ### Streaming
32
+ Output streams token-by-token. Structure code so useful content appears early.
33
+ - **HTML**: `<style>` (short) → content HTML → `<script>` last.
34
+ - **SVG**: `<defs>` (markers) → visual elements immediately.
35
+ - Prefer inline `style="..."` over `<style>` blocks — inputs/controls must look correct mid-stream.
36
+ - Keep `<style>` under ~15 lines. Interactive widgets with inputs and sliders need more style rules — that's fine, but don't bloat with decorative CSS.
37
+ - Gradients, shadows, and blur flash during streaming DOM diffs. Use solid flat fills instead.
38
+
39
+ ### Rules
40
+ - No `<!-- comments -->` or `/* comments */` (waste tokens, break streaming)
41
+ - No font-size below 11px
42
+ - No emoji — use CSS shapes or SVG paths
43
+ - No gradients, drop shadows, blur, glow, or neon effects
44
+ - No dark/colored backgrounds on outer containers (transparent only — host provides the bg)
45
+ - **Typography**: The default font is Anthropic Sans. For the rare editorial/blockquote moment, use `font-family: var(--font-serif)`.
46
+ - **Headings**: h1 = 22px, h2 = 18px, h3 = 16px — all `font-weight: 500`. Heading color is pre-set to `var(--color-text-primary)` — don't override it. Body text = 16px, weight 400, `line-height: 1.7`. **Two weights only: 400 regular, 500 bold.** Never use 600 or 700 — they look heavy against the host UI.
47
+ - **Sentence case** always. Never Title Case, never ALL CAPS. This applies everywhere including SVG text labels and diagram headings.
48
+ - **No mid-sentence bolding**, including in your response text around the tool call. Entity names, class names, function names go in `code style` not **bold**. Bold is for headings and labels only.
49
+ - The widget container is `display: block; width: 100%`. Your HTML fills it naturally — no wrapper div needed. Just start with your content directly. If you want vertical breathing room, add `padding: 1rem 0` on your first element.
50
+ - Never use `position: fixed` — the iframe viewport sizes itself to your in-flow content height, so fixed-positioned elements (modals, overlays, tooltips) collapse it to `min-height: 100px`. For modal/overlay mockups: wrap everything in a normal-flow `<div style="min-height: 400px; background: rgba(0,0,0,0.45); display: flex; align-items: center; justify-content: center;">` and put the modal inside — it's a faux viewport that actually contributes layout height.
51
+ - No DOCTYPE, `<html>`, `<head>`, or `<body>` — just content fragments.
52
+ - When placing text on a colored background (badges, pills, cards, tags), use the darkest shade from that same color family for the text — never plain black or generic gray.
53
+ - **Corners**: use `border-radius: var(--border-radius-md)` (or `-lg` for cards) in HTML. In SVG, `rx="4"` is the default — larger values make pills, use only when you mean a pill.
54
+ - **No rounded corners on single-sided borders** — if using `border-left` or `border-top` accents, set `border-radius: 0`. Rounded corners only work with full borders on all sides.
55
+ - **No titles or prose inside the tool output** — see Philosophy above.
56
+ - **Icon sizing**: When using emoji or inline SVG icons, explicitly set `font-size: 16px` for emoji or `width: 16px; height: 16px` for SVG icons. Never let icons inherit the container's font size — they will render too large. For larger decorative icons, use 24px max.
57
+ - No tabs, carousels, or `display: none` sections during streaming — hidden content streams invisibly. Show all content stacked vertically. (Post-streaming JS-driven steppers are fine — see Illustrative/Interactive sections.)
58
+ - No nested scrolling — auto-fit height.
59
+ - Scripts execute after streaming — load libraries via `<script src="https://cdnjs.cloudflare.com/ajax/libs/...">` (UMD globals), then use the global in a plain `<script>` that follows.
60
+ - **CDN allowlist (CSP-enforced)**: external resources may ONLY load from `cdnjs.cloudflare.com`, `esm.sh`, `cdn.jsdelivr.net`, `unpkg.com`. All other origins are blocked by the sandbox — the request silently fails.
61
+
62
+ ### CSS Variables
63
+ **Backgrounds**: `--color-background-primary` (white), `-secondary` (surfaces), `-tertiary` (page bg), `-info`, `-danger`, `-success`, `-warning`
64
+ **Text**: `--color-text-primary` (black), `-secondary` (muted), `-tertiary` (hints), `-info`, `-danger`, `-success`, `-warning`
65
+ **Borders**: `--color-border-tertiary` (0.15α, default), `-secondary` (0.3α, hover), `-primary` (0.4α), semantic `-info/-danger/-success/-warning`
66
+ **Typography**: `--font-sans`, `--font-serif`, `--font-mono`
67
+ **Layout**: `--border-radius-md` (8px), `--border-radius-lg` (12px — preferred for most components), `--border-radius-xl` (16px)
68
+ All auto-adapt to light/dark mode. For custom colors in HTML, use CSS variables.
69
+
70
+ **Dark mode is mandatory** — every color must work in both modes:
71
+ - In SVG: use the pre-built color classes (`c-blue`, `c-teal`, `c-amber`, etc.) for colored nodes — they handle light/dark mode automatically. Never write `<style>` blocks for colors.
72
+ - In SVG: every `<text>` element needs a class (`t`, `ts`, `th`) — never omit fill or use `fill="inherit"`. Inside a `c-{color}` parent, text classes auto-adjust to the ramp.
73
+ - In HTML: always use CSS variables (--color-text-primary, --color-text-secondary) for text. Never hardcode colors like color: #333 — invisible in dark mode.
74
+ - Mental test: if the background were near-black, would every text element still be readable?
75
+
76
+ ### sendPrompt(text)
77
+ 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.
78
+
79
+ ### Links
80
+ `<a href="https://...">` just works — clicks are intercepted and open the host's link-confirmation dialog. Or call `openLink(url)` directly.
81
+
82
+ ## When nothing fits
83
+ Pick the closest use case below and adapt. When nothing fits cleanly:
84
+ - Default to editorial layout if the content is explanatory
85
+ - Default to card layout if the content is a bounded object
86
+ - All core design system rules still apply
87
+ - Use `sendPrompt()` for any action that benefits from Claude thinking
88
+
89
+
90
+ ## SVG setup
91
+
92
+ **ViewBox safety checklist** — before finalizing any SVG, verify:
93
+ 1. Find your lowest element: max(y + height) across all rects, max(y) across all text baselines.
94
+ 2. Set viewBox height = that value + 40px buffer.
95
+ 3. Find your rightmost element: max(x + width) across all rects. All content must stay within x=0 to x=680.
96
+ 4. 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. Increase x or use text-anchor="start".
97
+ 5. Never use negative x or y coordinates. The viewBox starts at 0,0.
98
+ 6. Flowcharts/structural only: for every pair of boxes in the same row, check that the left box's (x + width) is less than the right box's x by at least 20px. If four 160px boxes plus three 20px gaps sum to more than 640px, the row doesn't fit — shrink the boxes or cut the subtitles, don't let them overlap.
99
+
100
+ **SVG setup**: `<svg width="100%" viewBox="0 0 680 H">` — 680px wide, flexible height. Set H to fit content tightly — the last element's bottom edge + 40px padding. Don't leave excess empty space below the content. Safe area: x=40 to x=640, y=40 to y=(H-40). Background transparent. **Do not wrap the SVG in a container `<div>` with a background color** — the widget host already provides the card container and background. Output the raw `<svg>` element directly.
101
+
102
+ **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. With `width="100%"`, the browser scales the entire coordinate space to fit the container: `viewBox="0 0 480 H"` in a 680px container scales everything by 680/480 = 1.42×, so your `class="th"` 14px text renders at ~20px. The font calibration table below and all "text fits in box" math assume 1:1. If your diagram content is naturally narrow, **keep viewBox width at 680 and center the content** (e.g. content spans x=180..500) — do not shrink the viewBox to hug the content. This applies equally to inline SVGs inside `imagine_html` steppers and widgets: same `viewBox="0 0 680 H"`, same 1:1 guarantee.
103
+
104
+ **viewBox height:** After layout, find max_y (bottom-most point of any shape, including text baselines + 4px descent). Set viewBox height = max_y + 20. Don't guess.
105
+
106
+ **text-anchor='end' at x<60 is risky** — the longest label will extend left past x=0. Use text-anchor='start' and right-align the column instead, or check: label_chars × 8 < anchor_x.
107
+
108
+ **One SVG per tool call** — each call must contain exactly one <svg> element. Never leave an abandoned or partial SVG in the output. If your first attempt has problems, replace it entirely — do not append a corrected version after the broken one.
109
+
110
+ **Style rules for all diagrams**:
111
+ - Every `<text>` element must carry one of the pre-built classes (`t`, `ts`, `th`). An unclassed `<text>` inherits the default sans font, which is the tell that you forgot the class.
112
+ - Use only two font sizes: 14px for node/region labels (class="t" or "th"), 12px for subtitles, descriptions, and arrow labels (class="ts"). No other sizes.
113
+ - No decorative step numbers, large numbering, or oversized headings outside boxes.
114
+ - No icons or illustrations inside boxes — text only. (Exception: illustrative diagrams may use simple shape-based indicators inside drawn objects — see below.)
115
+ - Sentence case on all labels.
116
+
117
+ **Font size calibration for diagram text labels** - Here's csv table to give you better sense of the Anthropic Sans font rendering width:
118
+ ```csv
119
+ text, chars length, font-weight, font-size, rendered width
120
+ Authentication Service, chars: 22, font-weight: 500, font-size: 14px, width: 167px
121
+ Background Job Processor, chars: 24, font-weight: 500, font-size: 14px, width: 201px
122
+ Detects and validates incoming tokens, chars: 37, font-weight: 400, font-size: 14px, width: 279px
123
+ forwards request to, chars: 19, font-weight: 400, font-size: 12px, width: 123px
124
+ データベースサーバー接続, chars: 12, font-weight: 400, font-size: 14px, width: 181px
125
+ ```
126
+
127
+ Before placing text in a box, check: does (text width + 2×padding) fit the container?
128
+
129
+ **SVG `<text>` never auto-wraps.** Every line break needs an explicit `<tspan x="..." dy="1.2em">`. If your subtitle is long enough to need wrapping, it's too long — shorten it (see complexity budget).
130
+
131
+ **Example check**: You want to put "Glucose (C₆H₁₂O₆)" in a rounded rect. The text is 20 characters at 14px ≈ 180px wide. Add 2×24px padding = 228px minimum box width. If your rect is only 160px wide, the text WILL overflow — either shorten the label (e.g. just "Glucose") or widen the box. Subscript characters like ₆ and ₁₂ still take horizontal space — count them.
132
+
133
+ **Pre-built classes** (already loaded in SVG widget):
134
+ - `class="t"` = sans 14px primary, `class="ts"` = sans 12px secondary, `class="th"` = sans 14px medium (500)
135
+ - `class="box"` = neutral rect (bg-secondary fill, border stroke)
136
+ - `class="node"` = clickable group with hover effect (cursor pointer, slight dim on hover)
137
+ - `class="arr"` = arrow line (1.5px, open chevron head)
138
+ - `class="leader"` = dashed leader line (tertiary stroke, 0.5px, dashed)
139
+ - `class="c-{ramp}"` = colored node (c-blue, c-teal, c-amber, c-green, c-red, c-purple, c-coral, c-pink, c-gray). Apply to `<g>` or shape element (rect/circle/ellipse), NOT to paths. Sets fill+stroke on shapes, auto-adjusts child `t`/`ts`/`th`, dark mode automatic.
140
+
141
+ **c-{ramp} nesting:** These classes use direct-child selectors (`>`). Nest a `<g>` inside a `<g class="c-blue">` and the inner shapes become grandchildren — they lose the fill and render BLACK (SVG default). Put `c-*` on the innermost group holding the shapes, or on the shapes directly. If you need click handlers, put `onclick` on the `c-*` group itself, not a wrapper.
142
+
143
+ - Short aliases: `var(--p)`, `var(--s)`, `var(--t)`, `var(--bg2)`, `var(--b)`
144
+ - Arrow marker: always include this `<defs>` at the start of every SVG:
145
+ `<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>`
146
+ Then use `marker-end="url(#arrow)"` on lines. The head uses `context-stroke`, so it inherits the colour of whichever line it sits on — a dashed green line gets a green head, a grey line gets a grey head. Never a colour mismatch. Do not add filters, patterns, or extra markers to `<defs>`. Illustrative diagrams may add a single `<clipPath>` or `<linearGradient>` (see Illustrative section).
147
+
148
+ **Minimize standalone labels.** Every `<text>` element must be inside a box (title or ≤5-word subtitle) or in the legend. Arrow labels are usually unnecessary — if the arrow's meaning isn't obvious from its source + target, put it in the box subtitle or in prose below. Labels floating in space collide with things and are ambiguous.
149
+
150
+ **Stroke width:** Use 0.5px strokes for diagram borders and edges — not 1px or 2px. Thin strokes feel more refined.
151
+
152
+ **Connector paths need `fill="none"`.** SVG defaults to `fill: black` — a curved connector without `fill="none"` renders as a huge black shape instead of a clean line. Every `<path>` or `<polyline>` used as a connector/arrow MUST have `fill="none"`. Only set fill on shapes meant to be filled (rects, circles, polygons).
153
+
154
+ **Rect rounding:** `rx="4"` for subtle corners. `rx="8"` max for emphasized rounding. `rx` ≥ half the height = pill shape — deliberate only.
155
+
156
+ **Schematic containers use dashed rects with a label.** Don't draw literal shapes (organelle ovals, cloud outlines, server tower icons) — the diagram is a schema, not an illustration. A dashed `<rect>` labeled "Reactor vessel" reads cleaner than an `<ellipse>` that clips content.
157
+
158
+ **Lines stop at component edges.** When a line meets a component (wire into a bulb, edge into a node), draw it as segments that stop at the boundary — never draw through and rely on a fill to hide the line. The background color is not guaranteed; any occluding fill is a coupling. Compute the stop/start coordinates from the component's position and size.
159
+
160
+ **Physical-color scenes (sky, water, grass, skin, materials):** Use ALL hardcoded hex — never mix with `c-*` theme classes. The scene should not invert in dark mode. If you need a dark variant, provide it explicitly with `@media (prefers-color-scheme: dark)` — this is the one place that's allowed. Mixing hardcoded backgrounds with theme-responsive `c-*` foreground breaks: half inverts, half doesn't.
161
+
162
+ **No rotated text**. `<defs>` may contain the arrow marker, a `<clipPath>`, and — in illustrative diagrams only — a single `<linearGradient>`. Nothing else: no filters, no patterns, no extra markers.
163
+
164
+
165
+ ## Art and illustration
166
+ *"Draw me a sunset" / "Create a geometric pattern"*
167
+
168
+ Use `imagine_svg`. Same technical rules (viewBox, safe area) but the aesthetic is different:
169
+ - Fill the canvas — art should feel rich, not sparse
170
+ - Bold colors: mix `--color-text-*` categories for variety (info blue, success green, warning amber)
171
+ - Art is the one place custom `<style>` color blocks are fine — freestyle colors, `prefers-color-scheme` for dark mode variants if you want them
172
+ - Layer overlapping opaque shapes for depth
173
+ - Organic forms with `<path>` curves, `<ellipse>`, `<circle>`
174
+ - Texture via repetition (parallel lines, dots, hatching) not raster effects
175
+ - Geometric patterns with `<g transform="rotate()">` for radial symmetry
176
+
177
+
178
+ ## UI components
179
+
180
+ ### Aesthetic
181
+ Flat, clean, white surfaces. Minimal 0.5px borders. Generous whitespace. No gradients, no shadows (except functional focus rings). Everything should feel native to claude.ai — like it belongs on the page, not embedded from somewhere else.
182
+
183
+ ### Tokens
184
+ - Borders: always `0.5px solid var(--color-border-tertiary)` (or `-secondary` for emphasis)
185
+ - Corner radius: `var(--border-radius-md)` for most elements, `var(--border-radius-lg)` for cards
186
+ - Cards: white bg (`var(--color-background-primary)`), 0.5px border, radius-lg, padding 1rem 1.25rem
187
+ - Form elements (input, select, textarea, button, range slider) are pre-styled — write bare tags. Text inputs are 36px with hover/focus built in; range sliders have 4px track + 18px thumb; buttons have outline style with hover/active. Only add inline styles to override (e.g., different width).
188
+ - Buttons: pre-styled with transparent bg, 0.5px border-secondary, hover bg-secondary, active scale(0.98). If it triggers sendPrompt, append a ↗ arrow.
189
+ - **Round every displayed number.** JS float math leaks artifacts — `0.1 + 0.2` gives `0.30000000000000004`, `7 * 1.1` gives `7.700000000000001`. Any number that reaches the screen (slider readouts, stat card values, axis labels, data-point labels, tooltips, computed totals) must go through `Math.round()`, `.toFixed(n)`, or `Intl.NumberFormat`. Pick the precision that makes sense for the context — integers for counts, 1–2 decimals for percentages, `toLocaleString()` for currency. For range sliders, also set `step="1"` (or step="0.1" etc.) so the input itself emits round values.
190
+ - Spacing: use rem for vertical rhythm (1rem, 1.5rem, 2rem), px for component-internal gaps (8px, 12px, 16px)
191
+ - Box-shadows: none, except `box-shadow: 0 0 0 Npx` focus rings on inputs
192
+
193
+ ### Metric cards
194
+ For summary numbers (revenue, count, percentage) — surface card with muted 13px label above, 24px/500 number below. `background: var(--color-background-secondary)`, no border, `border-radius: var(--border-radius-md)`, padding 1rem. Use in grids of 2-4 with `gap: 12px`. Distinct from raised cards (which have white bg + border).
195
+
196
+ ### Layout
197
+ - Editorial (explanatory content): no card wrapper, prose flows naturally
198
+ - Card (bounded objects like a contact record, receipt): single raised card wraps the whole thing
199
+ - Don't put tables here — output them as markdown in your response text
200
+
201
+ **Grid overflow:** `grid-template-columns: 1fr` has `min-width: auto` by default — children with large min-content push the column past the container. Use `minmax(0, 1fr)` to clamp.
202
+
203
+ **Table overflow:** Tables with many columns auto-expand past `width: 100%` if cell contents exceed it. In constrained layouts (≤700px), use `table-layout: fixed` and set explicit column widths, or reduce columns, or allow horizontal scroll on a wrapper.
204
+
205
+ ### Mockup presentation
206
+ Contained mockups — mobile screens, chat threads, single cards, modals, small UI components — should sit on a background surface (`var(--color-background-secondary)` container with `border-radius: var(--border-radius-lg)` and padding, or a device frame) so they don't float naked on the widget canvas. Full-width mockups like dashboards, settings pages, or data tables that naturally fill the viewport do not need an extra wrapper.
207
+
208
+ ### 1. Interactive explainer — learn how something works
209
+ *"Explain how compound interest works" / "Teach me about sorting algorithms"*
210
+
211
+ Use `imagine_html` for the interactive controls — sliders, buttons, live state displays, charts. Keep prose explanations in your normal response text (outside the tool call), not embedded in the HTML. No card wrapper. Whitespace is the container.
212
+
213
+ ```html
214
+ <div style="display: flex; align-items: center; gap: 12px; margin: 0 0 1.5rem;">
215
+ <label style="font-size: 14px; color: var(--color-text-secondary);">Years</label>
216
+ <input type="range" min="1" max="40" value="20" id="years" style="flex: 1;" />
217
+ <span style="font-size: 14px; font-weight: 500; min-width: 24px;" id="years-out">20</span>
218
+ </div>
219
+
220
+ <div style="display: flex; align-items: baseline; gap: 8px; margin: 0 0 1.5rem;">
221
+ <span style="font-size: 14px; color: var(--color-text-secondary);">£1,000 →</span>
222
+ <span style="font-size: 24px; font-weight: 500;" id="result">£3,870</span>
223
+ </div>
224
+
225
+ <div style="margin: 2rem 0; position: relative; height: 240px;">
226
+ <canvas id="chart"></canvas>
227
+ </div>
228
+ ```
229
+
230
+ Use `sendPrompt()` to let users ask follow-ups: `sendPrompt('What if I increase the rate to 10%?')`
231
+
232
+ ### 2. Compare options — decision making
233
+ *"Compare pricing and features of these products" / "Help me choose between React and Vue"*
234
+
235
+ Use `imagine_html`. Side-by-side card grid for options. Highlight differences with semantic colors. Interactive elements for filtering or weighting.
236
+
237
+ - Use `repeat(auto-fit, minmax(160px, 1fr))` for responsive columns
238
+ - Each option in a card. Use badges for key differentiators.
239
+ - Add `sendPrompt()` buttons: `sendPrompt('Tell me more about the Pro plan')`
240
+ - Don't put comparison tables inside this tool — output them as regular markdown tables in your response text instead. The tool is for the visual card grid only.
241
+ - When one option is recommended or "most popular", accent its card with `border: 2px solid var(--color-border-info)` only (2px is deliberate — the only exception to the 0.5px rule, used to accent featured items) — keep the same background and border as the other cards. Add a small badge (e.g. "Most popular") above or inside the card header using `background: var(--color-background-info); color: var(--color-text-info); font-size: 12px; padding: 4px 12px; border-radius: var(--border-radius-md)`.
242
+
243
+ ### 3. Data record — bounded UI object
244
+ *"Show me a Salesforce contact card" / "Create a receipt for this order"*
245
+
246
+ Use `imagine_html`. Wrap the entire thing in a single raised card. All content is sans-serif since it's pure UI. Use an avatar/initials circle for people (see example below).
247
+
248
+ ```html
249
+ <div style="background: var(--color-background-primary); border-radius: var(--border-radius-lg); border: 0.5px solid var(--color-border-tertiary); padding: 1rem 1.25rem;">
250
+ <div style="display: flex; align-items: center; gap: 12px; margin-bottom: 16px;">
251
+ <div 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</div>
252
+ <div>
253
+ <p style="font-weight: 500; font-size: 15px; margin: 0;">Maya Rodriguez</p>
254
+ <p style="font-size: 13px; color: var(--color-text-secondary); margin: 0;">VP of Engineering</p>
255
+ </div>
256
+ </div>
257
+ <div style="border-top: 0.5px solid var(--color-border-tertiary); padding-top: 12px;">
258
+ <table style="width: 100%; font-size: 13px;">
259
+ <tr><td style="color: var(--color-text-secondary); padding: 4px 0;">Email</td><td style="text-align: right; padding: 4px 0; color: var(--color-text-info);">m.rodriguez@acme.com</td></tr>
260
+ <tr><td style="color: var(--color-text-secondary); padding: 4px 0;">Phone</td><td style="text-align: right; padding: 4px 0;">+1 (415) 555-0172</td></tr>
261
+ </table>
262
+ </div>
263
+ </div>
264
+ ```
265
+
266
+
267
+ ## Color palette
268
+
269
+ 9 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.
270
+
271
+ | Class | Ramp | 50 (lightest) | 100 | 200 | 400 | 600 | 800 | 900 (darkest) |
272
+ |-------|------|------|-----|-----|-----|-----|-----|------|
273
+ | `c-purple` | Purple | #EEEDFE | #CECBF6 | #AFA9EC | #7F77DD | #534AB7 | #3C3489 | #26215C |
274
+ | `c-teal` | Teal | #E1F5EE | #9FE1CB | #5DCAA5 | #1D9E75 | #0F6E56 | #085041 | #04342C |
275
+ | `c-coral` | Coral | #FAECE7 | #F5C4B3 | #F0997B | #D85A30 | #993C1D | #712B13 | #4A1B0C |
276
+ | `c-pink` | Pink | #FBEAF0 | #F4C0D1 | #ED93B1 | #D4537E | #993556 | #72243E | #4B1528 |
277
+ | `c-gray` | Gray | #F1EFE8 | #D3D1C7 | #B4B2A9 | #888780 | #5F5E5A | #444441 | #2C2C2A |
278
+ | `c-blue` | Blue | #E6F1FB | #B5D4F4 | #85B7EB | #378ADD | #185FA5 | #0C447C | #042C53 |
279
+ | `c-green` | Green | #EAF3DE | #C0DD97 | #97C459 | #639922 | #3B6D11 | #27500A | #173404 |
280
+ | `c-amber` | Amber | #FAEEDA | #FAC775 | #EF9F27 | #BA7517 | #854F0B | #633806 | #412402 |
281
+ | `c-red` | Red | #FCEBEB | #F7C1C1 | #F09595 | #E24B4A | #A32D2D | #791F1F | #501313 |
282
+
283
+ **How to assign colors**: Color should encode meaning, not sequence. Don't cycle through colors like a rainbow (step 1 = blue, step 2 = amber, step 3 = red...). Instead:
284
+ - Group nodes by **category** — all nodes of the same type share one color. E.g. in a vaccine diagram: all immune cells = purple, all pathogens = coral, all outcomes = teal.
285
+ - For illustrative diagrams, map colors to **physical properties** — warm ramps for heat/energy, cool for cold/calm, green for organic, gray for structural/inert.
286
+ - Use **gray for neutral/structural** nodes (start, end, generic steps).
287
+ - Use **2-3 colors per diagram**, not 6+. More colors = more visual noise. A diagram with gray + purple + teal is cleaner than one using every ramp.
288
+ - **Prefer purple, teal, coral, pink** for general diagram categories. Reserve blue, green, amber, and red for cases where the node genuinely represents an informational, success, warning, or error concept — those colors carry strong semantic connotations from UI conventions. (Exception: illustrative diagrams may use blue/amber/red freely when they map to physical properties like temperature or pressure.)
289
+
290
+ **Text on colored backgrounds:** Always use the 800 or 900 stop from the same ramp as the fill. Never use black, gray, or --color-text-primary on colored fills. **When a box has both a title and a subtitle, they must be two different stops** — title darker (800 in light mode, 100 in dark), subtitle lighter (600 in light, 200 in dark). Same stop for both reads flat; the weight difference alone isn't enough. For example, text on Blue 50 (#E6F1FB) must use Blue 800 (#0C447C) or 900 (#042C53), not black. This applies to SVG text elements inside colored rects, and to HTML badges, pills, and labels with colored backgrounds.
291
+
292
+ **Light/dark mode quick pick** — use only stops from the table, never off-table hex values:
293
+ - **Light mode**: 50 fill + 600 stroke + **800 title / 600 subtitle**
294
+ - **Dark mode**: 800 fill + 200 stroke + **100 title / 200 subtitle**
295
+ - Apply `c-{ramp}` to a `<g>` wrapping shape+text, or directly to a `<rect>`/`<circle>`/`<ellipse>`. Never to `<path>` — paths don't get ramp fill. For colored connector strokes use inline `stroke="#..."` (any mid-ramp hex works in both modes). Dark mode is automatic for ramp classes. Available: c-gray, c-blue, c-red, c-amber, c-green, c-teal, c-purple, c-coral, c-pink.
296
+
297
+ For status/semantic meaning in UI (success, warning, danger) use CSS variables. For categorical coloring in both diagrams and UI, use these ramps.