dreative 0.1.0 → 0.3.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/README.md +35 -35
- package/dist/cli/index.js +8 -8
- package/dist/server/preview.js +73 -73
- package/dist/shared/design.js +3 -0
- package/dist/ui/index.html +11 -11
- package/package.json +44 -44
- package/skill/dreative/DESIGN.md +478 -358
- package/skill/dreative/SKILL.md +119 -108
- package/skill/dreative/skills/3d.md +134 -131
- package/skill/dreative/skills/cinematic.md +180 -0
- package/skill/dreative/skills/immersive.md +220 -0
- package/skill/dreative/skills/interaction.md +131 -126
- package/skill/dreative/skills/motion.md +147 -125
- package/skill/dreative/skills/refined.md +99 -0
- package/dist/server/ai.js +0 -177
|
@@ -1,126 +1,131 @@
|
|
|
1
|
-
# Dreative Specialist Skill — Micro-interactions & Effect Craft
|
|
2
|
-
|
|
3
|
-
Load this file when `plan.skills` includes `interaction`, or the brief/prompt asks
|
|
4
|
-
for hover effects, cursor work, tilt, glow, "make it feel alive/tactile/premium".
|
|
5
|
-
It EXTENDS DESIGN.md §6/§9/§10 — every ban there still stands (no hover-scale on
|
|
6
|
-
`<img>`, custom cursors only on explicit request, one marquee max). This skill is
|
|
7
|
-
about the last 5% of feel: small, physical, consistent responses to input.
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
- **
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
- **
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
- **
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
- **
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
-
|
|
113
|
-
|
|
114
|
-
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
-
|
|
125
|
-
-
|
|
126
|
-
|
|
1
|
+
# Dreative Specialist Skill — Micro-interactions & Effect Craft
|
|
2
|
+
|
|
3
|
+
Load this file when `plan.skills` includes `interaction`, or the brief/prompt asks
|
|
4
|
+
for hover effects, cursor work, tilt, glow, "make it feel alive/tactile/premium".
|
|
5
|
+
It EXTENDS DESIGN.md §6/§9/§10 — every ban there still stands (no hover-scale on
|
|
6
|
+
`<img>`, custom cursors only on explicit request, one marquee max). This skill is
|
|
7
|
+
about the last 5% of feel: small, physical, consistent responses to input.
|
|
8
|
+
DESIGN.md §13 governs the touch story: everything pointer-driven here is
|
|
9
|
+
fine-pointer-only, and whatever hover reveals must be reachable by tap.
|
|
10
|
+
If an effect needs different markup (wrappers, layers, split spans), follow
|
|
11
|
+
DESIGN.md §11's transformation-depth ladder — offer the restructure and, once
|
|
12
|
+
confirmed, change the structure rather than approximating the effect in CSS.
|
|
13
|
+
|
|
14
|
+
## 0. The feel system
|
|
15
|
+
|
|
16
|
+
Micro-interactions are a SYSTEM, not garnish. Before adding any, fix three global
|
|
17
|
+
constants and apply them everywhere: one hover response vocabulary, one press
|
|
18
|
+
response, one focus style. A page where every card hovers differently reads as
|
|
19
|
+
assembled, not designed.
|
|
20
|
+
|
|
21
|
+
- **Press** (all clickables): `active:scale-[0.98]` (buttons) or
|
|
22
|
+
`active:scale-[0.99]` (large cards) + 100ms ease-out. This single rule adds more
|
|
23
|
+
perceived quality per byte than anything else in this file.
|
|
24
|
+
- **Hover** (pick ONE per element class): background tint shift, border-color
|
|
25
|
+
lift, shadow deepen (tinted to bg hue), or underline draw. 150-200ms.
|
|
26
|
+
- **Focus**: `:focus-visible` ring, 2px, offset 2px, accent color — identical on
|
|
27
|
+
every interactive element, never removed.
|
|
28
|
+
- Everything targets the 80ms "feels instant" threshold for input feedback.
|
|
29
|
+
|
|
30
|
+
## 1. Pointer-tracking effects (the premium tier)
|
|
31
|
+
|
|
32
|
+
All pointer tracking is springs/damping (Motion `useSpring` on `useMotionValue`,
|
|
33
|
+
or lerp in rAF: `x += (target - x) * 0.12`) — raw 1:1 tracking feels robotic.
|
|
34
|
+
Desktop-only: gate behind `@media (hover: hover) and (pointer: fine)`; touch gets
|
|
35
|
+
the static design, not a broken half-effect. All of these are decoration — cap at
|
|
36
|
+
1-2 distinct pointer effects per page, on the signature element's territory.
|
|
37
|
+
|
|
38
|
+
- **Magnetic elements**: on pointer-move within a proximity zone, translate the
|
|
39
|
+
element toward the cursor at 15-25% of offset (buttons) with the LABEL moving
|
|
40
|
+
a further ~10% for parallax depth; spring back on leave
|
|
41
|
+
(`stiffness 150, damping 15`). Reserve for 1-2 primary CTAs or nav items.
|
|
42
|
+
- **Spotlight cards**: radial-gradient that follows the pointer —
|
|
43
|
+
`background: radial-gradient(240px circle at var(--x) var(--y),
|
|
44
|
+
<accent 6-10% alpha>, transparent 65%)` on an overlay div; update CSS vars in
|
|
45
|
+
rAF. For grids, track on the CONTAINER and light borders of all cards from one
|
|
46
|
+
listener (the Aceternity/Linear look). Alpha ≤ 0.1; visible-but-subtle.
|
|
47
|
+
- **3D tilt**: perspective 800-1000px, max tilt 4-8° (10°+ is 2015 flash),
|
|
48
|
+
computed from pointer offset to card center, damped; add a moving specular
|
|
49
|
+
`linear-gradient` highlight at low alpha for material realism. Cards with text:
|
|
50
|
+
≤ 5° or readability suffers.
|
|
51
|
+
- **Image distortion / lens effects** need WebGL — that's `skills/3d.md` §4
|
|
52
|
+
territory; don't fake them with CSS filters.
|
|
53
|
+
|
|
54
|
+
## 2. Hover reveals and state morphs
|
|
55
|
+
|
|
56
|
+
- **Underline draw**: `background-image: linear-gradient(accent, accent)` sized
|
|
57
|
+
`0% 1.5px → 100% 1.5px` on hover, 250ms expo-out, origin left. The correct link
|
|
58
|
+
hover for editorial registers.
|
|
59
|
+
- **Text swap/scramble**: label slides up revealing a duplicate from below
|
|
60
|
+
(wrap in `overflow-hidden`, translateY both spans). Scramble/decode effects
|
|
61
|
+
only on dark-tech/playful briefs, ≤ 600ms, never on body copy.
|
|
62
|
+
- **Card reveals**: secondary info (arrow, meta row, CTA) slides/fades in ON TOP
|
|
63
|
+
of a stable layout — the card must never change size on hover (layout shift =
|
|
64
|
+
amateur tell). Arrows translate 2-4px on hover (`group-hover:translate-x-1`),
|
|
65
|
+
they don't appear from nothing.
|
|
66
|
+
- **Icon morphs**: hamburger↔close, play↔pause as two-path SVG morphs or rotated
|
|
67
|
+
strokes, 200ms. Icons that rotate/bounce on every hover = noise; icons respond
|
|
68
|
+
only when the response means something (chevron rotates because the section
|
|
69
|
+
opened).
|
|
70
|
+
- Checkbox/toggle/radio: hand-styled with an SVG check that draws in
|
|
71
|
+
(`stroke-dashoffset` 200ms) — the native-looking-but-smoother tier. Toggles
|
|
72
|
+
slide with a spring, thumb squashes slightly at rest ends.
|
|
73
|
+
|
|
74
|
+
## 3. Surface effects (no pointer needed)
|
|
75
|
+
|
|
76
|
+
- **Glow borders**: `conic-gradient` rotating behind a masked 1px border
|
|
77
|
+
(`@property --angle` + animation, or padding-box/border-box double background).
|
|
78
|
+
One element per page, dark surfaces only, accent-hued — this is a signature
|
|
79
|
+
move, not a card default.
|
|
80
|
+
- **Border beam / tracer**: an accent segment orbiting a card border via
|
|
81
|
+
`offset-path: border-box` (or rect()) — same rationing as glow.
|
|
82
|
+
- **Gradient shift**: oversized `background-size: 200%` + position animation on
|
|
83
|
+
a CTA, ≤ 2 hues from the palette. Never on text (gradient text is banned).
|
|
84
|
+
- **Noise/grain**: a tiled 128px PNG/data-URI at 2-4% opacity as a fixed overlay
|
|
85
|
+
can kill flat-gradient banding on brand pages; `feTurbulence` inline SVG is
|
|
86
|
+
banned (DESIGN.md §7) — use a pre-baked texture.
|
|
87
|
+
- **Blend modes**: `mix-blend-mode: difference` for text crossing light/dark
|
|
88
|
+
boundaries (fixed nav over sections); `multiply/screen` to sit imagery into
|
|
89
|
+
tinted surfaces. Test in both themes; blend modes are the #1 source of
|
|
90
|
+
invisible-text bugs.
|
|
91
|
+
- Shadows that feel physical: 2-3 stacked layers, tinted to the background hue,
|
|
92
|
+
y-offset ≈ blur/2 (`0 1px 2px, 0 4px 8px, 0 16px 32px` at descending alpha).
|
|
93
|
+
One elevation scale page-wide.
|
|
94
|
+
|
|
95
|
+
## 4. Scroll-adjacent feel
|
|
96
|
+
|
|
97
|
+
(Choreography lives in `skills/motion.md`; these are ambient behaviors.)
|
|
98
|
+
|
|
99
|
+
- **Sticky nav transform**: past ~80px scroll, nav gains blur backdrop
|
|
100
|
+
(`backdrop-blur-md` + bg at 70-85% alpha + hairline border-b), height eases
|
|
101
|
+
72→60px. Drive from IntersectionObserver on a sentinel, not scroll position.
|
|
102
|
+
- **Scroll progress**: thin accent bar (2px) via `scroll-timeline` /
|
|
103
|
+
`animation-timeline: scroll()`, CSS-only. Long-form articles only.
|
|
104
|
+
- **Hide-on-scroll-down nav**: product register only, translate ±100% with 300ms
|
|
105
|
+
ease, 8px hysteresis so it doesn't flicker.
|
|
106
|
+
|
|
107
|
+
## 5. Feedback micro-moments (product register)
|
|
108
|
+
|
|
109
|
+
- Button loading: label crossfades to spinner INSIDE the button at fixed width
|
|
110
|
+
(measure or `min-w`), never a layout jump; success flashes a check 600ms before
|
|
111
|
+
reverting.
|
|
112
|
+
- Copy-to-clipboard: icon morphs to check + 1.2s revert; optional 150ms
|
|
113
|
+
background pulse. No toast for copy.
|
|
114
|
+
- Form errors: input border→error color + one 4px x-axis shake (3 oscillations,
|
|
115
|
+
250ms total, reduced-motion: none) + message fades in below. Shake ONCE per
|
|
116
|
+
submit, never loop.
|
|
117
|
+
- Optimistic toggles (likes, stars): fill instantly with a 1→1.2→1 spring pop on
|
|
118
|
+
the icon; reconcile silently on failure with an inline note.
|
|
119
|
+
- Skeletons: shaped like the real layout, shimmer via one masked gradient sweep
|
|
120
|
+
(1.4s linear infinite), same radius system as the content it becomes.
|
|
121
|
+
|
|
122
|
+
## 6. Guardrails
|
|
123
|
+
|
|
124
|
+
- Decorative pointer effects: max 1-2 distinct kinds per page, desktop-only,
|
|
125
|
+
`prefers-reduced-motion` disables tracking (element stays styled, static).
|
|
126
|
+
- Nothing in this file may cause layout shift, block scrolling, steal focus, or
|
|
127
|
+
attach a raw `scroll`/`mousemove` listener without rAF batching + cleanup.
|
|
128
|
+
- Every effect must survive keyboard use: whatever hover reveals, focus reveals.
|
|
129
|
+
- Effects use palette tokens (accent/neutral), never introduce new hues.
|
|
130
|
+
- If an effect can't be justified in one sentence of communication value
|
|
131
|
+
(affordance, state, hierarchy, brand voice), it's noise — cut it (DESIGN.md §6).
|
|
@@ -1,125 +1,147 @@
|
|
|
1
|
-
# Dreative Specialist Skill — Motion & Scroll Choreography
|
|
2
|
-
|
|
3
|
-
Load this file when `plan.skills` includes `motion`, or the brief/prompt asks for
|
|
4
|
-
animation, parallax, scroll storytelling, kinetic type, or "cinematic" feel.
|
|
5
|
-
It EXTENDS DESIGN.md §6 (which still applies: 100/300/500 durations, ease-out
|
|
6
|
-
exponential curves, reduced-motion fallbacks, no scroll listeners, no bounce).
|
|
7
|
-
This file is about doing ambitious motion WELL, not about adding more of it.
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
- **
|
|
20
|
-
|
|
21
|
-
`
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
-
|
|
110
|
-
|
|
111
|
-
`
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
- **
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
- **
|
|
125
|
-
|
|
1
|
+
# Dreative Specialist Skill — Motion & Scroll Choreography
|
|
2
|
+
|
|
3
|
+
Load this file when `plan.skills` includes `motion`, or the brief/prompt asks for
|
|
4
|
+
animation, parallax, scroll storytelling, kinetic type, or "cinematic" feel.
|
|
5
|
+
It EXTENDS DESIGN.md §6 (which still applies: 100/300/500 durations, ease-out
|
|
6
|
+
exponential curves, reduced-motion fallbacks, no scroll listeners, no bounce).
|
|
7
|
+
This file is about doing ambitious motion WELL, not about adding more of it.
|
|
8
|
+
Every effect here needs a mobile strategy per DESIGN.md §13 (shorter pins,
|
|
9
|
+
halved parallax, 600ms mobile entrance budget) — decide it at design time.
|
|
10
|
+
If the requested motion needs structure the current markup can't express (pinned
|
|
11
|
+
sections, split text, persistent stages), use DESIGN.md §11's transformation-depth
|
|
12
|
+
ladder: offer restructure as an option and, once confirmed, rebuild the markup —
|
|
13
|
+
don't fake choreography onto the old skeleton.
|
|
14
|
+
|
|
15
|
+
## 0. Pick the tool by the job, not by habit
|
|
16
|
+
|
|
17
|
+
- **CSS only** — hover/focus/press states, one-shot entrances, marquees, simple
|
|
18
|
+
scroll reveals via `animation-timeline: view()`. Zero JS cost; always first choice.
|
|
19
|
+
- **Motion (`motion/react`, formerly Framer Motion)** — React apps: presence
|
|
20
|
+
(`AnimatePresence`), layout animation (`layout` prop = free FLIP), springs,
|
|
21
|
+
`whileInView`, gesture props. The default for React product+brand pages.
|
|
22
|
+
- **GSAP + ScrollTrigger** — timeline choreography: multiple elements coordinated
|
|
23
|
+
over one scroll range, scrubbed sequences, pinned sections, kinetic type.
|
|
24
|
+
Use when a Motion version would need 4+ manually-synced `useScroll` hooks.
|
|
25
|
+
- **Lenis** — smooth scroll wrapper for scroll-driven brand pages. Only on brand
|
|
26
|
+
register with motion dial ≥7; never in product UI. Sync ScrollTrigger with
|
|
27
|
+
`lenis.on('scroll', ScrollTrigger.update)`.
|
|
28
|
+
|
|
29
|
+
One animation system per page. Motion AND GSAP on the same page = two spring
|
|
30
|
+
vocabularies fighting; pick one and commit.
|
|
31
|
+
|
|
32
|
+
## 1. Springs beat durations for anything interactive
|
|
33
|
+
|
|
34
|
+
Duration+easing is for one-shot choreography (entrances, exits). Anything that
|
|
35
|
+
tracks input or can be interrupted (drag, hover follow, toggles, layout shifts)
|
|
36
|
+
uses springs — they redirect mid-flight without a visible restart.
|
|
37
|
+
|
|
38
|
+
- Motion defaults: `{ type: "spring", stiffness: 300, damping: 30 }` = snappy UI;
|
|
39
|
+
`stiffness: 120, damping: 20` = soft brand movement. Overshoot (`damping < 15`)
|
|
40
|
+
only on playful briefs, and only on small elements — never on layout.
|
|
41
|
+
- `visualDuration` (Motion ≥11.13) sets spring feel by time: easier to reason about.
|
|
42
|
+
- Never spring opacity or color; springs are for transform. Crossfade those.
|
|
43
|
+
|
|
44
|
+
## 2. Orchestration: one timeline, one story
|
|
45
|
+
|
|
46
|
+
The scattered-reveals look (every section fades up independently) is the #1 motion
|
|
47
|
+
tell. Instead:
|
|
48
|
+
|
|
49
|
+
- **Hero entrance** = ONE composed sequence: parent `staggerChildren: 0.08`,
|
|
50
|
+
`delayChildren` after nav settles; elements enter in reading order; total ≤ 900ms.
|
|
51
|
+
Nothing else on the page gets entrance choreography.
|
|
52
|
+
- **Below the fold**: at most 2-3 sections get `whileInView` reveals (`once: true`,
|
|
53
|
+
`margin: "-20% 0px"`), and they should differ (a clip reveal here, a stagger
|
|
54
|
+
there) — not the same fade-and-rise stamped on everything.
|
|
55
|
+
- Stagger direction carries meaning: top-down for lists, center-out for grids
|
|
56
|
+
(`delay: Math.abs(i - mid) * 0.05`), left-right only for horizontal sequences.
|
|
57
|
+
- Exits are faster than entrances (~75%) and simpler (fade + small offset; never
|
|
58
|
+
reverse the full entrance).
|
|
59
|
+
|
|
60
|
+
## 3. Scroll choreography (motion dial ≥ 7)
|
|
61
|
+
|
|
62
|
+
- **Scrub vs trigger**: scrub (`scrub: 0.5–1` or Motion `useScroll`+`useTransform`)
|
|
63
|
+
for progress-bound narrative (a product rotating, a number counting, a diagram
|
|
64
|
+
assembling). Triggered one-shots for everything else. Scrubbed text reveals are
|
|
65
|
+
worn out; scrub things that MOVE, trigger things that APPEAR.
|
|
66
|
+
- **Pinning**: max ONE pinned sequence per page (`ScrollTrigger pin: true`, or
|
|
67
|
+
`position: sticky` + a tall parent — prefer sticky, it's free and un-janks).
|
|
68
|
+
Pin length ≤ 2.5 viewport heights; past that users feel trapped.
|
|
69
|
+
- **Parallax**: subtle = 8-15% differential (`useTransform(scrollYProgress, [0,1],
|
|
70
|
+
["-8%","8%"])`); apply to media/decoration, never body text. 2-3 layers max.
|
|
71
|
+
- **CSS scroll-driven animations** (`animation-timeline: view(); animation-range:
|
|
72
|
+
entry 0% cover 40%`) handle simple reveals/parallax with zero JS — use for
|
|
73
|
+
progressive enhancement, gate with `@supports (animation-timeline: view())`.
|
|
74
|
+
- Progress-linked values snap to keyframes users can feel: use eased ranges
|
|
75
|
+
(`useTransform` with cubic arrays), not raw linear mapping.
|
|
76
|
+
- Never scroll-jack (hijacking wheel delta into slide-snapping). `scroll-snap` on
|
|
77
|
+
a horizontal strip is fine; taking over vertical page scroll is not.
|
|
78
|
+
|
|
79
|
+
## 4. Kinetic type and text reveal
|
|
80
|
+
|
|
81
|
+
- Split text with `SplitText` (GSAP, now free) or manual word-`<span>` wrapping;
|
|
82
|
+
animate **words or lines, not characters** for readability (chars only for short
|
|
83
|
+
display words ≤ 12 chars). Wrap split parents in `overflow-hidden` line masks and
|
|
84
|
+
slide lines up `y: "110%" → 0` — the line-mask reveal reads as premium; per-char
|
|
85
|
+
fade reads as 2021 template.
|
|
86
|
+
- `aria-label` the original string on the split container; split spans get
|
|
87
|
+
`aria-hidden`. Re-splitting on resize: debounce, or use `SplitText`'s autoSplit.
|
|
88
|
+
- Counters: animate with `useSpring`/gsap `snap: 1`, `tabular-nums` mandatory,
|
|
89
|
+
duration ≤ 1.2s, trigger once in view.
|
|
90
|
+
|
|
91
|
+
## 5. Layout & presence
|
|
92
|
+
|
|
93
|
+
- Motion `layout` prop for reflow (filtering grids, expanding cards, reordering) —
|
|
94
|
+
it's FLIP under the hood, transform-only. `layoutId` for shared-element morphs
|
|
95
|
+
(card → modal). Wrap conditional trees in `AnimatePresence mode="popLayout"`.
|
|
96
|
+
- Accordion/height: `grid-template-rows: 0fr → 1fr` (CSS, cheap) or Motion
|
|
97
|
+
`height: "auto"` (it measures for you). Never `max-height: 9999px`.
|
|
98
|
+
- **View Transitions API** for page-level transitions (`document.startViewTransition`,
|
|
99
|
+
or the framework wrapper e.g. Next `<ViewTransition>`): name persistent elements
|
|
100
|
+
with `view-transition-name` so they morph across routes. Feature-gate; fall back
|
|
101
|
+
to instant navigation, not a JS fade.
|
|
102
|
+
|
|
103
|
+
## 6. Performance and accessibility (non-negotiable)
|
|
104
|
+
|
|
105
|
+
- Transform/opacity only in hot paths; promote animating layers sparingly
|
|
106
|
+
(`will-change` set just-in-time, removed after). > 6 simultaneously-animating
|
|
107
|
+
elements = re-choreograph.
|
|
108
|
+
- All scroll work driven by IntersectionObserver / ScrollTrigger / `useScroll`
|
|
109
|
+
(rAF-batched) — a raw `scroll` listener is a hard ban (DESIGN.md).
|
|
110
|
+
- Test the tab hidden→visible case: loops must not accumulate; `whileInView` must
|
|
111
|
+
not re-fire (`once: true`).
|
|
112
|
+
- `prefers-reduced-motion`: scrubbed narratives get a static end-state, entrances
|
|
113
|
+
become plain fades ≤ 200ms, marquees stop. In Motion use `useReducedMotion()`
|
|
114
|
+
and branch the variants — don't just shorten durations.
|
|
115
|
+
- Content exists without JS: initial styles are the VISIBLE state; animation
|
|
116
|
+
libraries then hide/offset from JS before first paint (`gsap.set`, Motion
|
|
117
|
+
`initial`). An SSR'd page must never flash-then-hide.
|
|
118
|
+
|
|
119
|
+
## 7. Recipes (copy the shape, restyle the skin)
|
|
120
|
+
|
|
121
|
+
- **Hero sequence**: nav fades in (150ms) → headline lines mask-slide up, 80ms
|
|
122
|
+
stagger → subtext + CTA fade-rise together → hero media scales 1.04→1 with 6px
|
|
123
|
+
blur→0. Total 900ms, expo-out.
|
|
124
|
+
- **Sticky product walkthrough**: `sticky` media column + scrolling step copy;
|
|
125
|
+
step index from IntersectionObserver on copy blocks; media crossfades/transforms
|
|
126
|
+
per step (springy, 300ms).
|
|
127
|
+
- **Marquee**: duplicated track, `animation: scroll Xs linear infinite`,
|
|
128
|
+
`width: max-content`, pause on hover, speed from content width (px/s constant,
|
|
129
|
+
~60-90px/s), masked edges with `mask-image: linear-gradient`.
|
|
130
|
+
- **Scrub showcase**: sticky canvas/image sequence, `useScroll` on the wrapper,
|
|
131
|
+
map progress to frame index / rotation; preload frames; ≤ 2.5 viewports tall.
|
|
132
|
+
- **Canvas product story** (capsul-in-pro.com's form): a single-product launch
|
|
133
|
+
page as one scroll-scrubbed narrative — the product renders on a full-page
|
|
134
|
+
canvas (image-sequence or WebGL) and scroll drives its assembly/rotation
|
|
135
|
+
while short copy beats fade in at fixed progress stops; the site ships as
|
|
136
|
+
one bundled app with explicit portrait/landscape variants (it gates on
|
|
137
|
+
orientation rather than half-working in both). Copy the shape: one subject,
|
|
138
|
+
one scrubbed timeline, copy anchored to progress ranges, per-orientation
|
|
139
|
+
choreography decided up front.
|
|
140
|
+
- **Text on a path** (verified on epic.net): a manifesto paragraph flows along a
|
|
141
|
+
curved SVG path (`<textPath>` or per-word transforms sampled from a curve) and
|
|
142
|
+
relaxes toward straight lines as scroll progress advances — the curve
|
|
143
|
+
amplitude is the scrubbed value. One per site; body text elsewhere stays flat.
|
|
144
|
+
- **Orbiting cursor label** (epic.net's video CTA): a circular text ring
|
|
145
|
+
("PLAY VIDEO ⟲") slowly rotates around the pointer while it's over the media
|
|
146
|
+
region — SVG `<textPath>` on a circle, damped position follow, constant
|
|
147
|
+
rotation. Replaces the play button; fine pointers only, real button fallback.
|