analyzthis_design 2.5.0 → 2.5.2
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/HOW-TO-USE.md +249 -326
- package/README.md +58 -13
- package/agents/calibration-benchmark.json +187 -0
- package/agents/cards/anuj.md +2 -2
- package/agents/cards/arjun.md +2 -2
- package/agents/cards/kavi.md +2 -1
- package/agents/cards/mood-board.md +3 -2
- package/agents/cards/noor.md +2 -2
- package/agents/cards/priya.md +1 -1
- package/agents/cards/zara.md +3 -3
- package/agents/chain.json +1 -1
- package/agents/design-spec-schema.json +18 -1
- package/agents/manifests/mood-board.json +1 -0
- package/agents/model-policy.json +12 -0
- package/agents/router.json +1 -1
- package/agents/session-schema.json +12 -2
- package/dist/HOW-TO-USE.md +249 -326
- package/dist/README.md +58 -13
- package/dist/agents/calibration-benchmark.json +187 -0
- package/dist/agents/cards/anuj.md +2 -2
- package/dist/agents/cards/arjun.md +2 -2
- package/dist/agents/cards/kavi.md +2 -1
- package/dist/agents/cards/mood-board.md +3 -2
- package/dist/agents/cards/noor.md +2 -2
- package/dist/agents/cards/priya.md +1 -1
- package/dist/agents/cards/zara.md +3 -3
- package/dist/agents/chain.json +1 -1
- package/dist/agents/design-spec-schema.json +18 -1
- package/dist/agents/manifests/mood-board.json +1 -0
- package/dist/agents/model-policy.json +12 -0
- package/dist/agents/router.json +1 -1
- package/dist/agents/session-schema.json +12 -2
- package/dist/bin/cli.js +154 -5
- package/dist/lib/calibrate.js +816 -0
- package/dist/lib/chunk-executor.js +41 -1
- package/dist/lib/chunk-models.js +4 -18
- package/dist/lib/chunk-router.js +22 -6
- package/dist/lib/chunk-run.js +55 -1
- package/dist/lib/chunk-synthesis.js +18 -2
- package/dist/lib/chunk-telemetry.js +77 -17
- package/dist/lib/collect.js +15 -1
- package/dist/lib/cost.js +15 -7
- package/dist/lib/design-spec.js +32 -2
- package/dist/lib/evolution-metrics.js +23 -1
- package/dist/lib/feedback-submit.js +50 -1
- package/dist/lib/feedback.js +15 -0
- package/dist/lib/lessons.js +8 -0
- package/dist/lib/mcp-server.js +119 -5
- package/dist/lib/model-policy.js +174 -0
- package/dist/lib/model-registry.js +71 -0
- package/dist/lib/moodboard.js +162 -28
- package/dist/lib/orchestrator/run.js +67 -8
- package/dist/lib/outcome.js +7 -2
- package/dist/lib/output-quality.js +95 -0
- package/dist/lib/reference-pack.js +9 -1
- package/dist/lib/session.js +48 -4
- package/dist/lib/system-prompt.js +3 -0
- package/dist/lib/ui-libraries.js +232 -0
- package/dist/skills/anuj/SKILL.md +4 -1
- package/dist/skills/arjun/SKILL.md +2 -2
- package/dist/skills/arjun/references/lens.md +15 -2
- package/dist/skills/design-director/SKILL.md +2 -0
- package/dist/skills/design-reference/SKILL.md +6 -0
- package/dist/skills/design-reference/motion.csv +11 -0
- package/dist/skills/design-reference/schema.json +12 -0
- package/dist/skills/design-reference/stacks/shadcn.csv +6 -0
- package/dist/skills/design-reference/ui-libraries.csv +46 -0
- package/dist/skills/design-reference/ux-guidelines.csv +12 -1
- package/dist/skills/design-spec/SKILL.md +1 -1
- package/dist/skills/getting-started/SKILL.md +2 -2
- package/dist/skills/kavi/SKILL.md +4 -3
- package/dist/skills/mood-board/SKILL.md +29 -3
- package/dist/skills/noor/SKILL.md +5 -1
- package/dist/skills/priya/SKILL.md +3 -0
- package/dist/skills/zara/SKILL.md +50 -3
- package/package.json +5 -2
- package/skills/anuj/SKILL.md +4 -1
- package/skills/arjun/SKILL.md +2 -2
- package/skills/arjun/references/lens.md +15 -2
- package/skills/design-director/SKILL.md +2 -0
- package/skills/design-reference/SKILL.md +6 -0
- package/skills/design-reference/motion.csv +11 -0
- package/skills/design-reference/schema.json +12 -0
- package/skills/design-reference/stacks/shadcn.csv +6 -0
- package/skills/design-reference/ui-libraries.csv +46 -0
- package/skills/design-reference/ux-guidelines.csv +12 -1
- package/skills/design-spec/SKILL.md +1 -1
- package/skills/getting-started/SKILL.md +2 -2
- package/skills/kavi/SKILL.md +4 -3
- package/skills/mood-board/SKILL.md +29 -3
- package/skills/noor/SKILL.md +5 -1
- package/skills/priya/SKILL.md +3 -0
- package/skills/zara/SKILL.md +50 -3
|
@@ -32,8 +32,11 @@ function buildPrompt(opts) {
|
|
|
32
32
|
lines.push('');
|
|
33
33
|
lines.push('**CRITIQUE** — Review an existing screen. Run personas: Arjun (UX + Visual) + Meera (Business) -> Priya (Feasibility) + Zara (Delight) -> Raj (synthesis). Output: composite score, SHIP/REVISE/BLOCK verdict, top 3 fixes.');
|
|
34
34
|
lines.push('');
|
|
35
|
+
lines.push('**DIRECTION** — Mood board (tagged URLs) or UI image board. For a UI board, Zara scouts 3-5 real shipped screens (never invent URLs, never generate AI comps). Arjun, Noor, Priya, Meera jury. She re-scouts if they skip (max 3 rounds).');
|
|
36
|
+
lines.push('');
|
|
35
37
|
lines.push('When the user says "design", "wireframe", "ideate", or "create" -> run CREATE mode.');
|
|
36
38
|
lines.push('When the user says "review", "critique", "audit", or "fix" -> run CRITIQUE mode.');
|
|
39
|
+
lines.push('When the user says "mood board", "UI board", "image board", or "visual direction" -> run DIRECTION mode.');
|
|
37
40
|
lines.push('');
|
|
38
41
|
|
|
39
42
|
lines.push('## Premise challenge (critical)');
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Detect installed motion / UX / visual-design libraries from package.json
|
|
5
|
+
* and copy-paste kit folders. Personas read Tech/Installed-UI-Libraries.md
|
|
6
|
+
* and session.installed_ui_libraries instead of guessing the stack.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const fs = require('fs');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
const retrieve = require('./retrieve');
|
|
12
|
+
|
|
13
|
+
const DEFAULT_BY_JOB = {
|
|
14
|
+
primitives: 'Shadcn UI',
|
|
15
|
+
motion: 'Motion',
|
|
16
|
+
icons: 'Lucide',
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const FOLDER_CANDIDATES = [
|
|
20
|
+
'components/ui',
|
|
21
|
+
'src/components/ui',
|
|
22
|
+
'app/components/ui',
|
|
23
|
+
'components/magicui',
|
|
24
|
+
'src/components/magicui',
|
|
25
|
+
'components/aceternity',
|
|
26
|
+
'src/components/aceternity',
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
function catalogRows() {
|
|
30
|
+
try {
|
|
31
|
+
return retrieve.loadCsv('ui-libraries.csv').rows || [];
|
|
32
|
+
} catch {
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function splitAliases(field) {
|
|
38
|
+
return String(field || '')
|
|
39
|
+
.split(';')
|
|
40
|
+
.map((s) => s.trim())
|
|
41
|
+
.filter(Boolean);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function npmMatches(depName, npmField) {
|
|
45
|
+
return splitAliases(npmField).some((alias) => {
|
|
46
|
+
if (alias.endsWith('/*')) {
|
|
47
|
+
const prefix = alias.slice(0, -1);
|
|
48
|
+
const pkg = alias.slice(0, -2);
|
|
49
|
+
return depName === pkg || depName.startsWith(prefix);
|
|
50
|
+
}
|
|
51
|
+
return depName === alias;
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function readPackageDeps(cwd) {
|
|
56
|
+
const pkgPath = path.join(cwd, 'package.json');
|
|
57
|
+
if (!fs.existsSync(pkgPath)) return { deps: [], pkgPath: null };
|
|
58
|
+
try {
|
|
59
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
60
|
+
const names = Object.keys({
|
|
61
|
+
...(pkg.dependencies || {}),
|
|
62
|
+
...(pkg.devDependencies || {}),
|
|
63
|
+
});
|
|
64
|
+
return { deps: names, pkgPath };
|
|
65
|
+
} catch {
|
|
66
|
+
return { deps: [], pkgPath };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function folderExists(cwd, rel) {
|
|
71
|
+
try {
|
|
72
|
+
return fs.statSync(path.join(cwd, rel)).isDirectory();
|
|
73
|
+
} catch {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function detectFolders(cwd) {
|
|
79
|
+
const found = [];
|
|
80
|
+
for (const rel of FOLDER_CANDIDATES) {
|
|
81
|
+
if (folderExists(cwd, rel)) found.push(rel);
|
|
82
|
+
}
|
|
83
|
+
return found;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function folderHitsRow(foundFolders, detectionFolders) {
|
|
87
|
+
const needles = splitAliases(detectionFolders).filter(Boolean);
|
|
88
|
+
if (!needles.length) return false;
|
|
89
|
+
return foundFolders.some((rel) =>
|
|
90
|
+
needles.some((n) => rel === n || rel.endsWith('/' + n) || rel.indexOf(n) !== -1));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @param {{ cwd: string }} opts
|
|
95
|
+
* @returns {{ installed: object[], missing_defaults: object[], folders: string[], full_kits: string[], mixed_kits: boolean }}
|
|
96
|
+
*/
|
|
97
|
+
function detectInstalledUiLibraries({ cwd } = {}) {
|
|
98
|
+
const root = path.resolve(cwd || process.cwd());
|
|
99
|
+
const { deps } = readPackageDeps(root);
|
|
100
|
+
const folders = detectFolders(root);
|
|
101
|
+
const rows = catalogRows();
|
|
102
|
+
const installed = [];
|
|
103
|
+
const seen = new Set();
|
|
104
|
+
|
|
105
|
+
for (const row of rows) {
|
|
106
|
+
const byNpm = deps.some((d) => npmMatches(d, row['Npm Names']));
|
|
107
|
+
const byFolder = folderHitsRow(folders, row['Detection Folders']);
|
|
108
|
+
if (!byNpm && !byFolder) continue;
|
|
109
|
+
const name = row.Library;
|
|
110
|
+
if (seen.has(name)) continue;
|
|
111
|
+
seen.add(name);
|
|
112
|
+
installed.push({
|
|
113
|
+
library: name,
|
|
114
|
+
job: row.Job,
|
|
115
|
+
persona: row.Persona,
|
|
116
|
+
import_example: row['Import Example'],
|
|
117
|
+
docs: row['Docs URL'],
|
|
118
|
+
do_not_use_for: row['Do Not Use For'],
|
|
119
|
+
bundle_hint: row['Bundle Hint'],
|
|
120
|
+
how: byNpm ? (byFolder ? 'package+folder' : 'package.json') : 'folder',
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const jobsPresent = new Set(installed.map((i) => i.job));
|
|
125
|
+
const missing_defaults = [];
|
|
126
|
+
Object.keys(DEFAULT_BY_JOB).forEach((job) => {
|
|
127
|
+
if (jobsPresent.has(job)) return;
|
|
128
|
+
// full-kit covers primitives
|
|
129
|
+
if (job === 'primitives' && jobsPresent.has('full-kit')) return;
|
|
130
|
+
const libName = DEFAULT_BY_JOB[job];
|
|
131
|
+
const row = rows.find((r) => r.Library === libName);
|
|
132
|
+
missing_defaults.push({
|
|
133
|
+
job,
|
|
134
|
+
library: libName,
|
|
135
|
+
install: row ? row.Install : '',
|
|
136
|
+
docs: row ? row['Docs URL'] : '',
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
const full_kits = installed.filter((i) => i.job === 'full-kit').map((i) => i.library);
|
|
141
|
+
const hasShadcn = installed.some((i) => i.library === 'Shadcn UI' || i.library === 'Radix UI');
|
|
142
|
+
const mixed_kits = full_kits.length > 1 || (full_kits.length > 0 && hasShadcn);
|
|
143
|
+
|
|
144
|
+
return { installed, missing_defaults, folders, full_kits, mixed_kits };
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function buildNoteMarkdown(detection) {
|
|
148
|
+
const date = new Date().toISOString().split('T')[0];
|
|
149
|
+
const installed = detection.installed || [];
|
|
150
|
+
const missing = detection.missing_defaults || [];
|
|
151
|
+
const lines = [
|
|
152
|
+
'---',
|
|
153
|
+
'title: Installed-UI-Libraries',
|
|
154
|
+
'tags: [tech, ui-libraries]',
|
|
155
|
+
'source: package.json',
|
|
156
|
+
'category: tech',
|
|
157
|
+
`collected_at: "${date}"`,
|
|
158
|
+
'enriched: true',
|
|
159
|
+
'---',
|
|
160
|
+
'',
|
|
161
|
+
'## Purpose',
|
|
162
|
+
'Libraries already in this repo that design personas must prefer. One library per job. Do not add a second full UI kit. Do not put marketing FX (Magic UI, Aceternity, 21st.dev, Lottie, Spline) on daily working dashboards.',
|
|
163
|
+
'',
|
|
164
|
+
'## Installed',
|
|
165
|
+
];
|
|
166
|
+
if (!installed.length) {
|
|
167
|
+
lines.push('- _(none of the catalogued packages detected)_');
|
|
168
|
+
} else {
|
|
169
|
+
for (const i of installed) {
|
|
170
|
+
lines.push(`- **${i.library}** (${i.job}) via ${i.how} — \`${i.import_example}\``);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
lines.push('', '## Missing defaults (optional — do not install unless the brief needs them)');
|
|
174
|
+
if (!missing.length) {
|
|
175
|
+
lines.push('- All default jobs covered.');
|
|
176
|
+
} else {
|
|
177
|
+
for (const m of missing) {
|
|
178
|
+
lines.push(`- **${m.job}:** ${m.library} — \`${m.install}\``);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
lines.push('', '## Kit rule');
|
|
182
|
+
if (detection.mixed_kits) {
|
|
183
|
+
lines.push('- **BLOCK mix:** more than one full kit (or a full kit plus Shadcn) is present. Priya: do not add more. Use the incumbent kit.');
|
|
184
|
+
} else if (detection.full_kits && detection.full_kits.length) {
|
|
185
|
+
lines.push(`- Incumbent full kit: **${detection.full_kits.join(', ')}**. Prescribe this kit's components; do not start a Shadcn tree.`);
|
|
186
|
+
} else {
|
|
187
|
+
lines.push('- No full kit detected. Shadcn + Radix is the greenfield default for Tailwind apps.');
|
|
188
|
+
}
|
|
189
|
+
lines.push('', '## Folders found');
|
|
190
|
+
if (!(detection.folders || []).length) {
|
|
191
|
+
lines.push('- _(none)_');
|
|
192
|
+
} else {
|
|
193
|
+
for (const f of detection.folders) lines.push(`- \`${f}\``);
|
|
194
|
+
}
|
|
195
|
+
lines.push('');
|
|
196
|
+
return lines.join('\n');
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function writeInstalledUiLibrariesNote({ vaultPath, detection, dryRun }) {
|
|
200
|
+
const md = buildNoteMarkdown(detection);
|
|
201
|
+
const rel = path.join('Tech', 'Installed-UI-Libraries.md');
|
|
202
|
+
if (dryRun || !vaultPath) {
|
|
203
|
+
return { vaultRel: rel, written: false, markdown: md };
|
|
204
|
+
}
|
|
205
|
+
const destDir = path.join(vaultPath, 'Tech');
|
|
206
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
207
|
+
const dest = path.join(destDir, 'Installed-UI-Libraries.md');
|
|
208
|
+
fs.writeFileSync(dest, md);
|
|
209
|
+
return { vaultRel: rel, written: true, markdown: md, dest };
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function sessionPayload(detection) {
|
|
213
|
+
return {
|
|
214
|
+
installed: (detection.installed || []).map((i) => ({
|
|
215
|
+
library: i.library,
|
|
216
|
+
job: i.job,
|
|
217
|
+
how: i.how,
|
|
218
|
+
})),
|
|
219
|
+
missing_defaults: detection.missing_defaults || [],
|
|
220
|
+
full_kits: detection.full_kits || [],
|
|
221
|
+
mixed_kits: !!detection.mixed_kits,
|
|
222
|
+
folders: detection.folders || [],
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
module.exports = {
|
|
227
|
+
detectInstalledUiLibraries,
|
|
228
|
+
writeInstalledUiLibrariesNote,
|
|
229
|
+
buildNoteMarkdown,
|
|
230
|
+
sessionPayload,
|
|
231
|
+
DEFAULT_BY_JOB,
|
|
232
|
+
};
|
|
@@ -31,6 +31,8 @@ You cannot know host tokens. Do not invent a dollar figure.
|
|
|
31
31
|
## Non-negotiables
|
|
32
32
|
|
|
33
33
|
- **Density never flattens the information hierarchy.** Whatever ranks #1 in Noor's declared hierarchy (or the most business-critical column/data point if no ranking was declared) stays the most prominent element on screen — leftmost column, largest, first-sorted, or otherwise visually dominant — even at full data density. "Everything is visible" is not the same as "everything is equally important."
|
|
34
|
+
- **Harden for production edge cases:** Audit that high-density tables and forms handle text overflow (`truncate`, `line-clamp-2`), extreme data lengths, zero/empty states, loading states, error boundaries, and form state hardening (`[ux-guidelines.csv, row 84, 110]`).
|
|
35
|
+
- **Prefer installed power-user libs:** If `installed_ui_libraries` has TanStack Table/Virtual, CMDK, Auto-Animate, `nuqs`, or a hotkeys library, specify those imports. Otherwise Shadcn Table + note “add TanStack if volume is high.” CMDK for Cmd+K on daily surfaces.
|
|
34
36
|
- Every data table has bulk selection
|
|
35
37
|
- Any action taken >10×/session has a keyboard shortcut
|
|
36
38
|
- Column configuration is user-controllable
|
|
@@ -38,7 +40,7 @@ You cannot know host tokens. Do not invent a dollar figure.
|
|
|
38
40
|
|
|
39
41
|
## What you fight against
|
|
40
42
|
|
|
41
|
-
Wizard flows that fragment a single task across multiple screens. Progressive disclosure that hides data expert users need immediately. "Clean" interfaces that strip data under the banner of simplicity.
|
|
43
|
+
Wizard flows that fragment a single task across multiple screens. Progressive disclosure that hides data expert users need immediately. "Clean" interfaces that strip data under the banner of simplicity. Fragile layouts that break when text overflows or data volume surges.
|
|
42
44
|
|
|
43
45
|
## Output — Concept B (text wireframe format)
|
|
44
46
|
|
|
@@ -93,6 +95,7 @@ Read from `~/.cursor/skills/design-reference/` to ground power-user critique in
|
|
|
93
95
|
| `app-interface.csv` | When mobile or React Native is in scope — cite touch target rules and gesture patterns |
|
|
94
96
|
| `ui-reasoning.csv` | When auditing the default state — check `Recommended_Pattern` for the product category to verify density is appropriate |
|
|
95
97
|
| `stacks/shadcn.csv` | When design system is ShadCN — confirm that DataTable, Command, and bulk-action components exist before specifying them |
|
|
98
|
+
| `ui-libraries.csv` | Table, command, hotkeys, url-state rows — cite Import Example; prefer installed |
|
|
96
99
|
|
|
97
100
|
**How to use:** When auditing a surface for power-user gaps, read `ux-guidelines.csv` and filter by `Category` = "Navigation", "Interaction", or "Data Table". Cite the `Issue`, `Do`, and `Severity` columns to make the gap concrete and actionable.
|
|
98
101
|
|
|
@@ -10,11 +10,11 @@ disable-model-invocation: true
|
|
|
10
10
|
|
|
11
11
|
You are Arjun. Product designer who came up through user research — 200+ user sessions across B2B SaaS — operations, analytics, and workflow tools for expert users in high-pressure, time-scarce environments. You speak for users not in the room.
|
|
12
12
|
|
|
13
|
-
You then spent 3 years on a design system team: built the token architecture, owned component specs, shipped 200+ production components. That means you run both the UX lens and the visual design lens in a single pass — you do not need to hand off basic visual quality issues to someone else. You know exactly why a layout feels unbalanced, why a palette feels wrong for the category, and why spacing that isn't on a scale creates visual noise, and you can name the fix precisely.
|
|
13
|
+
You then spent 3 years on a design system team: built the token architecture, owned component specs, shipped 200+ production components. That means you run both the UX lens and the visual design lens in a single pass — you do not need to hand off basic visual quality issues to someone else. You know exactly why a layout feels unbalanced, why a palette feels wrong for the category, and why spacing that isn't on a scale creates visual noise, and you can name the fix precisely. You actively scan for and eliminate generic AI-slop patterns (card nesting syndrome, un-tinted pure blacks, gray text on colored badges, purple gradient clichés, and bouncy animations).
|
|
14
14
|
|
|
15
15
|
## Allowed / forbidden jobs
|
|
16
16
|
|
|
17
|
-
**Allowed:** UX Honeycomb critique; the full Visual Design Audit (hierarchy, color, typography, spacing, components, style fit, micro-interactions); diagnosing visual issues against the declared information hierarchy and DS tokens.
|
|
17
|
+
**Allowed:** UX Honeycomb critique; the full Visual Design Audit (hierarchy, color, typography, spacing, components, style fit, micro-interactions, anti-slop craftsmanship checks, bolder vs. quieter balance); diagnosing visual issues against the declared information hierarchy and DS tokens.
|
|
18
18
|
|
|
19
19
|
**Forbidden:** brand-system recovery as a primary job — this is a diagnostic pass only, using `colors.csv` + knowledge bank tokens, never CSS patches or `!important` overrides; running a delight pass (hand off to Zara); implementing code without explicit build approval (see Assess-only below).
|
|
20
20
|
|
|
@@ -214,8 +214,19 @@ Combined Arjun score: (UX score + Visual score) / 2 → [X/5]
|
|
|
214
214
|
- Missing timestamps users repeatedly asked for
|
|
215
215
|
- Modal interruptions that break expert mid-flow
|
|
216
216
|
- Single-session generalizations — always qualify with sample size
|
|
217
|
-
|
|
218
|
-
|
|
217
|
+
- Touch targets under 44×44px on mobile or tablet surfaces (`[ux-guidelines.csv, row 109]`)
|
|
218
|
+
|
|
219
|
+
**Visual & Anti-AI-Slop Checks:**
|
|
220
|
+
- **Card Nesting Syndrome:** Wrapping every section in nested cards (`div.card > div.card > div.card`). Flag this and replace with clean whitespace, subtle horizontal rules, and typographic hierarchy (`[ux-guidelines.csv, row 100]`).
|
|
221
|
+
- **Untinted / Harsh Neutrals:** Pure `#000000` black or dead `#888888` gray with zero undertone. Replace with brand-tinted neutrals (e.g. slate, zinc, warm gray) (`[ux-guidelines.csv, row 101]`).
|
|
222
|
+
- **Gray Text on Colored Backgrounds:** Light or medium gray text placed on colored hero sections, pills, or cards that destroys WCAG contrast. Enforce high-contrast tinted white/dark tones (`[ux-guidelines.csv, row 102]`).
|
|
223
|
+
- **AI Purple/Blue Gradient Clichés:** Defaulting to generic purple-to-blue or pink gradient text and cards on every screen. Use intentional brand palettes, crisp solid accents, or clean subtle tinted backgrounds (`[ux-guidelines.csv, row 103]`).
|
|
224
|
+
- **Heading Icon Tile Crutch:** Sticking a rounded-square bordered icon tile above every single section heading. Use strong typographic hierarchy instead of decorative icon crutches (`[ux-guidelines.csv, row 104]`).
|
|
225
|
+
- **Bouncy / Elastic Easing:** Bouncy, elastic spring overshoot or animations >400ms that feel gimmicky. Enforce crisp 150–250ms ease-out transitions (`[ux-guidelines.csv, row 105]`).
|
|
226
|
+
- **Runaway Reading Width:** Paragraphs stretching beyond 75 characters per line without max-width constraint. Constrain reading columns to 45–75ch (`[ux-guidelines.csv, row 106]`).
|
|
227
|
+
- **Bolder vs. Quieter Balance:**
|
|
228
|
+
- *Too Timid (Needs to be Bolder):* Everything has identical medium font size and gray tint with no clear focal point. Scale rank #1 up, increase contrast, establish a dominant visual anchor (`[ux-guidelines.csv, row 107]`).
|
|
229
|
+
- *Over-Decorated (Needs to be Quieter):* Every widget has borders, badges, glows, and shadows. Strip away redundant borders and let white space carry the structure (`[ux-guidelines.csv, row 108]`).
|
|
219
230
|
- Visual hierarchy doesn't match the declared information hierarchy — the most important element isn't the most visually prominent one, even when Noor's ranking says it should be
|
|
220
231
|
- Wrong product-type style — e.g. an editorial serif like Playfair Display on a developer tool signals luxury, not technical trust
|
|
221
232
|
- Spacing chaos — 7px, 13px, 22px gaps instead of a consistent 4/8/16/32 scale
|
|
@@ -259,6 +270,8 @@ Read from `~/.cursor/skills/design-reference/` when grounding critique in specif
|
|
|
259
270
|
| `colors.csv` | Always for the Visual Design Audit — grounds the Color System dimension. Filter: match `Product Type` to the session context product, then compare the design's actual palette against the recommended tokens. |
|
|
260
271
|
| `typography.csv` | Always for the Visual Design Audit — grounds the Typography dimension. Filter: match `Best For` and `Mood/Style Keywords` to the session context product type. |
|
|
261
272
|
| `icons.csv` | When icons are visible on the screen — audit for family and weight consistency. Check whether all icons come from the same family (e.g., Phosphor) and share the same visual weight (e.g., all regular, not a mix of regular and bold). |
|
|
273
|
+
| `motion.csv` | Always for Micro-interactions — cite Timing and Easing. Flag bounce and >400ms. |
|
|
274
|
+
| `ui-libraries.csv` | Always — tokens, typography, icons, charts, a11y. Prefer `installed_ui_libraries`. One icon family (Lucide or Phosphor). Floating UI for popover collision. Tremor/Recharts for dashboards. Fontsource/`next/font` when present. |
|
|
262
275
|
|
|
263
276
|
**How to use:** Filter rows by product type or platform matching the session context. Quote the `Do`, `Don't`, and `Severity` columns directly in your critique instead of giving abstract advice.
|
|
264
277
|
|
|
@@ -108,6 +108,8 @@ Read `skills/arjun/SKILL.md` — scoped **spec review only**:
|
|
|
108
108
|
- Typography scale consistent?
|
|
109
109
|
- Spacing rhythm (`tokens.spacing`) sufficient?
|
|
110
110
|
- Color classes WCAG-safe per knowledge bank?
|
|
111
|
+
- Anti-slop craftsmanship checks: no nested cards, no untinted pure black/gray, no gray text on colored backgrounds, and motion timing locked to 150–250ms ease-out (`[ux-guidelines.csv, row 100-105]`, `[motion.csv, row 1]`).
|
|
112
|
+
- If `motion.enabled`: library + import from installed or `ui-libraries.csv`; `reduced_motion` filled; no Magic UI / Aceternity / Lottie on daily surfaces.
|
|
111
113
|
|
|
112
114
|
Update `spec_verdict`. All three pass → set `"status": "ship"`.
|
|
113
115
|
|
|
@@ -25,6 +25,8 @@ Shared knowledge base for all 7 design personas. Each CSV covers a specific desi
|
|
|
25
25
|
| `landing.csv` | Landing page layout patterns — section order, CTA placement, color strategy, conversion optimization | Meera, Zara |
|
|
26
26
|
| `charts.csv` | 25 chart types — when to use, when not to use, accessibility grade, library recommendation | Arjun, Zara |
|
|
27
27
|
| `icons.csv` | Phosphor icon catalog — name, keywords, import code, usage context, style | Noor, Zara |
|
|
28
|
+
| `motion.csv` | Motion craft rules — enter/exit, layout, hover, lists, celebration, reduced-motion, timings | Zara, Arjun |
|
|
29
|
+
| `ui-libraries.csv` | Motion, UX, and visual-design packages — npm names, jobs, imports, when not to use | Zara, Arjun, Anuj, Noor, Priya |
|
|
28
30
|
| `react-performance.csv` | React rendering patterns — memoization, lazy loading, virtualization, bundle splitting | Priya |
|
|
29
31
|
| `stacks/nextjs.csv` | Next.js-specific patterns and component guidance | Priya |
|
|
30
32
|
| `stacks/react.csv` | React-specific patterns | Priya |
|
|
@@ -52,6 +54,8 @@ Every time you cite a value from a reference file, use this format inline:
|
|
|
52
54
|
- `[ui-reasoning.csv, row 6: "Financial Dashboard — must_have: real-time-updates, must_have: high-contrast"]`
|
|
53
55
|
- `[styles.csv, row 14: "Glassmorphism — Effects: backdrop-blur(20px) + border: 1px rgba(255,255,255,0.2)"]`
|
|
54
56
|
- `[stacks/shadcn.csv, row 8: "DataTable — supports column visibility toggle and row selection"]`
|
|
57
|
+
- `[motion.csv, row 1: "Animate enter with 150-250ms ease-out — Severity: High"]`
|
|
58
|
+
- `[ui-libraries.csv, row 23: "CMDK — Job: command — daily power-user palettes"]`
|
|
55
59
|
|
|
56
60
|
**Never cite abstractly.** "Add a 44px touch target" is wrong. `[ux-guidelines.csv, row 22: "Minimum 44×44px — Severity: High"]` is correct. The row number and quoted value make the output reproducible across AI sessions.
|
|
57
61
|
|
|
@@ -74,6 +78,8 @@ All files live at: `~/.cursor/skills/design-reference/`
|
|
|
74
78
|
├── landing.csv
|
|
75
79
|
├── charts.csv
|
|
76
80
|
├── icons.csv
|
|
81
|
+
├── motion.csv
|
|
82
|
+
├── ui-libraries.csv
|
|
77
83
|
├── react-performance.csv
|
|
78
84
|
└── stacks/
|
|
79
85
|
├── nextjs.csv
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
No,Category,Library,Timing,Easing,Do,Don't,Code Example Good,Code Example Bad,Severity
|
|
2
|
+
1,enter-exit,motion,150-250ms,ease-out,Animate enter with 150-250ms ease-out and exit slightly faster; wrap lists in AnimatePresence,Use bounce elastic or durations over 400ms on UI chrome,"<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ duration: 0.2; ease: 'easeOut' }}>","<motion.div animate={{ y: [0;-8;0] }} transition={{ type: 'spring'; bounce: 0.6 }}>",High
|
|
3
|
+
2,layout,motion,200-300ms,ease-out,Use layout or layoutId for shared-element moves so the eye can track rank #1,Animate top/left/width/height (layout thrash) or skip layout animation entirely,"<motion.div layoutId=""primary-cta"" transition={{ duration: 0.22; ease: 'easeOut' }}>","style={{ top: animatedTop }} without transform",Medium
|
|
4
|
+
3,hover-tap,motion,150ms,ease-out,Hover and press feedback in 150ms; keep scale under 1.03 on product UI,Elastic spring on buttons or hover that moves layout,"<motion.button whileHover={{ scale: 1.02 }} whileTap={{ scale: 0.98 }} transition={{ duration: 0.15 }}>","whileHover={{ scale: 1.15 }} transition={{ type: 'spring'; bounce: 0.8 }}",High
|
|
5
|
+
4,list,@formkit/auto-animate,200ms,ease-out,Use Auto-Animate for insert/remove/reorder on tables and filters when the package is installed,Hand-roll FLIP or bounce rows in and out,useAutoAnimate() on the tbody or list parent,animate-bounce on every new table row,Medium
|
|
6
|
+
5,scroll,lenis,n/a,smooth,Lenis only on marketing or long-scroll storytelling pages,Smooth-scroll hijack on app chrome dashboards or data tables,Lenis on a landing page with prefers-reduced-motion disable,new Lenis() on an invoice queue,High
|
|
7
|
+
6,celebration,canvas-confetti,one-shot,n/a,Fire confetti once at a Peak-End milestone (first success) then never again on that surface,Confetti on every save click or page load,"confetti({ particleCount: 60; spread: 50 }) once on first invoice created",confetti() inside a useEffect with no guard,High
|
|
8
|
+
7,reduced-motion,css,0ms,none,Honor prefers-reduced-motion: reduce — opacity only or no motion,Ignore the media query or force parallax,"@media (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; } }",ScrollTrigger parallax with no reduced-motion branch,High
|
|
9
|
+
8,enter-exit,motion,400ms+,bounce,Never use bounce or elastic easing on menus dialogs dropdowns or tables,animate-bounce or spring bounce > 0.2 on product chrome,transition={{ duration: 0.2; ease: 'easeOut' }},className=""animate-bounce"" on a Sheet,High
|
|
10
|
+
9,celebration,lottie-react,one-shot,n/a,Lottie or Rive only as Zara's single peak on onboarding or empty-state illustration,Looping Lottie on a daily dashboard,"<Lottie animationData={success} loop={false} /> inside prefers-reduced-motion check","<Lottie loop autoplay /> in the app shell",High
|
|
11
|
+
10,hover-tap,css,150-250ms,ease-out,CSS transitions with transform and opacity are enough when Motion is not installed,Animate width height top left or box-shadow on every hover,transition-transform duration-200 ease-out hover:scale-[1.02],transition-all duration-700 ease-in-out hover:h-32,Medium
|
|
@@ -70,6 +70,18 @@
|
|
|
70
70
|
"no_column": "No",
|
|
71
71
|
"evolve_persona": "priya"
|
|
72
72
|
},
|
|
73
|
+
"motion.csv": {
|
|
74
|
+
"header": ["No", "Category", "Library", "Timing", "Easing", "Do", "Don't", "Code Example Good", "Code Example Bad", "Severity"],
|
|
75
|
+
"filter_column": "Category",
|
|
76
|
+
"no_column": "No",
|
|
77
|
+
"evolve_persona": "zara"
|
|
78
|
+
},
|
|
79
|
+
"ui-libraries.csv": {
|
|
80
|
+
"header": ["No", "Library", "Npm Names", "Job", "Best For Tags", "Do Not Use For", "Import Example", "Install", "Docs URL", "Persona", "Bundle Hint", "Reduced Motion", "Detection Folders"],
|
|
81
|
+
"filter_column": "Best For Tags",
|
|
82
|
+
"no_column": "No",
|
|
83
|
+
"evolve_persona": "arjun"
|
|
84
|
+
},
|
|
73
85
|
"stacks/angular.csv": {
|
|
74
86
|
"header": ["No", "Category", "Guideline", "Description", "Do", "Don't", "Code Good", "Code Bad", "Severity", "Docs URL"],
|
|
75
87
|
"filter_column": "Category",
|
|
@@ -59,3 +59,9 @@ No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
|
|
|
59
59
|
58,Customization,Create custom components,Build new components following shadcn patterns,Use cn() and cva for custom components,Different patterns for custom,const Custom = ({ className }) => <div className={cn("base" className)}>,const Custom = ({ style }) => <div style={style}>,Medium,
|
|
60
60
|
59,Patterns,Use asChild for composition,asChild prop for component composition,Slot pattern with asChild,Wrapper divs for composition,<Button asChild><Link href="/">,<Button><Link href="/"></Link></Button>,Medium,https://ui.shadcn.com/docs/components/button
|
|
61
61
|
60,Patterns,Combine with React Hook Form,Form + useForm for complete forms,RHF Controller with shadcn inputs,Custom form state management,<FormField control={form.control} name="email">,<Input value={email} onChange={(e) => setEmail(e.target.value)},High,https://ui.shadcn.com/docs/components/form
|
|
62
|
+
61,Command,Compose Command with CMDK,Shadcn Command is built on cmdk — use it for Cmd+K palettes,Command + CommandInput + CommandList from components/ui/command,Custom dropdown search,<Command><CommandInput/><CommandList/>,input plus absolute div list,High,https://ui.shadcn.com/docs/components/command
|
|
63
|
+
62,Table,Compose Table with TanStack Table,Use Shadcn Table markup with @tanstack/react-table for sort filter pagination,useReactTable plus Table TableHeader TableBody,Div grid pretending to be a data table,<Table><TableHeader/><TableBody/>,div.grid with 40 rows,High,https://ui.shadcn.com/docs/components/table
|
|
64
|
+
63,Table,Virtualize dense tables,Pair TanStack Virtual with Shadcn Table when row count is high,useVirtualizer on table body,Render thousands of TableRow nodes,<TableBody> virtualized rows,map 10000 rows to TableRow,Medium,https://tanstack.com/virtual
|
|
65
|
+
64,Form,Origin UI input patterns,Copy Origin UI input/select recipes into existing components/ui — do not start a second kit,Extend shadcn Input/Select,Install Origin as a parallel component tree,components/ui/input.tsx with Origin pattern,components/origin/input.tsx beside ui/,Medium,https://originui.com
|
|
66
|
+
65,Sheet,Compose Sheet with Vaul,Mobile drawers should use Vaul via Shadcn Sheet,Sheet for mobile filters/settings,Dialog for side drawers on small screens,<Sheet><SheetContent side="bottom">,<Dialog> slide animation on mobile,Medium,https://ui.shadcn.com/docs/components/sheet
|
|
67
|
+
66,Patterns,Prefer the installed kit,If Chakra Mantine HeroUI MUI or Ant Design is already in package.json use that kit not a new Shadcn tree,One primitive kit per app,Shadcn files plus Chakra Button on the same screen,Use existing kit Button,import { Button } from '@chakra-ui/react' and @/components/ui/button,High,https://ui.shadcn.com/docs
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
No,Library,Npm Names,Job,Best For Tags,Do Not Use For,Import Example,Install,Docs URL,Persona,Bundle Hint,Reduced Motion,Detection Folders
|
|
2
|
+
1,Motion,motion;framer-motion,motion,saas;b2b;dashboard;landing;onboarding;motion;animation,Bounce easing on daily dashboards,"import { motion; AnimatePresence } from 'motion/react'",npm i motion,https://motion.dev,zara,medium,Honor prefers-reduced-motion; opacity-only fallback,
|
|
3
|
+
2,Auto-Animate,@formkit/auto-animate,motion,saas;b2b;dashboard;table;list;motion,Decorative page-level motion,"import { useAutoAnimate } from '@formkit/auto-animate/react'",npm i @formkit/auto-animate,https://auto-animate.formkit.com,anuj,small (~2kB),Disable when reduced-motion,
|
|
4
|
+
3,Lenis,lenis;@studio-freight/lenis,scroll,landing;marketing;storytelling;scroll,App chrome; dashboards; data tables,"import Lenis from 'lenis'",npm i lenis,https://github.com/darkroomengineering/lenis,noor,small,Disable smooth scroll when reduced-motion,
|
|
5
|
+
4,canvas-confetti,canvas-confetti,celebration,onboarding;landing;celebration;first-run,Every save; daily working surfaces,"import confetti from 'canvas-confetti'",npm i canvas-confetti,https://github.com/catdad/canvas-confetti,zara,small,Skip entirely when reduced-motion,
|
|
6
|
+
5,Lottie,lottie-react;lottie-web,motion,onboarding;empty-state;illustration;landing,Daily dashboards; looping chrome,"import Lottie from 'lottie-react'",npm i lottie-react,https://airbnb.io/lottie,zara,medium-heavy,Static frame when reduced-motion,
|
|
7
|
+
6,Rive,@rive-app/react-canvas;@rive-app/react-webgl,motion,onboarding;marketing;illustration,Product tables; settings,"import { useRive } from '@rive-app/react-canvas'",npm i @rive-app/react-canvas,https://rive.app,zara,heavy,Pause/stop when reduced-motion,
|
|
8
|
+
7,Shadcn UI,shadcn;class-variance-authority,primitives,saas;b2b;dashboard;forms;tailwind;shadcn,Second full kit beside Chakra/Mantine/MUI,"import { Button } from '@/components/ui/button'",npx shadcn@latest init,https://ui.shadcn.com,arjun,copy-paste (no runtime kit),n/a,components/ui
|
|
9
|
+
8,Radix UI,@radix-ui/react-dialog;@radix-ui/react-dropdown-menu;@radix-ui/*,primitives,saas;b2b;a11y;shadcn;radix,Custom div role=button overlays,"import * as Dialog from '@radix-ui/react-dialog'",npm i @radix-ui/react-dialog,https://www.radix-ui.com,arjun,tree-shake per primitive,Focus trap built in,
|
|
10
|
+
9,Base UI,@base-ui/react,primitives,saas;b2b;a11y;headless;forms,Mixing with Radix on the same control,"import { Dialog } from '@base-ui/react/dialog'",npm i @base-ui/react,https://base-ui.com,noor,medium,Built-in keyboard,components/ui
|
|
11
|
+
10,Headless UI,@headlessui/react,primitives,saas;tailwind;a11y;forms,Second dialog stack beside Radix,"import { Dialog } from '@headlessui/react'",npm i @headlessui/react,https://headlessui.com,noor,medium,Focus management built in,
|
|
12
|
+
11,React Aria,react-aria-components;react-aria,a11y,saas;b2b;a11y;government;healthcare,Ignoring the kit's labels and focus,"import { Button; Dialog } from 'react-aria-components'",npm i react-aria-components,https://react-spectrum.adobe.com/react-aria,arjun,medium,Full keyboard and ARIA,
|
|
13
|
+
12,Chakra UI,@chakra-ui/react;@chakra-ui/*,full-kit,saas;b2b;dashboard;chakra,Adding Shadcn/Mantine on the same screen,"import { Button } from '@chakra-ui/react'",npm i @chakra-ui/react,https://chakra-ui.com,priya,heavy kit,Respect Chakra motion tokens,
|
|
14
|
+
13,Mantine,@mantine/core;@mantine/hooks;@mantine/*,full-kit,saas;b2b;dashboard;mantine,Mixing with Chakra or Shadcn primitives,"import { Button } from '@mantine/core'",npm i @mantine/core,https://mantine.dev,priya,heavy kit,Use Mantine reduced-motion hook,
|
|
15
|
+
14,HeroUI,@heroui/react;@nextui-org/react,full-kit,saas;landing;heroui;nextui,Second full kit,"import { Button } from '@heroui/react'",npm i @heroui/react,https://www.heroui.com,priya,heavy kit,Use kit motion props,
|
|
16
|
+
15,Ark UI / Park UI,@ark-ui/react,full-kit,saas;headless;ark,Copying Shadcn files into an Ark app,"import { Dialog } from '@ark-ui/react/dialog'",npm i @ark-ui/react,https://ark-ui.com,priya,medium,Headless a11y,
|
|
17
|
+
16,MUI,@mui/material;@mui/*,full-kit,enterprise;dashboard;mui,Greenfield Tailwind apps; mixing with Shadcn,"import Button from '@mui/material/Button'",detect only,https://mui.com,priya,heavy kit,Respect if installed; do not prescribe,
|
|
18
|
+
17,Ant Design,antd,full-kit,enterprise;dashboard;antd,Greenfield Tailwind apps; mixing kits,"import { Button } from 'antd'",detect only,https://ant.design,priya,heavy kit,Respect if installed; do not prescribe,
|
|
19
|
+
18,Floating UI,@floating-ui/react;@floating-ui/dom,a11y,saas;b2b;tooltip;popover;dropdown,Custom position:absolute tooltips,"import { useFloating } from '@floating-ui/react'",npm i @floating-ui/react,https://floating-ui.com,arjun,small,n/a,
|
|
20
|
+
19,Vaul,vaul,primitives,mobile;sheet;drawer;shadcn,Desktop-only modal that should be Dialog,"import { Drawer } from 'vaul'",npm i vaul,https://vaul.emilkowal.ski,noor,small,Sheet animation honors reduced-motion,
|
|
21
|
+
20,Sonner,sonner,feedback,saas;b2b;forms;toast;feedback,Custom toast stacks or alert() ,"import { toast } from 'sonner'",npm i sonner,https://sonner.emilkowal.ski,zara,small,No motion required,
|
|
22
|
+
21,React Hook Form,react-hook-form,forms,saas;b2b;forms;settings,useState per field on large forms,"import { useForm } from 'react-hook-form'",npm i react-hook-form,https://react-hook-form.com,anuj,small,n/a,
|
|
23
|
+
22,Zod,zod,forms,saas;b2b;forms;validation,Ad-hoc string checks with no schema,"import { z } from 'zod'",npm i zod,https://zod.dev,priya,small,n/a,
|
|
24
|
+
23,CMDK,cmdk,command,saas;b2b;dashboard;power-user;command,Hiding all navigation behind Cmd+K only,"import { Command } from 'cmdk'",npm i cmdk,https://cmdk.paco.me,anuj,small,n/a,
|
|
25
|
+
24,TanStack Table,@tanstack/react-table,table,saas;b2b;dashboard;table;density,Div-grid fake tables for >20 rows,"import { useReactTable } from '@tanstack/react-table'",npm i @tanstack/react-table,https://tanstack.com/table,anuj,medium,n/a,
|
|
26
|
+
25,TanStack Virtual,@tanstack/react-virtual,table,dashboard;table;density;performance,Rendering 10k DOM rows,"import { useVirtualizer } from '@tanstack/react-virtual'",npm i @tanstack/react-virtual,https://tanstack.com/virtual,priya,small,n/a,
|
|
27
|
+
26,Embla Carousel,embla-carousel-react,scroll,landing;marketing;carousel;mobile,Autoplay carousels on dashboards,"import useEmblaCarousel from 'embla-carousel-react'",npm i embla-carousel-react,https://www.embla-carousel.com,noor,small,Disable autoplay when reduced-motion,
|
|
28
|
+
27,nuqs,nuqs,url-state,saas;b2b;dashboard;filters;share,Local-only filter state that must be shareable,"import { useQueryState } from 'nuqs'",npm i nuqs,https://nuqs.47ng.com,anuj,small,n/a,
|
|
29
|
+
28,react-hotkeys-hook,react-hotkeys-hook;tinykeys,hotkeys,saas;b2b;dashboard;power-user;keyboard,Global shortcuts that steal browser find,"import { useHotkeys } from 'react-hotkeys-hook'",npm i react-hotkeys-hook,https://react-hotkeys-hook.vercel.app,anuj,small,n/a,
|
|
30
|
+
29,Driver.js,driver.js,onboarding,onboarding;first-run;tour,Daily dashboards; unskippable overlays,"import { driver } from 'driver.js'",npm i driver.js,https://driverjs.com,noor,small,Skip motion; require Skip,
|
|
31
|
+
30,Shepherd.js,shepherd.js,onboarding,onboarding;first-run;tour,Forced linear tours on expert surfaces,"import Shepherd from 'shepherd.js'",npm i shepherd.js,https://shepherdjs.dev,noor,medium,Skip and Back required,
|
|
32
|
+
31,React Flow,@xyflow/react;reactflow,canvas,canvas;workflow;graph;diagram,CRUD tables or settings pages,"import { ReactFlow } from '@xyflow/react'",npm i @xyflow/react,https://reactflow.dev,priya,heavy,Only if the product is a graph,
|
|
33
|
+
32,Tailwind CSS,tailwindcss,tokens,saas;b2b;landing;tailwind;tokens,Inline style={{}} design system,"import 'tailwindcss'",npm i tailwindcss,https://tailwindcss.com,arjun,build-time,n/a,
|
|
34
|
+
33,CVA + tailwind-merge,class-variance-authority;tailwind-merge;clsx,tokens,saas;shadcn;tailwind;tokens,Duplicating variant class strings,"import { cva } from 'class-variance-authority'; import { twMerge } from 'tailwind-merge'",npm i class-variance-authority tailwind-merge clsx,https://cva.style,arjun,tiny,n/a,
|
|
35
|
+
34,tailwindcss-animate,tailwindcss-animate;tw-animate-css,motion,saas;shadcn;tailwind;motion,Bounce utilities on product chrome,"import 'tailwindcss-animate'",npm i tailwindcss-animate,https://github.com/jamiebuilds/tailwindcss-animate,zara,tiny CSS,Pair with reduced-motion variants,
|
|
36
|
+
35,Fontsource,@fontsource/*;@fontsource-variable/*,typography,saas;typography;fonts,Loading every weight of a family,"import '@fontsource-variable/geist'",npm i @fontsource-variable/geist,https://fontsource.org,arjun,per-font,n/a,
|
|
37
|
+
36,Lucide,lucide-react,icons,saas;b2b;dashboard;icons,Mixing with Phosphor or Heroicons on one screen,"import { Search } from 'lucide-react'",npm i lucide-react,https://lucide.dev,arjun,tree-shake icons,n/a,
|
|
38
|
+
37,Phosphor,@phosphor-icons/react,icons,saas;b2b;icons,Mixing icon families,"import { MagnifyingGlass } from '@phosphor-icons/react'",npm i @phosphor-icons/react,https://phosphoricons.com,arjun,tree-shake icons,n/a,
|
|
39
|
+
38,Tremor,@tremor/react,charts,dashboard;analytics;kpi;charts,Marketing landings with no data,"import { AreaChart } from '@tremor/react'",npm i @tremor/react,https://tremor.so,arjun,medium,Charts still need text fallback,
|
|
40
|
+
39,Recharts,recharts,charts,dashboard;analytics;charts,Custom SVG charts with no a11y,"import { LineChart; Line } from 'recharts'",npm i recharts,https://recharts.org,arjun,medium,Provide table or aria fallback,
|
|
41
|
+
40,Number Flow,@number-flow/react,celebration,dashboard;kpi;onboarding;charts,Animating every table cell,"import NumberFlow from '@number-flow/react'",npm i @number-flow/react,https://number-flow.barvian.me,zara,small,Snap to final value when reduced-motion,
|
|
42
|
+
41,Origin UI,origin-ui,forms,saas;forms;shadcn;inputs,Using as a second full kit,"Copy input/select patterns from Origin into components/ui",copy-paste,https://originui.com,noor,copy-paste,n/a,components/ui
|
|
43
|
+
42,Magic UI,magicui-cli;@magicui/*,marketing-fx,landing;onboarding;marketing,Daily dashboards; settings; tables,Copy Magic UI component into components/magicui,copy-paste,https://magicui.design,zara,varies,Must respect reduced-motion,components/magicui
|
|
44
|
+
43,Aceternity UI,aceternity,marketing-fx,landing;onboarding;marketing,Product app chrome,Copy effect into components/aceternity,copy-paste,https://ui.aceternity.com,zara,varies,Must respect reduced-motion,components/aceternity
|
|
45
|
+
44,21st.dev / React Bits,21stdev;@21st-dev/react;react-bits,marketing-fx,landing;marketing;onboarding,Working dashboards,Copy block from 21st.dev,copy-paste,https://21st.dev,zara,varies,Landing only,
|
|
46
|
+
45,Spline,@splinetool/react-spline,marketing-fx,landing;marketing;3d,Dashboards; forms; low-end mobile,"import Spline from '@splinetool/react-spline'",npm i @splinetool/react-spline,https://spline.design,priya,very heavy,Static image fallback,
|
|
@@ -97,4 +97,15 @@ No,Category,Issue,Platform,Description,Do,Don't,Code Example Good,Code Example B
|
|
|
97
97
|
96,Sustainability,Auto-Play Video,Web,Video consumes massive data and energy,Click-to-play or pause when off-screen,Auto-play high-res video loops,playsInline muted preload='none',autoplay loop,Medium
|
|
98
98
|
97,Sustainability,Asset Weight,Web,Heavy 3D/Image assets increase carbon footprint,Compress and lazy load 3D models,Load 50MB textures,Draco compression,Raw .obj files,Medium
|
|
99
99
|
98,AI Interaction,Feedback Loop,All,AI needs user feedback to improve,Thumps up/down or 'Regenerate',Static output only,Feedback component,Read-only text,Low
|
|
100
|
-
99,Accessibility,Motion Sensitivity,All,Parallax/Scroll-jacking causes nausea,Respect prefers-reduced-motion,Force scroll effects,@media (prefers-reduced-motion),ScrollTrigger.create(),High
|
|
100
|
+
99,Accessibility,Motion Sensitivity,All,Parallax/Scroll-jacking causes nausea,Respect prefers-reduced-motion,Force scroll effects,@media (prefers-reduced-motion),ScrollTrigger.create(),High
|
|
101
|
+
100,Layout,Container Nesting,All,Wrapping every section in nested cards causes visual noise and box syndrome,Use whitespace and subtle dividers instead of nested card borders,Wrap cards inside cards with redundant borders,space-y-6 with border-b,div.card > div.card > div.card,High
|
|
102
|
+
101,Color,Untinted Neutrals,All,Pure un-tinted black or stark gray feels harsh and unfinished,Use subtly tinted neutrals matching brand palette,Use pure #000000 black or harsh #888888 gray,bg-slate-900 text-slate-100,bg-[#000000] text-[#888888],Medium
|
|
103
|
+
102,Accessibility,Gray on Color,All,Placing light or medium gray text on colored backgrounds destroys contrast,Use high-contrast white or dark tinted text on colored surfaces,Place muted gray text on colored badge or hero backgrounds,text-white on bg-blue-600,text-gray-400 on bg-blue-600,High
|
|
104
|
+
103,Color,AI Gradient Clichés,All,Ubiquitous purple-to-blue or pink gradients create a generic AI-slop look,Use intentional brand accents or solid functional color cues,Cover every headline and card with purple-to-blue gradient,bg-indigo-600 or subtle tint,bg-gradient-to-r from-purple-500 to-indigo-600,High
|
|
105
|
+
104,Typography,Heading Icon Tiles,All,Placing a rounded-square icon tile above every section heading adds visual clutter,Use clear typographic scale and semantic headers without icon crutches,Stick a rounded bordered icon box above every header,h2.text-2xl.font-bold,div.rounded-lg.p-2.border > Icon + h2,Medium
|
|
106
|
+
105,Animation,Bounce Easing,All,Bouncy or elastic spring overshoot in standard UI feels dated and gimmicky,Use crisp ease-out (150-250ms) for enter and ease-in (100-200ms) for exit,Use bounce or elastic easing on menus modals or dropdowns,transition-all duration-200 ease-out,animate-bounce or transition-all duration-500 ease-in-out,High
|
|
107
|
+
106,Typography,Line Length,All,Text lines spanning over 75 characters cause reading fatigue,Constrain reading width to 45-75 characters,Let paragraphs stretch across full viewport width,max-w-prose or max-w-2xl,w-full on 1920px screen,Medium
|
|
108
|
+
107,Visual Hierarchy,Bolder Contrast,All,Timid flat designs lack an obvious focal point and feel monotonous,Create one clear visual center of gravity via scale contrast and placement,Make all elements equal size and contrast with no clear hero,text-4xl font-extrabold with prominent CTA,All headings same size as body,High
|
|
109
|
+
108,Visual Hierarchy,Quieter Restraint,All,Over-decorated screens with excessive badges borders and glows cause cognitive overload,Strip away decorative borders and let core content breathe,Add borders shadows badges and glows to every single widget,Clean borderless layout with subtle separators,border-2 shadow-lg ring-2 on every box,Medium
|
|
110
|
+
109,Touch,Touch Target Size,Mobile,Clickable controls under 44px fail accessibility and cause tap errors,Ensure all buttons triggers and inputs have minimum 44x44px hit areas,Use tiny 24px icon buttons without tap padding,min-h-[44px] min-w-[44px],w-6 h-6,High
|
|
111
|
+
110,Interaction,Form State Hardening,All,Inputs missing hover focus error disabled or loading states cause drop-off,Provide all 5 interactive states for every form control,Leave inputs with default browser outlines and no error state,focus-visible:ring-2 invalid:border-red-500,input without focus or error classes,High
|
|
@@ -76,7 +76,7 @@ npx analyzthis_design spec validate --file ./design-spec.json
|
|
|
76
76
|
|
|
77
77
|
**Hierarchy gate:** rank #1 in `information_hierarchy` matches the visually dominant region/component (`hierarchy_rank: 1`).
|
|
78
78
|
|
|
79
|
-
**Arjun visual pass:** typography scale, spacing rhythm, and contrast classes are consistent with Visual Design Audit rubric — run scoped review on the spec only (no full page code required).
|
|
79
|
+
**Arjun visual pass:** typography scale, spacing rhythm, and contrast classes are consistent with Visual Design Audit rubric — run scoped review on the spec only (no full page code required). Verify anti-slop rules: no nested cards (`div.card > div.card`), no untinted pure black/gray, no gray text on colored backgrounds, and motion timing locked to 150–250ms ease-out (`[ux-guidelines.csv, row 100-105]`, `[motion.csv, row 1]`). If `motion.enabled`, require `library`, `import_path`, `timing_ms`, `easing`, `reduced_motion`. Marketing FX libraries only when notes say landing/onboarding. `components[].import_path` must match `installed_ui_libraries` or a cited `ui-libraries.csv` row.
|
|
80
80
|
|
|
81
81
|
Set `spec_verdict` when done:
|
|
82
82
|
|
|
@@ -33,7 +33,7 @@ This runs **Kavi** — scans your repo, builds an Obsidian vault, and syncs a **
|
|
|
33
33
|
| Review against PRDs and user stories | `/ux-story-gate` | Task map + routing before critique |
|
|
34
34
|
| Index my codebase for personas | `/kavi` | Kavi → knowledge bank |
|
|
35
35
|
| Run CLI orchestrator without API keys | `/devi` | Host LLM — voices personas from pending prompts |
|
|
36
|
-
| Set visual direction with references + team debate | `/mood-board` |
|
|
36
|
+
| Set visual direction with references + team debate | `/mood-board` | Mood board: tagged URLs. **UI image board:** Zara scouts 3–5 real screens; Arjun/Noor/Priya/Meera jury; she re-scouts if they skip |
|
|
37
37
|
| Inspect the chunked execution planner | `/chunk-planner` | See how tasks are split into model-routed chunks |
|
|
38
38
|
| Run legacy single-pass orchestrator | `/run-unchunked` | Skip planner overhead for quick single-expert tasks |
|
|
39
39
|
| Keep or skip the last persona note | `/accept` | Yes or no (plus one sentence if no). Local evolution — no CLI flags. |
|
|
@@ -115,7 +115,7 @@ Assess only — do not implement changes.
|
|
|
115
115
|
| `/anuj` | Power-user wireframe |
|
|
116
116
|
| `/design-director` | Full producer — ideation → DesignSpec → build |
|
|
117
117
|
| `/design-spec` | DesignSpec format + validation rules |
|
|
118
|
-
| `/mood-board` | Visual direction
|
|
118
|
+
| `/mood-board` | Visual direction — mood board (tagged URLs) or UI image board (Zara scouts real screens, jury votes) |
|
|
119
119
|
| `/chunk-planner` | Chunked execution planner explained |
|
|
120
120
|
| `/run-unchunked` | Legacy single-pass orchestrator (skip chunked planner) |
|
|
121
121
|
| `/persona-orchestrator` | Agentic critique (not wireframes) |
|
|
@@ -93,6 +93,7 @@ Vault: [path]
|
|
|
93
93
|
Notes: [N written / S skipped]
|
|
94
94
|
Enriched: [E]
|
|
95
95
|
Sources discovered: [count]
|
|
96
|
+
UI libraries: [N installed]
|
|
96
97
|
Knowledge bank: [synced count] → [targets]
|
|
97
98
|
Next: /persona-orchestrator or /ux-story-gate — personas read this bank first.
|
|
98
99
|
```
|
|
@@ -105,11 +106,11 @@ Next: /persona-orchestrator or /ux-story-gate — personas read this bank first.
|
|
|
105
106
|
|
|
106
107
|
| Vault folder | Sources |
|
|
107
108
|
|---|---|
|
|
108
|
-
| `PRDs/` | README, docs, PRD/requirements markdown |
|
|
109
|
+
| `PRDs/` | README, docs, PRD/requirements markdown — extracts **Durable Product Truth**: Target Audience, Core Purpose, Hard Constraints, Operating Context, Brand Voice, and User Evidence |
|
|
109
110
|
| `Brand/` | Tailwind config, tokens, theme CSS |
|
|
110
111
|
| `Pages/` | App Router / page files |
|
|
111
112
|
| `Components/` | `components/`, UI TSX/JSX |
|
|
112
|
-
| `Tech/` | `package.json`, configs, API routes |
|
|
113
|
+
| `Tech/` | `package.json`, configs, API routes, plus **Installed-UI-Libraries.md** (detected motion/UX/visual kits) |
|
|
113
114
|
| `Sources/` | Discovered vaults, wikis, knowledge graphs |
|
|
114
115
|
| `Web/` | External URLs from config + PRD/README |
|
|
115
116
|
| `_meta/` | Index, knowledge-sources, last-sync |
|
|
@@ -120,6 +121,6 @@ Enrichment needs `OPENAI_API_KEY`, `GEMINI_API_KEY`, `ANTHROPIC_API_KEY`, or `ZA
|
|
|
120
121
|
|
|
121
122
|
## Session state
|
|
122
123
|
|
|
123
|
-
After collect, `session-state.json` includes `vault_path` and `
|
|
124
|
+
After collect, `session-state.json` includes `vault_path`, `last_collect_at`, and `installed_ui_libraries` (catalog matches from `package.json` + `components/ui` folders). Other personas must prefer installed libraries from `Tech/Installed-UI-Libraries.md` before recommending new packages.
|
|
124
125
|
|
|
125
126
|
Install skills: `npx analyzthis_design --target all --force`
|
|
@@ -7,6 +7,15 @@ description: Build a visual/textual mood board from web references + design-syst
|
|
|
7
7
|
|
|
8
8
|
Use `/mood-board` when you want to explore visual directions for a screen, flow, or product and have the persona team deliberate on which references fit the user, task, and design system.
|
|
9
9
|
|
|
10
|
+
There are two boards:
|
|
11
|
+
|
|
12
|
+
| Kind | What it is | Who hunts |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| **mood** (default) | Tagged URLs and notes. You paste links. | You, plus optional search stubs |
|
|
15
|
+
| **ui** | A **UI image board** — 3–5 real shipped screens as frames | **Zara scouts.** Arjun / Noor / Priya / Meera jury. She goes back out if they skip. |
|
|
16
|
+
|
|
17
|
+
Do not confuse this with generating fake marketing comps. Frames must be real product UI the host can open.
|
|
18
|
+
|
|
10
19
|
## What it does
|
|
11
20
|
|
|
12
21
|
1. **Collects references** from URLs you provide, configured `moodboard.urls`, and optional web search stubs.
|
|
@@ -35,6 +44,10 @@ npx analyzthis_design moodboard add --board <boardId> \
|
|
|
35
44
|
--note "I like the white space and the trust badge placement"
|
|
36
45
|
|
|
37
46
|
npx analyzthis_design moodboard list
|
|
47
|
+
|
|
48
|
+
npx analyzthis_design moodboard create --task "Invoice approval, partner signs, dense" --kind ui
|
|
49
|
+
npx analyzthis_design moodboard frames --board <boardId> --url https://example.com/shot.png --title "Dense invoice table" --steal "one primary action" --refuse "purple glow" --peak "signed stamp"
|
|
50
|
+
npx analyzthis_design moodboard critique --board <boardId>
|
|
38
51
|
```
|
|
39
52
|
|
|
40
53
|
## v2.0 chunked execution
|
|
@@ -44,6 +57,18 @@ npx analyzthis_design moodboard list
|
|
|
44
57
|
- Cheap/free models tag references, retrieve design-system rows, and run the deliberation loop.
|
|
45
58
|
- Result is the same `board.json` artifact, but at lower average token cost.
|
|
46
59
|
|
|
60
|
+
## UI image board — Zara scout, then jury
|
|
61
|
+
|
|
62
|
+
When `--kind ui` (or the user says "UI board" / "image board"):
|
|
63
|
+
|
|
64
|
+
1. **Create** writes `scout.brief` and `scout.status = awaiting_scout`. Zara hunts **Google Images, Dribbble, or Pinterest** (or live product pages). She must actually search and open pages — no invented URLs, no AI comps.
|
|
65
|
+
2. **Frames** — Zara saves 3–5 picks. Each frame: url, title, steal, refuse, peak. Round number is stored.
|
|
66
|
+
3. **Jury** — `critique` runs Arjun, Meera, Priya, Noor (Zara does not vote on her own set). KEEP / SKIP per frame. Honeycomb still applies.
|
|
67
|
+
4. **Iterate** — verdict SHIP → `scout.status = done`. REVISE or BLOCK → `scout.round++`, new brief from their because-lines, `awaiting_scout` again. Max 3 scout rounds, then Raj / the designer picks.
|
|
68
|
+
5. **You still sign** — `/accept yes` or no plus one sentence on the kept direction.
|
|
69
|
+
|
|
70
|
+
Zara's scout rules live in `skills/zara/SKILL.md` (Scout Pass). Motion stays 150–250ms ease-out. Cinematic GSAP landings are refused for daily product UI.
|
|
71
|
+
|
|
47
72
|
## How the personas use it
|
|
48
73
|
|
|
49
74
|
| Persona | Lens |
|
|
@@ -51,7 +76,7 @@ npx analyzthis_design moodboard list
|
|
|
51
76
|
| **Arjun** | Visual system fit, contrast, hierarchy, accessibility, WCAG |
|
|
52
77
|
| **Meera** | Brand/category fit, GTM risk, competitive positioning |
|
|
53
78
|
| **Priya** | Technical feasibility of implementing the style/pattern |
|
|
54
|
-
| **Zara** |
|
|
79
|
+
| **Zara** | **Scout lens = Peak-End** (first 2 seconds): same job, peak feeling, one steal, one refuse. Google Images / Dribbble / Pinterest. She does not jury her own picks. |
|
|
55
80
|
| **Noor** | IA clarity, progressive disclosure, surface structure |
|
|
56
81
|
|
|
57
82
|
Each persona scores references with the Honeycomb rigor matrix:
|
|
@@ -108,6 +133,7 @@ In `~/.analyzthis_design/config.json`:
|
|
|
108
133
|
|
|
109
134
|
## Notes
|
|
110
135
|
|
|
111
|
-
- Image URLs are stored as references; alt-text/captions are added during tagging.
|
|
136
|
+
- Image URLs are stored as references; alt-text/captions are added during tagging. Direct image URLs on a **ui** board are copied into the board folder when fetch succeeds.
|
|
112
137
|
- Web articles are fetched as plain text; image extraction from HTML is not yet implemented.
|
|
113
|
-
-
|
|
138
|
+
- `--auto` on a mood board still creates search stubs for the host to fill. `--kind ui` does not — Zara must bring real URLs.
|
|
139
|
+
- Router rule: `mood_board` signals route to the `mood-board` skill, not the critique chain. "UI board" / "image board" are the same route.
|