ima2-gen 2.0.15 → 2.0.16

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 (125) hide show
  1. package/README.md +30 -0
  2. package/bin/commands/skill.js +336 -17
  3. package/bin/ima2.js +22 -2
  4. package/bin/lib/doctor-checks.js +6 -4
  5. package/config.js +1 -0
  6. package/docs/CLI.md +25 -3
  7. package/docs/PROMPT_STUDIO.ko.md +29 -0
  8. package/docs/PROMPT_STUDIO.md +31 -0
  9. package/docs/migration/runtime-test-inventory.md +7 -1
  10. package/lib/agentImageVideoGen.js +8 -0
  11. package/lib/agentQueueStore.js +36 -10
  12. package/lib/agentQueueWorker.js +79 -7
  13. package/lib/agentRuntime.js +2 -0
  14. package/lib/assetLifecycle.js +40 -8
  15. package/lib/canvasVersionStore.js +86 -0
  16. package/lib/cardNewsGenerator.js +37 -3
  17. package/lib/cardNewsJobStore.js +10 -0
  18. package/lib/cardNewsManifestStore.js +6 -12
  19. package/lib/cardNewsPath.js +25 -0
  20. package/lib/db.js +2 -0
  21. package/lib/generatePipeline.js +474 -0
  22. package/lib/generationInputValidation.js +32 -0
  23. package/lib/grokImageCore.js +18 -1
  24. package/lib/historyIndex.js +11 -4
  25. package/lib/historyList.js +3 -0
  26. package/lib/imageMetadata.js +3 -0
  27. package/lib/inflight.js +30 -3
  28. package/lib/multimodePipeline.js +462 -0
  29. package/lib/nodeGeneration.js +440 -0
  30. package/lib/nodeValidation.js +23 -0
  31. package/lib/oauthProxy/generators.js +3 -246
  32. package/lib/oauthProxy/multimodeGenerators.js +251 -0
  33. package/lib/routeHelpers.js +9 -2
  34. package/package.json +2 -2
  35. package/routes/agent.js +4 -4
  36. package/routes/canvasVersions.js +21 -1
  37. package/routes/cardNews.js +2 -1
  38. package/routes/edit.js +25 -9
  39. package/routes/events.js +5 -1
  40. package/routes/generate.js +2 -481
  41. package/routes/keys.js +31 -39
  42. package/routes/multimode.js +2 -502
  43. package/routes/nodes.js +3 -448
  44. package/routes/video.js +12 -3
  45. package/routes/videoExtended.js +19 -4
  46. package/server.js +53 -1
  47. package/skills/ima2/SKILL.md +204 -0
  48. package/skills/ima2-front/SKILL.md +611 -0
  49. package/skills/ima2-front/references/a11y-patterns.md +134 -0
  50. package/skills/ima2-front/references/aesthetics.md +327 -0
  51. package/skills/ima2-front/references/anti-slop.md +241 -0
  52. package/skills/ima2-front/references/asset-requirements.md +431 -0
  53. package/skills/ima2-front/references/brand-asset-sourcing.md +122 -0
  54. package/skills/ima2-front/references/color-system.md +132 -0
  55. package/skills/ima2-front/references/consistency-locks.md +20 -0
  56. package/skills/ima2-front/references/crud-ui.md +53 -0
  57. package/skills/ima2-front/references/dropdown-layer.md +110 -0
  58. package/skills/ima2-front/references/i18n-global.md +104 -0
  59. package/skills/ima2-front/references/iterative-design.md +90 -0
  60. package/skills/ima2-front/references/korea-2026.md +174 -0
  61. package/skills/ima2-front/references/layout-discipline.md +161 -0
  62. package/skills/ima2-front/references/liquid-glass.md +181 -0
  63. package/skills/ima2-front/references/logo-sections.md +194 -0
  64. package/skills/ima2-front/references/mobile-ux.md +144 -0
  65. package/skills/ima2-front/references/performance-budget.md +106 -0
  66. package/skills/ima2-front/references/preflight-full.md +58 -0
  67. package/skills/ima2-front/references/product-density.md +53 -0
  68. package/skills/ima2-front/references/prototype-variants.md +54 -0
  69. package/skills/ima2-front/references/reference-capture.md +120 -0
  70. package/skills/ima2-front/references/responsive-viewport.md +139 -0
  71. package/skills/ima2-front/references/seo-baseline.md +123 -0
  72. package/skills/ima2-front/references/soft-3d-asset-gates.md +70 -0
  73. package/skills/ima2-front/references/stacks/astro.md +204 -0
  74. package/skills/ima2-front/references/stacks/mobile-native.md +281 -0
  75. package/skills/ima2-front/references/stacks/nextjs.md +219 -0
  76. package/skills/ima2-front/references/stacks/react.md +264 -0
  77. package/skills/ima2-front/references/stacks/svelte.md +235 -0
  78. package/skills/ima2-front/references/stacks/vanilla.md +226 -0
  79. package/skills/ima2-front/references/theme-switching.md +82 -0
  80. package/skills/ima2-front/references/top-bar.md +126 -0
  81. package/skills/ima2-front/references/typography-wrapping.md +270 -0
  82. package/skills/ima2-front/references/ux-writing-ko.md +62 -0
  83. package/skills/ima2-front/references/visual-verification.md +102 -0
  84. package/skills/ima2-uiux/SKILL.md +477 -0
  85. package/skills/ima2-uiux/references/anti-slop-judgment.md +39 -0
  86. package/skills/ima2-uiux/references/color-system.md +80 -0
  87. package/skills/ima2-uiux/references/design-isms.md +194 -0
  88. package/skills/ima2-uiux/references/design-read-example.md +33 -0
  89. package/skills/ima2-uiux/references/design-system-bootstrap.md +133 -0
  90. package/skills/ima2-uiux/references/favicon-logo.md +355 -0
  91. package/skills/ima2-uiux/references/form-patterns.md +118 -0
  92. package/skills/ima2-uiux/references/intent-discovery-ladder.md +86 -0
  93. package/skills/ima2-uiux/references/korean-design-vocabulary.md +52 -0
  94. package/skills/ima2-uiux/references/layout-macrostructures.md +54 -0
  95. package/skills/ima2-uiux/references/logo-trust-sections.md +96 -0
  96. package/skills/ima2-uiux/references/mobile-native-ux.md +207 -0
  97. package/skills/ima2-uiux/references/product-personalities.md +118 -0
  98. package/skills/ima2-uiux/references/responsive-nav.md +66 -0
  99. package/skills/ima2-uiux/references/typography-line-breaks.md +193 -0
  100. package/skills/ima2-uiux/references/ux-preflight.md +65 -0
  101. package/skills/ima2-uiux/references/ux-states.md +197 -0
  102. package/skills/ima2-uiux/references/visual-hierarchy.md +115 -0
  103. package/ui/dist/.vite/manifest.json +13 -13
  104. package/ui/dist/assets/AgentWorkspace-CtYt4SF5.js +3 -0
  105. package/ui/dist/assets/{CardNewsWorkspace-Cdxn1ohU.js → CardNewsWorkspace-DN5cVqG5.js} +1 -1
  106. package/ui/dist/assets/GenerationRequestLogPanel-DnmUQdKR.js +1 -0
  107. package/ui/dist/assets/{NodeCanvas-C67sLboA.js → NodeCanvas-CxpfIBI0.js} +1 -1
  108. package/ui/dist/assets/PromptBuilderPanel-C2R3ObtR.js +2 -0
  109. package/ui/dist/assets/{PromptImportDialog-DeQXsEEv.js → PromptImportDialog-BIxz_yEx.js} +2 -2
  110. package/ui/dist/assets/PromptImportDiscoverySection-BQTlPMME.js +1 -0
  111. package/ui/dist/assets/PromptImportFolderSection-Ds_Th9O3.js +1 -0
  112. package/ui/dist/assets/{PromptLibraryPanel-Db3xEPM_.js → PromptLibraryPanel-Rs4l45pV.js} +2 -2
  113. package/ui/dist/assets/{SettingsWorkspace-BDk_1W-V.js → SettingsWorkspace-p1AZ6uT9.js} +1 -1
  114. package/ui/dist/assets/index-0-_vgFGs.js +4 -0
  115. package/ui/dist/assets/index-Dm3pFxV4.js +23 -0
  116. package/ui/dist/assets/index-J8yDF3Ch.css +1 -0
  117. package/ui/dist/index.html +2 -2
  118. package/ui/dist/assets/AgentWorkspace-DAg_7zpY.js +0 -3
  119. package/ui/dist/assets/GenerationRequestLogPanel-C_qvEUi2.js +0 -1
  120. package/ui/dist/assets/PromptBuilderPanel-DjvVdAie.js +0 -2
  121. package/ui/dist/assets/PromptImportDiscoverySection-CrwyUKYI.js +0 -1
  122. package/ui/dist/assets/PromptImportFolderSection-CToGMqYE.js +0 -1
  123. package/ui/dist/assets/index-2oG6in1i.css +0 -1
  124. package/ui/dist/assets/index-CoxMOXAU.js +0 -23
  125. package/ui/dist/assets/index-p8egnGHk.js +0 -4
@@ -0,0 +1,193 @@
1
+ # Typography Line Breaks — Design Judgment Guide
2
+
3
+ When to apply text wrapping control, how to evaluate line break quality, and what to check during visual verification.
4
+
5
+ Read `dev-frontend/references/core/typography-wrapping.md` for the CSS implementation.
6
+
7
+ ---
8
+
9
+ ## 1. The Problem
10
+
11
+ AI-generated and unreviewed web pages share a common tell: **uncontrolled text wrapping**. Headings break at arbitrary points, creating orphaned words, lopsided rags, and awkward visual rhythm.
12
+
13
+ **Before (slop):**
14
+ ```
15
+ Connects to what you
16
+ already run ← "already run" orphaned, feels broken
17
+ ```
18
+
19
+ **After (controlled):**
20
+ ```
21
+ Connects to what
22
+ you already run ← Balanced, intentional
23
+ ```
24
+
25
+ The difference is subtle but immediately signals whether a page was designed or merely generated.
26
+
27
+ ---
28
+
29
+ ## When Each Tool Applies
30
+
31
+ | Element | Tool | Rationale |
32
+ |---------|------|-----------|
33
+ | Hero headline | `text-wrap: balance` + `max-width: 40-45ch` | High-visibility, must look intentional on every viewport |
34
+ | **Hero subtitle/description** | **`text-wrap: balance`** + `max-width: 35-40ch` | **Short descriptor — `pretty` is insufficient at 1-2 lines** |
35
+ | Section title | `text-wrap: balance` + `max-width: 50-55ch` | Consistency across sections |
36
+ | Card title | `text-wrap: balance` + `max-width: 30-35ch` | Tight containers need compact control |
37
+ | **Card description (1-3 lines)** | **`text-wrap: balance`** + `max-width: 30-35ch` | **Short descriptor — orphans extremely visible in small containers** |
38
+ | **Caption / label text** | **`text-wrap: balance`** + `max-width: 25-30ch` | **Short descriptor — same reason** |
39
+ | Body paragraph (4+ lines) | `text-wrap: pretty` + `max-width: 65ch` | Orphan prevention at paragraph end |
40
+ | CTA/button label | Manual — keep to 1 line | Never let a CTA break across lines |
41
+ | Navigation links | No wrapping needed | Always single-line |
42
+ | Stat label | `max-width: 20ch` | Keep compact under the number |
43
+ | Badge/tag text | `white-space: nowrap` | Never wrap |
44
+
45
+ ### Short Descriptors — The Missing Category
46
+
47
+ Text that is **1-3 lines long** is neither a heading nor a body paragraph. Examples:
48
+ - Hero subtitle / description
49
+ - Card description / preview text
50
+ - Product one-liner
51
+ - Testimonial snippet
52
+ - Feature description under an icon
53
+
54
+ **Rule: Short descriptors MUST use `text-wrap: balance`, not `pretty`.**
55
+
56
+ `text-wrap: pretty` optimizes the last few lines of long paragraphs. On 1-2 line text, the algorithm has nothing to redistribute — orphans pass through unchanged. `balance` distributes characters evenly across ALL lines, which is exactly what short text needs.
57
+
58
+ **Before (pretty on short text — orphan passes through):**
59
+ ```
60
+ 마다가스카르 바닐라 시럽과 벨벳 스팀밀크의 조
61
+ 화. ← "화." orphaned
62
+ ```
63
+
64
+ **After (balance on short text — redistributed):**
65
+ ```
66
+ 마다가스카르 바닐라 시럽과
67
+ 벨벳 스팀밀크의 조화. ← balanced
68
+ ```
69
+
70
+ ---
71
+
72
+ ## Heading Break Quality Criteria
73
+
74
+ When reviewing a heading visually, check:
75
+
76
+ 1. **No orphaned single word** — The last line should have at least 2 words (or ~33% of the longest line's length)
77
+ 2. **Balanced distribution** — Line lengths should be roughly equal, not one long line + one short stub
78
+ 3. **Semantic grouping** — Breaks should happen between thought units, not in the middle of a phrase
79
+ 4. **Viewport resilience** — The heading should look good at 390px, 768px, 1024px, AND 1440px, and at ARBITRARY widths between them (drag-resize / split-screen check — see the dynamic rewrap layer below)
80
+ 5. **Language-aware** — Korean (한글) headings with `word-break: keep-all` to prevent mid-word breaks
81
+
82
+ **Bad breaks (cut mid-phrase):**
83
+ ```
84
+ Everything you check in Datadog, without leaving
85
+ vim ← orphan
86
+ ```
87
+
88
+ **Good breaks (between thought units):**
89
+ ```
90
+ Everything you check in Datadog,
91
+ without leaving vim ← balanced, semantic
92
+ ```
93
+
94
+ ---
95
+
96
+ ## Dynamic Rewrap Judgment (verified 2026-07-07)
97
+
98
+ Text must break at natural phrase boundaries at ANY width, not just canonical
99
+ breakpoints — containers resize continuously (drag-resizable panels,
100
+ split-screen halves, foldables, mobile URL-bar dvh changes, container-query
101
+ crossings). Judgment layer on top of the criteria above:
102
+
103
+ - Breaks are chosen by the browser at render width; a heading that breaks
104
+ semantically at 390/768/1024/1440 can still orphan at 700px. Judge text in
105
+ CONTAINERS (sidebar, modal, half-window), not only device presets.
106
+ - Prefer break-opportunity control (`keep-all`, `balance`, `max-width` in
107
+ `ch`) over width-specific hacks (`<br>`, manual media-query text swaps) —
108
+ hacks guarantee bad breaks at in-between widths.
109
+ - Korean note: `text-wrap` only chooses among EXISTING break opportunities;
110
+ with `keep-all`, opportunities are 어절 boundaries — verify long 어절 and
111
+ mixed ko/Latin strings don't overflow narrow chips/buttons.
112
+ - Mechanics + verification checklist (container-width sweep, dvh/zoom,
113
+ overflow asserts): `dev-frontend/references/core/typography-wrapping.md`
114
+ § Dynamic-Viewport Verification and
115
+ `dev-frontend/references/core/responsive-viewport.md` (container queries,
116
+ split-screen band).
117
+
118
+ ## Visual Verification Additions
119
+
120
+ Add these checks to the UX pre-flight:
121
+
122
+ - [ ] Hero headline renders balanced on desktop (1440px) AND mobile (390px)
123
+ - [ ] No heading has an orphaned single word on the last line
124
+ - [ ] Section titles do not exceed 55ch per line
125
+ - [ ] Body paragraphs do not exceed 65ch per line
126
+ - [ ] CTA buttons do not break across lines at any viewport
127
+ - [ ] Korean headlines preserve word integrity (no mid-syllable breaks)
128
+ - [ ] `text-wrap: balance` is applied to all headings globally
129
+
130
+ ---
131
+
132
+ ## Common Mistakes
133
+
134
+ | Mistake | Why it happens | Fix |
135
+ |---------|---------------|-----|
136
+ | Using `<br>` for line breaks | Works at one viewport, breaks at others | Use `text-wrap: balance` instead |
137
+ | `max-width` in `px` | Doesn't adapt to font size changes | Use `ch` units |
138
+ | No `max-width` on headings | Lines stretch full container width | Add `max-width: 45-55ch` |
139
+ | `text-wrap: balance` on body text | Performance cost, limited to ~6 lines | Use `text-wrap: pretty` for paragraphs |
140
+ | Ignoring mobile line breaks | Heading looks good on desktop but orphans on mobile | Test at 390px |
141
+ | Same `max-width` for all heading levels | Different font sizes produce different visual widths | Scale `max-width` by heading level |
142
+
143
+ ---
144
+
145
+ ## Korean Typography Notes
146
+
147
+ ```css
148
+ [lang="ko"] {
149
+ word-break: keep-all;
150
+ overflow-wrap: break-word;
151
+ }
152
+
153
+ [lang="ko"] h1, [lang="ko"] h2 {
154
+ text-wrap: balance;
155
+ word-break: keep-all;
156
+ }
157
+ ```
158
+
159
+ `word-break: keep-all` is critical for Korean — without it, browsers break Hangul at any syllable boundary, creating unreadable mid-word splits.
160
+
161
+ ### Korean Orphan Criteria (MANDATORY)
162
+
163
+ Korean text with `word-break: keep-all` prevents mid-word breaks but creates a specific orphan pattern: the last word gets pushed to a new line alone. This is especially visible with verb endings.
164
+
165
+ **Korean last-line minimum:** The last line must contain at least **4 characters (2 syllable blocks)** or **33% of the longest line's width**. A line with only "합니다.", "화.", "입니다.", or any 1-3 character fragment is ALWAYS wrong.
166
+
167
+ **Common Korean orphan patterns (all failures):**
168
+ ```
169
+ 직접 로스팅한 싱글 오리진 원두와 제철 디저트를 매일 준비
170
+ 합니다. ← FAIL: "합니다." alone (3 chars + punctuation)
171
+
172
+ 마다가스카르 바닐라 시럽과 벨벳 스팀밀크의 조
173
+ 화. ← FAIL: "화." alone (1 char + punctuation)
174
+
175
+ 16시간 저온 추출 콜드브루에 부드러운 우유를 더했습니
176
+ 다. ← FAIL: "다." alone (1 char + punctuation)
177
+ ```
178
+
179
+ **Fix priority for Korean short text:**
180
+ 1. Use `text-wrap: balance` (not `pretty`) — this alone fixes most cases
181
+ 2. If `balance` still orphans, adjust `max-width` by ±2-3ch to shift the break point
182
+ 3. As last resort, rewrite the copy to avoid the orphan
183
+
184
+ **`text-wrap: pretty` does NOT solve Korean orphans in short text.** The `pretty` algorithm targets the last 4-8 lines of long paragraphs. On 1-3 line Korean text, it has no effect — the orphan passes through unchanged. This is the single most common Korean typography failure in AI-generated pages.
185
+
186
+ ### `-webkit-line-clamp` Conflict
187
+
188
+ `-webkit-line-clamp` (used for "show 2 lines with ellipsis") **disables `text-wrap` entirely**. The browser switches to a legacy layout mode where `balance` and `pretty` have no effect.
189
+
190
+ If you need line clamping AND orphan control:
191
+ - Accept that clamped text will have uncontrolled wrapping, OR
192
+ - Set `max-width` carefully so the natural break avoids orphans, OR
193
+ - Use JavaScript-based truncation that preserves `text-wrap`
@@ -0,0 +1,65 @@
1
+ # UX Preflight Checklist
2
+
3
+ Run this checklist **before delivery** of any UI feature. Each item is a binary pass/fail.
4
+
5
+ ---
6
+
7
+ ## 1. State Coverage
8
+
9
+ | State | Check | Pass? |
10
+ |-------|-------|-------|
11
+ | Empty | First-time user sees helpful guidance, not a blank screen | |
12
+ | Loading | Skeleton or spinner matches final layout shape | |
13
+ | Error | User knows what failed AND how to recover | |
14
+ | Partial | Mixed loaded/pending content is visually coherent | |
15
+ | Success | Confirmation is visible without being disruptive | |
16
+ | Offline | Graceful degradation or clear "offline" indicator | |
17
+
18
+ ## Onboarding
19
+
20
+ - [ ] First-run experience guides without blocking
21
+ - [ ] Progressive disclosure: advanced features hidden until needed
22
+ - [ ] Empty states include a clear primary action ("Create your first...")
23
+ - [ ] No dead-end screens (every state has a next action)
24
+
25
+ ## Error States
26
+
27
+ - [ ] Error messages are specific (not "Something went wrong")
28
+ - [ ] Recovery action is available (retry, go back, contact support)
29
+ - [ ] Form errors appear inline, not only as toast/alert
30
+ - [ ] Network errors distinguish timeout from server error
31
+
32
+ ## Loading States
33
+
34
+ - [ ] Skeleton loaders match actual content layout
35
+ - [ ] No layout shift when content loads
36
+ - [ ] Long operations show progress (determinate > indeterminate)
37
+ - [ ] Optimistic UI used where safe (toggling, starring, archiving)
38
+
39
+ ## Interaction Feedback
40
+
41
+ - [ ] Every clickable element has hover + active states
42
+ - [ ] Destructive actions require confirmation
43
+ - [ ] Undo available for reversible actions
44
+ - [ ] Focus states visible for keyboard navigation
45
+
46
+ ## Responsive Verification
47
+
48
+ - [ ] Test at 390px (mobile), 768px (tablet), 1440px (desktop)
49
+ - [ ] No horizontal scroll at any viewport
50
+ - [ ] Touch targets ≥ 44px on mobile
51
+ - [ ] Navigation is accessible at all breakpoints
52
+
53
+ ## Typography
54
+
55
+ - [ ] Headings render balanced (no orphaned single word)
56
+ - [ ] Body text max-width ≤ 65ch
57
+ - [ ] Line height comfortable for body (1.5-1.7) and headings (1.1-1.3)
58
+ - [ ] CJK text uses `word-break: keep-all` where appropriate
59
+
60
+ ## Accessibility Minimum
61
+
62
+ - [ ] All images have meaningful `alt` text (or `alt=""` for decorative)
63
+ - [ ] Color contrast passes WCAG AA (4.5:1 text, 3:1 large text)
64
+ - [ ] Skip-to-content link present
65
+ - [ ] Forms have associated labels
@@ -0,0 +1,197 @@
1
+ ## 1. Onboarding & First-Run Patterns
2
+
3
+ Design first-run experiences that deliver value immediately.
4
+
5
+ **Rules:**
6
+ - Enable action before profile completion. Let users DO something valuable first.
7
+ - Deliver core value within 60 seconds of first interaction.
8
+ - Collect only essential data on Day 1. Gather intent early (goal/use case) to personalize.
9
+ - Make every tutorial, walkthrough, and setup step skippable.
10
+ - Provide starter content, templates, or sample data so the first screen is never empty.
11
+
12
+ ### Welcome Screen Anatomy
13
+ ```
14
+ ┌─────────────────────────────────┐
15
+ │ [Brand mark / illustration] │
16
+ │ │
17
+ │ Headline (value proposition) │
18
+ │ Subtext (1 line, what to do) │
19
+ │ │
20
+ │ [Primary CTA: Start Action] │
21
+ │ Skip / Later (text link) │
22
+ └─────────────────────────────────┘
23
+ ```
24
+
25
+ ### Feature Discovery Patterns
26
+
27
+ | Pattern | When to Use | When to Avoid |
28
+ |---------|-------------|---------------|
29
+ | Contextual tooltip | First time a feature appears | Already-discovered features |
30
+ | Coach mark (spotlight) | Complex multi-step workflows | Simple, self-explanatory UI |
31
+ | Feature tour (multi-step) | Major new feature release | First-time onboarding (too heavy) |
32
+ | Empty-state-as-onboarding | Dashboard/list views with no data | Views that always have data |
33
+ | Progressive profile | Collecting user preferences over time | One-time setup flows |
34
+
35
+ ### Permission Request Timing
36
+ Ask for permissions at the moment of need, not during onboarding. Explain why before asking: "To send you updates, we need notification access."
37
+
38
+ ---
39
+
40
+ ## 2. Empty State Design
41
+
42
+ Every major view MUST have a designed empty state. Never leave a screen blank or show a generic "No data" message.
43
+
44
+ ### Three Types
45
+
46
+ | Type | When | Tone |
47
+ |------|------|------|
48
+ | Informational | Content absent, user hasn't acted yet | Neutral, guiding: "Add your first project to get started" |
49
+ | Action-oriented | Feature requires user input to populate | Encouraging, CTA-forward: "Create your first workspace" |
50
+ | Celebratory | All items completed/resolved | Positive reinforcement: "All caught up!" |
51
+
52
+ ### Composition Template
53
+ ```
54
+ ┌─────────────────────────────────┐
55
+ │ [Illustration / Icon] │
56
+ │ (contextual, not generic) │
57
+ │ │
58
+ │ Headline (short, specific) │
59
+ │ Subtext (1 line, optional) │
60
+ │ │
61
+ │ [Primary CTA button] │
62
+ │ Secondary link (optional) │
63
+ └─────────────────────────────────┘
64
+ ```
65
+
66
+ **Rules:**
67
+ - Tailor copy to the specific scenario: first-use vs empty-search vs completed-tasks each get different messages.
68
+ - Use direct language ("Your cart is empty") not vague ("Nothing here yet").
69
+ - Single prominent CTA. Never show multiple competing actions.
70
+ - Match visuals to design system (colors, fonts, spacing, illustration style).
71
+ - For search results: suggest alternatives ("Try adjusting filters or checking spelling").
72
+ - For first-use: provide starter templates or sample data to reduce uncertainty.
73
+ - Use ARIA live regions to notify assistive technology when content state changes.
74
+
75
+ ---
76
+
77
+ ## 3. Error State Taxonomy
78
+
79
+ Every error message follows: (1) what happened, (2) why, (3) what to do next.
80
+
81
+ | Pattern | When | Recovery | Severity |
82
+ |---------|------|----------|----------|
83
+ | Inline validation | Structured input (email, password) | Real-time feedback as user types | Preventative |
84
+ | Toast notification | Low-severity temporary errors | Brief 3-5s non-modal, optional retry | Ambient |
85
+ | Banner | System-wide warnings (maintenance, degraded) | Persistent, dismissible, with details link | Ambient |
86
+ | Full-page error | Critical system failure, content cannot load | Centered: Try Again + escape hatch | Interrupting |
87
+ | Empty-state error | No search results, empty filtered lists | Suggest alternatives or creation paths | Informational |
88
+ | Network failure | Lost connection | Enable offline mode where possible, auto-retry on reconnect | Interrupting |
89
+ | Timeout | Server response > 10–15s | Offer Cancel + Keep Waiting | Interrupting |
90
+ | Permission denied | User lacks role access | Offer Request Access or role upgrade info | Informational |
91
+ | 404 Not Found | URL does not exist | Branded page + search bar + top nav links. Never a dead end | Informational |
92
+ | Rate limiting | API limits exceeded | Banner with wait time + link to docs | Ambient |
93
+
94
+ **Rules:**
95
+ - Never use generic messages ("Invalid input"). Be specific ("Password must contain at least 8 characters").
96
+ - Never blame the user. "Enter a valid email address" not "You entered an invalid email."
97
+ - Every error needs one primary action (retry, fix, request access) and one optional escape hatch (home, support).
98
+ - For multi-step forms: surface errors at each step, not at final submission.
99
+ - Never rely on color alone for error indication. Pair red with icons AND text.
100
+ - Match error tone to product surface: playful for casual apps, professional for finance/health.
101
+ - Severity hierarchy: Preventative (inline) → Ambient (toast) → Interrupting (full-page). Use full-page ONLY for showstoppers.
102
+
103
+ ---
104
+
105
+ ## 4. Loading State Patterns
106
+
107
+ ### Skeleton Loaders
108
+ - Match the skeleton to the real layout (same heights, widths, spacing).
109
+ - Shimmer direction: left-to-right, single wave, 1.5–2s duration.
110
+ - Animate with `background-position` on a gradient — not opacity flicker.
111
+ - Show skeleton for a minimum of 300ms to avoid flash.
112
+
113
+ ### Decision Table
114
+
115
+ | Scenario | Pattern | Details |
116
+ |----------|---------|---------|
117
+ | Page initial load | Skeleton | Match layout, show immediately |
118
+ | Data refresh | Stale-while-revalidate | Show old data + subtle loading indicator |
119
+ | Action result | Optimistic update | Apply change immediately, revert on error |
120
+ | Long operation (> 3s) | Progress bar / percentage | Show estimated time if available |
121
+ | Background process | Toast / status badge | Non-blocking notification |
122
+ | Infinite scroll | Skeleton rows at bottom | 3–5 placeholder rows |
123
+
124
+ ### Skeleton → Content Transition
125
+ Fade skeleton out, fade content in. Duration: 200ms. Never pop — the transition must feel continuous.
126
+
127
+ ---
128
+
129
+ ## 5. Progressive Disclosure
130
+
131
+ Show ONLY essential information first. Defer advanced/optional content behind explicit user action.
132
+
133
+ ### Three Categories
134
+
135
+ | Category | Mechanism | Example |
136
+ |----------|-----------|---------|
137
+ | Step-by-step | Sequential multi-stage | Checkout: shipping → method → payment → confirm |
138
+ | Conditional | Hidden until explicitly requested | "Advanced Settings" toggle |
139
+ | Contextual | Content surfaced based on prior input | Show company fields only after selecting "Business" |
140
+
141
+ ### UI Components for Disclosure
142
+
143
+ | Component | Use For |
144
+ |-----------|---------|
145
+ | Accordion | Structured information (FAQ, settings groups) |
146
+ | Tabs | Categorized content at the same level |
147
+ | Conditional form fields | Show/hide based on prior input |
148
+ | Tooltip / popover | Context help on hover/click |
149
+ | "Show more" link | Optional fields in forms |
150
+ | Lazy loading | Supplementary content on scroll |
151
+
152
+ **Rules:**
153
+ - Discoverability test: hidden features MUST be findable when needed. If users cannot discover advanced options, the pattern has failed.
154
+ - Do NOT use progressive disclosure when users need to compare information simultaneously.
155
+ - Do NOT hide critical safety information or destructive-action warnings.
156
+ - Save progress at each disclosure step. Users must be able to return without losing work.
157
+ - Default to simple. "Advanced Settings" collapsed by default.
158
+ - For forms: show only required fields initially. Optional fields appear via "Show more options."
159
+ - For dashboards: show summary KPIs first. Drill-down detail on click.
160
+ - For settings: group into Basic (visible) and Advanced (collapsed).
161
+
162
+ ---
163
+
164
+ ## 6. Error Page Taxonomy
165
+
166
+ | Page | Content | Tone |
167
+ |------|---------|------|
168
+ | **404** | Branded page + search bar + top nav + "popular pages" links | Friendly, helpful |
169
+ | **500** | Branded page + "We're working on it" + status page link + retry button | Reassuring, transparent |
170
+ | **Maintenance** | Branded page + estimated return time + status page link | Professional, time-bound |
171
+ | **Offline** | Service worker cached page + "You're offline" + cached content list | Informative, functional |
172
+
173
+ Rules:
174
+ - Every error page maintains site branding (logo, colors)
175
+ - Every error page has a path back (nav, home link, search)
176
+ - Never show stack traces or technical errors to end users
177
+ - 500 page: auto-retry with exponential backoff (2s, 4s, 8s) + manual retry button
178
+ - Offline page: cache in service worker during first successful visit
179
+ - Maintenance page: deploy as static HTML (doesn't depend on the broken server)
180
+
181
+ ### Service Worker Offline Shell
182
+
183
+ ```javascript
184
+ self.addEventListener('install', (event) => {
185
+ event.waitUntil(
186
+ caches.open('offline-v1').then(cache => cache.add('/offline.html'))
187
+ );
188
+ });
189
+
190
+ self.addEventListener('fetch', (event) => {
191
+ if (event.request.mode === 'navigate') {
192
+ event.respondWith(
193
+ fetch(event.request).catch(() => caches.match('/offline.html'))
194
+ );
195
+ }
196
+ });
197
+ ```
@@ -0,0 +1,115 @@
1
+ # Visual Hierarchy
2
+
3
+ The arrangement of visual elements by importance so the viewer's eye follows a deliberate path: most important → supporting → peripheral. Hierarchy is created through six levers: **size, weight, color, spacing, position, density**.
4
+
5
+ ## 1. Size Scale
6
+
7
+ ```
8
+ Level 1 (hero headline): clamp(2.25rem, 4vw + 1rem, 4rem)
9
+ Level 2 (section heading): clamp(1.5rem, 2.5vw + 0.75rem, 2.5rem)
10
+ Level 3 (subsection): clamp(1.125rem, 1.5vw + 0.5rem, 1.5rem)
11
+ Level 4 (body): 1rem (16px base)
12
+ Level 5 (caption/meta): 0.875rem
13
+ Level 6 (legal/fine print): 0.75rem
14
+ ```
15
+
16
+ - Adjacent levels must differ by at least 1.25x ratio (L1:L2 ≥ 1.5x, L2:L3 ≥ 1.25x)
17
+ - Never use more than 4 levels on a single viewport screen
18
+ - Hero headline ≥ 2x body size or it reads as a paragraph
19
+
20
+ ## 2. Weight Contrast
21
+
22
+ | Role | Weight | Use |
23
+ |------|--------|-----|
24
+ | Primary heading | 700-800 | Hero, section titles |
25
+ | Secondary heading | 600 | Subsection, card titles |
26
+ | Body emphasis | 500-600 | Key phrases, inline bold |
27
+ | Body text | 400 | Default reading text |
28
+ | De-emphasized | 300-400 | Captions, timestamps, metadata |
29
+
30
+ - Primary vs body weight difference ≥ 200 (e.g., 700 vs 400)
31
+ - Never use weight alone to create hierarchy — pair with size
32
+ - Display-scale exception: at display sizes, size contrast may replace weight
33
+ contrast; a 300-400 light headline is legal when >= 3x body size
34
+ (FE-HERO-LIGHT-CENTER-01). The 700-800 primary-heading row applies to
35
+ in-content headings, not display heroes.
36
+ - Monospace/code blocks: weight 400-500 max
37
+
38
+ ## 3. Color Emphasis
39
+
40
+ ```
41
+ Level 1 (primary): var(--color-text-primary) — full contrast, used sparingly
42
+ Level 2 (secondary): var(--color-text-secondary) — 70-80% of primary contrast
43
+ Level 3 (tertiary): var(--color-text-tertiary) — 50-60% of primary contrast
44
+ Level 4 (disabled): var(--color-text-disabled) — 35-40% of primary contrast
45
+ Accent: var(--color-accent) — reserved for ONE interactive element per viewport
46
+ ```
47
+
48
+ - Accent color on max 1-2 elements per viewport (CTA + link, not more)
49
+ - If everything is accent-colored, nothing is — the "purple wash" anti-pattern
50
+ - Heading color ≠ body color unless intentionally monochrome
51
+ - Background color creates hierarchy: white surface > gray surface > dark surface for cards
52
+
53
+ ## 4. Spacing as Hierarchy
54
+
55
+ ```
56
+ Section gap (between major sections): clamp(4rem, 8vw, 8rem)
57
+ Subsection gap: clamp(2rem, 4vw, 4rem)
58
+ Element group gap: 1.5rem - 2rem
59
+ Element gap (within a group): 0.5rem - 1rem
60
+ Tight (label-to-input, icon-to-text): 0.25rem - 0.5rem
61
+ ```
62
+
63
+ - More whitespace around an element = more important (isolation draws the eye)
64
+ - Hero section: generous padding (≥ 6rem top/bottom) — signals "start here"
65
+ - Dense sections contrast with sparse sections to create rhythm
66
+ - Gap between sections > gap within sections > gap between elements (nesting principle)
67
+
68
+ ## 5. Position Priority
69
+
70
+ | Position | Priority | Use |
71
+ |----------|----------|-----|
72
+ | Above the fold, center | Highest | Hero headline, primary CTA |
73
+ | Above the fold, left | High | Navigation, brand mark |
74
+ | Below fold, first scroll | Medium | Social proof, key features |
75
+ | Mid-page | Standard | Detailed features, comparison |
76
+ | Footer area | Low | Legal, secondary nav, contact |
77
+
78
+ - Primary CTA must appear above the fold
79
+ - Repeat CTA after every 2-3 sections on long pages
80
+ - F-pattern for text-heavy pages, Z-pattern for marketing/landing
81
+ - Mobile: stack in strict priority order (most important = topmost)
82
+
83
+ ## 6. Density Contrast
84
+
85
+ | Section Type | Density | Purpose |
86
+ |-------------|---------|---------|
87
+ | Hero | Sparse (1-3 elements) | Focus attention on single message |
88
+ | Social proof | Medium (logos + quote) | Build trust without overwhelming |
89
+ | Features | Dense (grid/cards) | Information delivery |
90
+ | CTA/pricing | Medium-sparse | Decision moment — clear options |
91
+ | Testimonial | Sparse (1 quote + photo) | Emotional pause, breathing room |
92
+
93
+ - Alternate dense/sparse sections to prevent fatigue
94
+ - Never stack two dense sections without a sparse break
95
+ - Sparse section immediately after hero creates "breathing room"
96
+
97
+ ## 7. Pre-commit Checklist
98
+
99
+ - [ ] Exactly 1 element per viewport is the obvious focal point
100
+ - [ ] Size ratio between heading levels ≥ 1.25x
101
+ - [ ] Weight difference between heading and body ≥ 200
102
+ - [ ] Accent color on ≤ 2 elements per viewport
103
+ - [ ] Section gaps > internal gaps > element gaps (nesting principle)
104
+ - [ ] Hero section has most whitespace on the page
105
+ - [ ] Primary CTA is above the fold
106
+ - [ ] Dense and sparse sections alternate
107
+ - [ ] F or Z reading pattern identifiable by squinting
108
+ - [ ] Color hierarchy has ≥ 3 distinct levels
109
+
110
+ ## 8. Cross-references
111
+
112
+ - Size scale clamp values: `dev-frontend/references/core/aesthetics.md` §Typography
113
+ - Section composition order: `layout-macrostructures.md`
114
+ - Responsive transforms: `dev-frontend/references/core/layout-discipline.md`
115
+ - Color tokens: `color-system.md`
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "index.html": {
3
- "file": "assets/index-CoxMOXAU.js",
3
+ "file": "assets/index-Dm3pFxV4.js",
4
4
  "name": "index",
5
5
  "src": "index.html",
6
6
  "isEntry": true,
@@ -17,11 +17,11 @@
17
17
  "src/components/PromptLibraryPanel.tsx"
18
18
  ],
19
19
  "css": [
20
- "assets/index-2oG6in1i.css"
20
+ "assets/index-J8yDF3Ch.css"
21
21
  ]
22
22
  },
23
23
  "src/components/GenerationRequestLogPanel.tsx": {
24
- "file": "assets/GenerationRequestLogPanel-C_qvEUi2.js",
24
+ "file": "assets/GenerationRequestLogPanel-DnmUQdKR.js",
25
25
  "name": "GenerationRequestLogPanel",
26
26
  "src": "src/components/GenerationRequestLogPanel.tsx",
27
27
  "isDynamicEntry": true,
@@ -30,7 +30,7 @@
30
30
  ]
31
31
  },
32
32
  "src/components/NodeCanvas.tsx": {
33
- "file": "assets/NodeCanvas-C67sLboA.js",
33
+ "file": "assets/NodeCanvas-CxpfIBI0.js",
34
34
  "name": "NodeCanvas",
35
35
  "src": "src/components/NodeCanvas.tsx",
36
36
  "isDynamicEntry": true,
@@ -42,7 +42,7 @@
42
42
  ]
43
43
  },
44
44
  "src/components/PromptImportDialog.tsx": {
45
- "file": "assets/PromptImportDialog-DeQXsEEv.js",
45
+ "file": "assets/PromptImportDialog-BIxz_yEx.js",
46
46
  "name": "PromptImportDialog",
47
47
  "src": "src/components/PromptImportDialog.tsx",
48
48
  "isDynamicEntry": true,
@@ -55,7 +55,7 @@
55
55
  ]
56
56
  },
57
57
  "src/components/PromptImportDiscoverySection.tsx": {
58
- "file": "assets/PromptImportDiscoverySection-CrwyUKYI.js",
58
+ "file": "assets/PromptImportDiscoverySection-BQTlPMME.js",
59
59
  "name": "PromptImportDiscoverySection",
60
60
  "src": "src/components/PromptImportDiscoverySection.tsx",
61
61
  "isDynamicEntry": true,
@@ -64,7 +64,7 @@
64
64
  ]
65
65
  },
66
66
  "src/components/PromptImportFolderSection.tsx": {
67
- "file": "assets/PromptImportFolderSection-CToGMqYE.js",
67
+ "file": "assets/PromptImportFolderSection-Ds_Th9O3.js",
68
68
  "name": "PromptImportFolderSection",
69
69
  "src": "src/components/PromptImportFolderSection.tsx",
70
70
  "isDynamicEntry": true,
@@ -73,7 +73,7 @@
73
73
  ]
74
74
  },
75
75
  "src/components/PromptLibraryPanel.tsx": {
76
- "file": "assets/PromptLibraryPanel-Db3xEPM_.js",
76
+ "file": "assets/PromptLibraryPanel-Rs4l45pV.js",
77
77
  "name": "PromptLibraryPanel",
78
78
  "src": "src/components/PromptLibraryPanel.tsx",
79
79
  "isDynamicEntry": true,
@@ -85,7 +85,7 @@
85
85
  ]
86
86
  },
87
87
  "src/components/SettingsWorkspace.tsx": {
88
- "file": "assets/SettingsWorkspace-BDk_1W-V.js",
88
+ "file": "assets/SettingsWorkspace-p1AZ6uT9.js",
89
89
  "name": "SettingsWorkspace",
90
90
  "src": "src/components/SettingsWorkspace.tsx",
91
91
  "isDynamicEntry": true,
@@ -94,7 +94,7 @@
94
94
  ]
95
95
  },
96
96
  "src/components/agent/AgentWorkspace.tsx": {
97
- "file": "assets/AgentWorkspace-DAg_7zpY.js",
97
+ "file": "assets/AgentWorkspace-CtYt4SF5.js",
98
98
  "name": "AgentWorkspace",
99
99
  "src": "src/components/agent/AgentWorkspace.tsx",
100
100
  "isDynamicEntry": true,
@@ -103,7 +103,7 @@
103
103
  ]
104
104
  },
105
105
  "src/components/canvas-mode/index.ts": {
106
- "file": "assets/index-p8egnGHk.js",
106
+ "file": "assets/index-0-_vgFGs.js",
107
107
  "name": "index",
108
108
  "src": "src/components/canvas-mode/index.ts",
109
109
  "isDynamicEntry": true,
@@ -112,7 +112,7 @@
112
112
  ]
113
113
  },
114
114
  "src/components/card-news/CardNewsWorkspace.tsx": {
115
- "file": "assets/CardNewsWorkspace-Cdxn1ohU.js",
115
+ "file": "assets/CardNewsWorkspace-DN5cVqG5.js",
116
116
  "name": "CardNewsWorkspace",
117
117
  "src": "src/components/card-news/CardNewsWorkspace.tsx",
118
118
  "isDynamicEntry": true,
@@ -121,7 +121,7 @@
121
121
  ]
122
122
  },
123
123
  "src/components/prompt-builder/PromptBuilderPanel.tsx": {
124
- "file": "assets/PromptBuilderPanel-DjvVdAie.js",
124
+ "file": "assets/PromptBuilderPanel-C2R3ObtR.js",
125
125
  "name": "PromptBuilderPanel",
126
126
  "src": "src/components/prompt-builder/PromptBuilderPanel.tsx",
127
127
  "isDynamicEntry": true,