tribunal-kit 3.0.0 → 4.0.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 (233) hide show
  1. package/.agent/ARCHITECTURE.md +99 -99
  2. package/.agent/GEMINI.md +52 -52
  3. package/.agent/agents/accessibility-reviewer.md +187 -220
  4. package/.agent/agents/ai-code-reviewer.md +199 -233
  5. package/.agent/agents/backend-specialist.md +215 -238
  6. package/.agent/agents/code-archaeologist.md +161 -181
  7. package/.agent/agents/database-architect.md +184 -207
  8. package/.agent/agents/debugger.md +191 -218
  9. package/.agent/agents/dependency-reviewer.md +103 -136
  10. package/.agent/agents/devops-engineer.md +218 -238
  11. package/.agent/agents/documentation-writer.md +201 -221
  12. package/.agent/agents/explorer-agent.md +160 -180
  13. package/.agent/agents/frontend-reviewer.md +160 -194
  14. package/.agent/agents/frontend-specialist.md +248 -237
  15. package/.agent/agents/game-developer.md +48 -52
  16. package/.agent/agents/logic-reviewer.md +116 -149
  17. package/.agent/agents/mobile-developer.md +200 -223
  18. package/.agent/agents/mobile-reviewer.md +162 -195
  19. package/.agent/agents/orchestrator.md +181 -211
  20. package/.agent/agents/penetration-tester.md +157 -174
  21. package/.agent/agents/performance-optimizer.md +183 -203
  22. package/.agent/agents/performance-reviewer.md +178 -211
  23. package/.agent/agents/precedence-reviewer.md +213 -0
  24. package/.agent/agents/product-manager.md +142 -162
  25. package/.agent/agents/product-owner.md +6 -25
  26. package/.agent/agents/project-planner.md +142 -162
  27. package/.agent/agents/qa-automation-engineer.md +225 -242
  28. package/.agent/agents/security-auditor.md +174 -194
  29. package/.agent/agents/seo-specialist.md +193 -213
  30. package/.agent/agents/sql-reviewer.md +161 -194
  31. package/.agent/agents/supervisor-agent.md +184 -203
  32. package/.agent/agents/swarm-worker-contracts.md +17 -17
  33. package/.agent/agents/swarm-worker-registry.md +46 -46
  34. package/.agent/agents/test-coverage-reviewer.md +160 -193
  35. package/.agent/agents/test-engineer.md +0 -21
  36. package/.agent/agents/type-safety-reviewer.md +175 -208
  37. package/.agent/patterns/generator.md +9 -9
  38. package/.agent/patterns/inversion.md +12 -12
  39. package/.agent/patterns/pipeline.md +9 -9
  40. package/.agent/patterns/reviewer.md +13 -13
  41. package/.agent/patterns/tool-wrapper.md +9 -9
  42. package/.agent/rules/GEMINI.md +63 -63
  43. package/.agent/scripts/append_flow.js +72 -0
  44. package/.agent/scripts/case_law_manager.py +525 -0
  45. package/.agent/scripts/compress_skills.py +167 -0
  46. package/.agent/scripts/consolidate_skills.py +173 -0
  47. package/.agent/scripts/deep_compress.py +202 -0
  48. package/.agent/scripts/minify_context.py +80 -0
  49. package/.agent/scripts/security_scan.py +1 -1
  50. package/.agent/scripts/skill_evolution.py +563 -0
  51. package/.agent/scripts/strip_tribunal.py +41 -0
  52. package/.agent/skills/agent-organizer/SKILL.md +100 -126
  53. package/.agent/skills/agentic-patterns/SKILL.md +0 -70
  54. package/.agent/skills/ai-prompt-injection-defense/SKILL.md +134 -160
  55. package/.agent/skills/api-patterns/SKILL.md +123 -215
  56. package/.agent/skills/api-security-auditor/SKILL.md +143 -177
  57. package/.agent/skills/app-builder/SKILL.md +334 -50
  58. package/.agent/skills/app-builder/templates/SKILL.md +13 -15
  59. package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +16 -16
  60. package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +22 -22
  61. package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +18 -18
  62. package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +20 -20
  63. package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +17 -17
  64. package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +18 -18
  65. package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +21 -21
  66. package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +19 -19
  67. package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +26 -26
  68. package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +26 -26
  69. package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +19 -19
  70. package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +18 -18
  71. package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +20 -20
  72. package/.agent/skills/appflow-wireframe/SKILL.md +95 -121
  73. package/.agent/skills/architecture/SKILL.md +169 -331
  74. package/.agent/skills/authentication-best-practices/SKILL.md +139 -173
  75. package/.agent/skills/bash-linux/SKILL.md +129 -154
  76. package/.agent/skills/behavioral-modes/SKILL.md +8 -69
  77. package/.agent/skills/brainstorming/SKILL.md +436 -104
  78. package/.agent/skills/building-native-ui/SKILL.md +152 -174
  79. package/.agent/skills/clean-code/SKILL.md +331 -360
  80. package/.agent/skills/code-review-checklist/SKILL.md +0 -62
  81. package/.agent/skills/config-validator/SKILL.md +115 -141
  82. package/.agent/skills/csharp-developer/SKILL.md +468 -528
  83. package/.agent/skills/database-design/SKILL.md +104 -369
  84. package/.agent/skills/deployment-procedures/SKILL.md +119 -145
  85. package/.agent/skills/devops-engineer/SKILL.md +295 -332
  86. package/.agent/skills/devops-incident-responder/SKILL.md +87 -113
  87. package/.agent/skills/doc.md +5 -5
  88. package/.agent/skills/documentation-templates/SKILL.md +27 -63
  89. package/.agent/skills/edge-computing/SKILL.md +131 -157
  90. package/.agent/skills/extract-design-system/SKILL.md +108 -134
  91. package/.agent/skills/framer-motion-expert/SKILL.md +111 -855
  92. package/.agent/skills/frontend-design/SKILL.md +151 -499
  93. package/.agent/skills/game-design-expert/SKILL.md +79 -105
  94. package/.agent/skills/game-engineering-expert/SKILL.md +96 -122
  95. package/.agent/skills/geo-fundamentals/SKILL.md +97 -124
  96. package/.agent/skills/github-operations/SKILL.md +279 -314
  97. package/.agent/skills/gsap-expert/SKILL.md +119 -826
  98. package/.agent/skills/i18n-localization/SKILL.md +113 -138
  99. package/.agent/skills/intelligent-routing/SKILL.md +167 -127
  100. package/.agent/skills/lint-and-validate/SKILL.md +16 -52
  101. package/.agent/skills/llm-engineering/SKILL.md +344 -357
  102. package/.agent/skills/local-first/SKILL.md +128 -154
  103. package/.agent/skills/mcp-builder/SKILL.md +92 -118
  104. package/.agent/skills/mobile-design/SKILL.md +213 -219
  105. package/.agent/skills/motion-engineering/SKILL.md +184 -0
  106. package/.agent/skills/nextjs-react-expert/SKILL.md +99 -698
  107. package/.agent/skills/nodejs-best-practices/SKILL.md +498 -559
  108. package/.agent/skills/observability/SKILL.md +293 -330
  109. package/.agent/skills/parallel-agents/SKILL.md +96 -122
  110. package/.agent/skills/performance-profiling/SKILL.md +217 -254
  111. package/.agent/skills/plan-writing/SKILL.md +92 -118
  112. package/.agent/skills/platform-engineer/SKILL.md +97 -123
  113. package/.agent/skills/playwright-best-practices/SKILL.md +137 -162
  114. package/.agent/skills/powershell-windows/SKILL.md +112 -146
  115. package/.agent/skills/project-idioms/SKILL.md +87 -0
  116. package/.agent/skills/python-patterns/SKILL.md +15 -35
  117. package/.agent/skills/python-pro/SKILL.md +148 -754
  118. package/.agent/skills/react-specialist/SKILL.md +123 -827
  119. package/.agent/skills/readme-builder/SKILL.md +23 -85
  120. package/.agent/skills/realtime-patterns/SKILL.md +269 -304
  121. package/.agent/skills/red-team-tactics/SKILL.md +18 -51
  122. package/.agent/skills/rust-pro/SKILL.md +623 -701
  123. package/.agent/skills/seo-fundamentals/SKILL.md +129 -154
  124. package/.agent/skills/server-management/SKILL.md +164 -190
  125. package/.agent/skills/shadcn-ui-expert/SKILL.md +181 -206
  126. package/.agent/skills/skill-creator/SKILL.md +24 -56
  127. package/.agent/skills/sql-pro/SKILL.md +579 -633
  128. package/.agent/skills/supabase-postgres-best-practices/SKILL.md +35 -66
  129. package/.agent/skills/swiftui-expert/SKILL.md +151 -176
  130. package/.agent/skills/systematic-debugging/SKILL.md +92 -118
  131. package/.agent/skills/tailwind-patterns/SKILL.md +516 -576
  132. package/.agent/skills/tdd-workflow/SKILL.md +111 -137
  133. package/.agent/skills/test-result-analyzer/SKILL.md +33 -73
  134. package/.agent/skills/testing-patterns/SKILL.md +512 -573
  135. package/.agent/skills/trend-researcher/SKILL.md +30 -71
  136. package/.agent/skills/ui-ux-pro-max/SKILL.md +8 -41
  137. package/.agent/skills/ui-ux-researcher/SKILL.md +51 -91
  138. package/.agent/skills/vue-expert/SKILL.md +127 -866
  139. package/.agent/skills/vulnerability-scanner/SKILL.md +354 -269
  140. package/.agent/skills/web-accessibility-auditor/SKILL.md +168 -193
  141. package/.agent/skills/web-design-guidelines/SKILL.md +25 -61
  142. package/.agent/skills/webapp-testing/SKILL.md +119 -145
  143. package/.agent/skills/whimsy-injector/SKILL.md +58 -132
  144. package/.agent/skills/workflow-optimizer/SKILL.md +28 -68
  145. package/.agent/workflows/api-tester.md +151 -151
  146. package/.agent/workflows/audit.md +127 -138
  147. package/.agent/workflows/brainstorm.md +110 -110
  148. package/.agent/workflows/changelog.md +112 -112
  149. package/.agent/workflows/create.md +124 -124
  150. package/.agent/workflows/debug.md +165 -189
  151. package/.agent/workflows/deploy.md +180 -189
  152. package/.agent/workflows/enhance.md +128 -151
  153. package/.agent/workflows/fix.md +114 -135
  154. package/.agent/workflows/generate.md +13 -4
  155. package/.agent/workflows/migrate.md +160 -160
  156. package/.agent/workflows/orchestrate.md +168 -168
  157. package/.agent/workflows/performance-benchmarker.md +114 -123
  158. package/.agent/workflows/plan.md +173 -173
  159. package/.agent/workflows/preview.md +80 -80
  160. package/.agent/workflows/refactor.md +161 -183
  161. package/.agent/workflows/review-ai.md +101 -129
  162. package/.agent/workflows/review.md +116 -116
  163. package/.agent/workflows/session.md +94 -94
  164. package/.agent/workflows/status.md +79 -79
  165. package/.agent/workflows/strengthen-skills.md +138 -139
  166. package/.agent/workflows/swarm.md +179 -179
  167. package/.agent/workflows/test.md +189 -211
  168. package/.agent/workflows/tribunal-backend.md +94 -113
  169. package/.agent/workflows/tribunal-database.md +95 -115
  170. package/.agent/workflows/tribunal-frontend.md +96 -118
  171. package/.agent/workflows/tribunal-full.md +93 -133
  172. package/.agent/workflows/tribunal-mobile.md +95 -119
  173. package/.agent/workflows/tribunal-performance.md +110 -133
  174. package/.agent/workflows/ui-ux-pro-max.md +122 -143
  175. package/README.md +30 -1
  176. package/bin/tribunal-kit.js +175 -12
  177. package/package.json +25 -4
  178. package/.agent/skills/api-patterns/api-style.md +0 -42
  179. package/.agent/skills/api-patterns/auth.md +0 -24
  180. package/.agent/skills/api-patterns/documentation.md +0 -26
  181. package/.agent/skills/api-patterns/graphql.md +0 -41
  182. package/.agent/skills/api-patterns/rate-limiting.md +0 -31
  183. package/.agent/skills/api-patterns/response.md +0 -37
  184. package/.agent/skills/api-patterns/rest.md +0 -40
  185. package/.agent/skills/api-patterns/security-testing.md +0 -122
  186. package/.agent/skills/api-patterns/trpc.md +0 -41
  187. package/.agent/skills/api-patterns/versioning.md +0 -22
  188. package/.agent/skills/app-builder/agent-coordination.md +0 -71
  189. package/.agent/skills/app-builder/feature-building.md +0 -53
  190. package/.agent/skills/app-builder/project-detection.md +0 -34
  191. package/.agent/skills/app-builder/scaffolding.md +0 -118
  192. package/.agent/skills/app-builder/tech-stack.md +0 -40
  193. package/.agent/skills/architecture/context-discovery.md +0 -43
  194. package/.agent/skills/architecture/examples.md +0 -94
  195. package/.agent/skills/architecture/pattern-selection.md +0 -68
  196. package/.agent/skills/architecture/patterns-reference.md +0 -50
  197. package/.agent/skills/architecture/trade-off-analysis.md +0 -77
  198. package/.agent/skills/brainstorming/dynamic-questioning.md +0 -360
  199. package/.agent/skills/database-design/database-selection.md +0 -43
  200. package/.agent/skills/database-design/indexing.md +0 -39
  201. package/.agent/skills/database-design/migrations.md +0 -48
  202. package/.agent/skills/database-design/optimization.md +0 -36
  203. package/.agent/skills/database-design/orm-selection.md +0 -30
  204. package/.agent/skills/database-design/schema-design.md +0 -56
  205. package/.agent/skills/frontend-design/animation-guide.md +0 -331
  206. package/.agent/skills/frontend-design/color-system.md +0 -329
  207. package/.agent/skills/frontend-design/decision-trees.md +0 -418
  208. package/.agent/skills/frontend-design/motion-graphics.md +0 -306
  209. package/.agent/skills/frontend-design/typography-system.md +0 -363
  210. package/.agent/skills/frontend-design/ux-psychology.md +0 -1116
  211. package/.agent/skills/frontend-design/visual-effects.md +0 -383
  212. package/.agent/skills/intelligent-routing/router-manifest.md +0 -65
  213. package/.agent/skills/mobile-design/decision-trees.md +0 -516
  214. package/.agent/skills/mobile-design/mobile-backend.md +0 -491
  215. package/.agent/skills/mobile-design/mobile-color-system.md +0 -420
  216. package/.agent/skills/mobile-design/mobile-debugging.md +0 -122
  217. package/.agent/skills/mobile-design/mobile-design-thinking.md +0 -357
  218. package/.agent/skills/mobile-design/mobile-navigation.md +0 -458
  219. package/.agent/skills/mobile-design/mobile-performance.md +0 -767
  220. package/.agent/skills/mobile-design/mobile-testing.md +0 -356
  221. package/.agent/skills/mobile-design/mobile-typography.md +0 -433
  222. package/.agent/skills/mobile-design/platform-android.md +0 -666
  223. package/.agent/skills/mobile-design/platform-ios.md +0 -561
  224. package/.agent/skills/mobile-design/touch-psychology.md +0 -537
  225. package/.agent/skills/nextjs-react-expert/1-async-eliminating-waterfalls.md +0 -312
  226. package/.agent/skills/nextjs-react-expert/2-bundle-bundle-size-optimization.md +0 -240
  227. package/.agent/skills/nextjs-react-expert/3-server-server-side-performance.md +0 -490
  228. package/.agent/skills/nextjs-react-expert/4-client-client-side-data-fetching.md +0 -264
  229. package/.agent/skills/nextjs-react-expert/5-rerender-re-render-optimization.md +0 -581
  230. package/.agent/skills/nextjs-react-expert/6-rendering-rendering-performance.md +0 -432
  231. package/.agent/skills/nextjs-react-expert/7-js-javascript-performance.md +0 -684
  232. package/.agent/skills/nextjs-react-expert/8-advanced-advanced-patterns.md +0 -150
  233. package/.agent/skills/vulnerability-scanner/checklists.md +0 -121
@@ -1,901 +1,194 @@
1
1
  ---
2
2
  name: gsap-expert
3
- description: GreenSock Animation Platform (GSAP 3.12+) mastery. Core tweens, timelines, ScrollTrigger, plugins, gsap.utils, React useGSAP hook, performance optimization, and multi-framework lifecycle cleanup. Use when building scroll-driven animations, complex sequencing, SVG morphing, or any animation beyond CSS capabilities.
3
+ description: GreenSock Animation Platform (GSAP 3.12+) mastery. Core tweens, timelines, ScrollTrigger, ScrollSmoother, plugins, React useGSAP hook, responsive animations, performance. Use when building scroll-driven animations, complex sequencing, SVG morphing, or any animation beyond CSS capabilities.
4
4
  allowed-tools: Read, Write, Edit, Glob, Grep
5
- version: 1.0.0
6
- last-updated: 2026-03-30
7
- applies-to-model: gemini-2.5-pro, claude-3-7-sonnet
5
+ version: 3.2.0
6
+ last-updated: 2026-04-07
7
+ applies-to-model: gemini-3-1-pro, claude-3-7-sonnet
8
8
  ---
9
9
 
10
- # GSAP Expert — GreenSock Animation Platform
10
+ # GSAP Expert — 3.12+ Dense Reference
11
11
 
12
- > GSAP is the professional-grade animation library. It is NOT jQuery `.animate()`.
13
- > Every tween must have a clear purpose, every timeline must clean up, and every ScrollTrigger must call `.kill()` on unmount.
12
+ ## Hallucination Traps (Read First)
13
+ - `gsap.registerPlugin(ScrollTrigger)` optional **REQUIRED** before any use must call before component mounts
14
+ - ❌ `easeInOut`, `Power2.easeOut` (GSAP 2 syntax) → ✅ `"power2.inOut"` (string, GSAP 3)
15
+ - ❌ `raw useEffect` for GSAP in React → ✅ `useGSAP` from `@gsap/react` — handles cleanup automatically
16
+ - ❌ Timeline position as 2nd arg → ✅ position is the **3rd** arg: `tl.to(el, { x: 100 }, "<")`
17
+ - ❌ `markers: true` in production → ✅ Debug only — never ship. `gsap.config({ markers: false })`
18
+ - ❌ Animate `width`, `height`, `top`, `left` → ✅ Only `x`, `y`, `scale`, `rotation`, `opacity` (GPU composited)
19
+ - ❌ 1 ScrollTrigger per list item → ✅ Use `ScrollTrigger.batch()` for lists — 1 battery per N items
20
+ - ❌ `dependencies` option spelled `deps` → ✅ option is `dependencies` (not `deps`)
21
+ - ❌ GSAP in Next.js Server Components → ✅ Always `"use client"` — GSAP is browser-only
14
22
 
15
23
  ---
16
24
 
17
- ## gsap-core — Core API
25
+ ## Core Tweens
18
26
 
19
- ### Tween Methods
27
+ ```javascript
28
+ gsap.to(".box", { x: 100, opacity: 1, duration: 1, ease: "power2.out" });
29
+ gsap.from(".box", { y: -50, opacity: 0, duration: 0.8 });
30
+ gsap.fromTo(".box", { x: -100 }, { x: 0, duration: 1, ease: "expo.out" });
31
+ gsap.set(".box", { transformOrigin: "center center", willChange: "transform" });
20
32
 
21
- ```js
22
- // gsap.to() animate FROM current state TO target
23
- gsap.to(".box", { x: 200, duration: 1, ease: "power2.out" });
24
-
25
- // gsap.from() — animate FROM target TO current state
26
- gsap.from(".box", { opacity: 0, y: 50, duration: 0.8 });
27
-
28
- // gsap.fromTo() — explicit start AND end (most predictable)
29
- gsap.fromTo(".box",
30
- { opacity: 0, y: 30 }, // from
31
- { opacity: 1, y: 0, duration: 1 } // to
32
- );
33
-
34
- // gsap.set() — instant property set, no animation
35
- gsap.set(".box", { transformOrigin: "center center" });
36
- ```
37
-
38
- ### Easing
39
-
40
- GSAP eases follow a `name.type` pattern. The names: `power1`–`power4`, `back`, `bounce`, `elastic`, `circ`, `expo`, `sine`, `steps`.
41
-
42
- ```js
43
- // Types: .in, .out, .inOut
44
- ease: "power3.inOut" // smooth acceleration + deceleration
45
- ease: "back.out(1.7)" // overshoot by 1.7 (default)
46
- ease: "elastic.out(1, 0.3)" // amplitude, period
47
- ease: "steps(5)" // stepped animation (sprite sheets)
48
- ease: "none" // linear
49
-
50
- // ❌ HALLUCINATION TRAP: These do NOT exist in GSAP 3+
51
- // ease: "easeInOut" — jQuery syntax, NOT GSAP
52
- // ease: "Power2.easeOut" — GSAP 2 syntax, DEPRECATED
53
- // ease: "Cubic.easeIn" — GSAP 2 syntax, DEPRECATED
54
- ```
55
-
56
- ### Duration & Stagger
57
-
58
- ```js
59
- // Duration is in seconds (NOT milliseconds like CSS/JS setTimeout)
60
- gsap.to(".items", {
61
- x: 100,
62
- duration: 0.6, // 0.6 seconds
63
- stagger: 0.1, // 0.1s between each element
64
-
65
- // Advanced stagger object
66
- stagger: {
67
- each: 0.1, // time between each
68
- from: "center", // "start", "center", "end", "edges", "random", or index
69
- grid: "auto", // for grid layouts
70
- ease: "power2.in", // ease the stagger distribution itself
71
- amount: 0.8, // total stagger time (alternative to `each`)
72
- }
73
- });
74
- ```
75
-
76
- ### Defaults
77
-
78
- ```js
79
- // Set project-wide defaults — DRY animation config
80
- gsap.defaults({
81
- duration: 0.8,
82
- ease: "power2.out",
83
- overwrite: "auto", // auto-kill conflicting tweens on same target
84
- });
85
-
86
- // Per-tween overrides always win
87
- gsap.to(".box", { x: 100, duration: 1.5 }); // uses 1.5, not 0.8
88
- ```
89
-
90
- ### Callbacks & Control
91
-
92
- ```js
93
- const tween = gsap.to(".box", {
94
- x: 200,
95
- onStart: () => console.log("started"),
96
- onUpdate: (self) => console.log(self.progress()),
97
- onComplete: () => console.log("done"),
98
- onReverseComplete: () => console.log("reversed"),
99
- });
100
-
101
- // Control methods
102
- tween.pause();
103
- tween.resume();
104
- tween.reverse();
105
- tween.seek(0.5); // jump to 0.5 seconds
106
- tween.progress(0.5); // jump to 50%
107
- tween.kill(); // destroy and garbage collect
33
+ // Stagger (multiple elements)
34
+ gsap.from(".item", { opacity: 0, y: 30, stagger: 0.08, ease: "power3.out" });
35
+ gsap.from(".item", { opacity: 0, stagger: { each: 0.1, from: "center", grid: "auto" } });
108
36
  ```
109
37
 
110
38
  ---
111
39
 
112
- ## gsap-timeline — Timelines
113
-
114
- ### Sequencing
115
-
116
- ```js
117
- const tl = gsap.timeline({
118
- defaults: { duration: 0.5, ease: "power2.out" },
119
- onComplete: () => console.log("Sequence done"),
120
- });
121
-
122
- tl.to(".title", { opacity: 1, y: 0 })
123
- .to(".subtitle", { opacity: 1, y: 0 }) // plays AFTER .title
124
- .to(".cta", { scale: 1, opacity: 1 }); // plays AFTER .subtitle
125
- ```
126
-
127
- ### Position Parameter (Critical Concept)
40
+ ## Timelines
128
41
 
129
- The position parameter is the **most powerful** sequencing tool in GSAP. It controls *when* a child animation starts relative to the timeline.
42
+ ```javascript
43
+ const tl = gsap.timeline({ defaults: { ease: "power2.out", duration: 0.6 } });
130
44
 
131
- ```js
132
- tl.to(".a", { x: 100 })
133
- .to(".b", { x: 100 }, "<") // "<" = same start time as previous
134
- .to(".c", { x: 100 }, ">") // ">" = after previous ends (default)
135
- .to(".d", { x: 100 }, "-=0.3") // 0.3s before previous ends (overlap)
136
- .to(".e", { x: 100 }, "+=0.5") // 0.5s after previous ends (gap)
137
- .to(".f", { x: 100 }, 2) // absolute: at exactly 2 seconds
138
- .to(".g", { x: 100 }, "<0.2") // 0.2s after previous animation's START
139
- .to(".h", { x: 100 }, ">-0.1"); // 0.1s before previous animation's END
45
+ tl.from(".hero-title", { y: 60, opacity: 0 })
46
+ .from(".hero-sub", { y: 40, opacity: 0 }, "-=0.4") // overlap 0.4s
47
+ .from(".hero-cta", { scale: 0.9, opacity: 0 }, "<0.1") // 0.1s after prev starts
48
+ .to(".hero-img", { x: 0, opacity: 1 }, 0.3); // absolute 0.3s into tl
140
49
 
141
- // HALLUCINATION TRAP: Position parameter is the 3rd argument, NOT a property
142
- // WRONG: tl.to(".a", { x: 100, position: "<" })
143
- // RIGHT: tl.to(".a", { x: 100 }, "<")
144
- ```
145
-
146
- ### Labels
50
+ // Position symbols:
51
+ // "<" same start time as previous tween
52
+ // ">" after previous ends
53
+ // "-=0.5" → 0.5s before previous ends (overlap)
54
+ // "+=0.5" → 0.5s after previous ends (gap)
55
+ // "2" → absolute 2s from timeline start
147
56
 
148
- ```js
149
- tl.addLabel("intro")
150
- .to(".title", { opacity: 1 })
151
- .addLabel("middle")
152
- .to(".content", { opacity: 1 })
153
- .to(".sidebar", { x: 0 }, "middle") // starts at the "middle" label
154
- .to(".footer", { y: 0 }, "middle+=0.3"); // 0.3s after the "middle" label
155
- ```
156
-
157
- ### Nesting Timelines
158
-
159
- ```js
160
- function introAnimation() {
161
- const tl = gsap.timeline();
162
- tl.from(".hero-title", { y: 60, opacity: 0 })
163
- .from(".hero-sub", { y: 40, opacity: 0 }, "-=0.3");
164
- return tl;
165
- }
166
-
167
- function contentAnimation() {
168
- const tl = gsap.timeline();
169
- tl.from(".card", { y: 80, opacity: 0, stagger: 0.15 });
170
- return tl;
171
- }
172
-
173
- // Master timeline nests sub-timelines
174
- const master = gsap.timeline();
175
- master
176
- .add(introAnimation())
177
- .add(contentAnimation(), "-=0.4"); // overlap by 0.4s
178
- ```
179
-
180
- ### Playback Control
181
-
182
- ```js
183
- const tl = gsap.timeline({ paused: true, repeat: -1, yoyo: true });
184
-
185
- tl.play();
186
- tl.pause();
187
- tl.reverse();
188
- tl.restart();
189
- tl.timeScale(2); // 2× speed
190
- tl.seek("middle"); // jump to label
191
- tl.totalProgress(); // 0–1 across all repeats
57
+ // Runtime control
58
+ tl.play(); tl.pause(); tl.reverse(); tl.seek(1.5); tl.timeScale(2); // 2x speed
192
59
  ```
193
60
 
194
61
  ---
195
62
 
196
- ## gsap-scrolltrigger — ScrollTrigger
197
-
198
- ### Registration (Required)
63
+ ## ScrollTrigger
199
64
 
200
- ```js
65
+ ```javascript
201
66
  import { gsap } from "gsap";
202
67
  import { ScrollTrigger } from "gsap/ScrollTrigger";
68
+ gsap.registerPlugin(ScrollTrigger); // REQUIRED — call once at module level
203
69
 
204
- gsap.registerPlugin(ScrollTrigger);
205
-
206
- // ❌ HALLUCINATION TRAP: ScrollTrigger MUST be registered before use
207
- // Forgetting gsap.registerPlugin() is the #1 GSAP bug in AI-generated code
208
- ```
209
-
210
- ### Basic Scroll-Linked Animation
211
-
212
- ```js
213
- gsap.to(".parallax-bg", {
214
- y: -200,
70
+ // Basic scroll-triggered animation
71
+ gsap.from(".section", {
215
72
  scrollTrigger: {
216
- trigger: ".hero-section", // element that triggers
217
- start: "top bottom", // "triggerPoint viewportPoint"
218
- end: "bottom top", // when to stop
219
- scrub: true, // links animation progress to scroll position
220
- markers: true, // DEBUG ONLY remove in production
221
- }
222
- });
223
- ```
224
-
225
- ### Start / End Syntax
226
-
227
- ```
228
- start: "top center" // trigger's top hits viewport's center
229
- start: "top 80%" // trigger's top hits 80% from viewport top
230
- start: "top top" // trigger's top hits viewport's top
231
- start: "center center" // trigger's center hits viewport's center
232
- start: "top bottom-=100" // 100px before trigger's top hits viewport's bottom
233
- ```
234
-
235
- ### Pinning
236
-
237
- ```js
238
- ScrollTrigger.create({
239
- trigger: ".sticky-section",
240
- start: "top top",
241
- end: "+=1000", // pin for 1000px of scrolling
242
- pin: true, // locks element in place
243
- pinSpacing: true, // adds equivalent space below (default: true)
244
- anticipatePin: 1, // reduces jank — pre-calculates pin
245
- });
246
- ```
247
-
248
- ### Scrub
249
-
250
- ```js
251
- // scrub: true — instant scrub (direct 1:1 with scroll)
252
- // scrub: 0.5 — smoothed scrub (0.5 second lag behind scroll position)
253
- // scrub: 3 — heavy smoothing (3 second catch-up, cinematic feel)
254
-
255
- gsap.to(".progress-bar", {
256
- scaleX: 1,
257
- scrollTrigger: {
258
- trigger: ".article",
259
- start: "top top",
260
- end: "bottom bottom",
261
- scrub: 0.3,
262
- }
263
- });
264
- ```
265
-
266
- ### Refresh & Cleanup (Critical)
267
-
268
- ```js
269
- // Force recalculation after DOM changes (images loaded, content injected)
270
- ScrollTrigger.refresh();
271
-
272
- // Batch refresh after many DOM mutations
273
- ScrollTrigger.refresh(true); // "safe" mode — deferred to next tick
274
-
275
- // Kill ALL ScrollTriggers (page transitions, SPA navigation)
276
- ScrollTrigger.killAll();
277
-
278
- // Kill a specific instance
279
- const st = ScrollTrigger.create({ /* ... */ });
280
- st.kill();
281
-
282
- // ❌ HALLUCINATION TRAP: Failing to kill ScrollTriggers on unmount
283
- // causes memory leaks, zombie listeners, and broken scroll behavior
284
- // in SPAs (Next.js, Nuxt, SvelteKit, Remix)
285
- ```
286
-
287
- ### Callbacks
288
-
289
- ```js
290
- ScrollTrigger.create({
291
- trigger: ".section",
292
- start: "top center",
293
- end: "bottom center",
294
- onEnter: () => console.log("entered from above"),
295
- onLeave: () => console.log("left going down"),
296
- onEnterBack: () => console.log("entered from below"),
297
- onLeaveBack: () => console.log("left going up"),
298
- onToggle: (self) => console.log("active:", self.isActive),
299
- onUpdate: (self) => console.log("progress:", self.progress),
300
- onRefresh: (self) => console.log("recalculated"),
301
- });
302
- ```
303
-
304
- ---
305
-
306
- ## gsap-plugins — Plugin Ecosystem
307
-
308
- ### Registration Pattern (All Plugins)
309
-
310
- ```js
311
- import { gsap } from "gsap";
312
- import { Flip } from "gsap/Flip";
313
- import { Draggable } from "gsap/Draggable";
314
- import { ScrollToPlugin } from "gsap/ScrollToPlugin";
315
-
316
- gsap.registerPlugin(Flip, Draggable, ScrollToPlugin);
317
-
318
- // ❌ HALLUCINATION TRAP: Every plugin MUST be registered
319
- // ❌ HALLUCINATION TRAP: Some plugins require a GSAP Club license
320
- // (ScrollSmoother, SplitText, Inertia, ScrambleText, MorphSVG, DrawSVG,
321
- // MotionPath, Physics2D, PhysicsProps, CustomBounce, CustomWiggle)
322
- // Free plugins: ScrollTrigger, Flip, Draggable, ScrollToPlugin, Observer,
323
- // TextPlugin, MotionPathPlugin, EasePack, CustomEase, GSDevTools (trial)
324
- ```
325
-
326
- ### Flip Plugin (FLIP Technique)
327
-
328
- ```js
329
- // 1. Capture current state
330
- const state = Flip.getState(".cards");
331
-
332
- // 2. Make DOM change (reparent, reclass, reorder)
333
- container.classList.toggle("grid-layout");
334
-
335
- // 3. Animate from old state to new state
336
- Flip.from(state, {
337
- duration: 0.6,
338
- ease: "power2.inOut",
339
- stagger: 0.05,
340
- absolute: true, // uses position:absolute during animation
341
- onComplete: () => console.log("Flip done"),
342
- });
343
- ```
344
-
345
- ### Draggable
346
-
347
- ```js
348
- Draggable.create(".slider-handle", {
349
- type: "x", // "x", "y", "x,y", "rotation"
350
- bounds: ".slider-track", // constrain to parent
351
- inertia: true, // requires InertiaPlugin (Club)
352
- edgeResistance: 0.65, // resistance at bounds edges
353
- onDrag: function () {
354
- console.log("x:", this.x); // `this` = Draggable instance
73
+ trigger: ".section",
74
+ start: "top 80%", // "triggerEdge viewportEdge"
75
+ end: "bottom 20%",
76
+ scrub: 1, // smooth scrubbing (seconds to catch up) | true = instant
77
+ pin: true, // pin element during scroll
78
+ anticipatePin: 1, // prevents jump on pin
79
+ markers: false, // NEVER true in production
355
80
  },
356
- onDragEnd: function () {
357
- console.log("endX:", this.endX); // projected landing position
358
- },
359
- snap: {
360
- x: (val) => Math.round(val / 50) * 50, // snap to 50px grid
361
- },
362
- });
363
- ```
364
-
365
- ### ScrollToPlugin
366
-
367
- ```js
368
- gsap.to(window, {
369
- duration: 1,
370
- scrollTo: { y: "#section-3", offsetY: 80 },
371
- ease: "power2.inOut",
81
+ y: 100, opacity: 0,
372
82
  });
373
83
 
374
- // Horizontal scroll-to
375
- gsap.to(".container", {
376
- scrollTo: { x: 500 },
377
- duration: 0.8,
378
- });
379
- ```
380
-
381
- ### ScrollSmoother (Club GreenSock)
382
-
383
- ```js
384
- // ⚠️ Club GreenSock plugin — requires license
385
- import { ScrollSmoother } from "gsap/ScrollSmoother";
386
-
387
- // HTML structure required:
388
- // <div id="smooth-wrapper">
389
- // <div id="smooth-content"> ...page... </div>
390
- // </div>
391
-
392
- const smoother = ScrollSmoother.create({
393
- wrapper: "#smooth-wrapper",
394
- content: "#smooth-content",
395
- smooth: 1.5, // seconds of smoothing
396
- effects: true, // enables data-speed and data-lag
397
- normalizeScroll: true, // prevents mobile address bar jank
398
- });
399
- ```
400
-
401
- ### Observer
402
-
403
- ```js
404
- import { Observer } from "gsap/Observer";
405
-
406
- Observer.create({
407
- target: window,
408
- type: "wheel,touch,pointer",
409
- onUp: () => goToNextSlide(),
410
- onDown: () => goToPrevSlide(),
411
- tolerance: 10, // pixel threshold before firing
412
- preventDefault: true,
413
- wheelSpeed: -1, // invert wheel direction
414
- });
415
- ```
416
-
417
- ### SplitText (Club GreenSock)
418
-
419
- ```js
420
- // ⚠️ Club GreenSock plugin — requires license
421
- import { SplitText } from "gsap/SplitText";
422
-
423
- const split = new SplitText(".hero-heading", {
424
- type: "chars,words,lines",
425
- linesClass: "split-line",
84
+ // Batch — for lists (1 ST instance per group, not per item)
85
+ ScrollTrigger.batch(".card", {
86
+ onEnter: (elements) => gsap.from(elements, { opacity: 0, y: 40, stagger: 0.08 }),
87
+ start: "top 85%",
426
88
  });
427
89
 
428
- gsap.from(split.chars, {
429
- opacity: 0,
430
- y: 20,
431
- rotateX: -60,
432
- stagger: 0.02,
433
- duration: 0.6,
434
- ease: "back.out(1.7)",
435
- onComplete: () => split.revert(), // CLEANUP — restore original DOM
90
+ // Pin + scrub storytelling
91
+ const tl = gsap.timeline({
92
+ scrollTrigger: { trigger: ".scene", pin: true, scrub: true, end: "+=3000" }
436
93
  });
94
+ tl.from(".layer-1", { x: -200 }).from(".layer-2", { x: 200 }, "<");
437
95
 
438
- // HALLUCINATION TRAP: Always call split.revert() when done
439
- // Leaving split DOM nodes causes accessibility and SEO issues
440
- ```
441
-
442
- ### CustomEase
443
-
444
- ```js
445
- import { CustomEase } from "gsap/CustomEase";
446
-
447
- CustomEase.create("myBounce", "M0,0 C0.14,0 0.27,0.58 0.32,0.82 ...");
448
- gsap.to(".box", { x: 300, ease: "myBounce" });
449
- ```
450
-
451
- ### GSDevTools
452
-
453
- ```js
454
- // Debug timeline visually — NEVER ship to production
455
- import { GSDevTools } from "gsap/GSDevTools";
456
-
457
- GSDevTools.create({ animation: masterTimeline });
458
- ```
459
-
460
- ---
461
-
462
- ## gsap-utils — Utility Functions
463
-
464
- ```js
465
- // clamp — constrain a value between min and max
466
- gsap.utils.clamp(0, 100, 150); // 100
467
-
468
- // mapRange — remap value from one range to another
469
- gsap.utils.mapRange(0, 100, 0, 1, 50); // 0.5
470
-
471
- // normalize — convert a value in a range to 0–1
472
- gsap.utils.normalize(0, 500, 250); // 0.5
473
-
474
- // interpolate — blend between values
475
- gsap.utils.interpolate(0, 100, 0.75); // 75
476
- gsap.utils.interpolate("red", "blue", 0.5); // blends colors
477
- gsap.utils.interpolate({ x: 0 }, { x: 100 }, 0.5); // { x: 50 }
478
-
479
- // random — random value (can be snapped)
480
- gsap.utils.random(0, 100); // float
481
- gsap.utils.random(0, 100, 5); // snapped to nearest 5
482
- gsap.utils.random([10, 20, 30]); // pick from array
483
-
484
- // snap — snap value to nearest increment or array value
485
- gsap.utils.snap(10, 23); // 20
486
- gsap.utils.snap([0, 50, 100], 38); // 50
487
-
488
- // toArray — convert selector/NodeList to a real array (safe)
489
- const boxes = gsap.utils.toArray(".box"); // always returns an Array
490
-
491
- // selector — scoped querySelector factory
492
- const q = gsap.utils.selector(myRef);
493
- gsap.to(q(".title"), { opacity: 1 }); // only searches within myRef
494
-
495
- // wrap — wrap index around an array
496
- const colors = ["red", "green", "blue"];
497
- gsap.utils.wrap(colors, 5); // "blue" (wraps around)
498
-
499
- // pipe — compose multiple utility functions
500
- const clampAndRound = gsap.utils.pipe(
501
- gsap.utils.clamp(0, 100),
502
- Math.round
503
- );
504
- clampAndRound(125.7); // 100
96
+ // Cleanup MANDATORY on SPA route unmount
97
+ ScrollTrigger.killAll(); // in component cleanup / router onChange
505
98
  ```
506
99
 
507
100
  ---
508
101
 
509
- ## gsap-react — React Integration
510
-
511
- ### The `useGSAP` Hook (Official)
102
+ ## React Integration (`useGSAP`)
512
103
 
513
- ```jsx
104
+ ```tsx
514
105
  import { useGSAP } from "@gsap/react";
515
106
  import { gsap } from "gsap";
107
+ import { ScrollTrigger } from "gsap/ScrollTrigger";
108
+ import { useRef } from "react";
516
109
 
517
- // HALLUCINATION TRAP: Do NOT use raw useEffect for GSAP in React
518
- // useEffect does not scope selectors, does not auto-cleanup, and causes
519
- // double-animation bugs in React 18+ Strict Mode
110
+ gsap.registerPlugin(ScrollTrigger); // once, outside component
520
111
 
521
- function HeroSection() {
522
- const containerRef = useRef(null);
112
+ export function HeroSection() {
113
+ const container = useRef<HTMLDivElement>(null);
523
114
 
524
115
  useGSAP(() => {
525
- // All selectors are automatically scoped to containerRef
116
+ // All GSAP code here is automatically scoped & cleaned up
526
117
  gsap.from(".hero-title", { y: 60, opacity: 0, duration: 0.8 });
527
- gsap.from(".hero-sub", { y: 40, opacity: 0, duration: 0.6, delay: 0.3 });
528
- }, { scope: containerRef }); // scope = auto querySelector boundary
529
-
530
- return (
531
- <div ref={containerRef}>
532
- <h1 className="hero-title">Welcome</h1>
533
- <p className="hero-sub">Subtitle</p>
534
- </div>
535
- );
536
- }
537
- ```
538
-
539
- ### Dependency Array (Re-running Animations)
540
-
541
- ```jsx
542
- useGSAP(() => {
543
- gsap.to(".counter", { innerText: count, snap: { innerText: 1 } });
544
- }, { dependencies: [count], scope: containerRef });
545
-
546
- // ❌ HALLUCINATION TRAP: The option is called `dependencies`, NOT `deps`
547
- ```
548
118
 
549
- ### Manual Context (Without useGSAP)
550
-
551
- ```jsx
552
- useEffect(() => {
553
- const ctx = gsap.context(() => {
554
- gsap.from(".box", { x: -100, opacity: 0 });
555
- }, containerRef); // scope
556
-
557
- return () => ctx.revert(); // CLEANUP — kills all tweens and ScrollTriggers
558
- }, []);
559
-
560
- // gsap.context() is GSAP's own cleanup mechanism
561
- // ctx.revert() kills every tween and ScrollTrigger created inside it
562
- ```
563
-
564
- ### Refs vs. Selectors
565
-
566
- ```jsx
567
- // ✅ Preferred: useRef + scope
568
- const boxRef = useRef(null);
569
- useGSAP(() => {
570
- gsap.to(boxRef.current, { x: 100 });
571
- }, { scope: containerRef });
572
-
573
- // ✅ Also fine: class selectors when scoped
574
- useGSAP(() => {
575
- gsap.to(".box", { x: 100 }); // scoped to containerRef
576
- }, { scope: containerRef });
577
-
578
- // ❌ BAD: Global selectors without scope
579
- useGSAP(() => {
580
- gsap.to(".box", { x: 100 }); // matches ALL .box elements globally
581
- });
582
- ```
119
+ gsap.from(".hero-card", {
120
+ scrollTrigger: { trigger: ".hero-card", start: "top 80%" },
121
+ y: 40, opacity: 0, stagger: 0.1,
122
+ });
123
+ }, { scope: container, dependencies: [] }); // re-runs when dependencies change
583
124
 
584
- ### SSR / Next.js Considerations
125
+ return <div ref={container}><h1 className="hero-title">...</h1></div>;
126
+ }
585
127
 
586
- ```jsx
587
- // Animations must only run on the client
128
+ // With cleanup for dynamic content:
588
129
  useGSAP(() => {
589
- // This hook already handles client-only execution
590
- gsap.from(".element", { opacity: 0 });
591
- }, { scope: containerRef });
592
-
593
- // For dynamic imports in Next.js (App Router)
594
- "use client"; // ← required at top of component file
595
-
596
- // ❌ HALLUCINATION TRAP: Do NOT import GSAP in server components
597
- // GSAP requires `window` and `document` — it will crash on the server
598
- ```
599
-
600
- ---
601
-
602
- ## gsap-performance — Performance Optimization
603
-
604
- ### Transforms Over Layout Properties (Critical)
605
-
606
- ```js
607
- // ✅ GPU-accelerated (composited — no layout recalculation)
608
- gsap.to(".box", { x: 100, y: 50, rotation: 45, scale: 1.2, opacity: 0.5 });
609
-
610
- // ❌ TRIGGERS LAYOUT REFLOW (expensive — avoid animating these)
611
- gsap.to(".box", { width: 200, height: 100, top: 50, left: 100, padding: 20 });
612
-
613
- // ❌ HALLUCINATION TRAP: AI often generates `{ left: 100 }` instead of `{ x: 100 }`
614
- // x/y use CSS transform: translate(), which is GPU-composited
615
- // left/top trigger layout recalculation on every frame = jank
616
- ```
617
-
618
- ### `will-change` Management
619
-
620
- ```js
621
- // GSAP auto-applies will-change: transform during animation
622
- // Do NOT manually add will-change to many elements — it wastes GPU memory
623
-
624
- // For known long-running animations, apply manually and remove after:
625
- gsap.set(".persistent-animation", { willChange: "transform" });
626
- // ... animation runs ...
627
- gsap.set(".persistent-animation", { willChange: "auto" }); // release GPU memory
628
- ```
629
-
630
- ### Batching & `gsap.ticker`
631
-
632
- ```js
633
- // Use gsap.ticker instead of requestAnimationFrame for sync
634
- gsap.ticker.add((time, deltaTime, frame) => {
635
- // Runs in sync with GSAP's internal RAF loop
636
- // Use for particle systems, canvas drawing, etc.
637
- });
638
-
639
- // Throttle ticker to 30fps (for low-power devices)
640
- gsap.ticker.fps(30);
641
-
642
- // Lazy rendering (default: true) — GSAP batches reads/writes
643
- // Only disable if you need synchronous layout reads mid-animation
644
- gsap.ticker.lagSmoothing(500, 33); // smooth large frame drops
645
- ```
646
-
647
- ### ScrollTrigger Performance
648
-
649
- ```js
650
- // ❌ BAD: One ScrollTrigger per item in a long list
651
- document.querySelectorAll(".item").forEach(item => {
652
- ScrollTrigger.create({ trigger: item, /* ... */ }); // 100+ instances = jank
653
- });
654
-
655
- // ✅ BETTER: Use ScrollTrigger.batch()
656
- ScrollTrigger.batch(".item", {
657
- onEnter: (elements) => {
658
- gsap.from(elements, { opacity: 0, y: 50, stagger: 0.1 });
659
- },
660
- onLeave: (elements) => {
661
- gsap.to(elements, { opacity: 0 });
662
- },
663
- });
664
-
665
- // ❌ HALLUCINATION TRAP: Never use `markers: true` in production
666
- // It injects visible debug DOM elements
667
- ```
668
-
669
- ### Overwrite Modes
670
-
671
- ```js
672
- // Prevent conflicting tweens from stacking
673
- gsap.to(".box", { x: 100, overwrite: "auto" });
674
-
675
- // Modes:
676
- // "auto" — kill only conflicting properties on same target (recommended)
677
- // true — kill ALL tweens on same target
678
- // false — allow stacking (default, can cause jank)
130
+ const ctx = gsap.context(() => {
131
+ gsap.from(".item", { opacity: 0, stagger: 0.05 });
132
+ }, container);
133
+ return () => ctx.revert(); // explicit cleanup if needed beyond useGSAP scope
134
+ }, { scope: container, dependencies: [items] });
679
135
  ```
680
136
 
681
137
  ---
682
138
 
683
- ## gsap-frameworks Vue, Svelte & Framework Lifecycle
684
-
685
- ### Vue 3 (Composition API)
686
-
687
- ```vue
688
- <script setup>
689
- import { ref, onMounted, onUnmounted } from "vue";
690
- import { gsap } from "gsap";
691
- import { ScrollTrigger } from "gsap/ScrollTrigger";
692
-
693
- gsap.registerPlugin(ScrollTrigger);
139
+ ## Responsive Animations (`gsap.matchMedia`)
694
140
 
695
- const containerRef = ref(null);
696
- let ctx;
141
+ ```javascript
142
+ // Replaces window.matchMedia listeners + resize handlers
143
+ const mm = gsap.matchMedia();
697
144
 
698
- onMounted(() => {
699
- ctx = gsap.context(() => {
700
- gsap.from(".box", {
701
- y: 60, opacity: 0, duration: 0.8,
702
- scrollTrigger: { trigger: ".box", start: "top 80%" },
703
- });
704
- }, containerRef.value); // scope to component root
145
+ mm.add("(min-width: 768px)", () => {
146
+ gsap.to(".sidebar", { x: 0, duration: 0.5 });
147
+ // Return cleanup function
148
+ return () => gsap.set(".sidebar", { x: -300 });
705
149
  });
706
150
 
707
- onUnmounted(() => {
708
- ctx.revert(); // CRITICAL: kills all tweens + ScrollTriggers
151
+ mm.add("(max-width: 767px)", () => {
152
+ gsap.to(".mobile-menu", { y: 0, duration: 0.4 });
709
153
  });
710
- </script>
711
-
712
- <template>
713
- <div ref="containerRef">
714
- <div class="box">Animated</div>
715
- </div>
716
- </template>
717
- ```
718
-
719
- ### Svelte
720
154
 
721
- ```svelte
722
- <script>
723
- import { onMount, onDestroy } from "svelte";
724
- import { gsap } from "gsap";
725
- import { ScrollTrigger } from "gsap/ScrollTrigger";
726
-
727
- gsap.registerPlugin(ScrollTrigger);
728
-
729
- let container;
730
- let ctx;
731
-
732
- onMount(() => {
733
- ctx = gsap.context(() => {
734
- gsap.from(".box", { y: 60, opacity: 0, duration: 0.8 });
735
- }, container);
155
+ // In React — use inside useGSAP
156
+ useGSAP(() => {
157
+ const mm = gsap.matchMedia();
158
+ mm.add("(prefers-reduced-motion: no-preference)", () => {
159
+ gsap.from(".hero", { y: 100, duration: 1 });
736
160
  });
737
-
738
- onDestroy(() => {
739
- ctx?.revert(); // cleanup on component destroy
161
+ mm.add("(prefers-reduced-motion: reduce)", () => {
162
+ gsap.set(".hero", { opacity: 1 }); // instant, no animation
740
163
  });
741
- </script>
742
-
743
- <div bind:this={container}>
744
- <div class="box">Animated</div>
745
- </div>
746
- ```
747
-
748
- ### Universal Cleanup Rules
749
-
750
- ```
751
- ✅ ALWAYS use gsap.context() in framework components
752
- ✅ ALWAYS call ctx.revert() on unmount/destroy/cleanup
753
- ✅ ALWAYS call ScrollTrigger.kill() or .killAll() on route changes (SPA)
754
- ✅ ALWAYS scope selectors to the component root
755
-
756
- ❌ NEVER leave orphaned ScrollTriggers after navigation
757
- ❌ NEVER use global selectors without scoping in component frameworks
758
- ❌ NEVER forget to revert SplitText instances (corrupts DOM)
759
- ```
760
-
761
- ---
762
-
763
- ## Common Animation Patterns
764
-
765
- ### Fade-In On Scroll (Batch)
766
-
767
- ```js
768
- ScrollTrigger.batch(".fade-in", {
769
- onEnter: (elements) => {
770
- gsap.fromTo(elements,
771
- { opacity: 0, y: 40 },
772
- { opacity: 1, y: 0, duration: 0.6, stagger: 0.1, ease: "power2.out" }
773
- );
774
- },
775
- start: "top 85%",
776
- });
777
- ```
778
-
779
- ### Horizontal Scroll Section
780
-
781
- ```js
782
- const sections = gsap.utils.toArray(".panel");
783
-
784
- gsap.to(sections, {
785
- xPercent: -100 * (sections.length - 1),
786
- ease: "none",
787
- scrollTrigger: {
788
- trigger: ".horizontal-container",
789
- pin: true,
790
- scrub: 1,
791
- snap: 1 / (sections.length - 1),
792
- end: () => "+=" + document.querySelector(".horizontal-container").offsetWidth,
793
- },
794
- });
795
- ```
796
-
797
- ### Magnetic Button
798
-
799
- ```js
800
- const btn = document.querySelector(".magnetic-btn");
801
-
802
- btn.addEventListener("mousemove", (e) => {
803
- const { left, top, width, height } = btn.getBoundingClientRect();
804
- const x = (e.clientX - left - width / 2) * 0.3;
805
- const y = (e.clientY - top - height / 2) * 0.3;
806
- gsap.to(btn, { x, y, duration: 0.3, ease: "power2.out" });
807
- });
808
-
809
- btn.addEventListener("mouseleave", () => {
810
- gsap.to(btn, { x: 0, y: 0, duration: 0.5, ease: "elastic.out(1, 0.3)" });
811
- });
812
- ```
813
-
814
- ### Counter / Number Ticker
815
-
816
- ```js
817
- const obj = { val: 0 };
818
- gsap.to(obj, {
819
- val: 12847,
820
- duration: 2,
821
- ease: "power1.out",
822
- snap: { val: 1 },
823
- onUpdate: () => {
824
- document.querySelector(".counter").textContent = obj.val.toLocaleString();
825
- },
826
164
  });
827
165
  ```
828
166
 
829
167
  ---
830
168
 
831
- ## Output Format
169
+ ## Plugin Reference
832
170
 
833
- When this skill produces or reviews code, structure your output as follows:
834
-
835
- ```
836
- ━━━ GSAP Expert Report ━━━━━━━━━━━━━━━━━━━━━━━━
837
- Skill: GSAP Expert
838
- GSAP Version: 3.12+
839
- Scope: [N files · N animations]
840
- ─────────────────────────────────────────────────
841
- Passed: [checks that passed, or "All clean"]
842
- ⚠️ Warnings: [non-blocking issues, or "None"]
843
- ❌ Blocked: [blocking issues requiring fix, or "None"]
844
- ─────────────────────────────────────────────────
845
- VBC status: PENDING → VERIFIED
846
- Evidence: [test output / lint pass / compile success]
847
- ```
848
-
849
- **VBC (Verification-Before-Completion) is mandatory.**
850
- Do not mark status as VERIFIED until concrete terminal evidence is provided.
171
+ | Plugin | Use For | Registration |
172
+ |--------|---------|-------------|
173
+ | `ScrollTrigger` | Scroll-driven animations | `gsap.registerPlugin(ScrollTrigger)` |
174
+ | `ScrollSmoother` | Smooth native scroll momentum | Requires `ScrollTrigger` + Club GSAP |
175
+ | `Flip` | Stateful layout morphing (FLIP technique) | `gsap.registerPlugin(Flip)` |
176
+ | `Draggable` | Interactive drag/sort/resize | `gsap.registerPlugin(Draggable)` |
177
+ | `SplitText` | Character/word/line text splits | Call `.revert()` after use to prevent SEO damage |
178
+ | `DrawSVG` | SVG stroke-dasharray animations | Club GSAP |
179
+ | `MorphSVG` | SVG path morphing | Club GSAP |
180
+ | `ScrollToPlugin` | Programmatic scroll-to | `gsap.registerPlugin(ScrollToPlugin)` |
851
181
 
852
182
  ---
853
183
 
854
- ## 🤖 LLM-Specific Traps
855
-
856
- AI coding assistants often fall into specific bad habits when generating GSAP code. These are strictly forbidden:
857
-
858
- 1. **GSAP v2 Syntax:** Using `TweenMax`, `TweenLite`, `TimelineMax`, `TimelineLite`, `Power2.easeOut`, or `CSSPlugin`. These are ALL deprecated in GSAP 3+. The correct API is `gsap.to()`, `gsap.timeline()`, and `ease: "power2.out"`.
859
- 2. **Missing Plugin Registration:** Every GSAP plugin MUST be registered with `gsap.registerPlugin()` before use. This includes ScrollTrigger, Flip, Draggable, etc.
860
- 3. **Missing Cleanup:** Every `gsap.context()` must have a corresponding `.revert()` on unmount. Every `ScrollTrigger` must be `.kill()`ed. Orphaned animations cause memory leaks.
861
- 4. **Layout Props Instead of Transforms:** Animating `width`, `height`, `top`, `left`, `margin`, `padding` instead of `x`, `y`, `scale`, `rotation`. Layout props trigger expensive reflows.
862
- 5. **Using `useEffect` Instead of `useGSAP`:** In React, always prefer the official `@gsap/react` `useGSAP` hook. It handles scoping, cleanup, and React 18+ Strict Mode.
863
- 6. **Hallucinating Easing Names:** `easeInOut`, `Cubic.easeIn`, `easeOutBounce` do NOT exist. Correct format: `power2.inOut`, `bounce.out`, `elastic.out(1, 0.3)`.
864
- 7. **Confusing `duration` Units:** GSAP uses seconds. CSS uses milliseconds. `duration: 300` in GSAP means 5 minutes, not 300ms.
865
- 8. **Shipping `markers: true`:** Debug markers must never reach production.
866
- 9. **Hallucinated Imports:** Using `import gsap from "gsap"` (default import) instead of `import { gsap } from "gsap"` (named import). Both work, but named is the documented standard.
867
- 10. **Inventing Plugin Names:** Only use real GSAP plugins. There is no `ParallaxPlugin`, `FadePlugin`, or `AnimatePlugin`.
868
-
869
- ---
184
+ ## Performance Rules
870
185
 
871
- ## 🏛️ Tribunal Integration (Anti-Hallucination)
872
-
873
- **Slash command: `/review` or `/tribunal-full`**
874
- **Active reviewers: `logic-reviewer` · `security-auditor` · `performance-optimizer`**
875
-
876
- ### ❌ Forbidden AI Tropes
877
-
878
- 1. **Blind Assumptions:** Never make an assumption without documenting it clearly with `// VERIFY: [reason]`.
879
- 2. **Silent Degradation:** Catching and suppressing GSAP errors without logging or handling.
880
- 3. **Context Amnesia:** Forgetting the user's constraints (e.g., generating Club plugin code when the user has a free license).
881
- 4. **Over-Animating:** Adding animations to every element "because it looks cool." Every animation must serve a UX purpose.
882
-
883
- ### ✅ Pre-Flight Self-Audit
884
-
885
- Review these questions before confirming output:
886
186
  ```
887
- Did I use GSAP 3+ syntax exclusively (no TweenMax/TweenLite)?
888
- Did I register every plugin with gsap.registerPlugin()?
889
- Did I clean up with gsap.context().revert() or ScrollTrigger.kill()?
890
- Did I use transforms (x, y, scale, rotation) instead of layout props?
891
- Did I use useGSAP (not useEffect) for React components?
892
- Did I mark Club-only plugins with a license warning comment?
893
- Did I remove markers: true from production code?
894
- ✅ Did I respect prefers-reduced-motion for accessibility?
187
+ Animate: x, y, scale, rotation, skewX/Y, opacity (GPU composited transforms)
188
+ Never: width, height, top, left, padding, margin (triggers layout/paint)
189
+ Use willChange: "transform" on elements that will animate
190
+ overwrite: "auto" to kill conflicting tweens automatically
191
+ ScrollTrigger.batch() for lists NOT 1 instance per item
192
+ gsap.ticker.lagSmoothing(0) in high-framerate contexts (optional)
193
+ Don't animate SVG path 'd' attribute directly — use MorphSVG plugin
895
194
  ```
896
-
897
- ### 🛑 Verification-Before-Completion (VBC) Protocol
898
-
899
- **CRITICAL:** You must follow a strict "evidence-based closeout" state machine.
900
- - ❌ **Forbidden:** Declaring a task complete because the output "looks correct."
901
- - ✅ **Required:** You are explicitly forbidden from finalizing any task without providing **concrete evidence** (terminal output, passing tests, compile success, or equivalent proof) that your output works as intended.