opencodekit 0.15.0 → 0.15.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +367 -31
- package/dist/template/.opencode/README.md +1 -1
- package/dist/template/.opencode/agent/vision.md +4 -4
- package/dist/template/.opencode/command/agent-browser.md +21 -0
- package/dist/template/.opencode/command/complete-next-task.md +77 -0
- package/dist/template/.opencode/command/create.md +38 -3
- package/dist/template/.opencode/command/design-audit.md +1 -1
- package/dist/template/.opencode/command/design.md +1 -1
- package/dist/template/.opencode/command/finish.md +8 -0
- package/dist/template/.opencode/command/frontend-design.md +21 -0
- package/dist/template/.opencode/command/index-knowledge.md +25 -0
- package/dist/template/.opencode/command/init.md +6 -0
- package/dist/template/.opencode/command/opensrc.md +58 -0
- package/dist/template/.opencode/command/skill-create.md +3 -3
- package/dist/template/.opencode/command/skill-optimize.md +2 -2
- package/dist/template/.opencode/command/start.md +15 -6
- package/dist/template/.opencode/command/ui-review.md +1 -1
- package/dist/template/.opencode/memory/_templates/prd.md +50 -14
- package/dist/template/.opencode/opencode.json +143 -159
- package/dist/template/.opencode/package.json +1 -1
- package/dist/template/.opencode/skill/accessibility-audit/SKILL.md +1 -1
- package/dist/template/.opencode/skill/agent-browser/SKILL.md +376 -0
- package/dist/template/.opencode/skill/design-system-audit/SKILL.md +1 -1
- package/dist/template/.opencode/skill/frontend-design/SKILL.md +155 -0
- package/dist/template/.opencode/skill/frontend-design/references/animation/motion-advanced.md +224 -0
- package/dist/template/.opencode/skill/frontend-design/references/animation/motion-core.md +171 -0
- package/dist/template/.opencode/skill/frontend-design/references/canvas/execution.md +90 -0
- package/dist/template/.opencode/skill/frontend-design/references/canvas/philosophy.md +94 -0
- package/dist/template/.opencode/skill/frontend-design/references/shadcn/accessibility.md +132 -0
- package/dist/template/.opencode/skill/frontend-design/references/shadcn/core-components.md +153 -0
- package/dist/template/.opencode/skill/frontend-design/references/shadcn/form-components.md +158 -0
- package/dist/template/.opencode/skill/frontend-design/references/shadcn/setup.md +69 -0
- package/dist/template/.opencode/skill/frontend-design/references/shadcn/theming.md +152 -0
- package/dist/template/.opencode/skill/frontend-design/references/tailwind/responsive.md +112 -0
- package/dist/template/.opencode/skill/frontend-design/references/tailwind/utilities-layout.md +134 -0
- package/dist/template/.opencode/skill/frontend-design/references/tailwind/utilities-styling.md +165 -0
- package/dist/template/.opencode/skill/frontend-design/references/tailwind/v4-config.md +147 -0
- package/dist/template/.opencode/skill/frontend-design/references/tailwind/v4-features.md +128 -0
- package/dist/template/.opencode/skill/index-knowledge/SKILL.md +358 -0
- package/dist/template/.opencode/skill/mockup-to-code/SKILL.md +1 -1
- package/dist/template/.opencode/skill/opensrc/SKILL.md +115 -0
- package/dist/template/.opencode/skill/opensrc/references/architecture.md +176 -0
- package/dist/template/.opencode/skill/opensrc/references/cli-usage.md +176 -0
- package/dist/template/.opencode/skill/opensrc/references/registry-support.md +137 -0
- package/dist/template/.opencode/skill/prd/SKILL.md +212 -0
- package/dist/template/.opencode/skill/prd-task/SKILL.md +128 -0
- package/dist/template/.opencode/skill/prd-task/references/prd-schema.json +28 -0
- package/dist/template/.opencode/skill/skill-creator/SKILL.md +155 -0
- package/dist/template/.opencode/skill/ui-ux-research/SKILL.md +1 -1
- package/dist/template/.opencode/skill/visual-analysis/SKILL.md +1 -1
- package/package.json +1 -1
- package/dist/template/.opencode/skill/frontend-aesthetics/SKILL.md +0 -117
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# Motion Advanced
|
|
2
|
+
|
|
3
|
+
Scroll, orchestration, TypeScript, performance.
|
|
4
|
+
|
|
5
|
+
## Scroll Animations
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { motion, useScroll, useTransform } from 'motion/react';
|
|
9
|
+
|
|
10
|
+
// Scroll progress
|
|
11
|
+
const { scrollYProgress } = useScroll();
|
|
12
|
+
const opacity = useTransform(scrollYProgress, [0, 1], [1, 0]);
|
|
13
|
+
|
|
14
|
+
<motion.div style={{ opacity }} />
|
|
15
|
+
|
|
16
|
+
// Element in view
|
|
17
|
+
<motion.div
|
|
18
|
+
initial={{ opacity: 0 }}
|
|
19
|
+
whileInView={{ opacity: 1 }}
|
|
20
|
+
viewport={{ once: true, margin: '-100px' }}
|
|
21
|
+
/>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Scroll-linked Animations
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
const { scrollYProgress } = useScroll({
|
|
28
|
+
target: ref,
|
|
29
|
+
offset: ['start end', 'end start']
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const y = useTransform(scrollYProgress, [0, 1], [100, -100]);
|
|
33
|
+
const scale = useTransform(scrollYProgress, [0, 0.5, 1], [0.8, 1, 0.8]);
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## AnimatePresence Modes
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
// Wait for exit before enter
|
|
40
|
+
<AnimatePresence mode="wait">
|
|
41
|
+
<motion.div key={currentPage} />
|
|
42
|
+
</AnimatePresence>
|
|
43
|
+
|
|
44
|
+
// Popover layout (no exit/enter overlap)
|
|
45
|
+
<AnimatePresence mode="popLayout">
|
|
46
|
+
{items.map(item => <motion.div key={item.id} layout />)}
|
|
47
|
+
</AnimatePresence>
|
|
48
|
+
|
|
49
|
+
// Sync (default) - exit and enter simultaneously
|
|
50
|
+
<AnimatePresence mode="sync" />
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Orchestration
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
const container = {
|
|
57
|
+
hidden: { opacity: 0 },
|
|
58
|
+
visible: {
|
|
59
|
+
opacity: 1,
|
|
60
|
+
transition: {
|
|
61
|
+
delayChildren: 0.3,
|
|
62
|
+
staggerChildren: 0.1,
|
|
63
|
+
staggerDirection: -1, // reverse
|
|
64
|
+
when: 'beforeChildren' // or 'afterChildren'
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## TypeScript
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
import type { Variants, Transition, MotionProps } from 'motion/react';
|
|
74
|
+
|
|
75
|
+
const variants: Variants = {
|
|
76
|
+
hidden: { opacity: 0 },
|
|
77
|
+
visible: { opacity: 1 }
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const transition: Transition = {
|
|
81
|
+
type: 'spring',
|
|
82
|
+
stiffness: 300
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
interface Props extends MotionProps {
|
|
86
|
+
isOpen: boolean;
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## useMotionValueEvent
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
import { useMotionValue, useMotionValueEvent } from 'motion/react';
|
|
94
|
+
|
|
95
|
+
const x = useMotionValue(0);
|
|
96
|
+
|
|
97
|
+
useMotionValueEvent(x, 'change', (latest) => {
|
|
98
|
+
console.log('x changed to', latest);
|
|
99
|
+
});
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## useInView
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
import { useInView } from 'motion/react';
|
|
106
|
+
|
|
107
|
+
const ref = useRef(null);
|
|
108
|
+
const isInView = useInView(ref, { once: true });
|
|
109
|
+
|
|
110
|
+
<div ref={ref}>
|
|
111
|
+
{isInView && <motion.div animate={{ opacity: 1 }} />}
|
|
112
|
+
</div>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Reorder (Drag to Reorder)
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
import { Reorder } from 'motion/react';
|
|
119
|
+
|
|
120
|
+
const [items, setItems] = useState([1, 2, 3]);
|
|
121
|
+
|
|
122
|
+
<Reorder.Group values={items} onReorder={setItems}>
|
|
123
|
+
{items.map(item => (
|
|
124
|
+
<Reorder.Item key={item} value={item}>
|
|
125
|
+
{item}
|
|
126
|
+
</Reorder.Item>
|
|
127
|
+
))}
|
|
128
|
+
</Reorder.Group>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Performance
|
|
132
|
+
|
|
133
|
+
### Use transform properties
|
|
134
|
+
```tsx
|
|
135
|
+
// Good - GPU accelerated
|
|
136
|
+
animate={{ x: 100, scale: 1.1, rotate: 45, opacity: 0.5 }}
|
|
137
|
+
|
|
138
|
+
// Avoid - triggers layout
|
|
139
|
+
animate={{ width: 200, left: 100, marginTop: 20 }}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Reduce motion
|
|
143
|
+
```tsx
|
|
144
|
+
import { useReducedMotion } from 'motion/react';
|
|
145
|
+
|
|
146
|
+
const prefersReduced = useReducedMotion();
|
|
147
|
+
|
|
148
|
+
<motion.div
|
|
149
|
+
animate={prefersReduced ? {} : { scale: 1.1 }}
|
|
150
|
+
/>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Layout animation performance
|
|
154
|
+
```tsx
|
|
155
|
+
// Add layoutId for better performance on shared layouts
|
|
156
|
+
<motion.div layoutId="card" />
|
|
157
|
+
|
|
158
|
+
// Use layoutRoot to isolate layout calculations
|
|
159
|
+
<motion.div layoutRoot />
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Common Patterns
|
|
163
|
+
|
|
164
|
+
### Fade in on scroll
|
|
165
|
+
```tsx
|
|
166
|
+
<motion.div
|
|
167
|
+
initial={{ opacity: 0, y: 50 }}
|
|
168
|
+
whileInView={{ opacity: 1, y: 0 }}
|
|
169
|
+
viewport={{ once: true }}
|
|
170
|
+
transition={{ duration: 0.6 }}
|
|
171
|
+
/>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Page transitions
|
|
175
|
+
```tsx
|
|
176
|
+
<AnimatePresence mode="wait">
|
|
177
|
+
<motion.main
|
|
178
|
+
key={pathname}
|
|
179
|
+
initial={{ opacity: 0, x: 20 }}
|
|
180
|
+
animate={{ opacity: 1, x: 0 }}
|
|
181
|
+
exit={{ opacity: 0, x: -20 }}
|
|
182
|
+
>
|
|
183
|
+
{children}
|
|
184
|
+
</motion.main>
|
|
185
|
+
</AnimatePresence>
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Expandable card
|
|
189
|
+
```tsx
|
|
190
|
+
<motion.div layout onClick={() => setExpanded(!expanded)}>
|
|
191
|
+
<motion.h2 layout="position">Title</motion.h2>
|
|
192
|
+
<AnimatePresence>
|
|
193
|
+
{expanded && (
|
|
194
|
+
<motion.p
|
|
195
|
+
initial={{ opacity: 0 }}
|
|
196
|
+
animate={{ opacity: 1 }}
|
|
197
|
+
exit={{ opacity: 0 }}
|
|
198
|
+
>
|
|
199
|
+
Content
|
|
200
|
+
</motion.p>
|
|
201
|
+
)}
|
|
202
|
+
</AnimatePresence>
|
|
203
|
+
</motion.div>
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## When to Use anime.js Instead
|
|
207
|
+
|
|
208
|
+
anime.js v4 still appropriate for:
|
|
209
|
+
- Complex SVG morphing (`svg.morphTo`)
|
|
210
|
+
- SVG line drawing (`svg.createDrawable`)
|
|
211
|
+
- Timeline-heavy sequences in vanilla JS
|
|
212
|
+
- Non-React projects
|
|
213
|
+
|
|
214
|
+
```javascript
|
|
215
|
+
// anime.js for SVG morphing
|
|
216
|
+
import { animate, svg } from 'animejs';
|
|
217
|
+
animate('#path1', { d: svg.morphTo('#path2'), duration: 1 });
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Installation
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
npm install motion
|
|
224
|
+
```
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# Motion Core (formerly Framer Motion)
|
|
2
|
+
|
|
3
|
+
**Import**: `import { motion, AnimatePresence } from 'motion/react'`
|
|
4
|
+
|
|
5
|
+
## Basic Animation
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
// Simple animate on mount
|
|
9
|
+
<motion.div
|
|
10
|
+
initial={{ opacity: 0, y: 20 }}
|
|
11
|
+
animate={{ opacity: 1, y: 0 }}
|
|
12
|
+
transition={{ duration: 0.6 }}
|
|
13
|
+
/>
|
|
14
|
+
|
|
15
|
+
// Shorthand (no transition object)
|
|
16
|
+
<motion.div animate={{ scale: 1.1 }} />
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Variants (Recommended Pattern)
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
const variants = {
|
|
23
|
+
hidden: { opacity: 0, y: 20 },
|
|
24
|
+
visible: { opacity: 1, y: 0 }
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
<motion.div
|
|
28
|
+
variants={variants}
|
|
29
|
+
initial="hidden"
|
|
30
|
+
animate="visible"
|
|
31
|
+
/>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Gestures
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
<motion.button
|
|
38
|
+
whileHover={{ scale: 1.05 }}
|
|
39
|
+
whileTap={{ scale: 0.95 }}
|
|
40
|
+
whileFocus={{ outline: '2px solid blue' }}
|
|
41
|
+
/>
|
|
42
|
+
|
|
43
|
+
// Drag
|
|
44
|
+
<motion.div
|
|
45
|
+
drag
|
|
46
|
+
dragConstraints={{ left: 0, right: 300 }}
|
|
47
|
+
dragElastic={0.2}
|
|
48
|
+
/>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Layout Animations
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
// Automatic layout animation
|
|
55
|
+
<motion.div layout />
|
|
56
|
+
|
|
57
|
+
// Shared layout
|
|
58
|
+
<motion.div layoutId="shared-element" />
|
|
59
|
+
|
|
60
|
+
// Layout with spring
|
|
61
|
+
<motion.div layout transition={{ type: 'spring', stiffness: 300 }} />
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Exit Animations (AnimatePresence)
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
import { AnimatePresence } from 'motion/react';
|
|
68
|
+
|
|
69
|
+
<AnimatePresence>
|
|
70
|
+
{isVisible && (
|
|
71
|
+
<motion.div
|
|
72
|
+
key="modal"
|
|
73
|
+
initial={{ opacity: 0 }}
|
|
74
|
+
animate={{ opacity: 1 }}
|
|
75
|
+
exit={{ opacity: 0 }}
|
|
76
|
+
/>
|
|
77
|
+
)}
|
|
78
|
+
</AnimatePresence>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Stagger Children
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
const container = {
|
|
85
|
+
hidden: { opacity: 0 },
|
|
86
|
+
visible: {
|
|
87
|
+
opacity: 1,
|
|
88
|
+
transition: { staggerChildren: 0.1 }
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const item = {
|
|
93
|
+
hidden: { opacity: 0, y: 20 },
|
|
94
|
+
visible: { opacity: 1, y: 0 }
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
<motion.ul variants={container} initial="hidden" animate="visible">
|
|
98
|
+
{items.map(i => <motion.li key={i} variants={item} />)}
|
|
99
|
+
</motion.ul>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Transition Types
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
// Spring (default for physical properties)
|
|
106
|
+
transition={{ type: 'spring', stiffness: 300, damping: 20 }}
|
|
107
|
+
|
|
108
|
+
// Tween
|
|
109
|
+
transition={{ type: 'tween', duration: 0.5, ease: 'easeInOut' }}
|
|
110
|
+
|
|
111
|
+
// Inertia (for drag)
|
|
112
|
+
transition={{ type: 'inertia', velocity: 50 }}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Common Easing
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
ease: 'linear'
|
|
119
|
+
ease: 'easeIn' | 'easeOut' | 'easeInOut'
|
|
120
|
+
ease: 'circIn' | 'circOut' | 'circInOut'
|
|
121
|
+
ease: 'backIn' | 'backOut' | 'backInOut'
|
|
122
|
+
ease: [0.4, 0, 0.2, 1] // cubic-bezier
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## useAnimate Hook
|
|
126
|
+
|
|
127
|
+
```tsx
|
|
128
|
+
import { useAnimate } from 'motion/react';
|
|
129
|
+
|
|
130
|
+
function Component() {
|
|
131
|
+
const [scope, animate] = useAnimate();
|
|
132
|
+
|
|
133
|
+
const handleClick = async () => {
|
|
134
|
+
await animate(scope.current, { x: 100 });
|
|
135
|
+
await animate(scope.current, { scale: 1.2 });
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
return <div ref={scope} onClick={handleClick} />;
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Motion Values
|
|
143
|
+
|
|
144
|
+
```tsx
|
|
145
|
+
import { useMotionValue, useTransform } from 'motion/react';
|
|
146
|
+
|
|
147
|
+
const x = useMotionValue(0);
|
|
148
|
+
const opacity = useTransform(x, [0, 100], [1, 0]);
|
|
149
|
+
|
|
150
|
+
<motion.div style={{ x, opacity }} drag="x" />
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Integration with Tailwind
|
|
154
|
+
|
|
155
|
+
```tsx
|
|
156
|
+
// Motion handles animation, Tailwind handles styling
|
|
157
|
+
<motion.div
|
|
158
|
+
className="bg-blue-500 rounded-lg p-4"
|
|
159
|
+
whileHover={{ scale: 1.05 }}
|
|
160
|
+
transition={{ type: 'spring' }}
|
|
161
|
+
/>
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Validation Checklist
|
|
165
|
+
|
|
166
|
+
- [ ] Import from `motion/react` (not `framer-motion`)
|
|
167
|
+
- [ ] Use variants for complex animations
|
|
168
|
+
- [ ] Wrap conditional renders with `AnimatePresence`
|
|
169
|
+
- [ ] Add `key` prop to animated elements in `AnimatePresence`
|
|
170
|
+
- [ ] Use `layout` for automatic layout animations
|
|
171
|
+
- [ ] Prefer `whileHover`/`whileTap` over CSS `:hover`
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Canvas Design Execution
|
|
2
|
+
|
|
3
|
+
Implementation, multi-page systems, quality standards.
|
|
4
|
+
|
|
5
|
+
## Subtle Reference Integration
|
|
6
|
+
|
|
7
|
+
Embed conceptual DNA without announcing:
|
|
8
|
+
- Niche reference woven invisibly
|
|
9
|
+
- Those who know feel it intuitively
|
|
10
|
+
- Others experience masterful composition
|
|
11
|
+
- Sophisticated, never literal
|
|
12
|
+
|
|
13
|
+
## Multi-Page Systems
|
|
14
|
+
|
|
15
|
+
### Approach
|
|
16
|
+
- First page as single page in coffee table book
|
|
17
|
+
- Distinctly different but cohesive
|
|
18
|
+
- Pages tell story tastefully
|
|
19
|
+
|
|
20
|
+
### Consistency
|
|
21
|
+
- Shared color palette
|
|
22
|
+
- Consistent typography
|
|
23
|
+
- Related composition
|
|
24
|
+
- Philosophical thread
|
|
25
|
+
|
|
26
|
+
### Variation
|
|
27
|
+
- Unique twist per page
|
|
28
|
+
- Different focal points
|
|
29
|
+
- Varied arrangements
|
|
30
|
+
- Progressive narrative
|
|
31
|
+
|
|
32
|
+
## Execution Checklist
|
|
33
|
+
|
|
34
|
+
Before finalizing:
|
|
35
|
+
- [ ] Philosophy guides every decision
|
|
36
|
+
- [ ] 90% visual, 10% text max
|
|
37
|
+
- [ ] Text minimal and integrated
|
|
38
|
+
- [ ] Nothing overlaps or falls off page
|
|
39
|
+
- [ ] Margins pristine
|
|
40
|
+
- [ ] Composition cohesive
|
|
41
|
+
- [ ] Meticulously crafted appearance
|
|
42
|
+
- [ ] Master-level execution
|
|
43
|
+
- [ ] Could be displayed in museum
|
|
44
|
+
|
|
45
|
+
## Quality Standards
|
|
46
|
+
|
|
47
|
+
### Avoid
|
|
48
|
+
- Cartoony aesthetics
|
|
49
|
+
- Amateur execution
|
|
50
|
+
- Text-heavy composition
|
|
51
|
+
- Random placement
|
|
52
|
+
- Overlapping elements
|
|
53
|
+
- Inconsistent spacing
|
|
54
|
+
- Generic AI generation
|
|
55
|
+
|
|
56
|
+
### Achieve
|
|
57
|
+
- Museum quality
|
|
58
|
+
- Magazine worthy
|
|
59
|
+
- Art object status
|
|
60
|
+
- Top-of-field craftsmanship
|
|
61
|
+
- Philosophical coherence
|
|
62
|
+
- Visual sophistication
|
|
63
|
+
- Systematic precision
|
|
64
|
+
|
|
65
|
+
## Refinement Process
|
|
66
|
+
|
|
67
|
+
### Initial Pass
|
|
68
|
+
Create based on philosophy and principles.
|
|
69
|
+
|
|
70
|
+
### Second Pass (Critical)
|
|
71
|
+
- Don't add more graphics
|
|
72
|
+
- Refine what exists
|
|
73
|
+
- Make extremely crisp
|
|
74
|
+
- Respect minimalism
|
|
75
|
+
- Increase cohesion
|
|
76
|
+
- Polish rather than expand
|
|
77
|
+
|
|
78
|
+
### Final
|
|
79
|
+
Pristine masterpiece, ready for museum display.
|
|
80
|
+
|
|
81
|
+
## Use Cases
|
|
82
|
+
|
|
83
|
+
- Brand identity systems
|
|
84
|
+
- Poster designs
|
|
85
|
+
- Visual manifestos
|
|
86
|
+
- Design system docs
|
|
87
|
+
- Art pieces
|
|
88
|
+
- Editorial design
|
|
89
|
+
- Exhibition materials
|
|
90
|
+
- Coffee table books
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Canvas Design Philosophy
|
|
2
|
+
|
|
3
|
+
Visual design philosophy for sophisticated compositions.
|
|
4
|
+
|
|
5
|
+
## Two-Phase Approach
|
|
6
|
+
|
|
7
|
+
### Phase 1: Philosophy Creation
|
|
8
|
+
Create aesthetic movement through form, space, color, composition. Not layouts - pure visual philosophy.
|
|
9
|
+
|
|
10
|
+
Structure (4-6 paragraphs):
|
|
11
|
+
- Space and form principles
|
|
12
|
+
- Color and material approach
|
|
13
|
+
- Scale and rhythm guidance
|
|
14
|
+
- Composition and balance
|
|
15
|
+
- Visual hierarchy system
|
|
16
|
+
|
|
17
|
+
### Phase 2: Visual Expression
|
|
18
|
+
Express through canvas:
|
|
19
|
+
- 90% visual design
|
|
20
|
+
- 10% essential text
|
|
21
|
+
- Museum-quality execution
|
|
22
|
+
- Systematic patterns
|
|
23
|
+
|
|
24
|
+
## Core Principles
|
|
25
|
+
|
|
26
|
+
### 1. Visual Communication First
|
|
27
|
+
Information lives in design, not paragraphs:
|
|
28
|
+
- Color zones and fields
|
|
29
|
+
- Geometric precision
|
|
30
|
+
- Spatial relationships
|
|
31
|
+
- Visual weight and tension
|
|
32
|
+
|
|
33
|
+
### 2. Minimal Text
|
|
34
|
+
Text as rare, powerful gesture:
|
|
35
|
+
- Never paragraphs
|
|
36
|
+
- Only essential words
|
|
37
|
+
- Integrated into architecture
|
|
38
|
+
- Typography as visual element
|
|
39
|
+
|
|
40
|
+
### 3. Expert Craftsmanship
|
|
41
|
+
Work must appear:
|
|
42
|
+
- Meticulously crafted
|
|
43
|
+
- Product of countless hours
|
|
44
|
+
- Master-level execution
|
|
45
|
+
- Museum-worthy quality
|
|
46
|
+
|
|
47
|
+
### 4. Systematic Patterns
|
|
48
|
+
Scientific visual language:
|
|
49
|
+
- Repeating patterns = rhythm
|
|
50
|
+
- Perfect geometric shapes
|
|
51
|
+
- Dense accumulation builds meaning
|
|
52
|
+
- Patient repetition rewards viewing
|
|
53
|
+
|
|
54
|
+
## Design Movements
|
|
55
|
+
|
|
56
|
+
### Concrete Poetry
|
|
57
|
+
Monumental form, bold geometry. Massive color blocks. Sculptural typography. Text as rare, powerful gesture.
|
|
58
|
+
|
|
59
|
+
### Chromatic Language
|
|
60
|
+
Color as information. Geometric precision. Color zones create meaning. Words only anchor what color shows.
|
|
61
|
+
|
|
62
|
+
### Analog Meditation
|
|
63
|
+
Quiet contemplation through texture. Paper grain, ink bleeds. Vast negative space. Images breathe across pages.
|
|
64
|
+
|
|
65
|
+
### Organic Systems
|
|
66
|
+
Natural clustering, modular growth. Rounded forms, organic arrangements. Information through diagrams.
|
|
67
|
+
|
|
68
|
+
### Geometric Silence
|
|
69
|
+
Pure order and restraint. Grid precision. Dramatic negative space. Swiss formalism meets Brutalist honesty.
|
|
70
|
+
|
|
71
|
+
## Implementation
|
|
72
|
+
|
|
73
|
+
### Color
|
|
74
|
+
```css
|
|
75
|
+
@theme {
|
|
76
|
+
--color-primary: oklch(0.55 0.22 264);
|
|
77
|
+
--color-accent: oklch(0.75 0.18 45);
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Limited (2-5), cohesive, purposeful relationships.
|
|
82
|
+
|
|
83
|
+
### Typography
|
|
84
|
+
- Light weights (200-300)
|
|
85
|
+
- Clean sans-serifs
|
|
86
|
+
- Geometric precision
|
|
87
|
+
- Small for labels, large for rare impact
|
|
88
|
+
|
|
89
|
+
### Composition
|
|
90
|
+
- Repeating patterns establish rhythm
|
|
91
|
+
- Perfect geometric shapes
|
|
92
|
+
- Nothing falls off page
|
|
93
|
+
- Nothing overlaps unintentionally
|
|
94
|
+
- Proper margins non-negotiable
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# shadcn/ui Accessibility
|
|
2
|
+
|
|
3
|
+
ARIA patterns, keyboard navigation, screen reader support via Radix UI.
|
|
4
|
+
|
|
5
|
+
## Radix Foundation
|
|
6
|
+
|
|
7
|
+
Built-in: keyboard navigation, screen reader announcements, focus management, ARIA automatic.
|
|
8
|
+
|
|
9
|
+
## Keyboard Navigation
|
|
10
|
+
|
|
11
|
+
### Focus Management
|
|
12
|
+
```tsx
|
|
13
|
+
<Button className="focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2">
|
|
14
|
+
|
|
15
|
+
<!-- Skip link -->
|
|
16
|
+
<a href="#main" className="sr-only focus:not-sr-only focus:absolute focus:top-4 focus:left-4 focus:z-50 focus:px-4 focus:py-2">
|
|
17
|
+
Skip to content
|
|
18
|
+
</a>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Dialog
|
|
22
|
+
Focus trapped automatically. Esc closes, Tab cycles.
|
|
23
|
+
|
|
24
|
+
### Dropdown/Menu
|
|
25
|
+
- Space/Enter: Open
|
|
26
|
+
- Arrow Up/Down: Navigate
|
|
27
|
+
- Esc: Close
|
|
28
|
+
- Tab: Close and move focus
|
|
29
|
+
|
|
30
|
+
## Screen Reader
|
|
31
|
+
|
|
32
|
+
### ARIA Labels
|
|
33
|
+
```tsx
|
|
34
|
+
<Button aria-label="Close dialog"><X /></Button>
|
|
35
|
+
<Input aria-label="Email address" type="email" />
|
|
36
|
+
|
|
37
|
+
<Button aria-describedby="delete-desc">Delete</Button>
|
|
38
|
+
<p id="delete-desc" className="sr-only">Permanently deletes account</p>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Screen Reader Only
|
|
42
|
+
```tsx
|
|
43
|
+
<Button>
|
|
44
|
+
<Trash className="h-4 w-4" />
|
|
45
|
+
<span className="sr-only">Delete item</span>
|
|
46
|
+
</Button>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Live Regions
|
|
50
|
+
```tsx
|
|
51
|
+
<div aria-live="polite">{message}</div>
|
|
52
|
+
<div aria-live="assertive">{error}</div>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Forms
|
|
56
|
+
|
|
57
|
+
### Labels
|
|
58
|
+
```tsx
|
|
59
|
+
<Label htmlFor="email">Email</Label>
|
|
60
|
+
<Input id="email" type="email" />
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Validation
|
|
64
|
+
```tsx
|
|
65
|
+
<Input aria-invalid={!!error} aria-describedby={error ? "email-error" : undefined} />
|
|
66
|
+
<FormMessage id="email-error" />
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Required Fields
|
|
70
|
+
```tsx
|
|
71
|
+
<Label htmlFor="name">
|
|
72
|
+
Name <span className="text-destructive">*</span>
|
|
73
|
+
<span className="sr-only">(required)</span>
|
|
74
|
+
</Label>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Fieldset
|
|
78
|
+
```tsx
|
|
79
|
+
<fieldset>
|
|
80
|
+
<legend className="text-lg font-semibold mb-4">Contact Info</legend>
|
|
81
|
+
<FormField name="email" />
|
|
82
|
+
</fieldset>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Color Contrast
|
|
86
|
+
|
|
87
|
+
WCAG AA: 4.5:1 normal text, 3:1 large text.
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
// Good
|
|
91
|
+
<p className="text-foreground">Primary</p>
|
|
92
|
+
<p className="text-muted-foreground">Secondary</p>
|
|
93
|
+
|
|
94
|
+
// Avoid
|
|
95
|
+
<p className="text-gray-400">Hard to read</p>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Focus Indicators
|
|
99
|
+
|
|
100
|
+
Always visible:
|
|
101
|
+
```tsx
|
|
102
|
+
<Button className="focus-visible:ring-2 focus-visible:ring-ring">
|
|
103
|
+
|
|
104
|
+
// Never: focus:outline-none without replacement
|
|
105
|
+
// Use focus-visible instead
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Motion Preferences
|
|
109
|
+
|
|
110
|
+
```css
|
|
111
|
+
@media (prefers-reduced-motion: reduce) {
|
|
112
|
+
* { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
```tsx
|
|
117
|
+
<div className="transition-all motion-reduce:transition-none">
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Checklist
|
|
121
|
+
|
|
122
|
+
- [ ] All interactive elements keyboard accessible
|
|
123
|
+
- [ ] Focus indicators visible
|
|
124
|
+
- [ ] Screen reader announces correctly
|
|
125
|
+
- [ ] Form errors announced
|
|
126
|
+
- [ ] Color contrast WCAG AA
|
|
127
|
+
- [ ] Semantic HTML
|
|
128
|
+
- [ ] ARIA labels for icon buttons
|
|
129
|
+
- [ ] Modal focus trap works
|
|
130
|
+
- [ ] Respects reduced motion
|
|
131
|
+
- [ ] Works at 200% zoom
|
|
132
|
+
- [ ] Skip links provided
|