wizz-method 1.3.2 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/package.json +1 -1
  2. package/skills-registry.yaml +12 -2
  3. package/src/skills-lib/ai-product-design/SKILL.md +85 -0
  4. package/src/skills-lib/ai-product-design/references/LICENSE +21 -0
  5. package/src/skills-lib/ai-product-design/references/ai-alignment-reasoning/bias-detection-design/SKILL.md +37 -0
  6. package/src/skills-lib/ai-product-design/references/ai-alignment-reasoning/consent-and-agency/SKILL.md +37 -0
  7. package/src/skills-lib/ai-product-design/references/ai-alignment-reasoning/escalation-design/SKILL.md +40 -0
  8. package/src/skills-lib/ai-product-design/references/ai-alignment-reasoning/guardrail-design/SKILL.md +36 -0
  9. package/src/skills-lib/ai-product-design/references/ai-alignment-reasoning/harm-anticipation/SKILL.md +108 -0
  10. package/src/skills-lib/ai-product-design/references/ai-alignment-reasoning/transparency-patterns/SKILL.md +36 -0
  11. package/src/skills-lib/ai-product-design/references/ai-alignment-reasoning/trust-calibration/SKILL.md +102 -0
  12. package/src/skills-lib/ai-product-design/references/ai-alignment-reasoning/value-specification/SKILL.md +39 -0
  13. package/src/skills-lib/ai-product-design/references/design-agent-orchestration/agent-role-design/SKILL.md +37 -0
  14. package/src/skills-lib/ai-product-design/references/design-agent-orchestration/failure-recovery/SKILL.md +37 -0
  15. package/src/skills-lib/ai-product-design/references/design-agent-orchestration/handoff-protocols/SKILL.md +45 -0
  16. package/src/skills-lib/ai-product-design/references/design-agent-orchestration/human-in-the-loop/SKILL.md +39 -0
  17. package/src/skills-lib/ai-product-design/references/design-agent-orchestration/observability-design/SKILL.md +48 -0
  18. package/src/skills-lib/ai-product-design/references/design-agent-orchestration/state-management/SKILL.md +95 -0
  19. package/src/skills-lib/ai-product-design/references/design-agent-orchestration/task-decomposition/SKILL.md +36 -0
  20. package/src/skills-lib/ai-product-design/references/evaluation/comparative-evaluation/SKILL.md +39 -0
  21. package/src/skills-lib/ai-product-design/references/evaluation/failure-taxonomy/SKILL.md +47 -0
  22. package/src/skills-lib/ai-product-design/references/evaluation/heuristic-evaluation-ai/SKILL.md +46 -0
  23. package/src/skills-lib/ai-product-design/references/evaluation/longitudinal-measurement/SKILL.md +38 -0
  24. package/src/skills-lib/ai-product-design/references/evaluation/output-quality-rubrics/SKILL.md +41 -0
  25. package/src/skills-lib/ai-product-design/references/evaluation/task-success-metrics/SKILL.md +35 -0
  26. package/src/skills-lib/ai-product-design/references/evaluation/user-satisfaction-signals/SKILL.md +50 -0
  27. package/src/skills-lib/ai-product-design/references/model-interaction-design/context-window-design/SKILL.md +28 -0
  28. package/src/skills-lib/ai-product-design/references/model-interaction-design/conversation-patterns/SKILL.md +37 -0
  29. package/src/skills-lib/ai-product-design/references/model-interaction-design/feedback-loops/SKILL.md +35 -0
  30. package/src/skills-lib/ai-product-design/references/model-interaction-design/frustration-detection/SKILL.md +91 -0
  31. package/src/skills-lib/ai-product-design/references/model-interaction-design/generative-ui/SKILL.md +34 -0
  32. package/src/skills-lib/ai-product-design/references/model-interaction-design/mixed-initiative-flow/SKILL.md +39 -0
  33. package/src/skills-lib/ai-product-design/references/model-interaction-design/multimodal-orchestration/SKILL.md +94 -0
  34. package/src/skills-lib/ai-product-design/references/model-interaction-design/progressive-disclosure/SKILL.md +33 -0
  35. package/src/skills-lib/ai-product-design/references/prompt-architecture/chain-of-thought-design/SKILL.md +45 -0
  36. package/src/skills-lib/ai-product-design/references/prompt-architecture/constraint-specification/SKILL.md +50 -0
  37. package/src/skills-lib/ai-product-design/references/prompt-architecture/context-engineering/SKILL.md +45 -0
  38. package/src/skills-lib/ai-product-design/references/prompt-architecture/few-shot-patterns/SKILL.md +47 -0
  39. package/src/skills-lib/ai-product-design/references/prompt-architecture/prompt-versioning/SKILL.md +42 -0
  40. package/src/skills-lib/ai-product-design/references/prompt-architecture/system-prompt-structure/SKILL.md +50 -0
  41. package/src/skills-lib/ai-product-design/references/prompt-architecture/template-design/SKILL.md +42 -0
  42. package/src/skills-lib/ai-product-design/references/system-behavior-shaping/behavioral-consistency/SKILL.md +36 -0
  43. package/src/skills-lib/ai-product-design/references/system-behavior-shaping/cultural-adaptation/SKILL.md +38 -0
  44. package/src/skills-lib/ai-product-design/references/system-behavior-shaping/domain-voice/SKILL.md +51 -0
  45. package/src/skills-lib/ai-product-design/references/system-behavior-shaping/emotional-design/SKILL.md +51 -0
  46. package/src/skills-lib/ai-product-design/references/system-behavior-shaping/error-personality/SKILL.md +45 -0
  47. package/src/skills-lib/ai-product-design/references/system-behavior-shaping/persona-architecture/SKILL.md +38 -0
  48. package/src/skills-lib/ai-product-design/references/system-behavior-shaping/tone-calibration/SKILL.md +39 -0
  49. package/src/skills-lib/algorithmic-art/LICENSE.txt +202 -0
  50. package/src/skills-lib/algorithmic-art/SKILL.md +405 -0
  51. package/src/skills-lib/algorithmic-art/templates/generator_template.js +223 -0
  52. package/src/skills-lib/algorithmic-art/templates/viewer.html +599 -0
  53. package/src/skills-lib/animate/README.md +41 -0
  54. package/src/skills-lib/animate/SKILL.md +179 -0
  55. package/src/skills-lib/animate/examples/animate-height.tsx +75 -0
  56. package/src/skills-lib/animate/examples/app-store-card.tsx +164 -0
  57. package/src/skills-lib/animate/examples/card-hover.tsx +79 -0
  58. package/src/skills-lib/animate/examples/feedback-popover.tsx +119 -0
  59. package/src/skills-lib/animate/examples/multi-step-flow.tsx +128 -0
  60. package/src/skills-lib/animate/examples/shared-layout.tsx +64 -0
  61. package/src/skills-lib/animate/examples/text-reveal.tsx +70 -0
  62. package/src/skills-lib/animate/examples/toast-stacking.tsx +95 -0
  63. package/src/skills-lib/animate/references/css-animations.md +232 -0
  64. package/src/skills-lib/animate/references/easing-and-timing.md +105 -0
  65. package/src/skills-lib/animate/references/framer-motion.md +356 -0
  66. package/src/skills-lib/animate/references/performance-accessibility.md +185 -0
  67. package/src/skills-lib/auth-and-secrets/SKILL.md +10 -0
  68. package/src/skills-lib/canvas-design/LICENSE.txt +202 -0
  69. package/src/skills-lib/canvas-design/SKILL.md +130 -0
  70. package/src/skills-lib/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +93 -0
  71. package/src/skills-lib/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
  72. package/src/skills-lib/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
  73. package/src/skills-lib/canvas-design/canvas-fonts/BigShoulders-OFL.txt +93 -0
  74. package/src/skills-lib/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
  75. package/src/skills-lib/canvas-design/canvas-fonts/Boldonse-OFL.txt +93 -0
  76. package/src/skills-lib/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
  77. package/src/skills-lib/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
  78. package/src/skills-lib/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
  79. package/src/skills-lib/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
  80. package/src/skills-lib/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
  81. package/src/skills-lib/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
  82. package/src/skills-lib/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +93 -0
  83. package/src/skills-lib/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
  84. package/src/skills-lib/canvas-design/canvas-fonts/DMMono-OFL.txt +93 -0
  85. package/src/skills-lib/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
  86. package/src/skills-lib/canvas-design/canvas-fonts/EricaOne-OFL.txt +94 -0
  87. package/src/skills-lib/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
  88. package/src/skills-lib/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
  89. package/src/skills-lib/canvas-design/canvas-fonts/GeistMono-OFL.txt +93 -0
  90. package/src/skills-lib/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
  91. package/src/skills-lib/canvas-design/canvas-fonts/Gloock-OFL.txt +93 -0
  92. package/src/skills-lib/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
  93. package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
  94. package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +93 -0
  95. package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
  96. package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
  97. package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
  98. package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
  99. package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
  100. package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
  101. package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
  102. package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
  103. package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +93 -0
  104. package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
  105. package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
  106. package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
  107. package/src/skills-lib/canvas-design/canvas-fonts/Italiana-OFL.txt +93 -0
  108. package/src/skills-lib/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
  109. package/src/skills-lib/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
  110. package/src/skills-lib/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
  111. package/src/skills-lib/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
  112. package/src/skills-lib/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
  113. package/src/skills-lib/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
  114. package/src/skills-lib/canvas-design/canvas-fonts/Jura-OFL.txt +93 -0
  115. package/src/skills-lib/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
  116. package/src/skills-lib/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
  117. package/src/skills-lib/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
  118. package/src/skills-lib/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
  119. package/src/skills-lib/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
  120. package/src/skills-lib/canvas-design/canvas-fonts/Lora-OFL.txt +93 -0
  121. package/src/skills-lib/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
  122. package/src/skills-lib/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
  123. package/src/skills-lib/canvas-design/canvas-fonts/NationalPark-OFL.txt +93 -0
  124. package/src/skills-lib/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
  125. package/src/skills-lib/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
  126. package/src/skills-lib/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
  127. package/src/skills-lib/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
  128. package/src/skills-lib/canvas-design/canvas-fonts/Outfit-OFL.txt +93 -0
  129. package/src/skills-lib/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
  130. package/src/skills-lib/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
  131. package/src/skills-lib/canvas-design/canvas-fonts/PixelifySans-OFL.txt +93 -0
  132. package/src/skills-lib/canvas-design/canvas-fonts/PoiretOne-OFL.txt +93 -0
  133. package/src/skills-lib/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
  134. package/src/skills-lib/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
  135. package/src/skills-lib/canvas-design/canvas-fonts/RedHatMono-OFL.txt +93 -0
  136. package/src/skills-lib/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
  137. package/src/skills-lib/canvas-design/canvas-fonts/Silkscreen-OFL.txt +93 -0
  138. package/src/skills-lib/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
  139. package/src/skills-lib/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
  140. package/src/skills-lib/canvas-design/canvas-fonts/SmoochSans-OFL.txt +93 -0
  141. package/src/skills-lib/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
  142. package/src/skills-lib/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -0
  143. package/src/skills-lib/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
  144. package/src/skills-lib/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
  145. package/src/skills-lib/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
  146. package/src/skills-lib/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
  147. package/src/skills-lib/canvas-design/canvas-fonts/WorkSans-OFL.txt +93 -0
  148. package/src/skills-lib/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
  149. package/src/skills-lib/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -0
  150. package/src/skills-lib/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
  151. package/src/skills-lib/design-motion-principles/SKILL.md +122 -0
  152. package/src/skills-lib/design-motion-principles/references/accessibility.md +52 -0
  153. package/src/skills-lib/design-motion-principles/references/anti-checklist.md +274 -0
  154. package/src/skills-lib/design-motion-principles/references/audit-checklist.md +137 -0
  155. package/src/skills-lib/design-motion-principles/references/creation-gotchas.md +36 -0
  156. package/src/skills-lib/design-motion-principles/references/demo-shell.html +275 -0
  157. package/src/skills-lib/design-motion-principles/references/emil-kowalski.md +121 -0
  158. package/src/skills-lib/design-motion-principles/references/jakub-krehel.md +80 -0
  159. package/src/skills-lib/design-motion-principles/references/jhey-tompkins.md +122 -0
  160. package/src/skills-lib/design-motion-principles/references/motion-cookbook.md +529 -0
  161. package/src/skills-lib/design-motion-principles/references/output-format.md +346 -0
  162. package/src/skills-lib/design-motion-principles/references/performance.md +82 -0
  163. package/src/skills-lib/design-motion-principles/references/report-template.html +1006 -0
  164. package/src/skills-lib/design-motion-principles/workflows/audit.md +203 -0
  165. package/src/skills-lib/design-motion-principles/workflows/create.md +87 -0
  166. package/src/skills-lib/web-security/SKILL.md +47 -4
  167. package/src/skills-lib/wizz-router/SKILL.md +4 -1
@@ -0,0 +1,529 @@
1
+ # Motion Cookbook
2
+
3
+ The single source of truth for motion **recipes** — implementation patterns and code. In Create mode this is your primary reference; in Audit mode load it when making implementation recommendations. Designer philosophy and decision frameworks live in the per-designer reference files; the code lives here.
4
+
5
+ ---
6
+
7
+ ## 1. Enter & Exit Animations
8
+
9
+ ### Enter Animation Recipe (Jakub)
10
+ A standard enter animation combines three properties:
11
+ - **Opacity**: 0 → 1
12
+ - **TranslateY**: ~8px → 0 (or calc(-100% - 4px) for full container slides)
13
+ - **Blur**: 4px → 0px
14
+
15
+ ```jsx
16
+ initial={{ opacity: 0, translateY: "calc(-100% - 4px)", filter: "blur(4px)" }}
17
+ animate={{ opacity: 1, translateY: 0, filter: "blur(0px)" }}
18
+ transition={{ type: "spring", duration: 0.45, bounce: 0 }}
19
+ ```
20
+
21
+ **Why blur?** It creates a "materializing" effect that feels more physical than opacity alone. The element appears to come into focus, not just fade in.
22
+
23
+ ### Exit Animation Subtlety (Jakub)
24
+ **Key Insight**: Exit animations should be subtler than enter animations.
25
+
26
+ When a component exits, it doesn't need the same amount of movement or attention as when entering. The user's focus is moving to what comes next, not what's leaving.
27
+
28
+ ```jsx
29
+ // Instead of full exit movement:
30
+ exit={{ translateY: "calc(-100% - 4px)" }}
31
+
32
+ // Use a subtle fixed value:
33
+ exit={{ translateY: "-12px", opacity: 0, filter: "blur(4px)" }}
34
+ ```
35
+
36
+ **Why this works**: Exits become softer, less jarring, and don't compete for attention with whatever is entering or remaining.
37
+
38
+ **When NOT to use subtle exits**:
39
+ - When the exit itself is meaningful (user-initiated dismissal)
40
+ - When you need to emphasize something leaving (error clearing, item deletion)
41
+ - Full-page transitions where directional continuity matters
42
+
43
+ ### Fill Mode for Persistence (Jhey)
44
+ Use `animation-fill-mode` to prevent jarring visual resets:
45
+ - `forwards`: Element retains animation styling after completion
46
+ - `backwards`: Element retains style from first keyframe before animation starts
47
+ - `both`: Retains styling in both directions
48
+
49
+ **Critical for**: Fade-in sequences with delays. Without `backwards`, elements flash at full opacity before their delayed animation starts, then pop to invisible, then fade in.
50
+
51
+ ---
52
+
53
+ ## 2. Easing & Timing
54
+
55
+ ### Duration Impacts Naturalness
56
+ > "Duration is all about timing, and timing has a big impact on the movement's naturalness." — Jhey Tompkins
57
+
58
+ ### Custom Easing is Essential (Emil)
59
+ > "Easing is the most important part of any animation. It can make a bad animation feel great."
60
+
61
+ Built-in CSS easing (`ease`, `ease-in-out`) lacks strength. Always use custom Bézier curves for professional results. Resources: easing.dev, easings.co
62
+
63
+ ### Easing Selection Guidelines (Jhey)
64
+ Each easing curve communicates something to the viewer. **Context matters more than rules.**
65
+
66
+ | Easing | Feel | Good For |
67
+ |--------|------|----------|
68
+ | `ease-out` | Fast start, gentle stop | Elements entering view (arriving) |
69
+ | `ease-in` | Gentle start, fast exit | Elements leaving view (departing) |
70
+ | `ease-in-out` | Gentle both ends | Elements changing state while visible |
71
+ | `linear` | Constant speed | Continuous loops, progress indicators |
72
+ | `spring` | Natural deceleration | Interactive elements, professional UI |
73
+
74
+ **The Context Rule**:
75
+ > "You wouldn't use 'Elastic' for a bank's website, but it might work perfectly for an energetic site for children."
76
+
77
+ Brand personality should drive easing choices. A playful brand can use bouncy, elastic easing. A professional brand should use subtle springs or ease-out.
78
+
79
+ **When NOT to use bouncy/elastic easing**:
80
+ - Professional/enterprise applications
81
+ - Frequently repeated interactions (gets tiresome)
82
+ - Error states or serious UI
83
+ - When users need to complete tasks quickly
84
+
85
+ ### Spring Animations (Jakub)
86
+ Prefer spring animations over linear/ease for more natural-feeling motion:
87
+ ```jsx
88
+ transition={{ type: "spring", duration: 0.45, bounce: 0 }}
89
+ transition={{ type: "spring", duration: 0.55, bounce: 0.1 }}
90
+ ```
91
+
92
+ **Why `bounce: 0`?** It gives smooth deceleration without overshoot—professional and refined. Reserve bounce > 0 for playful contexts.
93
+
94
+ ### The linear() Function (Jhey)
95
+ CSS `linear()` enables bounce, elastic, and spring effects in pure CSS:
96
+ ```css
97
+ :root {
98
+ --bounce-easing: linear(
99
+ 0, 0.004, 0.016, 0.035, 0.063, 0.098, 0.141 13.6%, 0.25, 0.391, 0.563, 0.765,
100
+ 1, 0.891 40.9%, 0.848, 0.813, 0.785, 0.766, 0.754, 0.75, 0.754, 0.766, 0.785,
101
+ 0.813, 0.848, 0.891 68.2%, 1 72.7%, 0.973, 0.953, 0.941, 0.938, 0.941, 0.953,
102
+ 0.973, 1, 0.988, 0.984, 0.988, 1
103
+ );
104
+ }
105
+ ```
106
+
107
+ Use Jake Archibald's linear() generator for custom curves: https://linear-easing-generator.netlify.app/
108
+
109
+ ### Stagger Techniques (Jhey)
110
+ `animation-delay` only applies once (not per iteration). Approaches:
111
+
112
+ 1. **Different delays with finite iterations** — Works for one-time sequences
113
+ 2. **Pad keyframes** to create stagger within the animation:
114
+ ```css
115
+ @keyframes spin {
116
+ 0%, 50% { transform: rotate(0deg); }
117
+ 100% { transform: rotate(360deg); }
118
+ }
119
+ ```
120
+
121
+ 3. **Negative delays** for "already in progress" effects:
122
+ ```css
123
+ .element { animation-delay: calc(var(--index) * -0.2s); }
124
+ ```
125
+ This makes animations appear mid-flight from the start—useful for staggered continuous animations.
126
+
127
+ ---
128
+
129
+ ## 3. Visual Effects
130
+
131
+ ### Shadows Instead of Borders (Jakub)
132
+ In light mode, prefer subtle multi-layer box-shadows over solid borders:
133
+ ```css
134
+ .card {
135
+ box-shadow:
136
+ 0px 0px 0px 1px rgba(0, 0, 0, 0.06),
137
+ 0px 1px 2px -1px rgba(0, 0, 0, 0.06),
138
+ 0px 2px 4px 0px rgba(0, 0, 0, 0.04);
139
+ }
140
+
141
+ /* Slightly darker on hover */
142
+ .card:hover {
143
+ box-shadow:
144
+ 0px 0px 0px 1px rgba(0, 0, 0, 0.08),
145
+ 0px 1px 2px -1px rgba(0, 0, 0, 0.08),
146
+ 0px 2px 4px 0px rgba(0, 0, 0, 0.06);
147
+ }
148
+ ```
149
+
150
+ **Why shadows over borders?**
151
+ - Shadows adapt to any background (images, gradients, varied colors) because they use transparency
152
+ - Borders are solid colors that may clash with dynamic backgrounds
153
+ - Multi-layer shadows create depth; single borders feel flat
154
+ - Shadows can be transitioned smoothly with `transition: box-shadow`
155
+
156
+ **When borders are fine**:
157
+ - Dark mode (shadows less visible anyway)
158
+ - When you need hard edges intentionally
159
+ - Simple interfaces where depth isn't needed
160
+
161
+ ### Gradients & Color Spaces (Jakub)
162
+ - Use `oklch` for gradients to avoid muddy midpoints:
163
+ ```css
164
+ element { background: linear-gradient(in oklch, blue, red); }
165
+ ```
166
+
167
+ - **Color hints** control where the blend midpoint appears (different from color stops)
168
+ - Layer gradients with `background-blend-mode` for unique effects
169
+
170
+ **Why oklch?** It interpolates through perceptually uniform color space, avoiding the gray/muddy zone that sRGB hits when blending complementary colors.
171
+
172
+ ### Blur as a Signal (Jakub)
173
+ Blur (via `filter: blur()`) combined with opacity and translate creates a "materializing" effect. Use blur to signal:
174
+ - **Entering focus**: blur → sharp
175
+ - **Losing relevance**: sharp → blur
176
+ - **State transitions**: blur during, sharp after
177
+
178
+ ---
179
+
180
+ ## 4. Optical Alignment
181
+
182
+ ### Geometric vs. Optical (Jakub)
183
+ > "Sometimes it's necessary to break out of geometric alignment to make things feel visually balanced."
184
+
185
+ **Buttons with icons**: Reduce padding on the icon side so content appears centered:
186
+ ```
187
+ [ Icon Text ] ← Geometric (mathematically centered, feels off)
188
+ [ Icon Text ] ← Optical (visually centered, feels right)
189
+ ```
190
+
191
+ **Play button icons**: The triangle points right, creating visual weight on the left. Shift it slightly right to appear centered.
192
+
193
+ **Icons in general**: Many icon packs account for optical balance, but asymmetric shapes (arrows, play, chevrons) may need manual margin/padding adjustment.
194
+
195
+ **The rule**: If it looks wrong despite being mathematically correct, trust your eyes and adjust.
196
+
197
+ ---
198
+
199
+ ## 5. Icon & State Animations (Jakub)
200
+
201
+ ### Contextual Icon Transitions
202
+ When icons change contextually (copy → check, loading → done), animate:
203
+ - Opacity
204
+ - Scale
205
+ - Blur
206
+
207
+ ```jsx
208
+ <AnimatePresence mode="wait">
209
+ {isCopied ? (
210
+ <motion.div
211
+ initial={{ opacity: 0, scale: 0.8, filter: "blur(4px)" }}
212
+ animate={{ opacity: 1, scale: 1, filter: "blur(0px)" }}
213
+ exit={{ opacity: 0, scale: 0.8, filter: "blur(4px)" }}
214
+ >
215
+ <CheckIcon />
216
+ </motion.div>
217
+ ) : (
218
+ <motion.div ...>
219
+ <CopyIcon />
220
+ </motion.div>
221
+ )}
222
+ </AnimatePresence>
223
+ ```
224
+
225
+ **Why animate icon swaps?** Instant swaps feel jarring and can be missed. Animated transitions:
226
+ - Draw attention to the state change
227
+ - Feel responsive and polished
228
+ - Give the user confidence their action registered
229
+
230
+ ---
231
+
232
+ ## 6. Shared Layout Animations (Jakub)
233
+
234
+ ### FLIP Technique via layoutId
235
+ Motion's `layoutId` prop enables smooth transitions between completely different components:
236
+ ```jsx
237
+ // In one location:
238
+ <motion.div layoutId="card" className="small-card" />
239
+
240
+ // In another location:
241
+ <motion.div layoutId="card" className="large-card" />
242
+ ```
243
+
244
+ Motion automatically animates between them using the FLIP technique (First, Last, Inverse, Play).
245
+
246
+ ### Best Practices
247
+ - Keep elements with `layoutId` **outside** of `AnimatePresence` to avoid conflicts
248
+ - If inside `AnimatePresence`, the initial/exit animations will trigger during layout animation (looks bad with opacity)
249
+ - Multiple elements can animate if each has a unique `layoutId`
250
+ - Works for different heights, widths, positions, and even component types (card → modal)
251
+
252
+ ---
253
+
254
+ ## 7. CSS Custom Properties & @property (Jhey)
255
+
256
+ ### Type Specification Unlocks Animation
257
+ The `@property` rule lets you declare types for CSS variables, enabling smooth interpolation:
258
+
259
+ ```css
260
+ @property --hue {
261
+ initial-value: 0;
262
+ inherits: false;
263
+ syntax: '<number>';
264
+ }
265
+
266
+ @keyframes rainbow {
267
+ to { --hue: 360; }
268
+ }
269
+ ```
270
+
271
+ **Available types**: length, number, percentage, color, angle, time, integer, transform-list
272
+
273
+ **Why this matters**: Without `@property`, CSS sees custom properties as strings. Strings can't interpolate—they just swap. With a declared type, the browser knows how to smoothly transition between values.
274
+
275
+ ### Decompose Complex Transforms
276
+ Instead of animating a monolithic transform (which can't interpolate curved paths), split into typed properties:
277
+
278
+ ```css
279
+ @property --x { syntax: '<percentage>'; initial-value: 0%; inherits: false; }
280
+ @property --y { syntax: '<percentage>'; initial-value: 0%; inherits: false; }
281
+
282
+ .ball {
283
+ transform: translateX(var(--x)) translateY(var(--y));
284
+ animation: throw 1s;
285
+ }
286
+
287
+ @keyframes throw {
288
+ 0% { --x: -500%; }
289
+ 50% { --y: -250%; }
290
+ 100% { --x: 500%; }
291
+ }
292
+ ```
293
+
294
+ This creates curved motion paths that would be impossible with standard transform animation—the ball arcs through space rather than moving in straight lines.
295
+
296
+ ### Scoped Variables for Dynamic Behavior (Jhey)
297
+ CSS custom properties respect scope, enabling powerful patterns:
298
+ ```css
299
+ .item { --delay: 0; animation-delay: calc(var(--delay) * 100ms); }
300
+ .item:nth-child(1) { --delay: 0; }
301
+ .item:nth-child(2) { --delay: 1; }
302
+ .item:nth-child(3) { --delay: 2; }
303
+ ```
304
+
305
+ Use scoped variables to create varied behavior from a single animation definition.
306
+
307
+ ---
308
+
309
+ ## 8. 3D CSS (Jhey)
310
+
311
+ ### Think in Cuboids
312
+ > "Think in cubes instead of boxes" — Jhey Tompkins
313
+
314
+ Complex 3D scenes are assemblies of cube-shaped elements (like LEGO). Decompose any 3D object into cuboids.
315
+
316
+ ### Essential Setup
317
+ ```css
318
+ .scene {
319
+ transform-style: preserve-3d;
320
+ perspective: 1000px;
321
+ }
322
+ ```
323
+
324
+ ### Responsive 3D
325
+ Use CSS variables for dimensions and `vmin` units:
326
+ ```css
327
+ .cube {
328
+ --size: 10vmin;
329
+ width: var(--size);
330
+ height: var(--size);
331
+ }
332
+ ```
333
+
334
+ ---
335
+
336
+ ## 9. Clip-Path Animations (Emil)
337
+
338
+ ### Why clip-path?
339
+ - Hardware-accelerated rendering
340
+ - No layout shifts
341
+ - No additional DOM elements needed
342
+ - Smoother than width/height animations
343
+
344
+ ### Basic Syntax
345
+ ```css
346
+ clip-path: inset(top right bottom left);
347
+ clip-path: circle(radius at x y);
348
+ clip-path: polygon(coordinates);
349
+ ```
350
+
351
+ ### Image Reveal Effect
352
+ ```css
353
+ .reveal {
354
+ clip-path: inset(0 0 100% 0); /* Hidden */
355
+ animation: reveal 1s forwards cubic-bezier(0.77, 0, 0.175, 1);
356
+ }
357
+
358
+ @keyframes reveal {
359
+ to { clip-path: inset(0 0 0 0); } /* Fully visible */
360
+ }
361
+ ```
362
+
363
+ ### Tab Transitions
364
+ Duplicate tab lists with different styling. Animate the overlay's clip-path to reveal only the active tab—creates smooth color transitions without timing issues.
365
+
366
+ ### Scroll-Driven with clip-path
367
+ ```javascript
368
+ const clipPathY = useTransform(scrollYProgress, [0, 1], ["100%", "0%"]);
369
+ const motionClipPath = useMotionTemplate`inset(0 0 ${clipPathY} 0)`;
370
+ ```
371
+
372
+ ### Text Mask Effect
373
+ Stack elements with complementary clip-paths:
374
+ ```css
375
+ .top { clip-path: inset(0 0 50% 0); } /* Shows top half */
376
+ .bottom { clip-path: inset(50% 0 0 0); } /* Shows bottom half */
377
+ ```
378
+ Adjust values on mouse interaction for seamless transitions.
379
+
380
+ ---
381
+
382
+ ## 10. Button & Interactive Feedback (Emil)
383
+
384
+ ### Scale on Press
385
+ Add immediate tactile feedback:
386
+ ```css
387
+ button:active {
388
+ transform: scale(0.97);
389
+ }
390
+ ```
391
+
392
+ ### Don't Animate from scale(0)
393
+ ```jsx
394
+ // BAD: Unnatural motion
395
+ initial={{ scale: 0 }}
396
+
397
+ // GOOD: Natural, gentle motion
398
+ initial={{ scale: 0.9, opacity: 0 }}
399
+ animate={{ scale: 1, opacity: 1 }}
400
+ ```
401
+
402
+ ### Tooltip Delay Pattern
403
+ First tooltip in a group: delay + animation. Subsequent tooltips: instant.
404
+ ```css
405
+ [data-instant] {
406
+ transition-duration: 0ms;
407
+ }
408
+ ```
409
+
410
+ ### Blur as a Bridge
411
+ When state transitions aren't smooth enough, add blur to mask imperfections:
412
+ ```css
413
+ .transitioning {
414
+ filter: blur(2px);
415
+ }
416
+ ```
417
+
418
+ ---
419
+
420
+ ## 11. CSS Transitions vs Keyframes (Emil)
421
+
422
+ ### Interruptibility Problem
423
+ CSS keyframes can't be interrupted mid-animation. When users rapidly trigger actions, elements "jump" to new positions rather than smoothly retargeting.
424
+
425
+ **Solution**: Use CSS transitions with state-driven classes:
426
+ ```jsx
427
+ useEffect(() => {
428
+ setMounted(true);
429
+ }, []);
430
+ ```
431
+
432
+ ```css
433
+ .element {
434
+ transform: translateY(100%);
435
+ transition: transform 400ms ease;
436
+ }
437
+ .element.mounted {
438
+ transform: translateY(0);
439
+ }
440
+ ```
441
+
442
+ ### Direct Style Updates for Performance
443
+ CSS variables cause style recalculation across all children. For frequent updates (drag operations), update styles directly:
444
+
445
+ ```javascript
446
+ // BAD: CSS variable (expensive cascade)
447
+ element.style.setProperty('--drag-y', `${y}px`);
448
+
449
+ // GOOD: Direct style (no cascade)
450
+ element.style.transform = `translateY(${y}px)`;
451
+ ```
452
+
453
+ ### Momentum-Based Dismissal
454
+ Use velocity (distance / time) instead of distance thresholds:
455
+ ```javascript
456
+ const velocity = dragDistance / elapsedTime;
457
+ if (velocity > 0.11) dismiss();
458
+ ```
459
+
460
+ Fast, short gestures should work—users shouldn't need to drag far.
461
+
462
+ ### Damping for Natural Boundaries
463
+ When dragging past boundaries, reduce movement progressively. Things in real life slow down before stopping.
464
+
465
+ ---
466
+
467
+ ## 12. Spring Physics (Emil)
468
+
469
+ ### Key Parameters
470
+ | Parameter | Effect |
471
+ |-----------|--------|
472
+ | **Stiffness** | How quickly spring reaches target (higher = faster) |
473
+ | **Damping** | How quickly oscillations settle (higher = less bounce) |
474
+ | **Mass** | Weight of object (higher = more momentum) |
475
+
476
+ ### Spring for Mouse Position
477
+ ```javascript
478
+ const springConfig = { stiffness: 300, damping: 30 };
479
+ const x = useSpring(mouseX, springConfig);
480
+ const y = useSpring(mouseY, springConfig);
481
+ ```
482
+
483
+ Use `useSpring` for any value that should interpolate smoothly rather than snap—nothing in the real world changes instantly.
484
+
485
+ ### Interruptibility
486
+ Great animations can be interrupted mid-play:
487
+ - Framer Motion supports interruption natively
488
+ - CSS transitions allow smooth interruption before completion
489
+ - Test by clicking rapidly—animations should blend, not queue
490
+
491
+ ---
492
+
493
+ ## 13. Origin-Aware Animations (Emil)
494
+
495
+ Animations should originate from their logical source:
496
+
497
+ ```css
498
+ /* Dropdown from button should expand from button, not center */
499
+ .dropdown {
500
+ transform-origin: top center;
501
+ }
502
+ ```
503
+
504
+ **Component library support:**
505
+ - Base UI: `--transform-origin` CSS variable
506
+ - Radix UI: `--radix-dropdown-menu-content-transform-origin`
507
+
508
+ ---
509
+
510
+ ## 14. Scroll-Driven Animations (Jhey)
511
+
512
+ ### The Core Problem
513
+ Scroll-driven animations are tied to scroll **speed**. If users scroll slowly, animations play slowly. This feels wrong for most UI—you want animations to trigger at a scroll position, not be controlled by scroll speed.
514
+
515
+ ### Duration Control Pattern
516
+ Use two coordinated animations:
517
+ 1. **Trigger animation**: Scroll-driven, toggles a custom property when element enters view
518
+ 2. **Main animation**: Traditional duration-based, activated via Style Query
519
+
520
+ This severs the connection between scroll speed and animation timing—the animation runs over a fixed duration once triggered, regardless of how fast the user scrolled.
521
+
522
+ ### Progressive Enhancement
523
+ Always provide fallbacks:
524
+ ```javascript
525
+ // IntersectionObserver fallback for browsers without scroll-driven animation support
526
+ if (!CSS.supports('animation-timeline', 'scroll()')) {
527
+ // Use IntersectionObserver instead
528
+ }
529
+ ```