wizz-method 1.3.1 → 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.
- package/package.json +1 -1
- package/skills-registry.yaml +12 -2
- package/src/modules/wizz/_shared/token-economy.md +3 -0
- package/src/modules/wizz/agents/wizz-ads/customize.toml +1 -0
- package/src/modules/wizz/agents/wizz-copy/customize.toml +1 -0
- package/src/modules/wizz/agents/wizz-designer/customize.toml +1 -0
- package/src/modules/wizz/agents/wizz-growth/customize.toml +1 -0
- package/src/modules/wizz/agents/wizz-maestro/customize.toml +1 -0
- package/src/modules/wizz/agents/wizz-memoria/customize.toml +1 -0
- package/src/modules/wizz/agents/wizz-qa/customize.toml +1 -0
- package/src/modules/wizz/agents/wizz-seo/customize.toml +1 -0
- package/src/modules/wizz/agents/wizz-social/customize.toml +1 -0
- package/src/modules/wizz/overrides/wizz-agent-analyst.toml +1 -0
- package/src/modules/wizz/overrides/wizz-agent-architect.toml +1 -0
- package/src/modules/wizz/overrides/wizz-agent-dev.toml +1 -0
- package/src/modules/wizz/overrides/wizz-agent-pm.toml +1 -0
- package/src/modules/wizz/overrides/wizz-agent-tech-writer.toml +1 -0
- package/src/modules/wizz/overrides/wizz-agent-ux-designer.toml +1 -0
- package/src/skills-lib/ai-product-design/SKILL.md +85 -0
- package/src/skills-lib/ai-product-design/references/LICENSE +21 -0
- package/src/skills-lib/ai-product-design/references/ai-alignment-reasoning/bias-detection-design/SKILL.md +37 -0
- package/src/skills-lib/ai-product-design/references/ai-alignment-reasoning/consent-and-agency/SKILL.md +37 -0
- package/src/skills-lib/ai-product-design/references/ai-alignment-reasoning/escalation-design/SKILL.md +40 -0
- package/src/skills-lib/ai-product-design/references/ai-alignment-reasoning/guardrail-design/SKILL.md +36 -0
- package/src/skills-lib/ai-product-design/references/ai-alignment-reasoning/harm-anticipation/SKILL.md +108 -0
- package/src/skills-lib/ai-product-design/references/ai-alignment-reasoning/transparency-patterns/SKILL.md +36 -0
- package/src/skills-lib/ai-product-design/references/ai-alignment-reasoning/trust-calibration/SKILL.md +102 -0
- package/src/skills-lib/ai-product-design/references/ai-alignment-reasoning/value-specification/SKILL.md +39 -0
- package/src/skills-lib/ai-product-design/references/design-agent-orchestration/agent-role-design/SKILL.md +37 -0
- package/src/skills-lib/ai-product-design/references/design-agent-orchestration/failure-recovery/SKILL.md +37 -0
- package/src/skills-lib/ai-product-design/references/design-agent-orchestration/handoff-protocols/SKILL.md +45 -0
- package/src/skills-lib/ai-product-design/references/design-agent-orchestration/human-in-the-loop/SKILL.md +39 -0
- package/src/skills-lib/ai-product-design/references/design-agent-orchestration/observability-design/SKILL.md +48 -0
- package/src/skills-lib/ai-product-design/references/design-agent-orchestration/state-management/SKILL.md +95 -0
- package/src/skills-lib/ai-product-design/references/design-agent-orchestration/task-decomposition/SKILL.md +36 -0
- package/src/skills-lib/ai-product-design/references/evaluation/comparative-evaluation/SKILL.md +39 -0
- package/src/skills-lib/ai-product-design/references/evaluation/failure-taxonomy/SKILL.md +47 -0
- package/src/skills-lib/ai-product-design/references/evaluation/heuristic-evaluation-ai/SKILL.md +46 -0
- package/src/skills-lib/ai-product-design/references/evaluation/longitudinal-measurement/SKILL.md +38 -0
- package/src/skills-lib/ai-product-design/references/evaluation/output-quality-rubrics/SKILL.md +41 -0
- package/src/skills-lib/ai-product-design/references/evaluation/task-success-metrics/SKILL.md +35 -0
- package/src/skills-lib/ai-product-design/references/evaluation/user-satisfaction-signals/SKILL.md +50 -0
- package/src/skills-lib/ai-product-design/references/model-interaction-design/context-window-design/SKILL.md +28 -0
- package/src/skills-lib/ai-product-design/references/model-interaction-design/conversation-patterns/SKILL.md +37 -0
- package/src/skills-lib/ai-product-design/references/model-interaction-design/feedback-loops/SKILL.md +35 -0
- package/src/skills-lib/ai-product-design/references/model-interaction-design/frustration-detection/SKILL.md +91 -0
- package/src/skills-lib/ai-product-design/references/model-interaction-design/generative-ui/SKILL.md +34 -0
- package/src/skills-lib/ai-product-design/references/model-interaction-design/mixed-initiative-flow/SKILL.md +39 -0
- package/src/skills-lib/ai-product-design/references/model-interaction-design/multimodal-orchestration/SKILL.md +94 -0
- package/src/skills-lib/ai-product-design/references/model-interaction-design/progressive-disclosure/SKILL.md +33 -0
- package/src/skills-lib/ai-product-design/references/prompt-architecture/chain-of-thought-design/SKILL.md +45 -0
- package/src/skills-lib/ai-product-design/references/prompt-architecture/constraint-specification/SKILL.md +50 -0
- package/src/skills-lib/ai-product-design/references/prompt-architecture/context-engineering/SKILL.md +45 -0
- package/src/skills-lib/ai-product-design/references/prompt-architecture/few-shot-patterns/SKILL.md +47 -0
- package/src/skills-lib/ai-product-design/references/prompt-architecture/prompt-versioning/SKILL.md +42 -0
- package/src/skills-lib/ai-product-design/references/prompt-architecture/system-prompt-structure/SKILL.md +50 -0
- package/src/skills-lib/ai-product-design/references/prompt-architecture/template-design/SKILL.md +42 -0
- package/src/skills-lib/ai-product-design/references/system-behavior-shaping/behavioral-consistency/SKILL.md +36 -0
- package/src/skills-lib/ai-product-design/references/system-behavior-shaping/cultural-adaptation/SKILL.md +38 -0
- package/src/skills-lib/ai-product-design/references/system-behavior-shaping/domain-voice/SKILL.md +51 -0
- package/src/skills-lib/ai-product-design/references/system-behavior-shaping/emotional-design/SKILL.md +51 -0
- package/src/skills-lib/ai-product-design/references/system-behavior-shaping/error-personality/SKILL.md +45 -0
- package/src/skills-lib/ai-product-design/references/system-behavior-shaping/persona-architecture/SKILL.md +38 -0
- package/src/skills-lib/ai-product-design/references/system-behavior-shaping/tone-calibration/SKILL.md +39 -0
- package/src/skills-lib/algorithmic-art/LICENSE.txt +202 -0
- package/src/skills-lib/algorithmic-art/SKILL.md +405 -0
- package/src/skills-lib/algorithmic-art/templates/generator_template.js +223 -0
- package/src/skills-lib/algorithmic-art/templates/viewer.html +599 -0
- package/src/skills-lib/animate/README.md +41 -0
- package/src/skills-lib/animate/SKILL.md +179 -0
- package/src/skills-lib/animate/examples/animate-height.tsx +75 -0
- package/src/skills-lib/animate/examples/app-store-card.tsx +164 -0
- package/src/skills-lib/animate/examples/card-hover.tsx +79 -0
- package/src/skills-lib/animate/examples/feedback-popover.tsx +119 -0
- package/src/skills-lib/animate/examples/multi-step-flow.tsx +128 -0
- package/src/skills-lib/animate/examples/shared-layout.tsx +64 -0
- package/src/skills-lib/animate/examples/text-reveal.tsx +70 -0
- package/src/skills-lib/animate/examples/toast-stacking.tsx +95 -0
- package/src/skills-lib/animate/references/css-animations.md +232 -0
- package/src/skills-lib/animate/references/easing-and-timing.md +105 -0
- package/src/skills-lib/animate/references/framer-motion.md +356 -0
- package/src/skills-lib/animate/references/performance-accessibility.md +185 -0
- package/src/skills-lib/auth-and-secrets/SKILL.md +10 -0
- package/src/skills-lib/canvas-design/LICENSE.txt +202 -0
- package/src/skills-lib/canvas-design/SKILL.md +130 -0
- package/src/skills-lib/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/BigShoulders-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Boldonse-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/DMMono-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/EricaOne-OFL.txt +94 -0
- package/src/skills-lib/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/GeistMono-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Gloock-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Italiana-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Jura-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Lora-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/NationalPark-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Outfit-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/PixelifySans-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/PoiretOne-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/RedHatMono-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Silkscreen-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/SmoochSans-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/WorkSans-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
- package/src/skills-lib/design-motion-principles/SKILL.md +122 -0
- package/src/skills-lib/design-motion-principles/references/accessibility.md +52 -0
- package/src/skills-lib/design-motion-principles/references/anti-checklist.md +274 -0
- package/src/skills-lib/design-motion-principles/references/audit-checklist.md +137 -0
- package/src/skills-lib/design-motion-principles/references/creation-gotchas.md +36 -0
- package/src/skills-lib/design-motion-principles/references/demo-shell.html +275 -0
- package/src/skills-lib/design-motion-principles/references/emil-kowalski.md +121 -0
- package/src/skills-lib/design-motion-principles/references/jakub-krehel.md +80 -0
- package/src/skills-lib/design-motion-principles/references/jhey-tompkins.md +122 -0
- package/src/skills-lib/design-motion-principles/references/motion-cookbook.md +529 -0
- package/src/skills-lib/design-motion-principles/references/output-format.md +346 -0
- package/src/skills-lib/design-motion-principles/references/performance.md +82 -0
- package/src/skills-lib/design-motion-principles/references/report-template.html +1006 -0
- package/src/skills-lib/design-motion-principles/workflows/audit.md +203 -0
- package/src/skills-lib/design-motion-principles/workflows/create.md +87 -0
- package/src/skills-lib/web-security/SKILL.md +47 -4
- package/src/skills-lib/wizz-router/SKILL.md +4 -1
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
# Framer Motion Reference
|
|
2
|
+
|
|
3
|
+
Framer Motion is the recommended animation library for React/Next.js applications.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install framer-motion
|
|
9
|
+
# or
|
|
10
|
+
pnpm add framer-motion
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
14
|
+
|
|
15
|
+
### Motion Components
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import { motion } from "framer-motion"
|
|
19
|
+
|
|
20
|
+
// Any HTML element can become animated
|
|
21
|
+
<motion.div
|
|
22
|
+
initial={{ opacity: 0, y: 20 }}
|
|
23
|
+
animate={{ opacity: 1, y: 0 }}
|
|
24
|
+
transition={{ duration: 0.3, ease: "easeOut" }}
|
|
25
|
+
>
|
|
26
|
+
Content
|
|
27
|
+
</motion.div>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Common Props
|
|
31
|
+
|
|
32
|
+
| Prop | Description |
|
|
33
|
+
|------|-------------|
|
|
34
|
+
| `initial` | Starting state (or `false` to disable) |
|
|
35
|
+
| `animate` | Target state |
|
|
36
|
+
| `exit` | Exit state (requires AnimatePresence) |
|
|
37
|
+
| `transition` | Animation configuration |
|
|
38
|
+
| `whileHover` | State while hovered |
|
|
39
|
+
| `whileTap` | State while pressed |
|
|
40
|
+
| `whileFocus` | State while focused |
|
|
41
|
+
| `whileInView` | State while in viewport |
|
|
42
|
+
|
|
43
|
+
## AnimatePresence
|
|
44
|
+
|
|
45
|
+
Required for exit animations. Wraps elements that may be removed from DOM.
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
import { motion, AnimatePresence } from "framer-motion"
|
|
49
|
+
|
|
50
|
+
function Modal({ isOpen, onClose, children }) {
|
|
51
|
+
return (
|
|
52
|
+
<AnimatePresence>
|
|
53
|
+
{isOpen && (
|
|
54
|
+
<motion.div
|
|
55
|
+
initial={{ opacity: 0 }}
|
|
56
|
+
animate={{ opacity: 1 }}
|
|
57
|
+
exit={{ opacity: 0 }}
|
|
58
|
+
transition={{ duration: 0.2 }}
|
|
59
|
+
>
|
|
60
|
+
{children}
|
|
61
|
+
</motion.div>
|
|
62
|
+
)}
|
|
63
|
+
</AnimatePresence>
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### AnimatePresence Props
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
<AnimatePresence
|
|
72
|
+
mode="wait" // 'sync' | 'wait' | 'popLayout'
|
|
73
|
+
initial={false} // Disable initial animation on mount
|
|
74
|
+
onExitComplete={() => {}} // Callback when all exits complete
|
|
75
|
+
>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
- `mode="sync"` (default): Enter and exit happen simultaneously
|
|
79
|
+
- `mode="wait"`: Wait for exit to complete before enter
|
|
80
|
+
- `mode="popLayout"`: Remove exiting elements from layout flow
|
|
81
|
+
|
|
82
|
+
## Variants
|
|
83
|
+
|
|
84
|
+
Variants define animation states that can be orchestrated across parent/children.
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
const containerVariants = {
|
|
88
|
+
hidden: { opacity: 0 },
|
|
89
|
+
visible: {
|
|
90
|
+
opacity: 1,
|
|
91
|
+
transition: {
|
|
92
|
+
staggerChildren: 0.1, // Delay between each child
|
|
93
|
+
delayChildren: 0.2, // Initial delay before children start
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const itemVariants = {
|
|
99
|
+
hidden: { opacity: 0, y: 20 },
|
|
100
|
+
visible: { opacity: 1, y: 0 }
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function List({ items }) {
|
|
104
|
+
return (
|
|
105
|
+
<motion.ul
|
|
106
|
+
variants={containerVariants}
|
|
107
|
+
initial="hidden"
|
|
108
|
+
animate="visible"
|
|
109
|
+
>
|
|
110
|
+
{items.map(item => (
|
|
111
|
+
<motion.li key={item.id} variants={itemVariants}>
|
|
112
|
+
{item.name}
|
|
113
|
+
</motion.li>
|
|
114
|
+
))}
|
|
115
|
+
</motion.ul>
|
|
116
|
+
)
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Layout Animations
|
|
121
|
+
|
|
122
|
+
Animate layout changes automatically with the `layout` prop.
|
|
123
|
+
|
|
124
|
+
```tsx
|
|
125
|
+
// Element animates when its position/size changes
|
|
126
|
+
<motion.div layout>
|
|
127
|
+
{isExpanded ? "Expanded content here" : "Collapsed"}
|
|
128
|
+
</motion.div>
|
|
129
|
+
|
|
130
|
+
// Layout types
|
|
131
|
+
<motion.div layout> // Animate position and size
|
|
132
|
+
<motion.div layout="position"> // Only animate position
|
|
133
|
+
<motion.div layout="size"> // Only animate size
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Shared Layout Animations (layoutId)
|
|
137
|
+
|
|
138
|
+
Elements with the same `layoutId` animate between each other.
|
|
139
|
+
|
|
140
|
+
```tsx
|
|
141
|
+
function Tabs({ tabs, activeTab, setActiveTab }) {
|
|
142
|
+
return (
|
|
143
|
+
<div className="flex gap-2">
|
|
144
|
+
{tabs.map(tab => (
|
|
145
|
+
<button
|
|
146
|
+
key={tab}
|
|
147
|
+
onClick={() => setActiveTab(tab)}
|
|
148
|
+
className="relative px-4 py-2"
|
|
149
|
+
>
|
|
150
|
+
{tab}
|
|
151
|
+
{activeTab === tab && (
|
|
152
|
+
<motion.div
|
|
153
|
+
layoutId="tab-indicator"
|
|
154
|
+
className="absolute inset-0 bg-blue-500 rounded -z-10"
|
|
155
|
+
transition={{ type: "spring", stiffness: 400, damping: 30 }}
|
|
156
|
+
/>
|
|
157
|
+
)}
|
|
158
|
+
</button>
|
|
159
|
+
))}
|
|
160
|
+
</div>
|
|
161
|
+
)
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### LayoutGroup
|
|
166
|
+
|
|
167
|
+
Group layout animations to prevent conflicts between independent animations.
|
|
168
|
+
|
|
169
|
+
```tsx
|
|
170
|
+
import { LayoutGroup } from "framer-motion"
|
|
171
|
+
|
|
172
|
+
<LayoutGroup>
|
|
173
|
+
<Tabs /> {/* These layout animations */}
|
|
174
|
+
</LayoutGroup>
|
|
175
|
+
<LayoutGroup>
|
|
176
|
+
<OtherTabs /> {/* Won't conflict with these */}
|
|
177
|
+
</LayoutGroup>
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Gestures
|
|
181
|
+
|
|
182
|
+
### Drag
|
|
183
|
+
|
|
184
|
+
```tsx
|
|
185
|
+
<motion.div
|
|
186
|
+
drag // Enable both axes
|
|
187
|
+
drag="x" // Horizontal only
|
|
188
|
+
drag="y" // Vertical only
|
|
189
|
+
dragConstraints={{ left: 0, right: 300, top: 0, bottom: 200 }}
|
|
190
|
+
dragElastic={0.2} // Elasticity outside constraints (0-1)
|
|
191
|
+
dragMomentum={true} // Continue after release
|
|
192
|
+
dragTransition={{ bounceStiffness: 600, bounceDamping: 20 }}
|
|
193
|
+
onDragStart={(event, info) => {}}
|
|
194
|
+
onDrag={(event, info) => {}}
|
|
195
|
+
onDragEnd={(event, info) => {}}
|
|
196
|
+
>
|
|
197
|
+
Drag me
|
|
198
|
+
</motion.div>
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Drag Info Object
|
|
202
|
+
|
|
203
|
+
```tsx
|
|
204
|
+
onDrag={(event, info) => {
|
|
205
|
+
info.point // { x, y } current position
|
|
206
|
+
info.delta // { x, y } change since last frame
|
|
207
|
+
info.offset // { x, y } offset from drag start
|
|
208
|
+
info.velocity // { x, y } current velocity
|
|
209
|
+
}}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Motion Values & Hooks
|
|
213
|
+
|
|
214
|
+
### useMotionValue
|
|
215
|
+
|
|
216
|
+
Create a value that updates without re-rendering.
|
|
217
|
+
|
|
218
|
+
```tsx
|
|
219
|
+
import { motion, useMotionValue, useTransform } from "framer-motion"
|
|
220
|
+
|
|
221
|
+
function Component() {
|
|
222
|
+
const x = useMotionValue(0)
|
|
223
|
+
|
|
224
|
+
// Transform x position to opacity
|
|
225
|
+
const opacity = useTransform(x, [-100, 0, 100], [0, 1, 0])
|
|
226
|
+
|
|
227
|
+
// Transform x to rotation
|
|
228
|
+
const rotate = useTransform(x, [-100, 100], [-10, 10])
|
|
229
|
+
|
|
230
|
+
return (
|
|
231
|
+
<motion.div
|
|
232
|
+
drag="x"
|
|
233
|
+
style={{ x, opacity, rotate }}
|
|
234
|
+
/>
|
|
235
|
+
)
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### useSpring
|
|
240
|
+
|
|
241
|
+
Create a spring-animated motion value.
|
|
242
|
+
|
|
243
|
+
```tsx
|
|
244
|
+
import { useSpring, useMotionValue } from "framer-motion"
|
|
245
|
+
|
|
246
|
+
function Component() {
|
|
247
|
+
const x = useMotionValue(0)
|
|
248
|
+
const springX = useSpring(x, { stiffness: 300, damping: 30 })
|
|
249
|
+
|
|
250
|
+
return (
|
|
251
|
+
<motion.div
|
|
252
|
+
onMouseMove={(e) => x.set(e.clientX)}
|
|
253
|
+
style={{ x: springX }}
|
|
254
|
+
/>
|
|
255
|
+
)
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### useScroll
|
|
260
|
+
|
|
261
|
+
Track scroll progress.
|
|
262
|
+
|
|
263
|
+
```tsx
|
|
264
|
+
import { useScroll, useTransform, motion } from "framer-motion"
|
|
265
|
+
|
|
266
|
+
function ProgressBar() {
|
|
267
|
+
const { scrollYProgress } = useScroll()
|
|
268
|
+
|
|
269
|
+
return (
|
|
270
|
+
<motion.div
|
|
271
|
+
className="fixed top-0 left-0 right-0 h-1 bg-blue-500 origin-left"
|
|
272
|
+
style={{ scaleX: scrollYProgress }}
|
|
273
|
+
/>
|
|
274
|
+
)
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Scroll within a container
|
|
278
|
+
const { scrollYProgress } = useScroll({
|
|
279
|
+
target: containerRef,
|
|
280
|
+
offset: ["start end", "end start"] // When to start/end tracking
|
|
281
|
+
})
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### useInView
|
|
285
|
+
|
|
286
|
+
Detect when element enters viewport.
|
|
287
|
+
|
|
288
|
+
```tsx
|
|
289
|
+
import { useInView } from "framer-motion"
|
|
290
|
+
|
|
291
|
+
function Component() {
|
|
292
|
+
const ref = useRef(null)
|
|
293
|
+
const isInView = useInView(ref, {
|
|
294
|
+
once: true, // Only trigger once
|
|
295
|
+
margin: "-100px" // Trigger 100px before entering
|
|
296
|
+
})
|
|
297
|
+
|
|
298
|
+
return (
|
|
299
|
+
<motion.div
|
|
300
|
+
ref={ref}
|
|
301
|
+
initial={{ opacity: 0, y: 50 }}
|
|
302
|
+
animate={isInView ? { opacity: 1, y: 0 } : {}}
|
|
303
|
+
/>
|
|
304
|
+
)
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## Transition Options
|
|
309
|
+
|
|
310
|
+
```tsx
|
|
311
|
+
const transition = {
|
|
312
|
+
// Timing
|
|
313
|
+
duration: 0.3,
|
|
314
|
+
delay: 0.1,
|
|
315
|
+
|
|
316
|
+
// Easing
|
|
317
|
+
ease: "easeOut", // or array: [0.23, 1, 0.32, 1]
|
|
318
|
+
|
|
319
|
+
// Spring physics
|
|
320
|
+
type: "spring",
|
|
321
|
+
stiffness: 400,
|
|
322
|
+
damping: 30,
|
|
323
|
+
mass: 1,
|
|
324
|
+
|
|
325
|
+
// Or duration-based spring
|
|
326
|
+
type: "spring",
|
|
327
|
+
duration: 0.3,
|
|
328
|
+
bounce: 0.2,
|
|
329
|
+
|
|
330
|
+
// Per-property transitions
|
|
331
|
+
opacity: { duration: 0.2 },
|
|
332
|
+
x: { type: "spring", stiffness: 300 },
|
|
333
|
+
|
|
334
|
+
// Repeat
|
|
335
|
+
repeat: Infinity,
|
|
336
|
+
repeatType: "reverse", // "loop" | "reverse" | "mirror"
|
|
337
|
+
repeatDelay: 0.5,
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
## Multi-Step Animations (Keyframes)
|
|
342
|
+
|
|
343
|
+
```tsx
|
|
344
|
+
<motion.div
|
|
345
|
+
animate={{
|
|
346
|
+
x: [0, 100, 0], // Move right then back
|
|
347
|
+
opacity: [0, 1, 1, 0], // Fade in, stay, fade out
|
|
348
|
+
scale: [1, 1.2, 1], // Grow then shrink
|
|
349
|
+
}}
|
|
350
|
+
transition={{
|
|
351
|
+
duration: 2,
|
|
352
|
+
times: [0, 0.5, 1], // When each keyframe occurs (0-1)
|
|
353
|
+
ease: "easeInOut",
|
|
354
|
+
}}
|
|
355
|
+
/>
|
|
356
|
+
```
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# Performance & Accessibility Reference
|
|
2
|
+
|
|
3
|
+
## Performance
|
|
4
|
+
|
|
5
|
+
### Target: 60 FPS
|
|
6
|
+
|
|
7
|
+
Animations should run at 60 frames per second (16.67ms per frame) for smooth motion.
|
|
8
|
+
|
|
9
|
+
### GPU-Accelerated Properties
|
|
10
|
+
|
|
11
|
+
Only these properties are hardware-accelerated and won't cause layout recalculation:
|
|
12
|
+
|
|
13
|
+
| Property | Notes |
|
|
14
|
+
|----------|-------|
|
|
15
|
+
| `transform` | translate, scale, rotate |
|
|
16
|
+
| `opacity` | Fade effects |
|
|
17
|
+
|
|
18
|
+
### Properties to Avoid Animating
|
|
19
|
+
|
|
20
|
+
These trigger layout recalculation and are expensive:
|
|
21
|
+
|
|
22
|
+
- `width`, `height`
|
|
23
|
+
- `top`, `left`, `right`, `bottom`
|
|
24
|
+
- `margin`, `padding`
|
|
25
|
+
- `border-width`
|
|
26
|
+
- `font-size`
|
|
27
|
+
|
|
28
|
+
**Instead**: Use `transform: scale()` instead of width/height, `transform: translate()` instead of top/left.
|
|
29
|
+
|
|
30
|
+
### will-change
|
|
31
|
+
|
|
32
|
+
Hints to the browser that an element will animate:
|
|
33
|
+
|
|
34
|
+
```css
|
|
35
|
+
.will-animate {
|
|
36
|
+
will-change: transform, opacity;
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Caution**: Use sparingly. Apply only to elements that actually animate, and remove after animation completes if possible. Overuse can hurt performance.
|
|
41
|
+
|
|
42
|
+
### Hardware Acceleration Hack
|
|
43
|
+
|
|
44
|
+
Force GPU layer creation (use sparingly):
|
|
45
|
+
|
|
46
|
+
```css
|
|
47
|
+
.force-gpu {
|
|
48
|
+
transform: translateZ(0);
|
|
49
|
+
/* or */
|
|
50
|
+
backface-visibility: hidden;
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Monitoring Performance
|
|
55
|
+
|
|
56
|
+
1. **Chrome DevTools**: Performance tab → Record during animation
|
|
57
|
+
2. **Rendering tab**: Enable "FPS meter" and "Paint flashing"
|
|
58
|
+
3. **Layers panel**: Check layer composition
|
|
59
|
+
|
|
60
|
+
### Common Performance Issues
|
|
61
|
+
|
|
62
|
+
| Issue | Solution |
|
|
63
|
+
|-------|----------|
|
|
64
|
+
| Janky scrolling | Use `transform` instead of `top/left` |
|
|
65
|
+
| Slow animations | Reduce number of animated elements |
|
|
66
|
+
| Memory spikes | Avoid creating new objects during animation |
|
|
67
|
+
| Layout thrashing | Batch DOM reads/writes |
|
|
68
|
+
|
|
69
|
+
## Accessibility
|
|
70
|
+
|
|
71
|
+
### prefers-reduced-motion
|
|
72
|
+
|
|
73
|
+
Users can indicate they prefer reduced motion in their system settings. Always respect this preference.
|
|
74
|
+
|
|
75
|
+
#### CSS Implementation
|
|
76
|
+
|
|
77
|
+
```css
|
|
78
|
+
/* Full animation by default */
|
|
79
|
+
.element {
|
|
80
|
+
transition: transform 300ms ease-out;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/* Reduced or no motion for users who prefer it */
|
|
84
|
+
@media (prefers-reduced-motion: reduce) {
|
|
85
|
+
.element {
|
|
86
|
+
transition: none;
|
|
87
|
+
/* or minimal transition */
|
|
88
|
+
transition: opacity 200ms ease-out;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
#### React/Framer Motion Implementation
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
import { useReducedMotion } from "framer-motion"
|
|
97
|
+
|
|
98
|
+
function AnimatedComponent() {
|
|
99
|
+
const shouldReduceMotion = useReducedMotion()
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
<motion.div
|
|
103
|
+
initial={{ opacity: 0, y: shouldReduceMotion ? 0 : 20 }}
|
|
104
|
+
animate={{ opacity: 1, y: 0 }}
|
|
105
|
+
transition={{ duration: shouldReduceMotion ? 0 : 0.3 }}
|
|
106
|
+
/>
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
#### Global Configuration with MotionConfig
|
|
112
|
+
|
|
113
|
+
```tsx
|
|
114
|
+
import { MotionConfig, useReducedMotion } from "framer-motion"
|
|
115
|
+
|
|
116
|
+
function App() {
|
|
117
|
+
const shouldReduceMotion = useReducedMotion()
|
|
118
|
+
|
|
119
|
+
return (
|
|
120
|
+
<MotionConfig reducedMotion={shouldReduceMotion ? "always" : "never"}>
|
|
121
|
+
{/* All motion components inside respect this setting */}
|
|
122
|
+
<YourApp />
|
|
123
|
+
</MotionConfig>
|
|
124
|
+
)
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### MotionConfig Options
|
|
129
|
+
|
|
130
|
+
| Value | Effect |
|
|
131
|
+
|-------|--------|
|
|
132
|
+
| `"never"` | Normal animations (default) |
|
|
133
|
+
| `"always"` | Skip all animations |
|
|
134
|
+
| `"user"` | Respect system `prefers-reduced-motion` setting |
|
|
135
|
+
|
|
136
|
+
### Accessible Animation Guidelines
|
|
137
|
+
|
|
138
|
+
1. **Provide alternatives**: Ensure content is accessible without animation
|
|
139
|
+
2. **Avoid flashing**: No content flashing more than 3 times per second
|
|
140
|
+
3. **Don't block interaction**: Animations shouldn't prevent users from interacting
|
|
141
|
+
4. **Keep it brief**: Long animations can be frustrating
|
|
142
|
+
5. **Purposeful motion**: Only animate when it adds value
|
|
143
|
+
6. **Pause controls**: For continuous animations, provide pause/stop
|
|
144
|
+
|
|
145
|
+
### Focus Management with Animations
|
|
146
|
+
|
|
147
|
+
```tsx
|
|
148
|
+
// Ensure focus moves appropriately with animated elements
|
|
149
|
+
function Modal({ isOpen }) {
|
|
150
|
+
const modalRef = useRef(null)
|
|
151
|
+
|
|
152
|
+
useEffect(() => {
|
|
153
|
+
if (isOpen) {
|
|
154
|
+
// Wait for enter animation before focusing
|
|
155
|
+
const timer = setTimeout(() => {
|
|
156
|
+
modalRef.current?.focus()
|
|
157
|
+
}, 300)
|
|
158
|
+
return () => clearTimeout(timer)
|
|
159
|
+
}
|
|
160
|
+
}, [isOpen])
|
|
161
|
+
|
|
162
|
+
return (
|
|
163
|
+
<AnimatePresence>
|
|
164
|
+
{isOpen && (
|
|
165
|
+
<motion.div
|
|
166
|
+
ref={modalRef}
|
|
167
|
+
tabIndex={-1}
|
|
168
|
+
initial={{ opacity: 0 }}
|
|
169
|
+
animate={{ opacity: 1 }}
|
|
170
|
+
exit={{ opacity: 0 }}
|
|
171
|
+
>
|
|
172
|
+
Modal content
|
|
173
|
+
</motion.div>
|
|
174
|
+
)}
|
|
175
|
+
</AnimatePresence>
|
|
176
|
+
)
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Testing Reduced Motion
|
|
181
|
+
|
|
182
|
+
1. **macOS**: System Preferences → Accessibility → Display → Reduce motion
|
|
183
|
+
2. **Windows**: Settings → Ease of Access → Display → Show animations
|
|
184
|
+
3. **iOS**: Settings → Accessibility → Motion → Reduce Motion
|
|
185
|
+
4. **Chrome DevTools**: Rendering tab → Emulate CSS media feature `prefers-reduced-motion`
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
name: auth-and-secrets
|
|
3
3
|
description: >
|
|
4
4
|
Segurança de autenticação e gestão de secrets. Usar quando: implementar auth, lidar com JWT/OAuth/SSO,
|
|
5
|
+
token no header vs URL, revogação de token no logout, enumeração de usuário/mensagem genérica,
|
|
5
6
|
guardar API keys ou credenciais, configurar Clerk/Supabase auth, revisar onde secrets estão armazenados,
|
|
6
7
|
rotação de credenciais, checar se .env está seguro.
|
|
7
8
|
---
|
|
@@ -22,6 +23,15 @@ description: >
|
|
|
22
23
|
- Refresh token com rotação: ao usar, invalide o anterior e emita novo
|
|
23
24
|
- Nunca coloque dados sensíveis no payload (é base64, não criptografia)
|
|
24
25
|
- Blacklist de tokens invalidados: Redis com TTL igual ao exp do token
|
|
26
|
+
- **Token no header `Authorization: Bearer`, NUNCA na URL/query string** (a URL vaza em logs de servidor, histórico do browser, header `Referer` e analytics)
|
|
27
|
+
- **Logout de verdade revoga o token**: coloque na blacklist (Redis, TTL = exp) e invalide o refresh token. Sem isso o access token continua válido depois do logout até expirar sozinho
|
|
28
|
+
|
|
29
|
+
### Enumeração de usuário
|
|
30
|
+
Evita que um atacante descubra quais e-mails existem na base (login, signup, reset de senha).
|
|
31
|
+
- Resposta idêntica para e-mail existente e inexistente: "Se o e-mail existir, enviamos um link"
|
|
32
|
+
- No login use mensagem genérica ("credenciais inválidas"), nunca "e-mail não cadastrado" vs "senha incorreta"
|
|
33
|
+
- Responda em **tempo constante**: rode o hash da senha mesmo quando o usuário não existe (senão o tempo de resposta denuncia quem existe)
|
|
34
|
+
- Reforce com rate limit por IP **e** por conta (ver web-security) para barrar varredura de e-mails
|
|
25
35
|
|
|
26
36
|
### OAuth / SSO
|
|
27
37
|
- Use biblioteca estabelecida, não implemente o flow manualmente
|