Product Scenario Diagram Generator · v2 / v3
Given a "title," produce a 1760×1120 scenario diagram. The style is fixed; do not redesign—just choose the layout + fill in the content.
Two orientations, pick one first:
| v2 · Cards | v3 · Graphic | |
|---|---|---|
| Subject | Rounded rectangle nodes + short labels | Large icons / circular nodes / graphic widgets |
| Content area | Has a solid white content card | None, graphics float directly on the light blue panel |
| Text volume | 5–7 entries of 2–4 characters | 3–4 entries of 2–3 characters |
| Best for | When you need to list and explain 5–6 concepts side by side | Few points, you want the graphics to speak for themselves |
| Templates | template-b/c-* | template-d/e-* |
Default to v3—these images often end up scaled to 240px wide, and graphics hold up better under scaling than text. Only fall back to v2 when the information itself is "5 parallel items, each must be read."
Why use HTML/CSS rendering instead of AI image generation: This set of diagrams has precise text and 1px strokes. Diffusion models blur text and stroke lines, and the same prompt produces different results each time. HTML rendering → screenshot: text is always clear, always editable, batchable, and reproducible.
Why the structure must be simple: The final viewing size for these diagrams is often 240px wide (web card), not 1760. At a 1/7 scale, "six nodes + micro-chart + thin skeleton bars" all turn into gray noise. The hard metric for v2 is: scaled to 240px, you can still read the gist of the title and each label.
Scaling Ruler (Memorize This Table First)
| Viewing Width | Scale | 48px Text Actual Display | Conclusion |
|---|---|---|---|
| 1760 (PPT fullscreen) | 1:1 | 48px | A bit large but acceptable |
| 480 (web large image) | 1/3.7 | 13px | Comfortable |
| 240 (web card) | 1/7.3 | 6.6px | Design verification size |
| 190 (list thumbnail) | 1/9.3 | 5.2px | At the limit |
Therefore: any text smaller than 40px must not appear, and any element smaller than 300px wide cannot support details.
Iron Laws (Violate any one and the result won't look right)
- Canvas 1760×1120 (11:7), pure white background, no gradient, no vignette, no border.
- The outer shell + panel two-layer coordinates are fixed; do not change them. This is the only source of "depth." The third-layer content white card belongs only to v2; v3 does not use it; graphics sit directly on the panel.
- The entire diagram has exactly 1 gradient icon tile, 170–200px square. It is the visual focal point.
- Total content area elements ≤ 7 (lines, handles do not count). More than 7, and they become noise in the thumbnail.
- Text: Title 76px, labels 48–50px, badge 44px. No 20px text exists.
- Hue locked to 200°–250°. The only warm color
#F58A8Acan only be used for "alerts." - No people, no perspective, no 3D, no photos, no environmental backgrounds. All rectangles strictly axis-aligned.
- Output only 1760×1120 one size, do not export derived thumbnail sizes like 660×420.
- All text must be real text (HTML text), not images or paths.
- Every connector line must have both ends resting on an element edge or on another line. Before delivery, the
render.pylink check must pass (exit code 0).
Fixed Geometry (Copy exactly, do not change)
| Layer | Element | left | top | w | h | r |
|---|---|---|---|---|---|---|
| L0 | canvas | 0 | 0 | 1760 | 1120 | – |
| L1 | shell outer white card | 110 | 66 | 1520 | 968 | 62 |
| L2 | panel light blue panel | 140 | 96 | 1460 | 908 | 50 |
| L3 | content white card | 180 | 240 | 1310 | 644 | 40 |
| L4 | badge marker | 1312 | custom | 320 | 128 | 32 |
| – | title | 190 | 132 | – | – | 76px / 600 |
Derived boundaries (for aligning content):
- Panel right edge 1600, bottom edge 1004; content card right edge 1490, bottom edge 884.
- Leave 120px blue strip from content card bottom to panel bottom (
1004 − 884). - Badge right edge 1632, extends 32px beyond panel—this is the "breakout," do not push it back into the card.
- Content area usable width = 180→1490, minus left/right 60px inner padding = 1190, elements must fit between 240–1430.
- Badge occupies 1312 and beyond, content element right edge must not exceed 1230, otherwise it will be covered.
Panel gradient (must stop at #F5FAFF, no lighter):
background:linear-gradient(180deg,#E4F1FF 0%,#E9F4FF 34%,#F2F9FF 74%,#F5FAFF 100%);
Element Size Minimums (v2)
| Element | Size | Description |
|---|---|---|
| Gradient tile | 170–200 square | Occupies 10–11% width, largest color block |
| Wide layer strip | 910×152 | One strip per layer, holds "icon + layer name" |
| Regular node | 330×132 | Three per row, spacing 35 |
| Output small card | 360×120 | Three per row, spacing 40 |
| Badge | 320×128 | Icon 46 + 44px text |
| Icon | 50–54 | stroke-width 2.2, too thin and it disappears when scaled |
| Connector line | 4px | dasharray 12 10, arrow is isosceles triangle |
| Selection handle | 20×20 | border 3px, center aligned to node corner |
Workflow
Step 1 · Long Title → Short Title + Badge
- Take the feature name, compress to 4–6 Chinese characters: "Technical Documentation & Knowledge Base Visualization-…" → "Document Diagram Generation."
- Badge copy is 4 characters (320px only fits 4 characters at 44px), must make a "promise": "One-Click Insert," "Only Change This Block," "Layout Unchanged," "Locally Editable."
- Example sentence writes a real sentence, do not write "Example Text."
Step 2 · Choose a Layout
| Title Feature | Layout | Template |
|---|---|---|
| One core → multiple output types, capability radiation, one hub N scenarios | D Core Branch (v3) | assets/template-d-orbit.html |
| A→B→C three steps, Upload → Parse → Store, Build → Test → Release | E Circular Pipeline (v3) | assets/template-e-pipeline.html |
| Input → Generate → Multiple outputs, transform, organize (needs text labels to explain) | B Top→Down Branch (v2) | assets/template-b-flow.html |
| Both "one-sentence generation" and "can edit after generation" (needs interface feel) | C-1 Canvas Editing State (v2) | assets/template-c-ui.html |
| Layered architecture (Access / Service / Data) explain layer by layer | C-2 Layered Selection State (v2) | assets/template-c-arch.html |
See references/layouts.md for details. Not sure: key points ≤ 4 go with D or E; information must be laid out sequentially to use C-2 (it looks clearest in thumbnails).
Step 3 · Modify the Template
Copy a template, only change these few things, do not modify a single line of the shell CSS:
.titletext;- Short labels in each item/node/card (2–4 characters);
- Badge
.badgetext (4 characters) +top(two badges vertical spacing ≥40px); - Example sentences in input fields / bubbles;
- When deleting an element, simultaneously delete its connector lines and arrows, otherwise dangling line ends will remain;
- When modifying connector lines, must follow the "hub + independent segment" method described in "How to Draw Connector Lines Without Breaking Them"—do not add turns arbitrarily.
Step 4 · Render
python <SKILL_DIR>/scripts/render.py <input.html> <output.png>
<SKILL_DIR> is the installation directory of this skill (where SKILL.md is located), not the current working directory—
your cwd is usually the user's project; directly writing scripts/render.py will fail to find the file.
The script copies the HTML to an ASCII temporary directory and then calls the headless browser—Chinese paths cause headless to silently fail, outputting a blank or old image. It also verifies the output is 1760×1120 and automatically checks that all connector line endpoints are not dangling—exit code 3 means broken lines, do not deliver.
Step 5 · Thumbnail Self-Check (Most Important Step)
python <SKILL_DIR>/scripts/preview.py <output.png> --width 240
You must actually look at the thumbnail, check against references/checklist.md. The judgment standard is only one sentence:
Scaled to 240px, can you still read the title, the gist of each label, and "which part is the focus"?
If not, then reduce elements, increase font size, do not add more detail.
v3 · Graphic (Icon & Graphic Element Driven)
One sentence: If you can draw it, don't write it.
v2 every element is "rounded rectangle + icon + text," all isomorphic, so the entire diagram reads like a set of process blocks. v3 only changes three things—remove the content white card, triple the icon size, let the graphics carry the semantics themselves.
Three Hard Rules
- Do not lay out the content white card. Graphics float directly on the light blue panel; white backgrounds are only for small items like badges, markers. Boundaries rely on shadows, not strokes.
- Icons ≥ 84px. Visual line width =
stroke × display size / 24, target 7–9px (about 1px when scaled to 240px). - Labels ≤ 4 entries, each 2–3 characters. More than 4 entries means you are still using text to explain things—go back and draw that information as a graphic.
Icon Library (50 Icons)
assets/icons.svg is a sprite. Inline the entire content into the page to use:
<body>
<!-- Paste all content of assets/icons.svg here -->
<svg><use href="#i-database"/></svg>
</body>
External references (<use href="icons.svg#i-database"/>) will be blocked by the browser due to cross-origin policy under file://,
and icons will completely disappear in the headless screenshot without any error.
python <SKILL_DIR>/scripts/iconlib.py --list # List all ids grouped
python <SKILL_DIR>/scripts/iconlib.py --preview p.png # Generate icon wall for picking icons
Groups: Charts/Drawings 12 · Technical Elements 15 · AI & Content 18 · Interactions 5.
Do not write stroke-width inside the symbol; match based on display size:
| Display Size | stroke |
|---|---|
| 84–108 | 1.9–2.0 |
| 130–140 | 1.5 |
| 170–190 | 1.3 |
If you cannot find a suitable icon, pick a similar one, do not draw a new shape on the fly—if line styles are inconsistent, the whole diagram immediately looks fake.
Element Parts (15 Items)
assets/parts.html is a page of part wall; each has a real sample + class name + size. Just copy HTML + CSS:
Gradient Tile · White Circle Badge · Breakout Badge · Label Capsule · Window Frame · Layer Stack · Gradient Arrow · Dashed Line · Selection Handle · Instruction Bubble · Ring Progress · Mini Bar Chart · Dot Pattern · Star Burst · Selected Tile.
Two Layouts
- D Core Branch → One core → multiple outputs. Center is "three staggered stacked pages + star burst," not a single icon.
- E Circular Pipeline → A→B→C three steps. The middle block is the only gradient element and the reader's first landing spot.
Both are assembled from the parts above; modifying the diagram just requires swapping icons and 2–3 character labels.
v2 Layout Skeletons
B Top→Down Branch (template-b-flow.html)
Input capsule 690×136 centered → vertical line → gradient tile 200 → vertical line to bus bar → horizontal bus bar splits into three branches → three output cards 360×120. Badge in top right.
C-1 Canvas Editing State (template-c-ui.html)
Top left tile 170 + input bar 850×118 → light blue canvas base 1160×352, contains three nodes 330×132, middle node selected → instruction bubble 430×112 below, connected to selected node with 4px dashed line. Badge in top right.
C-2 Layered Selection State (template-c-arch.html)
Three 910×152 layer strips stacked vertically (spacing 40, entire group vertically centered), middle one selected with a 104px gradient small tile → two badges on the right. Least information, best thumbnail readability.
v2 Element Parts (6, Enough)
- Gradient Icon Tile —
170–200 / r44–52 / linear-gradient(135deg,#4A9DFC,#5E92F9 45%,#7C6BF5)+ white linear icon (84–100px, stroke-width 1.6) + bottom glow0 18 40 rgba(74,157,252,.42), 0 0 40 8 rgba(124,107,245,.14). - Badge — White background
320×128 / r32+0 20 48 rgba(31,71,141,.16)+ 46px blue icon + 44px text. - Layer Strip / Node — White background +
3px #C9DCF2stroke + 90px light blue rounded icon block +50px/500label. Do not add skeleton bars, just write real text. - Selected State —
5px #4A9DFC+0 0 0 12px rgba(74,157,252,.11)+ four-corner 20px handles (center aligned to corners) + optional embedded gradient small tile. Do not draw a dashed selection box (lines will pass through it). - Connector Line —
4px / #A9C7EC / dasharray 12 10, arrow is an isosceles triangleM827 716 h16 l-8 14 z. Cannot use a right triangle. - Canvas Base —
#F8FBFF / 2px #DDEBFB / r36, groups "nodes + bubbles" together to avoid a scattered image.
How to Draw Connector Lines Without Breaking Them
Connector lines are the only part that requires manually writing absolute coordinates, and they are the most error-prone. A line missing hundreds of pixels can still make the whole drawing look "okay"—it's invisible at 1760 original size without zooming in, and at 240px it's completely invisible, until someone points it out after delivery.
Branches Must Be Split into "Hub + Independent Segments"
Wrong—one path turns mid-way and branches, the bus bar only covers the leftmost branch:
<path d="M835 652 V690 H435 V716"/> <!-- vertical → left horizontal → vertical, breaks here -->
<path d="M835 690 V716"/>
<path d="M1235 690 V716"/> <!-- start point hangs in empty space -->
Correct—all intersections coincide at the endpoint level:
<path d="M835 652 V690"/> <!-- vertical line lands at hub (835,690) -->
<path d="M835 690 H435"/> <!-- left half of bus bar -->
<path d="M835 690 H1235"/> <!-- right half of bus bar -->
<path d="M435 690 V716"/> <!-- three branch lines, start point y all equal to bus bar y -->
<path d="M835 690 V716"/>
<path d="M1235 690 V716"/>
Three rules:
- One path does only one thing: either goes straight down or goes straight across. Do not turn and then branch mid-path.
- Bus bar ends must equal the x of the leftmost and rightmost branch lines; these three numbers must literally be identical in the code. Change one side, adjust the other.
- Branch line end point y = card top − 14 (14 is arrow height); branch line start point y = bus bar y.
Automatically Checked at Every Render
render.py automatically calls linklint.py after rendering: it has the browser compute the actual endpoints of each line,
then checks whether each endpoint touches an element edge (≤8px) or intersects another line (≤3px).
If not satisfied, it's a dangling line, and the coordinates are printed:
[x] Found 1 dangling endpoint:
Line 6, start point at (1235,690), nearest object is 40px away d="M1235 690 V716"
In this case, the exit code is 3, do not deliver. You can also check separately:
python <SKILL_DIR>/scripts/linklint.py scene.html -v
Filled shapes like arrow triangles and relation diamonds are not checked (their base is already placed on the line end), but they are treated as connectable targets—so connecting a line to an arrow is valid.
This check only recognizes geometry, not "looks about right." It once caught a real incident: The right branch of a three-way fork was missing an entire 800px horizontal segment, while the entire diagram looked perfectly normal to the naked eye.
Common Mistakes (All Real Experiences)
| Phenomenon | Cause | Fix |
|---|---|---|
| Blurs into a gray mess at 240px | Elements too small, too many | Reduce elements to ≤7, increase font size to 48px, thicken strokes to 3–5px |
| Skeleton bars look like gray noise in thumbnail | Used decorative skeleton bars | Replace with real short labels (2–4 characters) |
| White strip at bottom, panel looks like just a border | Gradient fades to #FBFCFE | Stop at #F5FAFF |
| Badge covers content | Content element exceeds 1230 | Keep content right edge within 1230 |
| Handle floats outside corner | Hand-written top not halved | handle.left = corner x − 10, top = corner y − 10 |
| Dashed line invisible | Covered by selected node's glow | Add z-index:6 to the svg containing the connector line |
| Arrow skewed, looks like right triangle | Path written incorrectly | Use isosceles triangle, see part 5 |
| Horizontal bus bar pressing on card | Branch point too low | Tile bottom → bus bar ≥38px, bus bar → card ≥40px |
| Three cards unevenly spaced | Hand-written left | Arrange equally spaced and verify center points align with arrows |
| Rendering blank/old image | HTML in Chinese path | Use scripts/render.py |
| Three diagrams inconsistent density | Element sizes each written differently | Use all values from "Element Size Minimums" table |
| Line breaks mid-way, branch line dangling | One path turns and only covers part of branches | Split into "hub + independent segments," see "How to Draw Connector Lines Without Breaking Them" |
| Bubble dashed line leaves a gap from node | Start point not on element edge | Start point y = element bottom, let linklint verify to 0px |
File Index
This skill is self-contained: all paths below are relative to the directory containing SKILL.md, no need to access other repositories or external documents.
SKILL.md
├── references/
│ ├── style-tokens.md Complete token table for colors, font sizes, border radii, shadows (including v3 graphic tokens)
│ ├── layouts.md Skeleton diagrams, applicable scenarios, element recipes for five layouts
│ └── checklist.md Pre-delivery checklist (includes 240px thumbnail verification, v3-specific items)
├── assets/
│ ├── icons.svg 50 linear icon sprite (inline into page, then <use href="#i-xxx"/>)
│ ├── parts.html 15 graphic part wall, can be viewed or copied
│ ├── template-d-orbit.html D Core Branch (v3)
│ ├── template-e-pipeline.html E Circular Pipeline (v3)
│ ├── _blank-shell.html Only shell layers, for building layouts from scratch
│ ├── template-b-flow.html B Top→Down Branch (v2)
│ ├── template-c-ui.html C-1 Canvas Editing State (v2)
│ └── template-c-arch.html C-2 Layered Selection State (v2)
├── scripts/
│ ├── render.py HTML → 1760×1120 PNG (path handling + browser detection + link check)
│ ├── linklint.py Check if each connector line's endpoint is dangling (automatically called by render.py)
│ ├── preview.py Generate 240px thumbnail for "thumbnail self-check"
│ └── iconlib.py List icon ids / generate icon wall
└── examples/ 5 finished diagrams + renderable source files, for reference only, not for generation
Text and graphics in templates are runnable real examples; modifying them directly is faster than starting from a blank page.