CommunityImagegithub.com

hwcloud-scene-image

Generates a product scenario diagram—a 1760×1120 PNG in a flat vector UI schematic style—with a pure white canvas, three-layer rounded card layout, blue-purple 135° gradient, strict 0° perspective, no people, and no photos. Offers v2 (card + short labels) and v3 (large icons / circular nodes / graphic widgets, minimal text) orientations, with 50 built-in linear icons and 15 graphic parts. The core constraint is thumbnail readability: the image will be displayed in a web card scaled down to 240px width. Use when you need a consistent, stylized diagram for product features, solution highlights, or technical capabilities that can be directly placed into PPT slides, websites, or product pages, or when you need to batch produce diagrams by title.

What is hwcloud-scene-image?

This AI agent skill automates the creation of product scenario diagrams in a flat, vector UI style optimized for thumbnail readability. It generates a strict 1760×1120 PNG image from a user-provided title, enforcing a unique visual system: pure white canvas, two or three layers of rounded cards, a blue-purple 135° gradient panel, and no 3D, perspective, people, or photos. The skill offers two distinct approaches: v2 (card-based, with short labels for text-heavy scenarios like listing 5-6 concepts) and v3 (graphic-driven, using large icons and minimal 2-3 character labels for low-text, high-visual-impact scenarios). Built-in assets include 50 linear icons and 15 graphic parts. The critical design constraint is that the image will often be viewed at only 240px width inside a web card, so every element—font size, stroke width, number of components—must survive a 7x reduction. The skill uses HTML/CSS rendering via a headless browser to a PNG snapshot, ensuring perfectly crisp text and reproducible outputs that AI image generators cannot achieve. It provides six fixed layout templates (B/C for v2, D/E for v2/v3), a strict geometry guide, automated link-integrity checking to prevent dangling connector lines, a thumbnail preview script for final validation, and a full file index of reference assets (style tokens, layout docs, checklist, icons, parts).

Works with✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/sunhaha369369/hwcloud-scene-image-skill/tree/HEAD

Installed? Explore more Image skills: steipete/songsee, affaan-m/frontend-design, mattpocock/improve-codebase-architecture · View all 6 →

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

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 · Cardsv3 · Graphic
SubjectRounded rectangle nodes + short labelsLarge icons / circular nodes / graphic widgets
Content areaHas a solid white content cardNone, graphics float directly on the light blue panel
Text volume5–7 entries of 2–4 characters3–4 entries of 2–3 characters
Best forWhen you need to list and explain 5–6 concepts side by sideFew points, you want the graphics to speak for themselves
Templatestemplate-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 WidthScale48px Text Actual DisplayConclusion
1760 (PPT fullscreen)1:148pxA bit large but acceptable
480 (web large image)1/3.713pxComfortable
240 (web card)1/7.36.6pxDesign verification size
190 (list thumbnail)1/9.35.2pxAt 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)

  1. Canvas 1760×1120 (11:7), pure white background, no gradient, no vignette, no border.
  2. 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.
  3. The entire diagram has exactly 1 gradient icon tile, 170–200px square. It is the visual focal point.
  4. Total content area elements ≤ 7 (lines, handles do not count). More than 7, and they become noise in the thumbnail.
  5. Text: Title 76px, labels 48–50px, badge 44px. No 20px text exists.
  6. Hue locked to 200°–250°. The only warm color #F58A8A can only be used for "alerts."
  7. No people, no perspective, no 3D, no photos, no environmental backgrounds. All rectangles strictly axis-aligned.
  8. Output only 1760×1120 one size, do not export derived thumbnail sizes like 660×420.
  9. All text must be real text (HTML text), not images or paths.
  10. Every connector line must have both ends resting on an element edge or on another line. Before delivery, the render.py link check must pass (exit code 0).

Fixed Geometry (Copy exactly, do not change)

LayerElementlefttopwhr
L0canvas0017601120–
L1shell outer white card11066152096862
L2panel light blue panel14096146090850
L3content white card180240131064440
L4badge marker1312custom32012832
–title190132––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)

ElementSizeDescription
Gradient tile170–200 squareOccupies 10–11% width, largest color block
Wide layer strip910×152One strip per layer, holds "icon + layer name"
Regular node330×132Three per row, spacing 35
Output small card360×120Three per row, spacing 40
Badge320×128Icon 46 + 44px text
Icon50–54stroke-width 2.2, too thin and it disappears when scaled
Connector line4pxdasharray 12 10, arrow is isosceles triangle
Selection handle20×20border 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 FeatureLayoutTemplate
One core → multiple output types, capability radiation, one hub N scenariosD Core Branch (v3)assets/template-d-orbit.html
A→B→C three steps, Upload → Parse → Store, Build → Test → ReleaseE 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 layerC-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:

  1. .title text;
  2. Short labels in each item/node/card (2–4 characters);
  3. Badge .badge text (4 characters) + top (two badges vertical spacing ≥40px);
  4. Example sentences in input fields / bubbles;
  5. When deleting an element, simultaneously delete its connector lines and arrows, otherwise dangling line ends will remain;
  6. 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

  1. 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.
  2. Icons ≥ 84px. Visual line width = stroke × display size / 24, target 7–9px (about 1px when scaled to 240px).
  3. 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 Sizestroke
84–1081.9–2.0
130–1401.5
170–1901.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)

  1. Gradient Icon Tile — 170–200 / r44–52 / linear-gradient(135deg,#4A9DFC,#5E92F9 45%,#7C6BF5) + white linear icon (84–100px, stroke-width 1.6) + bottom glow 0 18 40 rgba(74,157,252,.42), 0 0 40 8 rgba(124,107,245,.14).
  2. Badge — White background 320×128 / r32 + 0 20 48 rgba(31,71,141,.16) + 46px blue icon + 44px text.
  3. Layer Strip / Node — White background + 3px #C9DCF2 stroke + 90px light blue rounded icon block + 50px/500 label. Do not add skeleton bars, just write real text.
  4. 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).
  5. Connector Line — 4px / #A9C7EC / dasharray 12 10, arrow is an isosceles triangle M827 716 h16 l-8 14 z. Cannot use a right triangle.
  6. 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:

  1. One path does only one thing: either goes straight down or goes straight across. Do not turn and then branch mid-path.
  2. 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.
  3. 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)

PhenomenonCauseFix
Blurs into a gray mess at 240pxElements too small, too manyReduce elements to ≤7, increase font size to 48px, thicken strokes to 3–5px
Skeleton bars look like gray noise in thumbnailUsed decorative skeleton barsReplace with real short labels (2–4 characters)
White strip at bottom, panel looks like just a borderGradient fades to #FBFCFEStop at #F5FAFF
Badge covers contentContent element exceeds 1230Keep content right edge within 1230
Handle floats outside cornerHand-written top not halvedhandle.left = corner x − 10, top = corner y − 10
Dashed line invisibleCovered by selected node's glowAdd z-index:6 to the svg containing the connector line
Arrow skewed, looks like right trianglePath written incorrectlyUse isosceles triangle, see part 5
Horizontal bus bar pressing on cardBranch point too lowTile bottom → bus bar ≥38px, bus bar → card ≥40px
Three cards unevenly spacedHand-written leftArrange equally spaced and verify center points align with arrows
Rendering blank/old imageHTML in Chinese pathUse scripts/render.py
Three diagrams inconsistent densityElement sizes each written differentlyUse all values from "Element Size Minimums" table
Line breaks mid-way, branch line danglingOne path turns and only covers part of branchesSplit into "hub + independent segments," see "How to Draw Connector Lines Without Breaking Them"
Bubble dashed line leaves a gap from nodeStart point not on element edgeStart 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.

Related Skills