get-shit-pretty 0.5.1 → 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 (45) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/bin/install.js +38 -19
  3. package/gsp/agents/gsp-accessibility-auditor.md +1 -4
  4. package/gsp/agents/gsp-ascii-artist.md +1 -1
  5. package/gsp/agents/gsp-brand-auditor.md +0 -2
  6. package/gsp/agents/gsp-brand-strategist.md +0 -2
  7. package/gsp/agents/gsp-brand-syncer.md +125 -0
  8. package/gsp/agents/gsp-builder.md +2 -7
  9. package/gsp/agents/gsp-campaign-director.md +0 -20
  10. package/gsp/agents/gsp-critic.md +15 -18
  11. package/gsp/agents/gsp-designer.md +0 -4
  12. package/gsp/agents/gsp-identity-designer.md +0 -4
  13. package/gsp/agents/gsp-pattern-architect.md +1 -63
  14. package/gsp/agents/gsp-project-researcher.md +0 -21
  15. package/gsp/agents/gsp-researcher.md +0 -2
  16. package/gsp/agents/gsp-reviewer.md +1 -12
  17. package/gsp/agents/gsp-scoper.md +0 -21
  18. package/gsp/hooks/hooks.json +11 -0
  19. package/gsp/prompts/01-design-system-architect.md +0 -46
  20. package/gsp/prompts/02-brand-identity-creator.md +1 -14
  21. package/gsp/prompts/03-ui-ux-pattern-master.md +1 -23
  22. package/gsp/prompts/04-marketing-asset-factory.md +1 -14
  23. package/gsp/prompts/05-implementation-spec-expert.md +0 -27
  24. package/gsp/prompts/06-design-critique-partner.md +1 -17
  25. package/gsp/prompts/07-design-trend-synthesizer.md +2 -29
  26. package/gsp/prompts/08-accessibility-auditor.md +4 -19
  27. package/gsp/prompts/09-design-to-code-translator.md +17 -31
  28. package/gsp/prompts/10-project-scoper.md +2 -36
  29. package/gsp/prompts/11-deliverable-reviewer.md +1 -50
  30. package/gsp/prompts/12-project-researcher.md +0 -39
  31. package/gsp/references/anti-patterns.md +173 -0
  32. package/gsp/references/block-patterns.md +44 -0
  33. package/gsp/references/chunk-format.md +31 -0
  34. package/gsp/references/style-preset-schema.md +63 -0
  35. package/gsp/references/visual-effects.md +247 -0
  36. package/gsp/references/visual-taste.md +120 -0
  37. package/gsp/skills/gsp-brand-sync/SKILL.md +101 -0
  38. package/gsp/skills/gsp-help/SKILL.md +1 -0
  39. package/gsp/skills/gsp-project-build/SKILL.md +89 -2
  40. package/gsp/skills/gsp-project-critique/SKILL.md +2 -0
  41. package/gsp/skills/gsp-project-design/SKILL.md +1 -0
  42. package/gsp/skills/gsp-style/SKILL.md +14 -217
  43. package/gsp/skills/gsp-typescale/SKILL.md +23 -319
  44. package/package.json +1 -1
  45. package/scripts/gsp-context-recovery.sh +71 -0
@@ -0,0 +1,173 @@
1
+ # AI Design Anti-Patterns
2
+
3
+ Convergence patterns that make AI-generated UI look AI-generated. Each entry: what it looks like, why it fails, what to do instead.
4
+
5
+ ---
6
+
7
+ ## Typography
8
+
9
+ **Inter/Roboto as default** — instantly signals "AI made this." Use Geist, Outfit, Cabinet Grotesk, Satoshi, or a brand-specific typeface.
10
+
11
+ **Hierarchy only through size** — creates monotone pages. Combine weight, color, spacing, and opacity to build clear typographic layers.
12
+
13
+ **Missing letter-spacing** — large type looks loose, small caps look cramped. Apply negative tracking on display sizes, positive on small text and all-caps.
14
+
15
+ **Proportional numbers in data tables** — columns won't align. Use `font-variant-numeric: tabular-nums` or a monospace face for numeric data.
16
+
17
+ **Orphaned words on last lines** — single words dangling below headings look unfinished. Use `text-wrap: balance` for headings, `text-wrap: pretty` for body.
18
+
19
+ **All-caps overuse** — screaming text flattens hierarchy. Reserve caps for overlines, labels, and navigation items only.
20
+
21
+ **Serif fonts in software UI** — serif faces fight functional interfaces. Sans-serif only for dashboards, tools, and product UI.
22
+
23
+ **Same weight everywhere** — 400 regular on every element is invisible hierarchy. Introduce medium (500) and semibold (600) to create contrast.
24
+
25
+ ---
26
+
27
+ ## Color
28
+
29
+ **Pure #000000** — harsh and unnatural on screens. Use off-black: `zinc-950`, `slate-900`, or a hue-tinted dark.
30
+
31
+ **Oversaturated accents above 80% chroma** — vibrate against neutrals and fail accessibility. Desaturate until the accent blends with the surrounding palette.
32
+
33
+ **AI purple/blue gradient aesthetic** — the single most recognizable AI fingerprint. Use neutral bases with one singular, considered accent color.
34
+
35
+ **Multiple accent colors** — fragments attention and looks undesigned. One accent, period. Use shade variations of that accent for states.
36
+
37
+ **Mixing warm and cool grays** — creates visual tension. Pick one temperature for your neutral scale and commit.
38
+
39
+ **Inconsistent shadow direction** — suggests multiple light sources, breaks spatial logic. Establish a single top-left or top-center light source.
40
+
41
+ **Random dark sections in a light page** — jarring breaks in visual continuity. Commit to one mode or use subtle shade shifts (e.g., `gray-50` to `gray-100`).
42
+
43
+ ---
44
+
45
+ ## Layout
46
+
47
+ **Centered-everything bias** — the laziest composition. Use split screen, left-aligned sections, asymmetric white-space when variance serves the brand.
48
+
49
+ **Generic 3-column equal card rows** — screams template. Use 2-column zig-zag, asymmetric grid, horizontal scroll, or masonry instead.
50
+
51
+ **`h-screen` for full-height sections** — breaks on mobile when the address bar hides/shows. Use `min-h-[100dvh]` with dynamic viewport units.
52
+
53
+ **No max-width container** — text lines stretch to 200+ characters on wide screens. Add `max-w-7xl mx-auto` or equivalent.
54
+
55
+ **Cards for everything** — elevation without purpose is noise. Use `border-t`, `divide-y`, or negative space for grouping. Cards only when elevation communicates hierarchy.
56
+
57
+ **Equal top/bottom padding** — bottom padding looks visually shorter due to optical illusion. Make bottom ~10-20% larger for balance.
58
+
59
+ **Complex flexbox percentage math** — fragile and hard to maintain. Use CSS Grid for reliable multi-column layouts.
60
+
61
+ **Buttons not bottom-aligned in card groups** — CTAs at different vertical positions look broken. Pin actions to the card bottom so they form a clean horizontal line.
62
+
63
+ **Inconsistent vertical rhythm** — side-by-side elements with misaligned baselines, titles, or images. Align shared elements across columns.
64
+
65
+ ---
66
+
67
+ ## Surfaces & Depth
68
+
69
+ **Generic `box-shadow` with untinted black** — looks pasted on. Tint shadows to match or complement the background hue.
70
+
71
+ **Flat design with zero texture** — sterile and lifeless. Add subtle noise, grain, or micro-patterns for tactile quality.
72
+
73
+ **Generic card borders everywhere** — monotonous elevation. Vary treatment: some borderless, some elevated, some with subtle background shifts.
74
+
75
+ **Inconsistent elevation** — random shadow sizes break spatial logic. Establish a z-layer system: flat, subtle, elevated, floating, overlay.
76
+
77
+ **Perfectly even gradients** — look synthetic. Break with radial gradients, noise overlays, or mesh gradients for organic depth.
78
+
79
+ ---
80
+
81
+ ## Content
82
+
83
+ **Lorem Ipsum placeholder text** — signals incomplete thinking. Write real draft copy, always. Even rough copy is better than Latin.
84
+
85
+ **Generic names: "John Doe", "Jane Smith"** — lazy and culturally flat. Invent creative, diverse, realistic names that feel like real people.
86
+
87
+ **Fake round numbers: 99.99%, $100.00, 50%** — obviously fake data. Use organic numbers: 47.2%, $99.00, 73%.
88
+
89
+ **AI copywriting cliches: "Elevate", "Seamless", "Unleash", "Next-Gen", "Delve"** — immediately identifiable as AI slop. Use concrete, specific verbs that describe what actually happens.
90
+
91
+ **"Oops!" error messages** — infantilizing and unhelpful. Be direct: "Connection failed. Try again."
92
+
93
+ **Exclamation marks in success messages** — "Saved!" feels insecure. Be confident and quiet: "Changes saved."
94
+
95
+ **Startup name slop: "Acme", "Nexus", "SmartFlow"** — generic placeholder branding. Invent contextual brand names with personality.
96
+
97
+ **Broken Unsplash URLs** — AI hallucinates image URLs that 404. Use `picsum.photos/seed/{name}/800/600` or SVG placeholders.
98
+
99
+ **Same avatar for multiple users** — destroys the illusion of real data. Unique asset per person.
100
+
101
+ **Title Case On Every Header** — looks like a newspaper from 2003. Use sentence case for modern UI.
102
+
103
+ ---
104
+
105
+ ## Motion
106
+
107
+ **Linear easing on everything** — mechanical and robotic. Use `cubic-bezier(0.16, 1, 0.3, 1)` or spring physics: `type: "spring", stiffness: 100, damping: 20`.
108
+
109
+ **Animating `top`/`left`/`width`/`height`** — triggers layout reflow, causes jank. Use `transform` and `opacity` only (GPU-accelerated).
110
+
111
+ **Instant transitions with zero duration** — feels broken. 200-300ms minimum for interactive element state changes.
112
+
113
+ **No `prefers-reduced-motion` respect** — accessibility violation. Always wrap animations in `@media (prefers-reduced-motion: no-preference)`.
114
+
115
+ **`window.addEventListener('scroll')` for scroll effects** — fires on every frame, kills performance. Use `IntersectionObserver` or CSS scroll-driven animations.
116
+
117
+ **Everything mounts simultaneously** — wall of content appearing at once has zero visual hierarchy. Stagger with `animation-delay` cascade or `staggerChildren`.
118
+
119
+ **Custom mouse cursors** — outdated gimmick that hurts performance and accessibility. Use native cursors.
120
+
121
+ ---
122
+
123
+ ## Components
124
+
125
+ **Default shadcn/ui without customization** — recognizable on sight. Customize radii, colors, shadows, and spacing to match the brand.
126
+
127
+ **Pill-shaped badges for everything** — visual clutter. Try square badges, flags, or plain styled text labels.
128
+
129
+ **3-card testimonial carousel with dots** — the most generic social proof pattern. Use masonry wall, embedded posts, or a single rotating quote.
130
+
131
+ **Modal for every interaction** — breaks flow and adds clicks. Use inline editing, slide-over panels, or expandable sections.
132
+
133
+ **Sun/moon dark mode toggle** — overdone and takes up prime real estate. Use dropdown, system preference detection, or integrate into settings.
134
+
135
+ **Generic circular spinner for loading** — tells user nothing about what's coming. Use skeleton loaders matching the actual layout shape.
136
+
137
+ **Accordion FAQ section** — feels like a support page from 2015. Use side-by-side list, searchable help, or inline progressive disclosure.
138
+
139
+ **4-column footer link farm** — nobody reads these. Simplify to main paths and legal links.
140
+
141
+ **Generic SVG user avatars** — the gray circle person. Use creative photo placeholders or styled initial letters.
142
+
143
+ ---
144
+
145
+ ## Code Quality
146
+
147
+ **Div soup** — inaccessible and unreadable. Use semantic HTML: `nav`, `main`, `article`, `aside`, `section`.
148
+
149
+ **Inline styles mixed with utility classes** — inconsistent styling strategy. Pick one approach per project.
150
+
151
+ **Hardcoded pixel widths** — breaks on every screen size. Use relative units: `%`, `rem`, `max-width`.
152
+
153
+ **Arbitrary `z-index: 9999`** — z-index arms race. Establish a clean z-index scale in the theme config.
154
+
155
+ **Missing alt text on meaningful images** — accessibility failure. Describe content for screen readers; use `alt=""` only for decorative images.
156
+
157
+ **Missing meta tags** — invisible to search and social. Include `title`, `description`, `og:image` at minimum.
158
+
159
+ **Commented-out dead code** — debug artifacts that signal carelessness. Remove all dead code before delivery.
160
+
161
+ **Import hallucinations** — AI invents packages that don't exist. Verify every import resolves to a real dependency in `package.json`.
162
+
163
+ **Emoji in UI code and markup** — unprofessional in product interfaces. Use quality icon sets: Phosphor, Heroicons, Lucide, or Radix Icons.
164
+
165
+ ---
166
+
167
+ ## How to Use
168
+
169
+ This reference is loaded by designer, builder, and critic agents. When generating or evaluating design:
170
+
171
+ 1. **Designer** — avoid these patterns when creating screen specs
172
+ 2. **Builder** — check implemented code against this list before marking a screen complete
173
+ 3. **Critic** — flag any anti-patterns found as issues in `prioritized-fixes.md`
@@ -89,3 +89,47 @@ Single row: logo + horizontal link list + copyright. Centered or space-between.
89
89
  | Testimonials | 3 cards | 2 cards | 1 card or scroll |
90
90
  | Pricing cards | Side by side | Side by side | Stacked |
91
91
  | Rich footer | 4 columns | 2×2 grid | Stacked |
92
+
93
+ ---
94
+
95
+ ## Advanced Compositions
96
+
97
+ ### Bento 2.0
98
+
99
+ Asymmetric grid where every cell is alive — each tile runs a perpetual micro-animation (pulse, float, shimmer, or infinite mini-carousel). Cells are self-contained components with their own animation loops, creating ambient motion across the grid. Mixed sizes: 1×1 through 2×2, 3-4 column grid.
100
+ **Responsive:** Collapse to 2-col then 1-col. Animations persist at all breakpoints — they're per-tile, not layout-dependent.
101
+
102
+ ### Split-screen scroll
103
+
104
+ Viewport divided into two vertical halves that scroll in opposite directions. Left pane scrolls content upward while right pane scrolls downward (or vice versa), creating a parallax tension effect. Content in each half is independent — typically images vs. text, or two complementary narratives.
105
+ **Responsive:** Stack vertically with normal unified scroll direction. No split on viewports < 768px.
106
+
107
+ ### Curtain reveal
108
+
109
+ Hero section that splits down the center like a curtain as the user scrolls, revealing the next section behind it. Each half translates outward (left half → left, right half → right) tied to scroll position. Content behind is fixed-position until fully revealed.
110
+ **Responsive:** Replace curtain split with a simple crossfade on mobile — the split effect requires sufficient viewport width to read.
111
+
112
+ ### Sticky scroll sequence
113
+
114
+ Image or video frames tied to scroll position, advancing one frame per scroll increment (like Apple product pages). A tall scroll container (300-500vh) drives a fixed-position media element through a sequence of states. Text callouts appear at keyframe positions.
115
+ **Responsive:** Replace scroll-tied frames with auto-playing video or animated sequence. Maintain text callouts as overlay cards.
116
+
117
+ ### Accordion image slider
118
+
119
+ 5-7 narrow vertical strips displayed side by side, each showing a slice of its full image. On hover, the targeted strip expands to full width while others compress. Creates an explorable gallery in a single viewport-height section.
120
+ **Responsive:** Convert to standard horizontal carousel with snap points on mobile. Hover-expand doesn't translate to touch.
121
+
122
+ ### Mega menu reveal
123
+
124
+ Full-viewport-width dropdown panel triggered by nav hover or click. Content organized in 3-5 columns with staggered fade-in (80ms per column). Includes category headers, link lists, optional featured image or CTA card. Overlay dims page content behind.
125
+ **Responsive:** Replace with full-screen slide-in panel from the side. Stagger animation applies to rows instead of columns.
126
+
127
+ ### Dynamic island
128
+
129
+ Pill-shaped floating UI component that morphs shape and content contextually — expanding to show notifications, progress bars, media controls, or status updates. Uses `border-radius` transitions and `layout` animation (Framer Motion `layoutId`) for smooth shape-shifting.
130
+ **Responsive:** Same behavior at all breakpoints. Adjust max-width and font size. Pin to top or bottom of viewport on mobile.
131
+
132
+ ### Command palette
133
+
134
+ `⌘K` / `Ctrl+K` triggered search overlay with fuzzy matching, keyboard navigation (arrow keys + enter), and grouped results (pages, actions, settings). Modal with input field, scrollable results list, and keyboard shortcut hints. Escape or click-outside to dismiss.
135
+ **Responsive:** Full-screen takeover on mobile with larger touch targets. Input auto-focused. Results fill available height.
@@ -46,3 +46,34 @@ Lightweight — just a lookup table. No prose.
46
46
  - **Self-contained:** each chunk must be understandable without loading other chunks
47
47
  - **Cross-references:** `## Related` section uses relative paths to related chunks
48
48
  - **Idempotent:** re-running a phase regenerates all chunks in that phase directory
49
+
50
+ ## Output Budgets
51
+
52
+ Context is finite. Every line in a chunk is consumed by downstream agents. Budget accordingly.
53
+
54
+ ### Per-chunk budgets
55
+
56
+ | Chunk type | Target | Hard max | Notes |
57
+ |-----------|--------|----------|-------|
58
+ | Phase chunk (design, research, etc.) | 50-150 lines | 200 lines | Self-contained, one concept per chunk |
59
+ | INDEX.md | 10-30 lines | 50 lines | Lookup table only, no prose |
60
+ | BUILD-LOG.md | 50-100 lines | 150 lines | Summary + tables, not narrative |
61
+ | Component spec | 30-80 lines | 120 lines | Props, states, behavior — not full implementation |
62
+ | Screen spec | 80-150 lines | 200 lines | Layout, components, interactions, states |
63
+
64
+ ### Per-phase budgets (total across all chunks)
65
+
66
+ | Phase | Target total | Hard max | Typical chunks |
67
+ |-------|-------------|----------|----------------|
68
+ | Brief | 100-200 lines | 300 lines | 2-4 |
69
+ | Research | 200-400 lines | 600 lines | 5-8 |
70
+ | Design | 300-600 lines | 800 lines | 6-12 |
71
+ | Critique | 100-200 lines | 300 lines | 2-4 |
72
+ | Build log | 50-100 lines | 150 lines | 1 |
73
+ | Review | 100-200 lines | 300 lines | 2-4 |
74
+
75
+ ### Terminal output (inline skills)
76
+
77
+ - **Diagnostic** (doctor, progress): uncapped — user needs to see it, does not persist in agent context
78
+ - **Greeting/status** (start): 20-40 lines
79
+ - **Phase transitions**: 10-20 lines
@@ -0,0 +1,63 @@
1
+ # Style Preset YAML Schema
2
+
3
+ Template for brand-derived style preset files (`{brand-name}.yml`). All values must trace to foundation chunks.
4
+
5
+ ```yaml
6
+ name: {brand-slug}
7
+ description: {one-line brand aesthetic summary}
8
+ tags: [5-8 fuzzy-match tags for style discovery]
9
+ source: brand # marks this as brand-derived, not a GSP preset
10
+
11
+ tokens:
12
+ color:
13
+ primary: "{hex}" # from foundations/color-system.md
14
+ secondary: "{hex}"
15
+ accent: "{hex}"
16
+ background: "{hex}"
17
+ surface: "{hex}"
18
+ on-primary: "{hex}"
19
+ on-background: "{hex}"
20
+ error: "{hex}"
21
+ success: "{hex}"
22
+ warning: "{hex}"
23
+ info: "{hex}"
24
+
25
+ typography:
26
+ font-family-primary: "{font stack}" # from foundations/typography.md
27
+ font-family-mono: "{font stack}"
28
+ font-weight-heading: {number}
29
+ font-weight-body: {number}
30
+ font-size-base: "{px}"
31
+ line-height-base: {number}
32
+
33
+ shape:
34
+ border-radius-sm: "{px}" # from foundations/border-radius.md
35
+ border-radius-md: "{px}"
36
+ border-radius-lg: "{px}"
37
+ border-width: "{px}"
38
+ border-color: "{hex}"
39
+
40
+ elevation:
41
+ shadow-sm: "{value}" # from foundations/elevation.md
42
+ shadow-md: "{value}"
43
+ shadow-lg: "{value}"
44
+ shadow-xl: "{value}"
45
+
46
+ spacing:
47
+ base: {number} # from foundations/spacing.md
48
+ scale: [{values}]
49
+
50
+ motion:
51
+ duration-fast: "{ms}"
52
+ duration-normal: "{ms}"
53
+ easing: "{value}"
54
+
55
+ dark_mode:
56
+ color:
57
+ background: "{hex}"
58
+ surface: "{hex}"
59
+ on-background: "{hex}"
60
+
61
+ compatibility: [] # leave empty for brand styles
62
+ clashes: []
63
+ ```
@@ -208,6 +208,253 @@ background: linear-gradient(to top, rgba(0,0,0,0.7) 0%, transparent 60%);
208
208
 
209
209
  ---
210
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
+
211
458
  ## Accessibility
212
459
 
213
460
  All visual effects must degrade gracefully: