tribunal-kit 4.2.0 → 4.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agent/ARCHITECTURE.md +21 -14
- package/.agent/agents/swarm-worker-contracts.md +5 -5
- package/.agent/agents/ui-ux-auditor.md +292 -0
- package/.agent/rules/GEMINI.md +8 -8
- package/.agent/scripts/__pycache__/_colors.cpython-311.pyc +0 -0
- package/.agent/scripts/__pycache__/_utils.cpython-311.pyc +0 -0
- package/.agent/scripts/__pycache__/case_law_manager.cpython-311.pyc +0 -0
- package/.agent/scripts/_colors.js +18 -0
- package/.agent/scripts/_utils.js +42 -0
- package/.agent/scripts/auto_preview.js +197 -0
- package/.agent/scripts/bundle_analyzer.js +290 -0
- package/.agent/scripts/case_law_manager.js +684 -0
- package/.agent/scripts/checklist.js +266 -0
- package/.agent/scripts/colors.js +17 -0
- package/.agent/scripts/compress_skills.js +141 -0
- package/.agent/scripts/consolidate_skills.js +149 -0
- package/.agent/scripts/context_broker.js +609 -0
- package/.agent/scripts/deep_compress.js +150 -0
- package/.agent/scripts/dependency_analyzer.js +272 -0
- package/.agent/scripts/graph_builder.js +199 -0
- package/.agent/scripts/graph_zoom.js +154 -0
- package/.agent/scripts/inner_loop_validator.js +465 -0
- package/.agent/scripts/lint_runner.js +187 -0
- package/.agent/scripts/minify_context.js +100 -0
- package/.agent/scripts/patch_skills_meta.js +156 -0
- package/.agent/scripts/patch_skills_output.js +244 -0
- package/.agent/scripts/schema_validator.js +297 -0
- package/.agent/scripts/security_scan.js +303 -0
- package/.agent/scripts/session_manager.js +276 -0
- package/.agent/scripts/skill_evolution.js +644 -0
- package/.agent/scripts/skill_integrator.js +313 -0
- package/.agent/scripts/strengthen_skills.js +193 -0
- package/.agent/scripts/strip_tribunal.js +47 -0
- package/.agent/scripts/swarm_dispatcher.js +360 -0
- package/.agent/scripts/test_runner.js +193 -0
- package/.agent/scripts/utils.js +32 -0
- package/.agent/scripts/verify_all.js +256 -0
- package/.agent/skills/agent-organizer/SKILL.md +12 -4
- package/.agent/skills/agentic-patterns/SKILL.md +12 -4
- package/.agent/skills/ai-prompt-injection-defense/SKILL.md +12 -4
- package/.agent/skills/api-patterns/SKILL.md +209 -201
- package/.agent/skills/api-security-auditor/SKILL.md +12 -4
- package/.agent/skills/app-builder/SKILL.md +12 -4
- package/.agent/skills/app-builder/templates/SKILL.md +76 -68
- package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +1 -1
- package/.agent/skills/appflow-wireframe/SKILL.md +12 -4
- package/.agent/skills/architecture/SKILL.md +12 -4
- package/.agent/skills/authentication-best-practices/SKILL.md +12 -4
- package/.agent/skills/bash-linux/SKILL.md +12 -4
- package/.agent/skills/behavioral-modes/SKILL.md +12 -4
- package/.agent/skills/brainstorming/SKILL.md +12 -4
- package/.agent/skills/building-native-ui/SKILL.md +12 -4
- package/.agent/skills/clean-code/SKILL.md +12 -4
- package/.agent/skills/code-review-checklist/SKILL.md +12 -4
- package/.agent/skills/config-validator/SKILL.md +12 -4
- package/.agent/skills/csharp-developer/SKILL.md +12 -4
- package/.agent/skills/data-validation-schemas/SKILL.md +290 -282
- package/.agent/skills/database-design/SKILL.md +202 -194
- package/.agent/skills/deployment-procedures/SKILL.md +12 -4
- package/.agent/skills/devops-engineer/SKILL.md +12 -4
- package/.agent/skills/devops-incident-responder/SKILL.md +12 -4
- package/.agent/skills/doc.md +1 -1
- package/.agent/skills/documentation-templates/SKILL.md +12 -4
- package/.agent/skills/edge-computing/SKILL.md +12 -4
- package/.agent/skills/error-resilience/SKILL.md +390 -382
- package/.agent/skills/extract-design-system/SKILL.md +12 -4
- package/.agent/skills/framer-motion-expert/SKILL.md +206 -199
- package/.agent/skills/frontend-design/SKILL.md +163 -155
- package/.agent/skills/game-design-expert/SKILL.md +12 -4
- package/.agent/skills/game-engineering-expert/SKILL.md +12 -4
- package/.agent/skills/geo-fundamentals/SKILL.md +12 -4
- package/.agent/skills/github-operations/SKILL.md +12 -4
- package/.agent/skills/gsap-core/SKILL.md +54 -48
- package/.agent/skills/gsap-frameworks/SKILL.md +54 -48
- package/.agent/skills/gsap-performance/SKILL.md +54 -48
- package/.agent/skills/gsap-plugins/SKILL.md +54 -48
- package/.agent/skills/gsap-react/SKILL.md +54 -48
- package/.agent/skills/gsap-scrolltrigger/SKILL.md +54 -48
- package/.agent/skills/gsap-timeline/SKILL.md +54 -48
- package/.agent/skills/gsap-utils/SKILL.md +54 -48
- package/.agent/skills/i18n-localization/SKILL.md +12 -4
- package/.agent/skills/intelligent-routing/SKILL.md +41 -33
- package/.agent/skills/knowledge-graph/SKILL.md +36 -0
- package/.agent/skills/lint-and-validate/SKILL.md +12 -4
- package/.agent/skills/llm-engineering/SKILL.md +12 -4
- package/.agent/skills/local-first/SKILL.md +12 -4
- package/.agent/skills/mcp-builder/SKILL.md +12 -4
- package/.agent/skills/mobile-design/SKILL.md +225 -217
- package/.agent/skills/monorepo-management/SKILL.md +296 -288
- package/.agent/skills/motion-engineering/SKILL.md +195 -187
- package/.agent/skills/nextjs-react-expert/SKILL.md +196 -188
- package/.agent/skills/nodejs-best-practices/SKILL.md +12 -4
- package/.agent/skills/observability/SKILL.md +12 -4
- package/.agent/skills/parallel-agents/SKILL.md +12 -4
- package/.agent/skills/performance-profiling/SKILL.md +12 -4
- package/.agent/skills/plan-writing/SKILL.md +12 -4
- package/.agent/skills/platform-engineer/SKILL.md +12 -4
- package/.agent/skills/playwright-best-practices/SKILL.md +12 -4
- package/.agent/skills/powershell-windows/SKILL.md +12 -4
- package/.agent/skills/project-idioms/SKILL.md +12 -4
- package/.agent/skills/python-patterns/SKILL.md +12 -4
- package/.agent/skills/python-pro/SKILL.md +285 -277
- package/.agent/skills/react-specialist/SKILL.md +239 -231
- package/.agent/skills/readme-builder/SKILL.md +12 -4
- package/.agent/skills/realtime-patterns/SKILL.md +12 -4
- package/.agent/skills/red-team-tactics/SKILL.md +12 -4
- package/.agent/skills/rust-pro/SKILL.md +12 -4
- package/.agent/skills/seo-fundamentals/SKILL.md +12 -4
- package/.agent/skills/server-management/SKILL.md +12 -4
- package/.agent/skills/shadcn-ui-expert/SKILL.md +12 -4
- package/.agent/skills/skill-creator/SKILL.md +12 -4
- package/.agent/skills/sql-pro/SKILL.md +12 -4
- package/.agent/skills/supabase-postgres-best-practices/SKILL.md +12 -4
- package/.agent/skills/swiftui-expert/SKILL.md +12 -4
- package/.agent/skills/systematic-debugging/SKILL.md +12 -4
- package/.agent/skills/tailwind-patterns/SKILL.md +12 -4
- package/.agent/skills/tdd-workflow/SKILL.md +12 -4
- package/.agent/skills/test-result-analyzer/SKILL.md +12 -4
- package/.agent/skills/testing-patterns/SKILL.md +12 -4
- package/.agent/skills/trend-researcher/SKILL.md +12 -4
- package/.agent/skills/typescript-advanced/SKILL.md +297 -289
- package/.agent/skills/ui-ux-pro-max/SKILL.md +12 -4
- package/.agent/skills/ui-ux-researcher/SKILL.md +12 -4
- package/.agent/skills/vue-expert/SKILL.md +237 -229
- package/.agent/skills/vulnerability-scanner/SKILL.md +12 -4
- package/.agent/skills/web-accessibility-auditor/SKILL.md +12 -4
- package/.agent/skills/web-design-guidelines/SKILL.md +12 -4
- package/.agent/skills/webapp-testing/SKILL.md +12 -4
- package/.agent/skills/whimsy-injector/SKILL.md +12 -4
- package/.agent/skills/workflow-optimizer/SKILL.md +12 -4
- package/.agent/workflows/audit.md +6 -6
- package/.agent/workflows/deploy.md +1 -1
- package/.agent/workflows/generate.md +23 -6
- package/.agent/workflows/session.md +5 -5
- package/.agent/workflows/swarm.md +2 -2
- package/README.md +242 -186
- package/bin/tribunal-kit.js +297 -57
- package/package.json +81 -77
- package/scripts/changelog.js +167 -0
- package/scripts/sync-version.js +81 -0
- package/scripts/validate-payload.js +73 -0
- package/.agent/scripts/__pycache__/auto_preview.cpython-311.pyc +0 -0
- package/.agent/scripts/__pycache__/bundle_analyzer.cpython-311.pyc +0 -0
- package/.agent/scripts/__pycache__/checklist.cpython-311.pyc +0 -0
- package/.agent/scripts/__pycache__/dependency_analyzer.cpython-311.pyc +0 -0
- package/.agent/scripts/__pycache__/security_scan.cpython-311.pyc +0 -0
- package/.agent/scripts/__pycache__/session_manager.cpython-311.pyc +0 -0
- package/.agent/scripts/__pycache__/skill_integrator.cpython-311.pyc +0 -0
- package/.agent/scripts/__pycache__/swarm_dispatcher.cpython-311.pyc +0 -0
- package/.agent/scripts/__pycache__/test_runner.cpython-311.pyc +0 -0
- package/.agent/scripts/__pycache__/verify_all.cpython-311.pyc +0 -0
- package/.agent/scripts/auto_preview.py +0 -180
- package/.agent/scripts/bundle_analyzer.py +0 -259
- package/.agent/scripts/case_law_manager.py +0 -755
- package/.agent/scripts/checklist.py +0 -209
- package/.agent/scripts/compress_skills.py +0 -167
- package/.agent/scripts/consolidate_skills.py +0 -173
- package/.agent/scripts/deep_compress.py +0 -202
- package/.agent/scripts/dependency_analyzer.py +0 -247
- package/.agent/scripts/lint_runner.py +0 -188
- package/.agent/scripts/minify_context.py +0 -80
- package/.agent/scripts/patch_skills_meta.py +0 -177
- package/.agent/scripts/patch_skills_output.py +0 -285
- package/.agent/scripts/schema_validator.py +0 -279
- package/.agent/scripts/security_scan.py +0 -224
- package/.agent/scripts/session_manager.py +0 -261
- package/.agent/scripts/skill_evolution.py +0 -563
- package/.agent/scripts/skill_integrator.py +0 -234
- package/.agent/scripts/strengthen_skills.py +0 -220
- package/.agent/scripts/strip_tribunal.py +0 -41
- package/.agent/scripts/swarm_dispatcher.py +0 -350
- package/.agent/scripts/test_runner.py +0 -192
- package/.agent/scripts/test_swarm_dispatcher.py +0 -163
- package/.agent/scripts/verify_all.py +0 -195
|
@@ -110,7 +110,7 @@ A Design System must mandate accessibility at the token level, preventing develo
|
|
|
110
110
|
|
|
111
111
|
---
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
|
|
114
114
|
|
|
115
115
|
AI coding assistants often fall into specific bad habits when dealing with this domain. These are strictly forbidden:
|
|
116
116
|
|
|
@@ -122,7 +122,7 @@ AI coding assistants often fall into specific bad habits when dealing with this
|
|
|
122
122
|
|
|
123
123
|
---
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
|
|
126
126
|
|
|
127
127
|
**Slash command: `/review` or `/tribunal-full`**
|
|
128
128
|
**Active reviewers: `logic-reviewer` · `security-auditor`**
|
|
@@ -133,7 +133,7 @@ AI coding assistants often fall into specific bad habits when dealing with this
|
|
|
133
133
|
2. **Silent Degradation:** Catching and suppressing errors without logging or handling.
|
|
134
134
|
3. **Context Amnesia:** Forgetting the user's constraints and offering generic advice instead of tailored solutions.
|
|
135
135
|
|
|
136
|
-
|
|
136
|
+
|
|
137
137
|
|
|
138
138
|
Review these questions before confirming output:
|
|
139
139
|
```
|
|
@@ -147,4 +147,12 @@ Review these questions before confirming output:
|
|
|
147
147
|
|
|
148
148
|
**CRITICAL:** You must follow a strict "evidence-based closeout" state machine.
|
|
149
149
|
- ❌ **Forbidden:** Declaring a task complete because the output "looks correct."
|
|
150
|
-
- ✅ **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.
|
|
150
|
+
- ✅ **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.
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
## Pre-Flight Checklist
|
|
154
|
+
- [ ] Have I reviewed the user's specific constraints and requests?
|
|
155
|
+
- [ ] Have I checked the environment for relevant existing implementations?
|
|
156
|
+
|
|
157
|
+
## VBC Protocol (Verification-Before-Completion)
|
|
158
|
+
You MUST verify existing code signatures and variables before attempting to modify or call them. No hallucination is permitted.
|
|
@@ -1,203 +1,202 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: framer-motion-expert
|
|
3
|
-
description: Framer Motion 12+ for React. Declarative animations, layout transitions, gestures, scroll-linked motion, AnimatePresence, useAnimate, LazyMotion. Use when building component animations, page transitions, shared layout animations, or gesture-driven UI.
|
|
4
|
-
allowed-tools: Read, Write, Edit, Glob, Grep
|
|
5
|
-
version: 3.1.0
|
|
6
|
-
last-updated: 2026-04-06
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# Framer Motion 12+ — Dense Reference
|
|
10
|
-
|
|
11
|
-
## Hallucination Traps (Read First)
|
|
12
|
-
- ❌ `<Motion>` (capital M) → ✅ `motion.div` (lowercase dot notation)
|
|
13
|
-
- ❌ `motion()` wrapper function → ✅ `motion.div`, `motion.span`, etc.
|
|
14
|
-
- ❌ `exitBeforeEnter` prop → ✅ `mode="wait"` on `<AnimatePresence>` (removed in FM7+)
|
|
15
|
-
- ❌ `exit` works without `<AnimatePresence>` → ✅ REQUIRES AnimatePresence wrapper
|
|
16
|
-
- ❌ `<AnimatePresence>` children without unique `key` → ✅ ALWAYS set `key`
|
|
17
|
-
- ❌ `stiffness + damping` AND `duration + bounce` together → ✅ pick ONE pair
|
|
18
|
-
- ❌ `m.div` without `<LazyMotion>` wrapper → ✅ REQUIRES LazyMotion parent
|
|
19
|
-
- ❌ `layout` animations with `domAnimation` feature set → ✅ requires `domMax`
|
|
20
|
-
- ❌ Force-animating `width`/`height`/`top`/`left` → ✅ use `x`,`y`,`scale`,`opacity` (GPU)
|
|
21
|
-
- ❌ `viewport.once` defaults to true → ✅ defaults to **false** — add `once: true` for entrance anims
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## Core Primitives
|
|
26
|
-
|
|
27
|
-
### `motion.X` / Declarative Animation
|
|
28
|
-
```tsx
|
|
29
|
-
import { motion } from "framer-motion";
|
|
30
|
-
<motion.div
|
|
31
|
-
initial={{ opacity: 0, y: 20 }}
|
|
32
|
-
animate={{ opacity: 1, y: 0 }}
|
|
33
|
-
exit={{ opacity: 0, y: -20 }}
|
|
34
|
-
transition={{ duration: 0.3, ease: "easeOut" }}
|
|
35
|
-
/>
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
### Variants (Stagger / Orchestration)
|
|
39
|
-
```tsx
|
|
40
|
-
const container = {
|
|
41
|
-
hidden: {},
|
|
42
|
-
visible: { transition: { staggerChildren: 0.08, delayChildren: 0.1 } },
|
|
43
|
-
};
|
|
44
|
-
const item = {
|
|
45
|
-
hidden: { opacity: 0, y: 20, filter: "blur(4px)" },
|
|
46
|
-
visible: { opacity: 1, y: 0, filter: "blur(0px)", transition: { duration: 0.4 } },
|
|
47
|
-
};
|
|
48
|
-
<motion.ul variants={container} initial="hidden" animate="visible">
|
|
49
|
-
{list.map(e => <motion.li key={e.id} variants={item}>{e.name}</motion.li>)}
|
|
50
|
-
</motion.ul>
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
//
|
|
59
|
-
transition={{ type: "spring",
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
## Layout Animations
|
|
96
|
-
|
|
97
|
-
```tsx
|
|
98
|
-
// layout prop — auto-animates position/size changes
|
|
99
|
-
<motion.div layout transition={{ type: "spring", stiffness: 200 }}>
|
|
100
|
-
{/* layout="position" = only position, layout="size" = only size */}
|
|
101
|
-
</motion.div>
|
|
102
|
-
|
|
103
|
-
// layoutId — shared element transition (morph between renders)
|
|
104
|
-
// List thumbnail → expanded modal:
|
|
105
|
-
<motion.div key={item.id} layoutId={`card-${item.id}`} /> // in list
|
|
106
|
-
<motion.div layoutId={`card-${selectedId}`} className="modal" /> // in modal
|
|
107
|
-
// ❌ TRAP: Cross-tree layoutId requires <LayoutGroup> wrapper
|
|
108
|
-
import { LayoutGroup } from "framer-motion";
|
|
109
|
-
<LayoutGroup><Sidebar /><MainContent /></LayoutGroup>
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
### AnimatePresence
|
|
113
|
-
```tsx
|
|
114
|
-
<AnimatePresence mode="sync"> {/* "sync"|"wait"|"popLayout" */}
|
|
115
|
-
{items.map(item => (
|
|
116
|
-
<motion.div key={item.id} /* ← REQUIRED */
|
|
117
|
-
initial={{ opacity: 0, height: 0 }}
|
|
118
|
-
animate={{ opacity: 1, height: "auto" }}
|
|
119
|
-
exit={{ opacity: 0, height: 0 }}
|
|
120
|
-
/>
|
|
121
|
-
))}
|
|
122
|
-
</AnimatePresence>
|
|
123
|
-
// mode="wait" — waits for exit before entering
|
|
124
|
-
// initial={false} on AnimatePresence — skip first-render animation
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
---
|
|
128
|
-
|
|
129
|
-
## Scroll Animations
|
|
130
|
-
|
|
131
|
-
```tsx
|
|
132
|
-
import { useScroll, useTransform } from "framer-motion";
|
|
133
|
-
// Page scroll progress (0–1)
|
|
134
|
-
const { scrollYProgress } = useScroll();
|
|
135
|
-
const y = useTransform(scrollYProgress, [0, 1], [0, -200]);
|
|
136
|
-
const opacity = useTransform(scrollYProgress, [0, 0.5], [1, 0]);
|
|
137
|
-
<motion.div style={{ y, opacity }} />
|
|
138
|
-
|
|
139
|
-
// Element-scoped scroll
|
|
140
|
-
const ref = useRef(null);
|
|
141
|
-
const { scrollYProgress } = useScroll({ target: ref, offset: ["start end", "end start"] });
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
---
|
|
145
|
-
|
|
146
|
-
## Hooks
|
|
147
|
-
|
|
148
|
-
### `useAnimate` — Imperative sequences
|
|
149
|
-
```tsx
|
|
150
|
-
import { useAnimate, stagger } from "framer-motion";
|
|
151
|
-
const [scope, animate] = useAnimate(); // ← returns [scope, animate] NOT [ref, controls]
|
|
152
|
-
await animate(".item", { opacity: 1 }, { delay: stagger(0.1) });
|
|
153
|
-
<div ref={scope}>...</div>
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
### `useMotionValue` + `useTransform` — No re-renders
|
|
157
|
-
```tsx
|
|
158
|
-
const x = useMotionValue(0);
|
|
159
|
-
const rotateY = useTransform(x, [-200, 200], [-45, 45]);
|
|
160
|
-
// ✅ useMotionValue does NOT trigger React re-renders — key perf advantage over useState
|
|
161
|
-
<motion.div style={{ x, rotateY }} drag="x" />
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
### `useSpring` / `useVelocity`
|
|
165
|
-
```tsx
|
|
166
|
-
const springX = useSpring(x, { stiffness: 300, damping: 30 });
|
|
167
|
-
const xVel = useVelocity(x);
|
|
168
|
-
const skewX = useTransform(xVel, [-1000, 0, 1000], [-15, 0, 15]);
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
---
|
|
172
|
-
|
|
173
|
-
## Performance & Bundle
|
|
174
|
-
|
|
175
|
-
```tsx
|
|
176
|
-
// LazyMotion — ~5KB vs ~30KB full bundle
|
|
177
|
-
import { LazyMotion, domAnimation, m } from "framer-motion";
|
|
178
|
-
// domAnimation ≈ 5KB | domMax ≈ 20KB (needed for layout/drag)
|
|
179
|
-
<LazyMotion features={domAnimation}><m.div animate={{ opacity: 1 }} /></LazyMotion>
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
### Accessibility
|
|
183
|
-
```tsx
|
|
184
|
-
import { useReducedMotion } from "framer-motion";
|
|
185
|
-
const reduce = useReducedMotion();
|
|
186
|
-
// opacity/color: always safe | position/scale/rotation: must be disabled when reduce=true
|
|
187
|
-
<motion.div animate={{ x: reduce ? 0 : 100, opacity: 1 }} transition={{ duration: reduce ? 0 : 0.5 }} />
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
### Rules
|
|
191
|
-
- ✅ Animate: `x`, `y`, `scale`, `rotation`, `opacity` (GPU composited)
|
|
192
|
-
- ❌ Never animate: `width`, `height`, `top`, `left`, `padding`, `margin` (causes layout thrashing)
|
|
193
|
-
- ✅ `useMotionValue` for animation-driven values — never `useState`
|
|
194
|
-
- ❌ Nest `AnimatePresence` only when necessary — each adds reconciler overhead
|
|
195
|
-
- `"use client"` required in Next.js — `motion.div` cannot run in Server Components
|
|
1
|
+
---
|
|
2
|
+
name: framer-motion-expert
|
|
3
|
+
description: Framer Motion 12+ for React. Declarative animations, layout transitions, gestures, scroll-linked motion, AnimatePresence, useAnimate, LazyMotion. Use when building component animations, page transitions, shared layout animations, or gesture-driven UI.
|
|
4
|
+
allowed-tools: Read, Write, Edit, Glob, Grep
|
|
5
|
+
version: 3.1.0
|
|
6
|
+
last-updated: 2026-04-06
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Framer Motion 12+ — Dense Reference
|
|
10
|
+
|
|
11
|
+
## Hallucination Traps (Read First)
|
|
12
|
+
- ❌ `<Motion>` (capital M) → ✅ `motion.div` (lowercase dot notation)
|
|
13
|
+
- ❌ `motion()` wrapper function → ✅ `motion.div`, `motion.span`, etc.
|
|
14
|
+
- ❌ `exitBeforeEnter` prop → ✅ `mode="wait"` on `<AnimatePresence>` (removed in FM7+)
|
|
15
|
+
- ❌ `exit` works without `<AnimatePresence>` → ✅ REQUIRES AnimatePresence wrapper
|
|
16
|
+
- ❌ `<AnimatePresence>` children without unique `key` → ✅ ALWAYS set `key`
|
|
17
|
+
- ❌ `stiffness + damping` AND `duration + bounce` together → ✅ pick ONE pair
|
|
18
|
+
- ❌ `m.div` without `<LazyMotion>` wrapper → ✅ REQUIRES LazyMotion parent
|
|
19
|
+
- ❌ `layout` animations with `domAnimation` feature set → ✅ requires `domMax`
|
|
20
|
+
- ❌ Force-animating `width`/`height`/`top`/`left` → ✅ use `x`,`y`,`scale`,`opacity` (GPU)
|
|
21
|
+
- ❌ `viewport.once` defaults to true → ✅ defaults to **false** — add `once: true` for entrance anims
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Core Primitives
|
|
26
|
+
|
|
27
|
+
### `motion.X` / Declarative Animation
|
|
28
|
+
```tsx
|
|
29
|
+
import { motion } from "framer-motion";
|
|
30
|
+
<motion.div
|
|
31
|
+
initial={{ opacity: 0, y: 20 }}
|
|
32
|
+
animate={{ opacity: 1, y: 0 }}
|
|
33
|
+
exit={{ opacity: 0, y: -20 }}
|
|
34
|
+
transition={{ duration: 0.3, ease: "easeOut" }}
|
|
35
|
+
/>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Variants (Stagger / Orchestration)
|
|
39
|
+
```tsx
|
|
40
|
+
const container = {
|
|
41
|
+
hidden: {},
|
|
42
|
+
visible: { transition: { staggerChildren: 0.08, delayChildren: 0.1 } },
|
|
43
|
+
};
|
|
44
|
+
const item = {
|
|
45
|
+
hidden: { opacity: 0, y: 20, filter: "blur(4px)" },
|
|
46
|
+
visible: { opacity: 1, y: 0, filter: "blur(0px)", transition: { duration: 0.4 } },
|
|
47
|
+
};
|
|
48
|
+
<motion.ul variants={container} initial="hidden" animate="visible">
|
|
49
|
+
{list.map(e => <motion.li key={e.id} variants={item}>{e.name}</motion.li>)}
|
|
50
|
+
</motion.ul>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Transitions
|
|
54
|
+
```tsx
|
|
55
|
+
// Tween (default)
|
|
56
|
+
transition={{ duration: 0.5, ease: "easeInOut", delay: 0.2, repeat: Infinity, repeatType: "reverse" }}
|
|
57
|
+
// Spring (physics)
|
|
58
|
+
transition={{ type: "spring", stiffness: 300, damping: 20 }} // OR use duration+bounce, not both
|
|
59
|
+
transition={{ type: "spring", duration: 0.8, bounce: 0.25 }}
|
|
60
|
+
// Per-property
|
|
61
|
+
transition={{ x: { type: "spring", stiffness: 300 }, opacity: { duration: 0.2 } }}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Gestures
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
// Hover/Tap/Focus
|
|
70
|
+
<motion.button
|
|
71
|
+
whileHover={{ scale: 1.05 }}
|
|
72
|
+
whileTap={{ scale: 0.95 }}
|
|
73
|
+
whileFocus={{ boxShadow: "0 0 0 3px rgba(66,153,225,0.6)" }}
|
|
74
|
+
transition={{ type: "spring", stiffness: 400, damping: 15 }}
|
|
75
|
+
/>
|
|
76
|
+
// Drag
|
|
77
|
+
<motion.div
|
|
78
|
+
drag="x" // "x" | "y" | true
|
|
79
|
+
dragConstraints={{ left: -100, right: 100 }}
|
|
80
|
+
dragElastic={0.2} // 0=hard stop, 1=free
|
|
81
|
+
dragMomentum={true}
|
|
82
|
+
dragSnapToOrigin
|
|
83
|
+
/>
|
|
84
|
+
// Scroll-triggered
|
|
85
|
+
<motion.div
|
|
86
|
+
initial={{ opacity: 0, y: 50 }}
|
|
87
|
+
whileInView={{ opacity: 1, y: 0 }}
|
|
88
|
+
viewport={{ once: true, amount: 0.3 }} // ← once: true is almost always what you want
|
|
89
|
+
/>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Layout Animations
|
|
196
95
|
|
|
96
|
+
```tsx
|
|
97
|
+
// layout prop — auto-animates position/size changes
|
|
98
|
+
<motion.div layout transition={{ type: "spring", stiffness: 200 }}>
|
|
99
|
+
{/* layout="position" = only position, layout="size" = only size */}
|
|
100
|
+
</motion.div>
|
|
101
|
+
|
|
102
|
+
// layoutId — shared element transition (morph between renders)
|
|
103
|
+
// List thumbnail → expanded modal:
|
|
104
|
+
<motion.div key={item.id} layoutId={`card-${item.id}`} /> // in list
|
|
105
|
+
<motion.div layoutId={`card-${selectedId}`} className="modal" /> // in modal
|
|
106
|
+
// ❌ TRAP: Cross-tree layoutId requires <LayoutGroup> wrapper
|
|
107
|
+
import { LayoutGroup } from "framer-motion";
|
|
108
|
+
<LayoutGroup><Sidebar /><MainContent /></LayoutGroup>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### AnimatePresence
|
|
112
|
+
```tsx
|
|
113
|
+
<AnimatePresence mode="sync"> {/* "sync"|"wait"|"popLayout" */}
|
|
114
|
+
{items.map(item => (
|
|
115
|
+
<motion.div key={item.id} /* ← REQUIRED */
|
|
116
|
+
initial={{ opacity: 0, height: 0 }}
|
|
117
|
+
animate={{ opacity: 1, height: "auto" }}
|
|
118
|
+
exit={{ opacity: 0, height: 0 }}
|
|
119
|
+
/>
|
|
120
|
+
))}
|
|
121
|
+
</AnimatePresence>
|
|
122
|
+
// mode="wait" — waits for exit before entering
|
|
123
|
+
// initial={false} on AnimatePresence — skip first-render animation
|
|
124
|
+
```
|
|
197
125
|
|
|
198
126
|
---
|
|
199
127
|
|
|
200
|
-
##
|
|
128
|
+
## Scroll Animations
|
|
129
|
+
|
|
130
|
+
```tsx
|
|
131
|
+
import { useScroll, useTransform } from "framer-motion";
|
|
132
|
+
// Page scroll progress (0–1)
|
|
133
|
+
const { scrollYProgress } = useScroll();
|
|
134
|
+
const y = useTransform(scrollYProgress, [0, 1], [0, -200]);
|
|
135
|
+
const opacity = useTransform(scrollYProgress, [0, 0.5], [1, 0]);
|
|
136
|
+
<motion.div style={{ y, opacity }} />
|
|
137
|
+
|
|
138
|
+
// Element-scoped scroll
|
|
139
|
+
const ref = useRef(null);
|
|
140
|
+
const { scrollYProgress } = useScroll({ target: ref, offset: ["start end", "end start"] });
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Hooks
|
|
146
|
+
|
|
147
|
+
### `useAnimate` — Imperative sequences
|
|
148
|
+
```tsx
|
|
149
|
+
import { useAnimate, stagger } from "framer-motion";
|
|
150
|
+
const [scope, animate] = useAnimate(); // ← returns [scope, animate] NOT [ref, controls]
|
|
151
|
+
await animate(".item", { opacity: 1 }, { delay: stagger(0.1) });
|
|
152
|
+
<div ref={scope}>...</div>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### `useMotionValue` + `useTransform` — No re-renders
|
|
156
|
+
```tsx
|
|
157
|
+
const x = useMotionValue(0);
|
|
158
|
+
const rotateY = useTransform(x, [-200, 200], [-45, 45]);
|
|
159
|
+
// ✅ useMotionValue does NOT trigger React re-renders — key perf advantage over useState
|
|
160
|
+
<motion.div style={{ x, rotateY }} drag="x" />
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### `useSpring` / `useVelocity`
|
|
164
|
+
```tsx
|
|
165
|
+
const springX = useSpring(x, { stiffness: 300, damping: 30 });
|
|
166
|
+
const xVel = useVelocity(x);
|
|
167
|
+
const skewX = useTransform(xVel, [-1000, 0, 1000], [-15, 0, 15]);
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Performance & Bundle
|
|
173
|
+
|
|
174
|
+
```tsx
|
|
175
|
+
// LazyMotion — ~5KB vs ~30KB full bundle
|
|
176
|
+
import { LazyMotion, domAnimation, m } from "framer-motion";
|
|
177
|
+
// domAnimation ≈ 5KB | domMax ≈ 20KB (needed for layout/drag)
|
|
178
|
+
<LazyMotion features={domAnimation}><m.div animate={{ opacity: 1 }} /></LazyMotion>
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Accessibility
|
|
182
|
+
```tsx
|
|
183
|
+
import { useReducedMotion } from "framer-motion";
|
|
184
|
+
const reduce = useReducedMotion();
|
|
185
|
+
// opacity/color: always safe | position/scale/rotation: must be disabled when reduce=true
|
|
186
|
+
<motion.div animate={{ x: reduce ? 0 : 100, opacity: 1 }} transition={{ duration: reduce ? 0 : 0.5 }} />
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Rules
|
|
190
|
+
- ✅ Animate: `x`, `y`, `scale`, `rotation`, `opacity` (GPU composited)
|
|
191
|
+
- ❌ Never animate: `width`, `height`, `top`, `left`, `padding`, `margin` (causes layout thrashing)
|
|
192
|
+
- ✅ `useMotionValue` for animation-driven values — never `useState`
|
|
193
|
+
- ❌ Nest `AnimatePresence` only when necessary — each adds reconciler overhead
|
|
194
|
+
- `"use client"` required in Next.js — `motion.div` cannot run in Server Components
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
|
|
201
200
|
|
|
202
201
|
AI coding assistants often fall into specific bad habits when dealing with this domain. These are strictly forbidden:
|
|
203
202
|
|
|
@@ -209,7 +208,7 @@ AI coding assistants often fall into specific bad habits when dealing with this
|
|
|
209
208
|
|
|
210
209
|
---
|
|
211
210
|
|
|
212
|
-
|
|
211
|
+
|
|
213
212
|
|
|
214
213
|
**Slash command: `/review` or `/tribunal-full`**
|
|
215
214
|
**Active reviewers: `logic-reviewer` · `security-auditor`**
|
|
@@ -220,7 +219,7 @@ AI coding assistants often fall into specific bad habits when dealing with this
|
|
|
220
219
|
2. **Silent Degradation:** Catching and suppressing errors without logging or handling.
|
|
221
220
|
3. **Context Amnesia:** Forgetting the user's constraints and offering generic advice instead of tailored solutions.
|
|
222
221
|
|
|
223
|
-
|
|
222
|
+
|
|
224
223
|
|
|
225
224
|
Review these questions before confirming output:
|
|
226
225
|
```
|
|
@@ -234,4 +233,12 @@ Review these questions before confirming output:
|
|
|
234
233
|
|
|
235
234
|
**CRITICAL:** You must follow a strict "evidence-based closeout" state machine.
|
|
236
235
|
- ❌ **Forbidden:** Declaring a task complete because the output "looks correct."
|
|
237
|
-
- ✅ **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.
|
|
236
|
+
- ✅ **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.
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
## Pre-Flight Checklist
|
|
240
|
+
- [ ] Have I reviewed the user's specific constraints and requests?
|
|
241
|
+
- [ ] Have I checked the environment for relevant existing implementations?
|
|
242
|
+
|
|
243
|
+
## VBC Protocol (Verification-Before-Completion)
|
|
244
|
+
You MUST verify existing code signatures and variables before attempting to modify or call them. No hallucination is permitted.
|