get-shit-pretty 0.5.0 → 0.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.
Files changed (68) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +1 -1
  3. package/bin/install.js +38 -19
  4. package/gsp/agents/gsp-accessibility-auditor.md +1 -4
  5. package/gsp/agents/gsp-ascii-artist.md +1 -1
  6. package/gsp/agents/gsp-brand-auditor.md +0 -2
  7. package/gsp/agents/gsp-brand-strategist.md +0 -2
  8. package/gsp/agents/gsp-brand-syncer.md +125 -0
  9. package/gsp/agents/gsp-builder.md +11 -14
  10. package/gsp/agents/gsp-campaign-director.md +0 -20
  11. package/gsp/agents/gsp-critic.md +15 -18
  12. package/gsp/agents/gsp-designer.md +6 -6
  13. package/gsp/agents/gsp-identity-designer.md +0 -4
  14. package/gsp/agents/{gsp-system-architect.md → gsp-pattern-architect.md} +5 -67
  15. package/gsp/agents/gsp-project-researcher.md +0 -21
  16. package/gsp/agents/gsp-researcher.md +0 -2
  17. package/gsp/agents/gsp-reviewer.md +4 -14
  18. package/gsp/agents/gsp-scoper.md +1 -22
  19. package/gsp/hooks/hooks.json +11 -0
  20. package/gsp/prompts/01-design-system-architect.md +0 -46
  21. package/gsp/prompts/02-brand-identity-creator.md +1 -14
  22. package/gsp/prompts/03-ui-ux-pattern-master.md +1 -21
  23. package/gsp/prompts/04-marketing-asset-factory.md +1 -14
  24. package/gsp/prompts/05-implementation-spec-expert.md +0 -27
  25. package/gsp/prompts/06-design-critique-partner.md +1 -17
  26. package/gsp/prompts/07-design-trend-synthesizer.md +2 -29
  27. package/gsp/prompts/08-accessibility-auditor.md +4 -19
  28. package/gsp/prompts/09-design-to-code-translator.md +21 -20
  29. package/gsp/prompts/10-project-scoper.md +2 -36
  30. package/gsp/prompts/11-deliverable-reviewer.md +1 -50
  31. package/gsp/prompts/12-project-researcher.md +0 -39
  32. package/gsp/references/anti-patterns.md +173 -0
  33. package/gsp/references/block-patterns.md +135 -0
  34. package/gsp/references/chunk-format.md +31 -0
  35. package/gsp/references/phase-transitions.md +78 -33
  36. package/gsp/references/style-preset-schema.md +63 -0
  37. package/gsp/references/visual-effects.md +475 -0
  38. package/gsp/references/visual-taste.md +120 -0
  39. package/gsp/skills/gsp-accessibility/SKILL.md +1 -1
  40. package/gsp/skills/gsp-brand-audit/SKILL.md +1 -3
  41. package/gsp/skills/gsp-brand-identity/SKILL.md +1 -4
  42. package/gsp/skills/gsp-brand-patterns/SKILL.md +30 -50
  43. package/gsp/skills/gsp-brand-research/SKILL.md +7 -4
  44. package/gsp/skills/gsp-brand-strategy/SKILL.md +1 -4
  45. package/gsp/skills/gsp-brand-sync/SKILL.md +101 -0
  46. package/gsp/skills/gsp-design-system/SKILL.md +1 -1
  47. package/gsp/skills/gsp-doctor/SKILL.md +7 -7
  48. package/gsp/skills/gsp-help/SKILL.md +2 -1
  49. package/gsp/skills/gsp-launch/SKILL.md +2 -3
  50. package/gsp/skills/gsp-project-brief/SKILL.md +7 -22
  51. package/gsp/skills/gsp-project-build/SKILL.md +108 -26
  52. package/gsp/skills/gsp-project-critique/SKILL.md +5 -33
  53. package/gsp/skills/gsp-project-design/SKILL.md +25 -26
  54. package/gsp/skills/gsp-project-research/SKILL.md +8 -17
  55. package/gsp/skills/gsp-project-review/SKILL.md +6 -37
  56. package/gsp/skills/gsp-start/SKILL.md +29 -12
  57. package/gsp/skills/gsp-style/SKILL.md +20 -223
  58. package/gsp/skills/gsp-typescale/SKILL.md +23 -319
  59. package/gsp/skills/gsp-update/SKILL.md +18 -10
  60. package/gsp/templates/branding/brief.md +13 -1
  61. package/gsp/templates/branding/roadmap.md +2 -2
  62. package/gsp/templates/branding/state.md +1 -1
  63. package/gsp/templates/phases/brief.md +1 -1
  64. package/gsp/templates/phases/{system.md → patterns.md} +3 -3
  65. package/gsp/templates/phases/review.md +1 -1
  66. package/package.json +1 -1
  67. package/scripts/gsp-context-recovery.sh +71 -0
  68. package/scripts/gsp-statusline.js +5 -1
@@ -0,0 +1,475 @@
1
+ # Visual Effects Reference — CSS Recipes
2
+
3
+ Production-ready CSS and Tailwind snippets for visual polish. Adapt values to the brand's tokens.
4
+
5
+ ---
6
+
7
+ ## Depth & Shadows
8
+
9
+ ### Layered shadows
10
+
11
+ ```css
12
+ /* Subtle — cards, inputs */
13
+ shadow-sm: 0 1px 2px rgba(0,0,0,0.04), 0 1px 4px rgba(0,0,0,0.06);
14
+
15
+ /* Medium — elevated cards, dropdowns */
16
+ shadow-md: 0 4px 6px rgba(0,0,0,0.04), 0 10px 24px rgba(0,0,0,0.08);
17
+
18
+ /* Dramatic — modals, floating elements */
19
+ shadow-lg: 0 8px 16px rgba(0,0,0,0.08), 0 24px 48px rgba(0,0,0,0.12);
20
+ ```
21
+
22
+ ### Glow effects
23
+
24
+ ```css
25
+ /* Primary color glow — CTAs, active states */
26
+ box-shadow: 0 0 20px rgba(var(--color-primary-rgb), 0.3), 0 0 40px rgba(var(--color-primary-rgb), 0.1);
27
+
28
+ /* Ambient glow — hero accents */
29
+ box-shadow: 0 0 80px 40px rgba(var(--color-accent-rgb), 0.15);
30
+ ```
31
+
32
+ ### Glassmorphism
33
+
34
+ ```css
35
+ backdrop-filter: blur(16px) saturate(180%);
36
+ background: rgba(255, 255, 255, 0.08);
37
+ border: 1px solid rgba(255, 255, 255, 0.12);
38
+ /* Tailwind: backdrop-blur-xl backdrop-saturate-[180%] bg-white/[0.08] border border-white/[0.12] */
39
+ ```
40
+
41
+ `@supports not (backdrop-filter: blur(1px))` — use solid bg with 90% opacity as fallback.
42
+
43
+ ---
44
+
45
+ ## Backgrounds & Texture
46
+
47
+ ### Gradient backgrounds
48
+
49
+ ```css
50
+ /* Linear sweep — hero backgrounds */
51
+ background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-secondary) 100%);
52
+
53
+ /* Radial orb — decorative accent behind content */
54
+ background: radial-gradient(circle at 30% 20%, rgba(var(--color-accent-rgb), 0.25) 0%, transparent 60%);
55
+
56
+ /* Mesh gradient — layer 2-3 radial gradients */
57
+ background:
58
+ radial-gradient(at 20% 80%, rgba(var(--color-primary-rgb), 0.2) 0%, transparent 50%),
59
+ radial-gradient(at 80% 20%, rgba(var(--color-accent-rgb), 0.15) 0%, transparent 50%),
60
+ radial-gradient(at 50% 50%, rgba(var(--color-secondary-rgb), 0.1) 0%, transparent 60%);
61
+ ```
62
+
63
+ ### Noise/grain texture
64
+
65
+ ```css
66
+ /* SVG noise overlay — tactile surfaces */
67
+ background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='0.03'/%3E%3C/svg%3E");
68
+ ```
69
+
70
+ ### Grid/dot overlay
71
+
72
+ ```css
73
+ /* Dot grid — tech/modern aesthetic, 3% opacity */
74
+ background-image: radial-gradient(circle, rgba(0,0,0,0.03) 1px, transparent 1px);
75
+ background-size: 24px 24px;
76
+ ```
77
+
78
+ ---
79
+
80
+ ## Motion & Animation
81
+
82
+ ### Entrance animations
83
+
84
+ ```css
85
+ /* Fade up — default content entrance */
86
+ @keyframes fade-up {
87
+ from { opacity: 0; transform: translateY(12px); }
88
+ to { opacity: 1; transform: translateY(0); }
89
+ }
90
+ .animate-fade-up { animation: fade-up 0.5s ease-out forwards; }
91
+
92
+ /* Stagger children — add delay per child */
93
+ .stagger > :nth-child(1) { animation-delay: 0ms; }
94
+ .stagger > :nth-child(2) { animation-delay: 80ms; }
95
+ .stagger > :nth-child(3) { animation-delay: 160ms; }
96
+ /* ... increment by 80ms */
97
+ ```
98
+
99
+ ### Hover transitions
100
+
101
+ ```css
102
+ /* Lift + shadow shift — cards */
103
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
104
+ &:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
105
+
106
+ /* Scale + brighten — buttons */
107
+ transition: transform 0.15s ease, filter 0.15s ease;
108
+ &:hover { transform: scale(1.02); filter: brightness(1.1); }
109
+
110
+ /* Border glow — inputs, cards */
111
+ transition: box-shadow 0.2s ease;
112
+ &:hover { box-shadow: 0 0 0 2px rgba(var(--color-primary-rgb), 0.2); }
113
+ ```
114
+
115
+ ### Scroll-triggered reveals
116
+
117
+ ```js
118
+ // Intersection Observer — add .visible class on scroll
119
+ const observer = new IntersectionObserver(
120
+ (entries) => entries.forEach(e => e.isIntersecting && e.target.classList.add('visible')),
121
+ { threshold: 0.1 }
122
+ );
123
+ document.querySelectorAll('[data-animate]').forEach(el => observer.observe(el));
124
+ ```
125
+
126
+ ### Loading states
127
+
128
+ ```css
129
+ /* Skeleton shimmer */
130
+ @keyframes shimmer {
131
+ 0% { background-position: -200% 0; }
132
+ 100% { background-position: 200% 0; }
133
+ }
134
+ .skeleton {
135
+ background: linear-gradient(90deg, var(--color-surface) 25%, var(--color-surface-hover) 50%, var(--color-surface) 75%);
136
+ background-size: 200% 100%;
137
+ animation: shimmer 1.5s infinite;
138
+ border-radius: var(--radius-sm);
139
+ }
140
+ ```
141
+
142
+ ---
143
+
144
+ ## Typography Effects
145
+
146
+ ### Gradient text
147
+
148
+ ```css
149
+ background: linear-gradient(135deg, var(--color-primary), var(--color-accent));
150
+ -webkit-background-clip: text;
151
+ -webkit-text-fill-color: transparent;
152
+ background-clip: text;
153
+ /* Tailwind: bg-gradient-to-r from-primary to-accent bg-clip-text text-transparent */
154
+ ```
155
+
156
+ ### Text glow
157
+
158
+ ```css
159
+ text-shadow: 0 0 20px rgba(var(--color-primary-rgb), 0.3);
160
+ ```
161
+
162
+ ---
163
+
164
+ ## Component Polish
165
+
166
+ ### Card hover
167
+
168
+ ```css
169
+ /* Lift + shadow + subtle border */
170
+ .card {
171
+ transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
172
+ border: 1px solid transparent;
173
+ }
174
+ .card:hover {
175
+ transform: translateY(-4px);
176
+ box-shadow: var(--shadow-lg);
177
+ border-color: rgba(var(--color-primary-rgb), 0.1);
178
+ }
179
+ ```
180
+
181
+ ### Button state progression
182
+
183
+ ```css
184
+ /* Rest → Hover → Active → Focus */
185
+ .btn {
186
+ transition: all 0.15s ease;
187
+ box-shadow: var(--shadow-sm);
188
+ }
189
+ .btn:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); filter: brightness(1.05); }
190
+ .btn:active { box-shadow: var(--shadow-sm); transform: translateY(0); filter: brightness(0.95); }
191
+ .btn:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
192
+ ```
193
+
194
+ ### Image treatments
195
+
196
+ ```css
197
+ /* Rounded + shadow — product images */
198
+ border-radius: var(--radius-lg); box-shadow: var(--shadow-md);
199
+
200
+ /* Hover zoom — gallery, cards */
201
+ .img-wrapper { overflow: hidden; border-radius: var(--radius-md); }
202
+ .img-wrapper img { transition: transform 0.3s ease; }
203
+ .img-wrapper:hover img { transform: scale(1.05); }
204
+
205
+ /* Gradient overlay — text over images */
206
+ background: linear-gradient(to top, rgba(0,0,0,0.7) 0%, transparent 60%);
207
+ ```
208
+
209
+ ---
210
+
211
+ ## Advanced Interactions
212
+
213
+ ### Spotlight border cards
214
+
215
+ Mouse-tracking radial gradient on a pseudo-element, creating a glowing border that follows the cursor.
216
+
217
+ ```css
218
+ .card { position: relative; border-radius: var(--radius-md); }
219
+ .card::before {
220
+ content: ''; position: absolute; inset: -1px; border-radius: inherit;
221
+ background: radial-gradient(600px circle at var(--x) var(--y),
222
+ rgba(var(--color-primary-rgb), 0.3), transparent 40%);
223
+ z-index: -1;
224
+ }
225
+ ```
226
+ ```js
227
+ card.addEventListener('mousemove', (e) => {
228
+ const r = card.getBoundingClientRect();
229
+ card.style.setProperty('--x', `${e.clientX - r.left}px`);
230
+ card.style.setProperty('--y', `${e.clientY - r.top}px`);
231
+ });
232
+ ```
233
+
234
+ **When to use:** Feature grids, pricing cards, portfolio tiles — anywhere cards need subtle life on hover.
235
+
236
+ ### Parallax tilt cards
237
+
238
+ 3D tilt effect tracking cursor position within the card bounds.
239
+
240
+ ```css
241
+ .tilt-card {
242
+ perspective: 800px;
243
+ transform-style: preserve-3d;
244
+ transition: transform 0.1s ease-out;
245
+ }
246
+ ```
247
+ ```js
248
+ card.addEventListener('mousemove', (e) => {
249
+ const r = card.getBoundingClientRect();
250
+ const x = (e.clientX - r.left) / r.width - 0.5;
251
+ const y = (e.clientY - r.top) / r.height - 0.5;
252
+ card.style.transform = `rotateY(${x * 10}deg) rotateX(${y * -10}deg)`;
253
+ });
254
+ card.addEventListener('mouseleave', () => card.style.transform = 'none');
255
+ ```
256
+
257
+ **When to use:** Product showcases, testimonial cards, image galleries where depth reinforces premium feel.
258
+
259
+ ### Magnetic buttons
260
+
261
+ Element pulls toward cursor proximity using Framer Motion spring physics.
262
+
263
+ ```tsx
264
+ const x = useMotionValue(0);
265
+ const y = useMotionValue(0);
266
+ function handleMouse(e: React.MouseEvent) {
267
+ const r = e.currentTarget.getBoundingClientRect();
268
+ x.set((e.clientX - r.left - r.width / 2) * 0.3);
269
+ y.set((e.clientY - r.top - r.height / 2) * 0.3);
270
+ }
271
+ <motion.button style={{ x, y }} onMouseMove={handleMouse}
272
+ onMouseLeave={() => { x.set(0); y.set(0); }}
273
+ transition={{ type: "spring", stiffness: 150, damping: 15 }} />
274
+ ```
275
+
276
+ **Performance:** CRITICAL — use `useMotionValue`, never `useState` for continuous animation. useState triggers re-renders every frame.
277
+ **When to use:** Primary CTAs, nav icons, floating action buttons — sparingly, max 2-3 per viewport.
278
+
279
+ ### Staggered orchestration
280
+
281
+ Cascade reveal for groups of elements entering the viewport.
282
+
283
+ ```tsx
284
+ // Framer Motion — container orchestration
285
+ <motion.div variants={{ show: { transition: { staggerChildren: 0.08 } } }}
286
+ initial="hidden" whileInView="show" viewport={{ once: true }}>
287
+ {items.map(item => (
288
+ <motion.div key={item.id}
289
+ variants={{ hidden: { opacity: 0, y: 20 }, show: { opacity: 1, y: 0 } }} />
290
+ ))}
291
+ </motion.div>
292
+ ```
293
+ ```css
294
+ /* CSS-only alternative */
295
+ .stagger-item { animation: fade-up 0.5s ease-out both;
296
+ animation-delay: calc(var(--index) * 80ms); }
297
+ ```
298
+
299
+ **When to use:** Feature lists, card grids, any repeated group entering on scroll. Limit to 6-8 items per stagger group.
300
+
301
+ ### Spring physics defaults
302
+
303
+ Standard spring configurations for interactive elements. Never use linear easing for UI motion.
304
+
305
+ ```tsx
306
+ // Interactive elements (buttons, toggles, cards)
307
+ transition={{ type: "spring", stiffness: 100, damping: 20 }}
308
+
309
+ // Snappy micro-interactions (checkboxes, switches)
310
+ transition={{ type: "spring", stiffness: 300, damping: 25 }}
311
+
312
+ // Gentle layout shifts (expanding panels, modals)
313
+ transition={{ type: "spring", stiffness: 60, damping: 18 }}
314
+ ```
315
+
316
+ **Performance:** Spring physics self-resolve — no need to specify duration. Overdamped (damping > 2√stiffness) prevents oscillation.
317
+ **When to use:** Every animated element. Springs feel organic; linear/ease-in-out feel mechanical.
318
+
319
+ ### Scroll-driven reveals
320
+
321
+ Native CSS scroll-driven animations or IntersectionObserver class toggling for entrance effects.
322
+
323
+ ```css
324
+ /* CSS scroll-driven (modern browsers) */
325
+ @keyframes reveal { from { opacity: 0; translate: 0 30px; } }
326
+ .scroll-reveal {
327
+ animation: reveal linear both;
328
+ animation-timeline: view();
329
+ animation-range: entry 0% entry 40%;
330
+ }
331
+ ```
332
+ ```css
333
+ /* IO fallback — toggle class */
334
+ .reveal { opacity: 0; transform: translateY(20px); transition: all 0.6s ease-out; }
335
+ .reveal.visible { opacity: 1; transform: translateY(0); }
336
+ ```
337
+
338
+ **Performance:** CSS `animation-timeline: view()` is compositor-driven — zero JS cost. Use IO fallback for Safari < 18.
339
+ **When to use:** Default entrance pattern for all below-fold content. Prefer CSS scroll-driven where supported.
340
+
341
+ ### Sticky scroll stacking
342
+
343
+ Sections with `position: sticky` that stack as user scrolls, creating a layered card deck effect.
344
+
345
+ ```css
346
+ .stack-section {
347
+ position: sticky;
348
+ top: calc(var(--index) * 40px);
349
+ height: 80vh;
350
+ border-radius: var(--radius-lg);
351
+ transition: scale 0.3s ease;
352
+ }
353
+ .stack-section:not(:last-child) { scale: calc(1 - var(--index) * 0.02); }
354
+ ```
355
+
356
+ **Performance:** Use `will-change: transform` on sticky elements. Limit to 4-6 stacking sections.
357
+ **When to use:** Case studies, feature deep-dives, storytelling sequences where layered reveal adds narrative weight.
358
+
359
+ ### Horizontal scroll hijack
360
+
361
+ Vertical scroll input translates to horizontal gallery panning.
362
+
363
+ ```css
364
+ .h-scroll-wrapper { overflow-x: scroll; scroll-snap-type: x mandatory; }
365
+ .h-scroll-wrapper > * {
366
+ scroll-snap-align: start; flex-shrink: 0; width: 80vw;
367
+ }
368
+ ```
369
+ ```js
370
+ // Alternative: translateX driven by scrollY
371
+ const x = useTransform(scrollY, [sectionTop, sectionBottom],
372
+ ['0%', `-${(items.length - 1) * 100}%`]);
373
+ ```
374
+
375
+ **Performance:** CSS `scroll-snap` is GPU-composited. JS transform approach needs `useMotionValue` for frame budgets.
376
+ **When to use:** Image galleries, timelines, portfolio showcases — when horizontal layout serves content better than vertical.
377
+
378
+ ### Text mask reveal
379
+
380
+ Large typography with media showing through the text shape.
381
+
382
+ ```css
383
+ .text-mask {
384
+ font-size: clamp(4rem, 12vw, 10rem);
385
+ font-weight: 900;
386
+ background: url('video-or-gradient.mp4') center/cover;
387
+ -webkit-background-clip: text;
388
+ background-clip: text;
389
+ -webkit-text-fill-color: transparent;
390
+ }
391
+ ```
392
+
393
+ **Performance:** `background-clip: text` with video is paint-heavy — limit to one instance per page.
394
+ **When to use:** Hero headlines, section dividers, brand moments where type IS the visual.
395
+
396
+ ### Kinetic marquee
397
+
398
+ Infinite horizontal text scroll, with hover pause or direction reversal.
399
+
400
+ ```css
401
+ .marquee { overflow: hidden; white-space: nowrap; }
402
+ .marquee-inner {
403
+ display: inline-flex; gap: 2rem;
404
+ animation: scroll-x 20s linear infinite;
405
+ }
406
+ .marquee:hover .marquee-inner { animation-direction: reverse; }
407
+ @keyframes scroll-x { to { transform: translateX(-50%); } }
408
+ ```
409
+
410
+ **Performance:** Duplicate content so the strip is 2× viewport width. `translateX` is compositor-only.
411
+ **When to use:** Logo walls, social proof tickers, decorative text bands between sections.
412
+
413
+ ### Directional hover
414
+
415
+ Detect which side the cursor enters and animate a fill from that direction.
416
+
417
+ ```js
418
+ function getDirection(e, el) {
419
+ const { top, left, width, height } = el.getBoundingClientRect();
420
+ const x = (e.clientX - left - width / 2) / width;
421
+ const y = (e.clientY - top - height / 2) / height;
422
+ return Math.round((Math.atan2(y, x) * (180 / Math.PI) + 180) / 90) % 4;
423
+ }
424
+ // Set CSS custom property: --enter-from: top|right|bottom|left
425
+ ```
426
+ ```css
427
+ .dir-hover::before {
428
+ transition: transform 0.3s ease;
429
+ transform: translateY(calc(var(--dir-y, 0) * 100%)) translateX(calc(var(--dir-x, 0) * 100%));
430
+ }
431
+ .dir-hover:hover::before { transform: translate(0, 0); }
432
+ ```
433
+
434
+ **When to use:** Nav links, card overlays, image hover reveals — adds spatial awareness to interactions.
435
+
436
+ ### Liquid glass refraction
437
+
438
+ Beyond basic glassmorphism — simulating realistic glass edge refraction and depth.
439
+
440
+ ```css
441
+ .liquid-glass {
442
+ backdrop-filter: blur(20px) saturate(200%);
443
+ background: rgba(255, 255, 255, 0.05);
444
+ border: 1px solid rgba(255, 255, 255, 0.1);
445
+ box-shadow:
446
+ inset 0 1px 0 rgba(255, 255, 255, 0.1), /* top edge highlight */
447
+ inset 0 -1px 0 rgba(0, 0, 0, 0.05), /* bottom edge shadow */
448
+ 0 8px 32px rgba(0, 0, 0, 0.12);
449
+ border-radius: var(--radius-lg);
450
+ }
451
+ ```
452
+
453
+ **Performance:** `backdrop-filter` triggers compositing — avoid stacking multiple blurred layers.
454
+ **When to use:** Floating toolbars, modal overlays, nav bars over dynamic backgrounds — upgrade from flat glassmorphism.
455
+
456
+ ---
457
+
458
+ ## Accessibility
459
+
460
+ All visual effects must degrade gracefully:
461
+
462
+ ```css
463
+ @media (prefers-reduced-motion: reduce) {
464
+ *, *::before, *::after {
465
+ animation-duration: 0.01ms !important;
466
+ animation-iteration-count: 1 !important;
467
+ transition-duration: 0.01ms !important;
468
+ }
469
+ }
470
+ ```
471
+
472
+ - Glow/shadow: ensure text contrast meets WCAG AA without effects
473
+ - Backdrop-blur: `@supports not (backdrop-filter: blur(1px))` solid bg fallback
474
+ - Gradient text: test contrast ratio of gradient endpoints, not just midpoint
475
+ - Hover transforms: keep magnitude small (2-4px translate, 1.02-1.05 scale) to avoid disorientation
@@ -0,0 +1,120 @@
1
+ # Visual Taste Evaluation Framework
2
+
3
+ Companion to `nielsen-heuristics.md`. Nielsen measures usability (/50); this measures visual quality (/75). Both are evaluated independently during critique — a design can score high on one and low on the other.
4
+
5
+ ## What Taste Means
6
+
7
+ Taste is intentionality in every decision. It's the difference between assembling parts and composing an experience.
8
+
9
+ - **Signal vs noise** — knowing what deserves emphasis and what should fade
10
+ - **Visual coherence** — all elements speaking the same design language
11
+ - **Confidence in constraints** — doing less with more intention
12
+ - **The gap between "it works" and "it feels right"**
13
+ - **Not decoration** — it's the absence of things that shouldn't be there
14
+
15
+ Taste cannot be added at the end. It's a quality that emerges when every decision — type, color, spacing, motion, content — serves the same story.
16
+
17
+ ## Sophistication Scale
18
+
19
+ | Level | Name | Description | Examples |
20
+ |-------|------|-------------|----------|
21
+ | 1 | Default | Browser defaults, no styling intention. Looks like a homework assignment. | Unstyled HTML, Craigslist |
22
+ | 2 | Functional | Styled but generic. Could be any product. Uses a component library without customization. | Default Bootstrap site, early-stage SaaS with Tailwind defaults |
23
+ | 3 | Polished | Consistent, professional, follows best practices. Looks like a well-made product. | Notion, Slack, most well-funded SaaS products |
24
+ | 4 | Refined | Intentional details, personality showing through. You notice the craft. | Raycast, Arc Browser, Lottie |
25
+ | 5 | Distinctive | Unmistakably this brand. Memorable. You'd recognize it without the logo. | Linear, Stripe, Vercel |
26
+
27
+ ## Taste Evaluation Checklist
28
+
29
+ Score each item 1-5. Total: X/75.
30
+
31
+ ### 1. Typography personality
32
+ Does the type choice have character beyond the default? Score 1 if Inter/system font with no hierarchy. Score 5 if a distinctive pairing embodies brand personality with clear weight and size hierarchy.
33
+
34
+ ### 2. Color intentionality
35
+ Is the palette considered or default? Score 1 if random, oversaturated, or too many hues. Score 5 if a cohesive system with clear semantic hierarchy and tinted neutrals.
36
+
37
+ ### 3. Spacing rhythm
38
+ Does whitespace feel intentional or arbitrary? Score 1 if inconsistent padding with no scale. Score 5 if a clear vertical rhythm creates breathing room and content grouping.
39
+
40
+ ### 4. Shadow & depth
41
+ Are surfaces creating meaningful hierarchy? Score 1 if flat or generic `box-shadow: 0 2px 4px rgba(0,0,0,.1)`. Score 5 if tinted shadows with consistent light direction communicate z-layers.
42
+
43
+ ### 5. Motion personality
44
+ Does animation match the brand's energy? Score 1 if no motion or linear easing. Score 5 if spring physics, choreographed entrances, and exit animations match brand character.
45
+
46
+ ### 6. Content authenticity
47
+ Does copy feel real or templated? Score 1 if Lorem Ipsum, "Welcome to our platform," or AI cliches. Score 5 if specific, voice-consistent, believable content throughout.
48
+
49
+ ### 7. Component individuality
50
+ Are components styled to brand or default? Score 1 if stock library defaults (default Radix, unstyled shadcn). Score 5 if radius, color, shadow, and motion are customized to match brand DNA.
51
+
52
+ ### 8. Layout confidence
53
+ Does the layout make bold choices or play it safe? Score 1 if generic centered single-column symmetry. Score 5 if intentional asymmetry, creative grid usage, or distinctive composition that serves the content.
54
+
55
+ ### 9. Visual coherence
56
+ Do all elements speak the same design language? Score 1 if mixing incompatible styles (glassmorphism + neubrutalism + flat). Score 5 if every element reinforces one visual story.
57
+
58
+ ### 10. Surface texture
59
+ Is there tactile quality or is it flat? Score 1 if pure flat vectors with no material quality. Score 5 if subtle grain, glass refraction, or tinted shadows create physical presence appropriate to brand.
60
+
61
+ ### 11. State completeness
62
+ Are all interaction states designed? Score 1 if hover, active, loading, empty, and error states are missing or unstyled. Score 5 if every state feels intentional with smooth transitions between them.
63
+
64
+ ### 12. Responsive craft
65
+ Is mobile a first-class experience? Score 1 if "it fits on mobile" is the only consideration. Score 5 if mobile has its own considered layout with touch-appropriate sizing and gestures.
66
+
67
+ ### 13. Icon consistency
68
+ Unified family, weight, style? Score 1 if mixed icon sets, inconsistent weights, or mismatched sizing. Score 5 if one curated set with consistent stroke width and optical alignment throughout.
69
+
70
+ ### 14. Image direction
71
+ Do images match brand personality? Score 1 if stock photos, broken URLs, or placeholder boxes. Score 5 if imagery style (photography, illustration, generative, CSS-only) is a deliberate brand choice.
72
+
73
+ ### 15. Overall impression
74
+ Does it feel like a $150k agency build? Score 1 if it looks AI-generated or template-derived. Score 5 if someone would ask "who designed this?"
75
+
76
+ ## Scoring
77
+
78
+ **X/75 total**, mapped to sophistication levels:
79
+
80
+ - **15-25**: Level 1-2 (Default/Functional) — needs significant visual work
81
+ - **26-40**: Level 3 (Polished) — professional but not distinctive
82
+ - **41-55**: Level 4 (Refined) — shows craft and personality
83
+ - **56-75**: Level 5 (Distinctive) — agency-quality, memorable
84
+
85
+ ## How to Improve Each Level
86
+
87
+ ### Level 2 → 3 (Functional → Polished)
88
+
89
+ - Swap default fonts for a considered pairing
90
+ - Establish a consistent spacing scale (4/8px or similar)
91
+ - Add hover states and transitions to all interactive elements
92
+ - Use one accent color consistently with tinted neutrals
93
+ - Add loading and empty states
94
+
95
+ ### Level 3 → 4 (Polished → Refined)
96
+
97
+ - Customize component library beyond defaults (radius, shadows, colors)
98
+ - Add subtle texture (noise grain, tinted shadows, soft gradients)
99
+ - Introduce spring physics for interactive motion
100
+ - Use staggered entrances instead of instant mounting
101
+ - Make responsive layouts feel native to each breakpoint
102
+
103
+ ### Level 4 → 5 (Refined → Distinctive)
104
+
105
+ - Create signature visual patterns unique to this brand
106
+ - Use advanced interactions (spotlight borders, magnetic elements, scroll choreography)
107
+ - Ensure every surface, shadow, and animation reinforces brand personality
108
+ - Content feels authored — specific voice, real data, believable context
109
+ - Someone could identify the brand from a screenshot without the logo
110
+
111
+ ## How to Use
112
+
113
+ This reference is loaded by the critique agent alongside `references/nielsen-heuristics.md`. During critique:
114
+
115
+ 1. Score each of the 15 taste items 1-5 with specific examples from the design
116
+ 2. Calculate total and map to sophistication level
117
+ 3. Write taste evaluation as a section in `critique.md`
118
+ 4. Include taste-specific fixes in `prioritized-fixes.md`
119
+
120
+ Usability (Nielsen's, /50) and Taste (/75) are evaluated separately. A design can be highly usable but lack taste, or be visually stunning but have usability problems. Both dimensions must be addressed.
@@ -117,7 +117,7 @@ Convert hex to relative luminance (sRGB linearization), then:
117
117
  Read token and palette files from the brand/project:
118
118
  - `{BRAND_PATH}/identity/palettes.json`
119
119
  - `{BRAND_PATH}/identity/color-system.md`
120
- - `{BRAND_PATH}/system/tokens.json`
120
+ - `{BRAND_PATH}/patterns/tokens.json`
121
121
  - `{BRAND_PATH}/identity/typography.md`
122
122
 
123
123
  If files don't exist, report which are missing and stop.
@@ -85,7 +85,5 @@ Update `evolution_scope` in `{BRAND_PATH}/config.json` with confirmed decisions.
85
85
 
86
86
  Update `{BRAND_PATH}/STATE.md`: set Phase 0 (Audit) to `complete`.
87
87
 
88
- Use `AskUserQuestion`:
89
- - **Continue to research** — "validate brand position against the market"
90
- - **Done for now** — "pick up later with /gsp:start"
88
+ Render phase transition (see `references/phase-transitions.md`).
91
89
  </process>
@@ -124,8 +124,5 @@ Use `AskUserQuestion`:
124
124
 
125
125
  Update `{BRAND_PATH}/STATE.md`: set Phase 3 (Identity) to `complete`, Prettiness Level to 80%.
126
126
 
127
- Render phase transition, then use `AskUserQuestion`:
128
- - **Continue to patterns** — "build tokens and components"
129
- - **View progress** — "see the full dashboard"
130
- - **Done for now** — "pick up later with /gsp:start"
127
+ Render phase transition (see `references/phase-transitions.md`).
131
128
  </process>