medesign 0.0.0-stage → 1.2.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.
- package/LICENSE +21 -0
- package/README.md +128 -2
- package/bin/medesign.js +200 -0
- package/integrations/claude-code/SKILL.md +20 -0
- package/integrations/cursor/medesign.mdc +26 -0
- package/medesign.config.js +46 -0
- package/package.json +62 -4
- package/presets/apple/design-tokens.css +115 -0
- package/presets/apple/guidelines.md +19 -0
- package/presets/apple/preset.json +53 -0
- package/presets/metha/design-tokens.css +127 -0
- package/presets/metha/guidelines.md +23 -0
- package/presets/metha/preset.json +53 -0
- package/presets/schema.json +102 -0
- package/presets/tesla/design-tokens.css +112 -0
- package/presets/tesla/guidelines.md +17 -0
- package/presets/tesla/preset.json +53 -0
- package/references/ai-tells.md +127 -0
- package/references/appendices.md +220 -0
- package/references/architecture.md +39 -0
- package/references/argon-design-archetypes.md +317 -0
- package/references/banner-sizes-and-styles.md +118 -0
- package/references/block-library.md +61 -0
- package/references/brand-design-tokens.md +42 -0
- package/references/catalog.json +108 -0
- package/references/cip-deliverable-guide.md +95 -0
- package/references/cip-design.md +121 -0
- package/references/cip-prompt-engineering.md +84 -0
- package/references/cip-style-guide.md +68 -0
- package/references/cli-architecture.md +146 -0
- package/references/components.md +240 -0
- package/references/dark-mode.md +23 -0
- package/references/design-core.md +42 -0
- package/references/design-md-protocol.md +75 -0
- package/references/design-routing.md +207 -0
- package/references/eng-imagery-content.md +71 -0
- package/references/eng-layout.md +28 -0
- package/references/eng-other.md +26 -0
- package/references/eng-states-theme.md +22 -0
- package/references/eng-type-color.md +44 -0
- package/references/icon-design.md +122 -0
- package/references/image-mockup-direction.md +53 -0
- package/references/image-to-code.md +46 -0
- package/references/impeccable-polish.md +85 -0
- package/references/intake.md +90 -0
- package/references/logo-color-psychology.md +101 -0
- package/references/logo-design.md +110 -0
- package/references/logo-prompt-engineering.md +158 -0
- package/references/logo-style-guide.md +109 -0
- package/references/mesurv-dna.md +104 -0
- package/references/micro-interactions-and-auto-animate.md +71 -0
- package/references/modern-craft-invariants.md +332 -0
- package/references/motion-tokens.md +99 -0
- package/references/preflight.md +110 -0
- package/references/proactive-motion.md +167 -0
- package/references/quality-gate.md +147 -0
- package/references/redesign-audit.md +38 -0
- package/references/redesign.md +52 -0
- package/references/slides-copywriting-formulas.md +84 -0
- package/references/slides-create.md +4 -0
- package/references/slides-html-template.md +295 -0
- package/references/slides-layout-patterns.md +137 -0
- package/references/slides-strategies.md +94 -0
- package/references/slides.md +42 -0
- package/references/social-photos-design.md +329 -0
- package/references/spatial-canvas-engine.md +160 -0
- package/references/stitch-system.md +184 -0
- package/references/style-extraction.md +17 -0
- package/references/styles/brutalist.md +88 -0
- package/references/styles/minimalist.md +81 -0
- package/references/styles/soft.md +94 -0
- package/references/threeui-spatial-engine.md +224 -0
- package/references/ui-styling-shadcn.md +336 -0
- package/references/ui-ux-vocabulary-vault.json +1223 -0
- package/references/ui-ux-vocabulary-vault.md +438 -0
- package/references/vocab-protocol.md +52 -0
- package/references/vocabulary.md +78 -0
- package/scripts/export-tokens.js +403 -0
- package/tests/browser-audit.js +442 -0
- package/tests/linter.js +412 -0
- package/tests/schemas/sarif-2.1.0.schema.json +2915 -0
- package/tests/visual-testbed.html +681 -0
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
# Social Photos Design Guide
|
|
2
|
+
|
|
3
|
+
Design social media images via HTML/CSS rendering + screenshot export. Orchestrates the bundled `ui-ux-pro-max`, `brand`, and `design-system` skills; screenshot export runs through Chrome headless, Playwright, or Puppeteer.
|
|
4
|
+
|
|
5
|
+
## Platform Sizes
|
|
6
|
+
|
|
7
|
+
| Platform | Type | Size (px) | Aspect |
|
|
8
|
+
|----------|------|-----------|--------|
|
|
9
|
+
| Instagram | Post | 1080 x 1080 | 1:1 |
|
|
10
|
+
| Instagram | Story/Reel | 1080 x 1920 | 9:16 |
|
|
11
|
+
| Instagram | Carousel | 1080 x 1350 | 4:5 |
|
|
12
|
+
| Facebook | Post | 1200 x 630 | ~1.9:1 |
|
|
13
|
+
| Facebook | Story | 1080 x 1920 | 9:16 |
|
|
14
|
+
| Twitter/X | Post | 1200 x 675 | 16:9 |
|
|
15
|
+
| Twitter/X | Card | 800 x 418 | ~1.91:1 |
|
|
16
|
+
| LinkedIn | Post | 1200 x 627 | ~1.91:1 |
|
|
17
|
+
| LinkedIn | Article | 1200 x 644 | ~1.86:1 |
|
|
18
|
+
| Pinterest | Pin | 1000 x 1500 | 2:3 |
|
|
19
|
+
| YouTube | Thumbnail | 1280 x 720 | 16:9 |
|
|
20
|
+
| TikTok | Cover | 1080 x 1920 | 9:16 |
|
|
21
|
+
| Threads | Post | 1080 x 1080 | 1:1 |
|
|
22
|
+
|
|
23
|
+
## Workflow
|
|
24
|
+
|
|
25
|
+
### Step 1: Plan the Work
|
|
26
|
+
|
|
27
|
+
Create TODO tasks with the runtime's native task list. Break down into:
|
|
28
|
+
- Requirement analysis task
|
|
29
|
+
- Idea generation task(s)
|
|
30
|
+
- HTML design task(s) — can parallelize per size/variant
|
|
31
|
+
- Screenshot export task(s) — can parallelize per file
|
|
32
|
+
- Report generation task
|
|
33
|
+
|
|
34
|
+
Spawn parallel subagents for independent tasks (e.g., multiple HTML files for different sizes).
|
|
35
|
+
|
|
36
|
+
### Step 2: Analyze Requirements
|
|
37
|
+
|
|
38
|
+
Parse user input for:
|
|
39
|
+
- **Subject/topic** — what the social photo represents
|
|
40
|
+
- **Target platforms** — which sizes needed (default: Instagram Post 1:1 + Story 9:16)
|
|
41
|
+
- **Visual style** — minimalist, bold, gradient, photo-based, etc.
|
|
42
|
+
- **Brand context** — read from `docs/brand-guidelines.md` if exists
|
|
43
|
+
- **Content elements** — headline, subtext, CTA, images, icons
|
|
44
|
+
- **Quantity** — how many variations (default: 3)
|
|
45
|
+
|
|
46
|
+
### Step 3: Generate Ideas
|
|
47
|
+
|
|
48
|
+
Create 3-5 concept ideas that:
|
|
49
|
+
- Match the input prompt/requirements
|
|
50
|
+
- Consider platform-specific best practices
|
|
51
|
+
- Vary in composition, color, typography approach
|
|
52
|
+
- Align with brand guidelines if available
|
|
53
|
+
|
|
54
|
+
Present ideas to user via `AskUserQuestion` for approval before designing.
|
|
55
|
+
|
|
56
|
+
### Step 4: Design HTML Files
|
|
57
|
+
|
|
58
|
+
Use these bundled skills in sequence:
|
|
59
|
+
|
|
60
|
+
1. **`brand`** — Extract brand colors, fonts, voice from user's project
|
|
61
|
+
2. **`design-system`** — Get design tokens (spacing, typography scale, color palette)
|
|
62
|
+
3. **`ui-ux-pro-max`** — Layout, hierarchy, visual balance; search a different style, palette, or font pairing per concept for design variety.
|
|
63
|
+
|
|
64
|
+
For each approved idea + each target size, create an HTML file:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
output/social-photos/
|
|
68
|
+
├── idea-1-instagram-post-1080x1080.html
|
|
69
|
+
├── idea-1-instagram-story-1080x1920.html
|
|
70
|
+
├── idea-2-instagram-post-1080x1080.html
|
|
71
|
+
├── idea-2-instagram-story-1080x1920.html
|
|
72
|
+
└── ...
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
#### HTML Design Rules
|
|
76
|
+
|
|
77
|
+
- **Viewport** — Set exact pixel dimensions matching target size
|
|
78
|
+
- **Self-contained** — Inline all CSS, embed fonts via Google Fonts CDN
|
|
79
|
+
- **No scrolling** — Everything fits in one viewport
|
|
80
|
+
- **High contrast** — Text readable at thumbnail size
|
|
81
|
+
- **Brand-aligned** — Use extracted brand colors/fonts
|
|
82
|
+
- **Safe zones** — Critical content within central 80% area
|
|
83
|
+
- **Typography** — Min 24px for headlines, min 16px for body at 1080px width
|
|
84
|
+
- **Visual hierarchy** — One focal point, clear reading flow
|
|
85
|
+
|
|
86
|
+
#### HTML Template Structure
|
|
87
|
+
|
|
88
|
+
```html
|
|
89
|
+
<!DOCTYPE html>
|
|
90
|
+
<html>
|
|
91
|
+
<head>
|
|
92
|
+
<meta charset="UTF-8">
|
|
93
|
+
<meta name="viewport" content="width={WIDTH}, initial-scale=1.0">
|
|
94
|
+
<link href="https://fonts.googleapis.com/css2?family={FONT}&display=swap" rel="stylesheet">
|
|
95
|
+
<style>
|
|
96
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
97
|
+
html, body {
|
|
98
|
+
width: {WIDTH}px;
|
|
99
|
+
height: {HEIGHT}px;
|
|
100
|
+
overflow: hidden;
|
|
101
|
+
font-family: '{FONT}', sans-serif;
|
|
102
|
+
}
|
|
103
|
+
.canvas {
|
|
104
|
+
width: {WIDTH}px;
|
|
105
|
+
height: {HEIGHT}px;
|
|
106
|
+
position: relative;
|
|
107
|
+
/* Background: gradient, solid, or image */
|
|
108
|
+
}
|
|
109
|
+
/* Design tokens from brand/design-system */
|
|
110
|
+
</style>
|
|
111
|
+
</head>
|
|
112
|
+
<body>
|
|
113
|
+
<div class="canvas">
|
|
114
|
+
<!-- Content layers -->
|
|
115
|
+
</div>
|
|
116
|
+
</body>
|
|
117
|
+
</html>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Step 5: Screenshot Export
|
|
121
|
+
|
|
122
|
+
Use Chrome headless, Playwright, or Puppeteer to capture exact-size screenshots.
|
|
123
|
+
|
|
124
|
+
**IMPORTANT:** Always add a delay (3-5s) after page load for fonts/images to fully render before capture.
|
|
125
|
+
|
|
126
|
+
#### Option A: Chrome Headless CLI (Recommended — zero dependencies)
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
CHROME="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
|
|
130
|
+
DELAY=5 # seconds for fonts/images to load
|
|
131
|
+
|
|
132
|
+
"$CHROME" \
|
|
133
|
+
--headless \
|
|
134
|
+
--disable-gpu \
|
|
135
|
+
--no-sandbox \
|
|
136
|
+
--hide-scrollbars \
|
|
137
|
+
--window-size="${WIDTH},${HEIGHT}" \
|
|
138
|
+
--virtual-time-budget=$((DELAY * 1000)) \
|
|
139
|
+
--screenshot="output.png" \
|
|
140
|
+
"file:///path/to/file.html"
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Key flags:
|
|
144
|
+
- `--virtual-time-budget=5000` — waits 5s virtual time for assets (Google Fonts, images) to load
|
|
145
|
+
- `--hide-scrollbars` — prevents scrollbar artifacts in screenshots
|
|
146
|
+
- `--window-size=WxH` — sets exact pixel dimensions
|
|
147
|
+
|
|
148
|
+
#### Option B: Browser automation provided by the runtime
|
|
149
|
+
|
|
150
|
+
If the runtime offers a browser-automation or screenshot capability (for example a browser MCP server), use it to:
|
|
151
|
+
1. Open each HTML file in browser
|
|
152
|
+
2. Set viewport to exact target dimensions
|
|
153
|
+
3. Wait 3-5s for fonts/images to fully load
|
|
154
|
+
4. Screenshot full page to PNG
|
|
155
|
+
5. Save to `output/social-photos/exports/`
|
|
156
|
+
|
|
157
|
+
#### Option C: Playwright script
|
|
158
|
+
|
|
159
|
+
```javascript
|
|
160
|
+
const { chromium } = require('playwright');
|
|
161
|
+
|
|
162
|
+
async function captureScreenshots(htmlFiles) {
|
|
163
|
+
const browser = await chromium.launch();
|
|
164
|
+
|
|
165
|
+
for (const file of htmlFiles) {
|
|
166
|
+
const [width, height] = file.match(/(\d+)x(\d+)/).slice(1).map(Number);
|
|
167
|
+
|
|
168
|
+
const page = await browser.newPage();
|
|
169
|
+
await page.setViewportSize({ width, height });
|
|
170
|
+
await page.goto(`file://${file}`, { waitUntil: 'networkidle' });
|
|
171
|
+
// Wait for fonts/images to fully render
|
|
172
|
+
await page.waitForTimeout(3000);
|
|
173
|
+
|
|
174
|
+
const outputPath = file.replace('.html', '.png').replace('social-photos/', 'social-photos/exports/');
|
|
175
|
+
await page.screenshot({ path: outputPath, type: 'png' });
|
|
176
|
+
await page.close();
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
await browser.close();
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
#### Option D: Puppeteer script
|
|
184
|
+
|
|
185
|
+
```javascript
|
|
186
|
+
const puppeteer = require('puppeteer');
|
|
187
|
+
|
|
188
|
+
async function captureScreenshots(htmlFiles) {
|
|
189
|
+
const browser = await puppeteer.launch();
|
|
190
|
+
|
|
191
|
+
for (const file of htmlFiles) {
|
|
192
|
+
const [width, height] = file.match(/(\d+)x(\d+)/).slice(1).map(Number);
|
|
193
|
+
|
|
194
|
+
const page = await browser.newPage();
|
|
195
|
+
await page.setViewport({ width, height, deviceScaleFactor: 2 }); // 2x for retina
|
|
196
|
+
await page.goto(`file://${file}`, { waitUntil: 'networkidle0' });
|
|
197
|
+
// Wait for fonts/images to fully render
|
|
198
|
+
await new Promise(r => setTimeout(r, 3000));
|
|
199
|
+
|
|
200
|
+
const outputPath = file.replace('.html', '.png').replace('social-photos/', 'social-photos/exports/');
|
|
201
|
+
await page.screenshot({ path: outputPath, type: 'png' });
|
|
202
|
+
await page.close();
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
await browser.close();
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
**IMPORTANT:** Use `deviceScaleFactor: 2` for retina-quality output (Puppeteer only).
|
|
210
|
+
|
|
211
|
+
### Step 6: Verify & Fix Designs
|
|
212
|
+
|
|
213
|
+
Open each exported PNG in an available browser or image viewer and inspect it:
|
|
214
|
+
|
|
215
|
+
1. Open exported screenshots and check for layout/styling issues
|
|
216
|
+
2. Verify: fonts rendered correctly, colors match brand, text readable at thumbnail size
|
|
217
|
+
3. Check: no overflow, no cut-off content, safe zones respected, visual hierarchy clear
|
|
218
|
+
4. If issues found → fix HTML source → re-export screenshot → verify again
|
|
219
|
+
5. Repeat until all designs pass visual QA
|
|
220
|
+
|
|
221
|
+
**Common issues to check:**
|
|
222
|
+
- Fonts not loaded (fallback to system fonts)
|
|
223
|
+
- Text overflow or clipping
|
|
224
|
+
- Elements outside safe zone (central 80%)
|
|
225
|
+
- Low contrast text (below WCAG AA 4.5:1)
|
|
226
|
+
- Misaligned elements or broken layouts
|
|
227
|
+
|
|
228
|
+
### Step 7: Generate Summary Report
|
|
229
|
+
|
|
230
|
+
Save the report as `plans/reports/{YYMMDD}-social-photos-{topic}.md`.
|
|
231
|
+
|
|
232
|
+
Report structure:
|
|
233
|
+
|
|
234
|
+
```markdown
|
|
235
|
+
# Social Photos Design Report
|
|
236
|
+
|
|
237
|
+
## Overview
|
|
238
|
+
- Prompt/requirements: {original input}
|
|
239
|
+
- Platforms: {target platforms}
|
|
240
|
+
- Variations: {count}
|
|
241
|
+
- Style: {chosen style}
|
|
242
|
+
|
|
243
|
+
## Ideas Generated
|
|
244
|
+
1. **{Idea name}** — {brief description, rationale}
|
|
245
|
+
2. ...
|
|
246
|
+
|
|
247
|
+
## Design Decisions
|
|
248
|
+
- Color palette: {colors used, why}
|
|
249
|
+
- Typography: {fonts, sizes, why}
|
|
250
|
+
- Layout: {composition approach, why}
|
|
251
|
+
- Brand alignment: {how brand guidelines influenced design}
|
|
252
|
+
|
|
253
|
+
## Output Files
|
|
254
|
+
| File | Size | Platform | Preview |
|
|
255
|
+
|------|------|----------|---------|
|
|
256
|
+
| exports/{filename}.png | {WxH} | {platform} | {description} |
|
|
257
|
+
|
|
258
|
+
## Why This Works
|
|
259
|
+
- {Platform-specific reasoning}
|
|
260
|
+
- {Brand alignment reasoning}
|
|
261
|
+
- {Visual hierarchy reasoning}
|
|
262
|
+
- {Engagement potential reasoning}
|
|
263
|
+
|
|
264
|
+
## Recommendations
|
|
265
|
+
- {A/B test suggestions}
|
|
266
|
+
- {Platform-specific tips}
|
|
267
|
+
- {Iteration opportunities}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Step 8: Organize Output
|
|
271
|
+
|
|
272
|
+
Organize all output files and reports:
|
|
273
|
+
- Move/copy exported PNGs to proper asset directories
|
|
274
|
+
- Ensure reports are in `plans/reports/` under the name from Step 7
|
|
275
|
+
- Clean up intermediate HTML files if requested
|
|
276
|
+
- Tag outputs with metadata (platform, size, concept name)
|
|
277
|
+
|
|
278
|
+
## Design Best Practices
|
|
279
|
+
|
|
280
|
+
### Platform-Specific Tips
|
|
281
|
+
|
|
282
|
+
- **Instagram** — Visual-first, minimal text (<20%), strong colors, lifestyle feel
|
|
283
|
+
- **Facebook** — Informative, can have more text, eye-catching in feed
|
|
284
|
+
- **Twitter/X** — Bold headlines, contrast for dark/light mode, clear message
|
|
285
|
+
- **LinkedIn** — Professional, clean, data-driven visuals, thought leadership
|
|
286
|
+
- **Pinterest** — Vertical format, text overlay on images, how-to style
|
|
287
|
+
- **YouTube** — Face close-ups perform best, bright colors, readable at small size
|
|
288
|
+
- **TikTok** — Trendy, energetic, bold typography, youth-oriented
|
|
289
|
+
|
|
290
|
+
### Art Direction Styles (Reuse from Banner)
|
|
291
|
+
|
|
292
|
+
| Style | Best For | Key Elements |
|
|
293
|
+
|-------|----------|--------------|
|
|
294
|
+
| Minimalist | SaaS, tech, luxury | Whitespace, single accent color, clean type |
|
|
295
|
+
| Bold Typography | Announcements, quotes | Large type, high contrast, minimal imagery |
|
|
296
|
+
| Gradient Mesh | Modern brands, apps | Fluid color transitions, floating elements |
|
|
297
|
+
| Photo-Based | Lifestyle, e-commerce | Hero image, subtle overlay, text on image |
|
|
298
|
+
| Geometric | Tech, fintech | Shapes, patterns, structured layouts |
|
|
299
|
+
| Glassmorphism | SaaS, modern apps | Frosted glass, blur effects, transparency |
|
|
300
|
+
| Flat Illustration | Education, health | Custom illustrations, friendly, approachable |
|
|
301
|
+
| Duotone | Creative, editorial | Two-color treatment on photos |
|
|
302
|
+
| Collage | Fashion, culture | Mixed media, overlapping elements |
|
|
303
|
+
| 3D/Isometric | Tech, product | Depth, shadows, modern perspective |
|
|
304
|
+
|
|
305
|
+
### Color & Contrast
|
|
306
|
+
|
|
307
|
+
- Ensure WCAG AA contrast ratio (4.5:1 min) for all text
|
|
308
|
+
- Test designs at 50% size to verify readability
|
|
309
|
+
- Consider platform dark/light mode compatibility
|
|
310
|
+
- Use brand primary color as dominant, secondary as accent
|
|
311
|
+
|
|
312
|
+
### Typography Hierarchy
|
|
313
|
+
|
|
314
|
+
| Element | Min Size (at 1080px) | Weight |
|
|
315
|
+
|---------|---------------------|--------|
|
|
316
|
+
| Headline | 48px | Bold/Black |
|
|
317
|
+
| Subheadline | 32px | Semibold |
|
|
318
|
+
| Body | 24px | Regular |
|
|
319
|
+
| Caption | 18px | Regular/Light |
|
|
320
|
+
| CTA | 28px | Bold |
|
|
321
|
+
|
|
322
|
+
## Security & Scope
|
|
323
|
+
|
|
324
|
+
This sub-skill handles social media image design only. Does NOT handle:
|
|
325
|
+
- Video content creation
|
|
326
|
+
- Animation/motion graphics
|
|
327
|
+
- Print production files (CMYK, bleed)
|
|
328
|
+
- Direct social media posting/scheduling
|
|
329
|
+
- AI image generation (supply images, or generate them with a separate authorized capability)
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# Infinite Spatial Canvas & Viewport Virtualization Engine
|
|
2
|
+
|
|
3
|
+
> [!NOTE]
|
|
4
|
+
> สถาปัตยกรรมระดับสูงสำหรับการพัฒนาผืนผ้าใบอินฟินิท (Infinite Spatial Canvas) รองรับการวาดเส้น แผนผัง และการแสดงผลองค์ประกอบกราฟิกนับหมื่นชิ้นที่ 60-120 FPS ถอดแบบองค์ความรู้จาก **tldraw**, **Excalidraw**, และ **Perfect Freehand**
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 1. การแปลงพิกัดมิติผืนผ้าใบ (Coordinate System & Matrix Transforms)
|
|
9
|
+
|
|
10
|
+
ระบบ Infinite Canvas ประกอบด้วย 2 ระนาบพิกัดที่ต้องแปลงไปมาแบบเรียลไทม์:
|
|
11
|
+
1. **Screen Space (Viewport):** พิกัดพิกเซลบนหน้าจออุปกรณ์ `(x, y)` เริ่มต้นจากมุมซ้ายบนของ Element
|
|
12
|
+
2. **World Space (Canvas Space):** พิกัดสมบูรณ์ในผืนผ้าใบไร้ขีดจำกัด `(wx, wy)` ที่คงที่แม้จะมีการ Zoom/Pan
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
// types/spatial.ts
|
|
16
|
+
export interface Camera {
|
|
17
|
+
x: number; // ค่า offset แนวนอน (World units)
|
|
18
|
+
y: number; // ค่า offset แนวตั้ง (World units)
|
|
19
|
+
zoom: number; // อัตราการซูม (เช่น 1.0 = 100%, 0.5 = 50%, 2.0 = 200%)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface Point {
|
|
23
|
+
x: number;
|
|
24
|
+
y: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface Box {
|
|
28
|
+
minX: number;
|
|
29
|
+
minY: number;
|
|
30
|
+
maxX: number;
|
|
31
|
+
maxY: number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// 1. แปลง Screen Coordinate -> World Coordinate (เมื่อคลิกเมาส์/ทัช)
|
|
35
|
+
export function screenToWorld(screenPt: Point, camera: Camera): Point {
|
|
36
|
+
return {
|
|
37
|
+
x: (screenPt.x - camera.x) / camera.zoom,
|
|
38
|
+
y: (screenPt.y - camera.y) / camera.zoom,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// 2. แปลง World Coordinate -> Screen Coordinate (เมื่อเรนเดอร์ลงจอ)
|
|
43
|
+
export function worldToScreen(worldPt: Point, camera: Camera): Point {
|
|
44
|
+
return {
|
|
45
|
+
x: worldPt.x * camera.zoom + camera.x,
|
|
46
|
+
y: worldPt.y * camera.zoom + camera.y,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// 3. ซูมเข้าหาตำแหน่งเคอร์เซอร์ (Zoom Towards Pointer)
|
|
51
|
+
export function zoomToPoint(
|
|
52
|
+
pointerScreen: Point,
|
|
53
|
+
camera: Camera,
|
|
54
|
+
deltaZoomFactor: number,
|
|
55
|
+
minZoom = 0.1,
|
|
56
|
+
maxZoom = 8.0
|
|
57
|
+
): Camera {
|
|
58
|
+
const nextZoom = Math.min(Math.max(camera.zoom * deltaZoomFactor, minZoom), maxZoom);
|
|
59
|
+
const worldPt = screenToWorld(pointerScreen, camera);
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
zoom: nextZoom,
|
|
63
|
+
x: pointerScreen.x - worldPt.x * nextZoom,
|
|
64
|
+
y: pointerScreen.y - worldPt.y * nextZoom,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## 2. Spatial Indexing & Viewport Culling (AABB)
|
|
72
|
+
|
|
73
|
+
การเรนเดอร์ทุก Shape บนหน้าจอจะทำให้ประสิทธิภาพพังทลายเมื่อวัตถุมีจำนวนมาก วิธีแก้ปัญหาคือการใช้ **Axis-Aligned Bounding Box (AABB)** เพื่อกรองและเรนเดอร์เฉพาะวัตถุที่อยู่ในขอบเขตกล้อง (Viewport Culling):
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
// spatial/culling.ts
|
|
77
|
+
|
|
78
|
+
// คำนวณขอบเขตสี่เหลี่ยมของ Viewport ใน World Space
|
|
79
|
+
export function getViewportWorldBounds(viewportWidth: number, viewportHeight: number, camera: Camera): Box {
|
|
80
|
+
const topLeft = screenToWorld({ x: 0, y: 0 }, camera);
|
|
81
|
+
const bottomRight = screenToWorld({ x: viewportWidth, y: viewportHeight }, camera);
|
|
82
|
+
return {
|
|
83
|
+
minX: Math.min(topLeft.x, bottomRight.x),
|
|
84
|
+
minY: Math.min(topLeft.y, bottomRight.y),
|
|
85
|
+
maxX: Math.max(topLeft.x, bottomRight.x),
|
|
86
|
+
maxY: Math.max(topLeft.y, bottomRight.y),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// ทดสอบการตัดกันของสี่เหลี่ยม AABB (O(1) Check)
|
|
91
|
+
export function intersects(a: Box, b: Box): boolean {
|
|
92
|
+
return a.minX <= b.maxX && a.maxX >= b.minX && a.minY <= b.maxY && a.maxY >= b.minY;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// เลือกเฉพาะ Shapes ที่อยู่ในสายตากล้อง
|
|
96
|
+
export function getVisibleShapes<T extends { bounds: Box }>(shapes: T[], viewportBounds: Box): T[] {
|
|
97
|
+
return shapes.filter(shape => intersects(shape.bounds, viewportBounds));
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## 3. Vector Freehand Smoothing Algorithm
|
|
104
|
+
|
|
105
|
+
การแปลงพิกัด Pointer เกรี้ยวกราด `[{x, y, pressure}]` ให้กลายเป็นโครงร่างเวกเตอร์ (SVG Polygon Path) ที่โค้งมนลื่นไหล พร้อมแรงกดแบบ Calligraphy:
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
// geometry/freehand.ts
|
|
109
|
+
|
|
110
|
+
export interface StrokePoint {
|
|
111
|
+
point: Point;
|
|
112
|
+
pressure: number;
|
|
113
|
+
distance: number;
|
|
114
|
+
vector: Point;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// คำนวณ Outline Polygon จากชุดจุดด้วยการจำลองความเร็วและมวล
|
|
118
|
+
export function getStrokeOutlinePoints(points: Point[], strokeWidth = 8, smoothing = 0.5): Point[] {
|
|
119
|
+
if (points.length < 2) return [];
|
|
120
|
+
|
|
121
|
+
const leftPoints: Point[] = [];
|
|
122
|
+
const rightPoints: Point[] = [];
|
|
123
|
+
|
|
124
|
+
for (let i = 0; i < points.length; i++) {
|
|
125
|
+
const curr = points[i];
|
|
126
|
+
const prev = points[Math.max(0, i - 1)];
|
|
127
|
+
const next = points[Math.min(points.length - 1, i + 1)];
|
|
128
|
+
|
|
129
|
+
const dx = next.x - prev.x;
|
|
130
|
+
const dy = next.y - prev.y;
|
|
131
|
+
const len = Math.hypot(dx, dy) || 1;
|
|
132
|
+
const nx = -dy / len;
|
|
133
|
+
const ny = dx / len;
|
|
134
|
+
|
|
135
|
+
const halfWidth = strokeWidth / 2;
|
|
136
|
+
leftPoints.push({ x: curr.x + nx * halfWidth, y: curr.y + ny * halfWidth });
|
|
137
|
+
rightPoints.push({ x: curr.x - nx * halfWidth, y: curr.y - ny * halfWidth });
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return [...leftPoints, ...rightPoints.reverse()];
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## 4. Multi-Layer Composition Architecture
|
|
147
|
+
|
|
148
|
+
โครงสร้างเลเยอร์ DOM/Canvas แยกอิสระเพื่อป้องกัน Repaint ทั้งหน้าจอ:
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
┌────────────────────────────────────────────────────────┐
|
|
152
|
+
│ 1. HUD / Minimap / Toolbars (HTML DOM - Fixed UI) │
|
|
153
|
+
├────────────────────────────────────────────────────────┤
|
|
154
|
+
│ 2. Selection Box / Transform Handles (SVG Overlay) │
|
|
155
|
+
├────────────────────────────────────────────────────────┤
|
|
156
|
+
│ 3. Interactive Shapes / Connectors (Culled Virtualized)│
|
|
157
|
+
├────────────────────────────────────────────────────────┤
|
|
158
|
+
│ 4. Infinite Coordinate Grid (CSS Shader or Canvas 2D) │
|
|
159
|
+
└────────────────────────────────────────────────────────┘
|
|
160
|
+
```
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: stitch-skill
|
|
3
|
+
description: "ออกแบบและสร้างระบบดีไซน์ระดับ Semantic สำหรับหน้าเว็บและแอป ผ่านไฟล์ DESIGN.md — ใช้เมื่อต้องการวางแผนและกำหนดมาตรฐาน UI สเปกฟอนต์ สี และ Micro-motion ตาม Google Stitch (Semantic design system, DESIGN.md generation, Google Stitch UI standards, typography scales, token contracts)"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Stitch Design Taste — Semantic Design System Skill
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
This skill generates `DESIGN.md` files optimized for Google Stitch screen generation. It translates the battle-tested anti-slop frontend engineering directives into Stitch's native semantic design language — descriptive, natural-language rules paired with precise values that Stitch's AI agent can interpret to produce premium, non-generic interfaces.
|
|
10
|
+
|
|
11
|
+
The generated `DESIGN.md` serves as the **single source of truth** for prompting Stitch to generate new screens that align with a curated, high-agency design language. Stitch interprets design through **"Visual Descriptions"** supported by specific color values, typography specs, and component behaviors.
|
|
12
|
+
|
|
13
|
+
## Prerequisites
|
|
14
|
+
- Access to Google Stitch via [labs.google/stitch](https://labs.google/stitch)
|
|
15
|
+
- Optionally: Stitch MCP Server for programmatic integration with Cursor, Antigravity, or Gemini CLI
|
|
16
|
+
|
|
17
|
+
## The Goal
|
|
18
|
+
Generate a `DESIGN.md` file that encodes:
|
|
19
|
+
1. **Visual atmosphere** — the mood, density, and design philosophy
|
|
20
|
+
2. **Color calibration** — neutrals, accents, and banned patterns with hex codes
|
|
21
|
+
3. **Typographic architecture** — font stacks, scale hierarchy, and anti-patterns
|
|
22
|
+
4. **Component behaviors** — buttons, cards, inputs with interaction states
|
|
23
|
+
5. **Layout principles** — grid systems, spacing philosophy, responsive strategy
|
|
24
|
+
6. **Motion philosophy** — animation engine specs, spring physics, perpetual micro-interactions
|
|
25
|
+
7. **Anti-patterns** — explicit list of banned AI design clichés
|
|
26
|
+
|
|
27
|
+
## Analysis & Synthesis Instructions
|
|
28
|
+
|
|
29
|
+
### 1. Define the Atmosphere
|
|
30
|
+
Evaluate the target project's intent. Use evocative adjectives from the taste spectrum:
|
|
31
|
+
- **Density:** "Art Gallery Airy" (1–3) → "Daily App Balanced" (4–7) → "Cockpit Dense" (8–10)
|
|
32
|
+
- **Variance:** "Predictable Symmetric" (1–3) → "Offset Asymmetric" (4–7) → "Artsy Chaotic" (8–10)
|
|
33
|
+
- **Motion:** "Static Restrained" (1–3) → "Fluid CSS" (4–7) → "Cinematic Choreography" (8–10)
|
|
34
|
+
|
|
35
|
+
Default baseline: Variance 8, Motion 6, Density 4. Adapt dynamically based on user's vibe description.
|
|
36
|
+
|
|
37
|
+
### 2. Map the Color Palette
|
|
38
|
+
For each color provide: **Descriptive Name** + **Hex Code** + **Functional Role**.
|
|
39
|
+
|
|
40
|
+
**Mandatory constraints:**
|
|
41
|
+
- Maximum 1 accent color. Saturation below 80%
|
|
42
|
+
- The "AI Purple/Blue Neon" aesthetic is strictly BANNED — no purple button glows, no neon gradients
|
|
43
|
+
- Use absolute neutral bases (Zinc/Slate) with high-contrast singular accents
|
|
44
|
+
- Stick to one palette for the entire output — no warm/cool gray fluctuation
|
|
45
|
+
- Never use pure black (`#000000`) — use Off-Black, Zinc-950, or Charcoal
|
|
46
|
+
|
|
47
|
+
### 3. Establish Typography Rules
|
|
48
|
+
- **Display/Headlines:** Track-tight, controlled scale. Not screaming. Hierarchy through weight and color, not just massive size
|
|
49
|
+
- **Body:** Relaxed leading, max 65 characters per line
|
|
50
|
+
- **Font Selection:** `Inter` is BANNED for premium/creative contexts. Force unique character: `Geist`, `Outfit`, `Cabinet Grotesk`, or `Satoshi`
|
|
51
|
+
- **Serif Ban:** Generic serif fonts (`Times New Roman`, `Georgia`, `Garamond`, `Palatino`) are BANNED. If serif is needed for editorial/creative contexts, use only distinctive modern serifs: `Fraunces`, `Gambarino`, `Editorial New`, or `Instrument Serif`. Serif is always BANNED in dashboards or software UIs
|
|
52
|
+
- **Dashboard Constraint:** Use Sans-Serif pairings exclusively (`Geist` + `Geist Mono` or `Satoshi` + `JetBrains Mono`)
|
|
53
|
+
- **High-Density Override:** When density exceeds 7, all numbers must use Monospace
|
|
54
|
+
|
|
55
|
+
### 4. Define the Hero Section
|
|
56
|
+
The Hero is the first impression and must be creative, striking, and never generic:
|
|
57
|
+
- **Inline Image Typography:** Embed small, contextual photos or visuals directly between words or letters in the headline. Images sit inline at type-height, rounded, acting as visual punctuation. This is the signature creative technique
|
|
58
|
+
- **No Overlapping:** Text must never overlap images or other text. Every element occupies its own clean spatial zone
|
|
59
|
+
- **No Filler Text:** "Scroll to explore", "Swipe down", scroll arrow icons, bouncing chevrons are BANNED. The content should pull users in naturally
|
|
60
|
+
- **Asymmetric Structure:** Centered Hero layouts BANNED when variance exceeds 4
|
|
61
|
+
- **CTA Restraint:** Maximum one primary CTA. No secondary "Learn more" links
|
|
62
|
+
|
|
63
|
+
### 5. Describe Component Stylings
|
|
64
|
+
For each component type, describe shape, color, shadow depth, and interaction behavior:
|
|
65
|
+
- **Buttons:** Tactile push feedback on active state. No neon outer glows. No custom mouse cursors
|
|
66
|
+
- **Cards:** Use ONLY when elevation communicates hierarchy. Tint shadows to background hue. For high-density layouts, replace cards with border-top dividers or negative space
|
|
67
|
+
- **Inputs/Forms:** Label above input, helper text optional, error text below. Standard gap spacing
|
|
68
|
+
- **Loading States:** Skeletal loaders matching layout dimensions — no generic circular spinners
|
|
69
|
+
- **Empty States:** Composed compositions indicating how to populate data
|
|
70
|
+
- **Error States:** Clear, inline error reporting
|
|
71
|
+
|
|
72
|
+
### 6. Define Layout Principles
|
|
73
|
+
- No overlapping elements — every element occupies its own clear spatial zone. No absolute-positioned content stacking
|
|
74
|
+
- Centered Hero sections are BANNED when variance exceeds 4 — force Split Screen, Left-Aligned, or Asymmetric Whitespace
|
|
75
|
+
- The generic "3 equal cards horizontally" feature row is BANNED — use 2-column Zig-Zag, asymmetric grid, or horizontal scroll
|
|
76
|
+
- CSS Grid over Flexbox math — never use `calc()` percentage hacks
|
|
77
|
+
- Contain layouts using max-width constraints (e.g., 1400px centered)
|
|
78
|
+
- Full-height sections must use `min-h-[100dvh]` — never `h-screen` (iOS Safari catastrophic jump)
|
|
79
|
+
|
|
80
|
+
### 7. Define Responsive Rules
|
|
81
|
+
Every design must work across all viewports:
|
|
82
|
+
- **Mobile-First Collapse (< 768px):** All multi-column layouts collapse to single column. No exceptions
|
|
83
|
+
- **No Horizontal Scroll:** Horizontal overflow on mobile is a critical failure
|
|
84
|
+
- **Typography Scaling:** Headlines scale via `clamp()`. Body text minimum `1rem`/`14px`
|
|
85
|
+
- **Touch Targets:** All interactive elements minimum `44px` tap target
|
|
86
|
+
- **Image Behavior:** Inline typography images (photos between words) stack below headline on mobile
|
|
87
|
+
- **Navigation:** Desktop horizontal nav collapses to clean mobile menu
|
|
88
|
+
- **Spacing:** Vertical section gaps reduce proportionally (`clamp(3rem, 8vw, 6rem)`)
|
|
89
|
+
|
|
90
|
+
### 8. Encode Motion Philosophy
|
|
91
|
+
- **Spring Physics default:** `stiffness: 100, damping: 20` — premium, weighty feel. No linear easing
|
|
92
|
+
- **Perpetual Micro-Interactions:** Every active component should have an infinite loop state (Pulse, Typewriter, Float, Shimmer)
|
|
93
|
+
- **Staggered Orchestration:** Never mount lists instantly — use cascade delays for waterfall reveals
|
|
94
|
+
- **Performance:** Animate exclusively via `transform` and `opacity`. Never animate `top`, `left`, `width`, `height`. Grain/noise filters on fixed pseudo-elements only
|
|
95
|
+
|
|
96
|
+
### 9. List Anti-Patterns (AI Tells)
|
|
97
|
+
Encode these as explicit "NEVER DO" rules in the DESIGN.md:
|
|
98
|
+
- No emojis anywhere
|
|
99
|
+
- No `Inter` font
|
|
100
|
+
- No generic serif fonts (`Times New Roman`, `Georgia`, `Garamond`) — distinctive modern serifs only if needed
|
|
101
|
+
- No pure black (`#000000`)
|
|
102
|
+
- No neon/outer glow shadows
|
|
103
|
+
- No oversaturated accents
|
|
104
|
+
- No excessive gradient text on large headers
|
|
105
|
+
- No custom mouse cursors
|
|
106
|
+
- No overlapping elements — clean spatial separation always
|
|
107
|
+
- No 3-column equal card layouts
|
|
108
|
+
- No generic names ("John Doe", "Acme", "Nexus")
|
|
109
|
+
- No fake round numbers (`99.99%`, `50%`)
|
|
110
|
+
- No AI copywriting clichés ("Elevate", "Seamless", "Unleash", "Next-Gen")
|
|
111
|
+
- No filler UI text: "Scroll to explore", "Swipe down", scroll arrows, bouncing chevrons
|
|
112
|
+
- No broken Unsplash links — use `picsum.photos` or SVG avatars
|
|
113
|
+
- No centered Hero sections (for high-variance projects)
|
|
114
|
+
|
|
115
|
+
## Output Format (DESIGN.md Structure)
|
|
116
|
+
|
|
117
|
+
```markdown
|
|
118
|
+
# Design System: [Project Title]
|
|
119
|
+
|
|
120
|
+
## 1. Visual Theme & Atmosphere
|
|
121
|
+
(Evocative description of the mood, density, variance, and motion intensity.
|
|
122
|
+
Example: "A restrained, gallery-airy interface with confident asymmetric layouts
|
|
123
|
+
and fluid spring-physics motion. The atmosphere is clinical yet warm — like a
|
|
124
|
+
well-lit architecture studio.")
|
|
125
|
+
|
|
126
|
+
## 2. Color Palette & Roles
|
|
127
|
+
- **Canvas White** (#F9FAFB) — Primary background surface
|
|
128
|
+
- **Pure Surface** (#FFFFFF) — Card and container fill
|
|
129
|
+
- **Charcoal Ink** (#18181B) — Primary text, Zinc-950 depth
|
|
130
|
+
- **Muted Steel** (#71717A) — Secondary text, descriptions, metadata
|
|
131
|
+
- **Whisper Border** (rgba(226,232,240,0.5)) — Card borders, 1px structural lines
|
|
132
|
+
- **[Accent Name]** (#XXXXXX) — Single accent for CTAs, active states, focus rings
|
|
133
|
+
(Max 1 accent. Saturation < 80%. No purple/neon.)
|
|
134
|
+
|
|
135
|
+
## 3. Typography Rules
|
|
136
|
+
- **Display:** [Font Name] — Track-tight, controlled scale, weight-driven hierarchy
|
|
137
|
+
- **Body:** [Font Name] — Relaxed leading, 65ch max-width, neutral secondary color
|
|
138
|
+
- **Mono:** [Font Name] — For code, metadata, timestamps, high-density numbers
|
|
139
|
+
- **Banned:** Inter, generic system fonts for premium contexts. Serif fonts banned in dashboards.
|
|
140
|
+
|
|
141
|
+
## 4. Component Stylings
|
|
142
|
+
* **Buttons:** Flat, no outer glow. Tactile -1px translate on active. Accent fill for primary, ghost/outline for secondary.
|
|
143
|
+
* **Cards:** Generously rounded corners (2.5rem). Diffused whisper shadow. Used only when elevation serves hierarchy. High-density: replace with border-top dividers.
|
|
144
|
+
* **Inputs:** Label above, error below. Focus ring in accent color. No floating labels.
|
|
145
|
+
* **Loaders:** Skeletal shimmer matching exact layout dimensions. No circular spinners.
|
|
146
|
+
* **Empty States:** Composed, illustrated compositions — not just "No data" text.
|
|
147
|
+
|
|
148
|
+
## 5. Layout Principles
|
|
149
|
+
(Grid-first responsive architecture. Asymmetric splits for Hero sections.
|
|
150
|
+
Strict single-column collapse below 768px. Max-width containment.
|
|
151
|
+
No flexbox percentage math. Generous internal padding.)
|
|
152
|
+
|
|
153
|
+
## 6. Motion & Interaction
|
|
154
|
+
(Spring physics for all interactive elements. Staggered cascade reveals.
|
|
155
|
+
Perpetual micro-loops on active dashboard components. Hardware-accelerated
|
|
156
|
+
transforms only. Isolated Client Components for CPU-heavy animations.)
|
|
157
|
+
|
|
158
|
+
## 7. Anti-Patterns (Banned)
|
|
159
|
+
(Explicit list of forbidden patterns: no emojis, no Inter, no pure black,
|
|
160
|
+
no neon glows, no 3-column equal grids, no AI copywriting clichés,
|
|
161
|
+
no generic placeholder names, no broken image links.)
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Best Practices
|
|
165
|
+
- **Be Descriptive:** "Deep Charcoal Ink (#18181B)" — not just "dark text"
|
|
166
|
+
- **Be Functional:** Explain what each element is used for
|
|
167
|
+
- **Be Consistent:** Same terminology throughout the document
|
|
168
|
+
- **Be Precise:** Include exact hex codes, rem values, pixel values in parentheses
|
|
169
|
+
- **Be Opinionated:** This is not a neutral template — it enforces a specific, premium aesthetic
|
|
170
|
+
|
|
171
|
+
## Tips for Success
|
|
172
|
+
1. Start with the atmosphere — understand the vibe before detailing tokens
|
|
173
|
+
2. Look for patterns — identify consistent spacing, sizing, and styling
|
|
174
|
+
3. Think semantically — name colors by purpose, not just appearance
|
|
175
|
+
4. Consider hierarchy — document how visual weight communicates importance
|
|
176
|
+
5. Encode the bans — anti-patterns are as important as the rules themselves
|
|
177
|
+
|
|
178
|
+
## Common Pitfalls to Avoid
|
|
179
|
+
- Using technical jargon without translation ("rounded-xl" instead of "generously rounded corners")
|
|
180
|
+
- Omitting hex codes or using only descriptive names
|
|
181
|
+
- Forgetting functional roles of design elements
|
|
182
|
+
- Being too vague in atmosphere descriptions
|
|
183
|
+
- Ignoring the anti-pattern list — these are what make the output premium
|
|
184
|
+
- Defaulting to generic "safe" designs instead of enforcing the curated aesthetic
|