@jaimevalasek/aioson 1.30.0 → 1.30.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/CHANGELOG.md +18 -0
- package/docs/design-previews/cognitive-core-ui-auth.html +95 -0
- package/docs/design-previews/cognitive-core-ui-kanban.html +231 -0
- package/docs/design-previews/cognitive-core-ui-list-detail.html +174 -0
- package/docs/design-previews/cognitive-core-ui-preview.css +1315 -0
- package/docs/design-previews/cognitive-core-ui-settings.html +142 -0
- package/docs/design-previews/cognitive-core-ui-website.html +190 -1009
- package/docs/design-previews/cognitive-core-ui.html +281 -463
- package/docs/design-previews/index.html +83 -31
- package/package.json +1 -1
- package/src/constants.js +578 -514
- package/template/.aioson/docs/integrations/dashboard-app-form-publish-mapping.md +183 -0
- package/template/.aioson/docs/play/README.md +74 -0
- package/template/.aioson/docs/play/agent-usage-guide.md +112 -0
- package/template/.aioson/docs/play/app-compatibility-guide.md +117 -0
- package/template/.aioson/docs/play/auth-services-and-testing.md +235 -0
- package/template/.aioson/docs/play/llm-data-and-bindings.md +238 -0
- package/template/.aioson/docs/play/manifest-and-runtime.md +267 -0
- package/template/.aioson/docs/play/source-map.md +104 -0
- package/template/.aioson/skills/design/aurora-command-ui/SKILL.md +266 -243
- package/template/.aioson/skills/design/aurora-command-ui/references/art-direction.md +293 -293
- package/template/.aioson/skills/design/aurora-command-ui/references/components.md +827 -827
- package/template/.aioson/skills/design/aurora-command-ui/references/dashboards.md +250 -250
- package/template/.aioson/skills/design/aurora-command-ui/references/design-tokens.md +585 -585
- package/template/.aioson/skills/design/aurora-command-ui/references/motion.md +365 -365
- package/template/.aioson/skills/design/aurora-command-ui/references/patterns.md +485 -482
- package/template/.aioson/skills/design/aurora-command-ui/references/websites.md +386 -387
- package/template/.aioson/skills/design/bold-editorial-ui/SKILL.md +228 -205
- package/template/.aioson/skills/design/bold-editorial-ui/references/art-direction.md +338 -338
- package/template/.aioson/skills/design/bold-editorial-ui/references/components.md +977 -977
- package/template/.aioson/skills/design/bold-editorial-ui/references/dashboards.md +218 -218
- package/template/.aioson/skills/design/bold-editorial-ui/references/design-tokens.md +326 -326
- package/template/.aioson/skills/design/bold-editorial-ui/references/motion.md +461 -461
- package/template/.aioson/skills/design/bold-editorial-ui/references/patterns.md +293 -293
- package/template/.aioson/skills/design/bold-editorial-ui/references/websites.md +352 -352
- package/template/.aioson/skills/design/clean-saas-ui/SKILL.md +233 -210
- package/template/.aioson/skills/design/clean-saas-ui/references/art-direction.md +319 -319
- package/template/.aioson/skills/design/clean-saas-ui/references/components.md +365 -365
- package/template/.aioson/skills/design/clean-saas-ui/references/dashboards.md +196 -196
- package/template/.aioson/skills/design/clean-saas-ui/references/design-tokens.md +244 -244
- package/template/.aioson/skills/design/clean-saas-ui/references/motion.md +235 -235
- package/template/.aioson/skills/design/clean-saas-ui/references/patterns.md +215 -215
- package/template/.aioson/skills/design/clean-saas-ui/references/websites.md +295 -295
- package/template/.aioson/skills/design/cognitive-core-ui/SKILL.md +239 -203
- package/template/.aioson/skills/design/cognitive-core-ui/references/art-direction.md +339 -339
- package/template/.aioson/skills/design/cognitive-core-ui/references/components.md +417 -407
- package/template/.aioson/skills/design/cognitive-core-ui/references/dashboards.md +289 -272
- package/template/.aioson/skills/design/cognitive-core-ui/references/design-tokens.md +525 -524
- package/template/.aioson/skills/design/cognitive-core-ui/references/motion.md +279 -279
- package/template/.aioson/skills/design/cognitive-core-ui/references/patterns.md +355 -289
- package/template/.aioson/skills/design/cognitive-core-ui/references/websites.md +443 -437
- package/template/.aioson/skills/design/glassmorphism-ui/SKILL.md +245 -222
- package/template/.aioson/skills/design/glassmorphism-ui/references/art-direction.md +159 -159
- package/template/.aioson/skills/design/glassmorphism-ui/references/components.md +498 -498
- package/template/.aioson/skills/design/glassmorphism-ui/references/dashboards.md +236 -236
- package/template/.aioson/skills/design/glassmorphism-ui/references/design-tokens.md +274 -274
- package/template/.aioson/skills/design/glassmorphism-ui/references/motion.md +355 -355
- package/template/.aioson/skills/design/glassmorphism-ui/references/patterns.md +198 -198
- package/template/.aioson/skills/design/glassmorphism-ui/references/websites.md +307 -307
- package/template/.aioson/skills/design/interface-design/SKILL.md +68 -47
- package/template/.aioson/skills/design/interface-design/references/components-and-states.md +105 -105
- package/template/.aioson/skills/design/interface-design/references/design-directions.md +101 -101
- package/template/.aioson/skills/design/interface-design/references/handoff-and-quality.md +92 -71
- package/template/.aioson/skills/design/interface-design/references/intent-and-domain.md +74 -74
- package/template/.aioson/skills/design/interface-design/references/tokens-and-depth.md +173 -173
- package/template/.aioson/skills/design/neo-brutalist-ui/SKILL.md +236 -213
- package/template/.aioson/skills/design/neo-brutalist-ui/references/art-direction.md +228 -228
- package/template/.aioson/skills/design/neo-brutalist-ui/references/components.md +855 -855
- package/template/.aioson/skills/design/neo-brutalist-ui/references/dashboards.md +334 -334
- package/template/.aioson/skills/design/neo-brutalist-ui/references/design-tokens.md +342 -342
- package/template/.aioson/skills/design/neo-brutalist-ui/references/motion.md +286 -286
- package/template/.aioson/skills/design/neo-brutalist-ui/references/patterns.md +458 -458
- package/template/.aioson/skills/design/neo-brutalist-ui/references/websites.md +723 -723
- package/template/.aioson/skills/design/premium-command-center-ui/SKILL.md +83 -62
- package/template/.aioson/skills/design/premium-command-center-ui/references/operations.md +74 -74
- package/template/.aioson/skills/design/premium-command-center-ui/references/patterns.md +116 -116
- package/template/.aioson/skills/design/premium-command-center-ui/references/validation.md +47 -47
- package/template/.aioson/skills/design/premium-command-center-ui/references/visual-system.md +215 -215
- package/template/.aioson/skills/design/pt.squarespace.com/.skill-meta.json +31 -31
- package/template/.aioson/skills/design/pt.squarespace.com/SKILL.md +94 -66
- package/template/.aioson/skills/design/pt.squarespace.com/references/components.md +366 -366
- package/template/.aioson/skills/design/pt.squarespace.com/references/design-tokens.md +150 -150
- package/template/.aioson/skills/design/pt.squarespace.com/references/motion.md +270 -270
- package/template/.aioson/skills/design/pt.squarespace.com/references/patterns.md +189 -189
- package/template/.aioson/skills/design/pt.squarespace.com/references/websites.md +161 -161
- package/template/.aioson/skills/design/warm-craft-ui/SKILL.md +232 -209
- package/template/.aioson/skills/design/warm-craft-ui/references/art-direction.md +324 -324
- package/template/.aioson/skills/design/warm-craft-ui/references/components.md +508 -508
- package/template/.aioson/skills/design/warm-craft-ui/references/dashboards.md +223 -223
- package/template/.aioson/skills/design/warm-craft-ui/references/design-tokens.md +374 -374
- package/template/.aioson/skills/design/warm-craft-ui/references/motion.md +356 -356
- package/template/.aioson/skills/design/warm-craft-ui/references/patterns.md +288 -288
- package/template/.aioson/skills/design/warm-craft-ui/references/websites.md +289 -289
|
@@ -1,235 +1,235 @@
|
|
|
1
|
-
# Motion — Clean SaaS UI
|
|
2
|
-
|
|
3
|
-
## Principle: functional, not decorative
|
|
4
|
-
|
|
5
|
-
Animation in Clean SaaS exists for **feedback and orientation**, not for impression.
|
|
6
|
-
|
|
7
|
-
Every animation must answer: does this help the user understand what happened, or where they are? If not, remove it.
|
|
8
|
-
|
|
9
|
-
- Keep everything fast: 150-250ms max for interactions, 300ms for page transitions
|
|
10
|
-
- Easing: `ease-out` for entrances, `ease-in` for exits
|
|
11
|
-
- **ZERO scroll animations on app pages** - only on marketing pages, and with restraint
|
|
12
|
-
- If the animation feels fast to the developer, it is probably the right speed for the user
|
|
13
|
-
|
|
14
|
-
---
|
|
15
|
-
|
|
16
|
-
## Timing tokens
|
|
17
|
-
|
|
18
|
-
```css
|
|
19
|
-
:root {
|
|
20
|
-
--transition-fast: 100ms ease;
|
|
21
|
-
--transition-base: 150ms ease;
|
|
22
|
-
--transition-slow: 250ms ease;
|
|
23
|
-
}
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
These are the only durations used in app pages. Never use values outside this range for UI interactions.
|
|
27
|
-
|
|
28
|
-
For page-level transitions (route change, modal open): max `300ms`.
|
|
29
|
-
|
|
30
|
-
---
|
|
31
|
-
|
|
32
|
-
## Entrances
|
|
33
|
-
|
|
34
|
-
### Fade In
|
|
35
|
-
- `opacity: 0 → 1`
|
|
36
|
-
- Duration: `200ms ease-out`
|
|
37
|
-
- Use for: any element appearing without positional change — tooltips, inline state changes
|
|
38
|
-
|
|
39
|
-
```css
|
|
40
|
-
@keyframes fadeIn {
|
|
41
|
-
from { opacity: 0; }
|
|
42
|
-
to { opacity: 1; }
|
|
43
|
-
}
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### Fade Up
|
|
47
|
-
- `translateY(8px) → translateY(0)` + `opacity: 0 → 1`
|
|
48
|
-
- Duration: `250ms ease-out`
|
|
49
|
-
- Use for: cards appearing, dashboard sections loading, notifications
|
|
50
|
-
- **8px displacement only** — smaller than warm-craft (12px) and cognitive-core (10px). Clean SaaS moves less.
|
|
51
|
-
|
|
52
|
-
```css
|
|
53
|
-
@keyframes fadeUp {
|
|
54
|
-
from { opacity: 0; transform: translateY(8px); }
|
|
55
|
-
to { opacity: 1; transform: translateY(0); }
|
|
56
|
-
}
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
### Scale In
|
|
60
|
-
- `scale(0.97) → scale(1)` + `opacity: 0 → 1`
|
|
61
|
-
- Duration: `200ms ease-out`
|
|
62
|
-
- Use for: modals, dropdowns, popovers, context menus
|
|
63
|
-
- **0.97 scale** — barely perceptible, just enough for spatial cue. Not 0.95 (too dramatic).
|
|
64
|
-
|
|
65
|
-
```css
|
|
66
|
-
@keyframes scaleIn {
|
|
67
|
-
from { opacity: 0; transform: scale(0.97); }
|
|
68
|
-
to { opacity: 1; transform: scale(1); }
|
|
69
|
-
}
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
---
|
|
73
|
-
|
|
74
|
-
## Micro-interactions
|
|
75
|
-
|
|
76
|
-
### Buttons
|
|
77
|
-
- **Hover**: background color shift, `100ms ease`
|
|
78
|
-
- **Press**: `scale(0.99)`, `60ms ease-in` — nearly imperceptible, just tactile
|
|
79
|
-
- **Loading**: spinner replaces leading icon, text unchanged, cursor: `not-allowed` during load
|
|
80
|
-
- **Success**: brief `checkmark` icon flash, `300ms`, then returns to default state
|
|
81
|
-
|
|
82
|
-
### Cards
|
|
83
|
-
- **Hover**: `box-shadow: var(--shadow-sm) → var(--shadow-md)`, `150ms ease`
|
|
84
|
-
- **NO translateY lift** — Clean SaaS cards do not "float up" on hover (unlike warm-craft). Cards stay grounded.
|
|
85
|
-
|
|
86
|
-
### Inputs
|
|
87
|
-
- **Focus**: `border-color → var(--accent)`, ring appears `ring-2 ring-accent/20`, `100ms ease`
|
|
88
|
-
- **Error**: border goes `border-semantic-danger`, shakes if invalid on submit (see below)
|
|
89
|
-
- **Validation success**: brief green border flash before returning to default
|
|
90
|
-
|
|
91
|
-
### Input shake (validation error)
|
|
92
|
-
```css
|
|
93
|
-
@keyframes shake {
|
|
94
|
-
0%, 100% { transform: translateX(0); }
|
|
95
|
-
20% { transform: translateX(-4px); }
|
|
96
|
-
40% { transform: translateX(4px); }
|
|
97
|
-
60% { transform: translateX(-3px); }
|
|
98
|
-
80% { transform: translateX(3px); }
|
|
99
|
-
}
|
|
100
|
-
/* Duration: 320ms — fast, firm, not cartoonish */
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
### Dropdowns
|
|
104
|
-
- Open: `scaleIn` + `fadeIn`, `150ms ease-out`, origin at trigger
|
|
105
|
-
- Close: `opacity: 1 → 0`, `100ms ease-in` — faster out than in
|
|
106
|
-
|
|
107
|
-
### Toggle switch
|
|
108
|
-
- Thumb: `translateX` from off to on position, `150ms ease`
|
|
109
|
-
- Background: color transition `bg-border-strong → bg-accent`, `150ms ease`
|
|
110
|
-
|
|
111
|
-
### Sidebar collapse (mobile)
|
|
112
|
-
- `translateX(-256px) → translateX(0)`, `250ms ease-out`
|
|
113
|
-
- Backdrop: `opacity: 0 → 0.4`, `200ms ease`
|
|
114
|
-
|
|
115
|
-
---
|
|
116
|
-
|
|
117
|
-
## Stagger
|
|
118
|
-
|
|
119
|
-
When multiple items appear together (card grid, list load, table rows):
|
|
120
|
-
|
|
121
|
-
- Delay per item: `40ms` — faster than warm-craft (60ms) to match efficiency feel
|
|
122
|
-
- Max staggered items: **4** — after 4, all remaining items appear simultaneously
|
|
123
|
-
- Base delay: `0ms` (first item appears immediately)
|
|
124
|
-
|
|
125
|
-
```
|
|
126
|
-
Item 1: 0ms delay
|
|
127
|
-
Item 2: 40ms delay
|
|
128
|
-
Item 3: 80ms delay
|
|
129
|
-
Item 4: 120ms delay
|
|
130
|
-
Item 5+: 120ms delay (same as item 4 — no more stagger)
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
---
|
|
134
|
-
|
|
135
|
-
## Page transitions
|
|
136
|
-
|
|
137
|
-
### Route change
|
|
138
|
-
- Old page: `opacity: 1 → 0`, `150ms ease-in`
|
|
139
|
-
- New page: `opacity: 0 → 1`, `200ms ease-out`
|
|
140
|
-
- Optionally: `translateY(4px) → 0` on new page entry
|
|
141
|
-
|
|
142
|
-
### Tab switch
|
|
143
|
-
- Content: `fadeIn` `200ms ease-out` — do NOT slide tabs horizontally (it's disorienting in data-dense apps)
|
|
144
|
-
|
|
145
|
-
### Modal open
|
|
146
|
-
- Backdrop: `opacity: 0 → 0.4`, `200ms ease`
|
|
147
|
-
- Modal: `scaleIn` `200ms ease-out`
|
|
148
|
-
|
|
149
|
-
### Modal close
|
|
150
|
-
- Modal: `scale(1) → scale(0.97)` + `opacity: 1 → 0`, `150ms ease-in`
|
|
151
|
-
- Backdrop: `opacity: 0.4 → 0`, `150ms ease`
|
|
152
|
-
|
|
153
|
-
### Toast
|
|
154
|
-
- Enter: `translateX(calc(100% + 16px)) → translateX(0)`, `250ms ease-out` (slides in from right)
|
|
155
|
-
- Auto-dismiss: after 5s, `opacity: 1 → 0` over `300ms`
|
|
156
|
-
- Manual dismiss: `opacity: 1 → 0` + `scale(0.96)`, `150ms ease-in`
|
|
157
|
-
|
|
158
|
-
---
|
|
159
|
-
|
|
160
|
-
## Loading states
|
|
161
|
-
|
|
162
|
-
### Skeleton pulse
|
|
163
|
-
```css
|
|
164
|
-
@keyframes pulse {
|
|
165
|
-
0%, 100% { opacity: 1; }
|
|
166
|
-
50% { opacity: 0.5; }
|
|
167
|
-
}
|
|
168
|
-
/* Duration: 1.5s — slower than a button transition, rhythmic */
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
### Spinner
|
|
172
|
-
```css
|
|
173
|
-
@keyframes spin {
|
|
174
|
-
from { transform: rotate(0deg); }
|
|
175
|
-
to { transform: rotate(360deg); }
|
|
176
|
-
}
|
|
177
|
-
/* Duration: 800ms linear infinite — smooth, not jerky */
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
### Progress bar (indeterminate)
|
|
181
|
-
```css
|
|
182
|
-
@keyframes indeterminate {
|
|
183
|
-
0% { left: -35%; right: 100%; }
|
|
184
|
-
60% { left: 100%; right: -90%; }
|
|
185
|
-
100% { left: 100%; right: -90%; }
|
|
186
|
-
}
|
|
187
|
-
/* Use only for operations with unknown duration (file upload, long request) */
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
---
|
|
191
|
-
|
|
192
|
-
## Scroll animations (marketing pages only)
|
|
193
|
-
|
|
194
|
-
**Zero scroll animations on app pages.** Users in admin panels, dashboards, and forms should never have elements jumping in as they scroll — it breaks focus on data.
|
|
195
|
-
|
|
196
|
-
On **marketing pages** only:
|
|
197
|
-
- `fadeUp` on section entry: `250ms ease-out`, trigger at `20% from bottom`
|
|
198
|
-
- Stagger feature cards on scroll: `60ms` delay per card (slightly more generous than app stagger)
|
|
199
|
-
- Hero screenshot: `fadeIn` with slight `scale(1.02) → scale(1)` for depth, `400ms ease-out`
|
|
200
|
-
|
|
201
|
-
---
|
|
202
|
-
|
|
203
|
-
## Reduced motion
|
|
204
|
-
|
|
205
|
-
**Required.** All motion must respect `prefers-reduced-motion`:
|
|
206
|
-
|
|
207
|
-
```css
|
|
208
|
-
@media (prefers-reduced-motion: reduce) {
|
|
209
|
-
*,
|
|
210
|
-
*::before,
|
|
211
|
-
*::after {
|
|
212
|
-
animation-duration: 0.01ms !important;
|
|
213
|
-
animation-iteration-count: 1 !important;
|
|
214
|
-
transition-duration: 0.01ms !important;
|
|
215
|
-
scroll-behavior: auto !important;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
When reduced motion is active:
|
|
221
|
-
- Transitions still happen but are near-instant
|
|
222
|
-
- State changes (hover, focus, active) remain functional — they just don't animate
|
|
223
|
-
- Spinners and skeletons still render correctly
|
|
224
|
-
|
|
225
|
-
---
|
|
226
|
-
|
|
227
|
-
## Motion anti-patterns
|
|
228
|
-
|
|
229
|
-
1. `transition: all` — always specify exact properties (`background-color`, `box-shadow`, etc.)
|
|
230
|
-
2. Duration > 300ms for any interactive element in the app
|
|
231
|
-
3. Bounce or spring easing — not this skill; that is warm-craft
|
|
232
|
-
4. Hover that moves the element in XY space (lift, slide) — cards stay grounded in Clean SaaS
|
|
233
|
-
5. Staggering more than 4 items
|
|
234
|
-
6. Scroll animations on any app page (list, dashboard, form, settings)
|
|
235
|
-
7. Animation on focus — focus rings appear instantly, no animation
|
|
1
|
+
# Motion — Clean SaaS UI
|
|
2
|
+
|
|
3
|
+
## Principle: functional, not decorative
|
|
4
|
+
|
|
5
|
+
Animation in Clean SaaS exists for **feedback and orientation**, not for impression.
|
|
6
|
+
|
|
7
|
+
Every animation must answer: does this help the user understand what happened, or where they are? If not, remove it.
|
|
8
|
+
|
|
9
|
+
- Keep everything fast: 150-250ms max for interactions, 300ms for page transitions
|
|
10
|
+
- Easing: `ease-out` for entrances, `ease-in` for exits
|
|
11
|
+
- **ZERO scroll animations on app pages** - only on marketing pages, and with restraint
|
|
12
|
+
- If the animation feels fast to the developer, it is probably the right speed for the user
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Timing tokens
|
|
17
|
+
|
|
18
|
+
```css
|
|
19
|
+
:root {
|
|
20
|
+
--transition-fast: 100ms ease;
|
|
21
|
+
--transition-base: 150ms ease;
|
|
22
|
+
--transition-slow: 250ms ease;
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
These are the only durations used in app pages. Never use values outside this range for UI interactions.
|
|
27
|
+
|
|
28
|
+
For page-level transitions (route change, modal open): max `300ms`.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Entrances
|
|
33
|
+
|
|
34
|
+
### Fade In
|
|
35
|
+
- `opacity: 0 → 1`
|
|
36
|
+
- Duration: `200ms ease-out`
|
|
37
|
+
- Use for: any element appearing without positional change — tooltips, inline state changes
|
|
38
|
+
|
|
39
|
+
```css
|
|
40
|
+
@keyframes fadeIn {
|
|
41
|
+
from { opacity: 0; }
|
|
42
|
+
to { opacity: 1; }
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Fade Up
|
|
47
|
+
- `translateY(8px) → translateY(0)` + `opacity: 0 → 1`
|
|
48
|
+
- Duration: `250ms ease-out`
|
|
49
|
+
- Use for: cards appearing, dashboard sections loading, notifications
|
|
50
|
+
- **8px displacement only** — smaller than warm-craft (12px) and cognitive-core (10px). Clean SaaS moves less.
|
|
51
|
+
|
|
52
|
+
```css
|
|
53
|
+
@keyframes fadeUp {
|
|
54
|
+
from { opacity: 0; transform: translateY(8px); }
|
|
55
|
+
to { opacity: 1; transform: translateY(0); }
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Scale In
|
|
60
|
+
- `scale(0.97) → scale(1)` + `opacity: 0 → 1`
|
|
61
|
+
- Duration: `200ms ease-out`
|
|
62
|
+
- Use for: modals, dropdowns, popovers, context menus
|
|
63
|
+
- **0.97 scale** — barely perceptible, just enough for spatial cue. Not 0.95 (too dramatic).
|
|
64
|
+
|
|
65
|
+
```css
|
|
66
|
+
@keyframes scaleIn {
|
|
67
|
+
from { opacity: 0; transform: scale(0.97); }
|
|
68
|
+
to { opacity: 1; transform: scale(1); }
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Micro-interactions
|
|
75
|
+
|
|
76
|
+
### Buttons
|
|
77
|
+
- **Hover**: background color shift, `100ms ease`
|
|
78
|
+
- **Press**: `scale(0.99)`, `60ms ease-in` — nearly imperceptible, just tactile
|
|
79
|
+
- **Loading**: spinner replaces leading icon, text unchanged, cursor: `not-allowed` during load
|
|
80
|
+
- **Success**: brief `checkmark` icon flash, `300ms`, then returns to default state
|
|
81
|
+
|
|
82
|
+
### Cards
|
|
83
|
+
- **Hover**: `box-shadow: var(--shadow-sm) → var(--shadow-md)`, `150ms ease`
|
|
84
|
+
- **NO translateY lift** — Clean SaaS cards do not "float up" on hover (unlike warm-craft). Cards stay grounded.
|
|
85
|
+
|
|
86
|
+
### Inputs
|
|
87
|
+
- **Focus**: `border-color → var(--accent)`, ring appears `ring-2 ring-accent/20`, `100ms ease`
|
|
88
|
+
- **Error**: border goes `border-semantic-danger`, shakes if invalid on submit (see below)
|
|
89
|
+
- **Validation success**: brief green border flash before returning to default
|
|
90
|
+
|
|
91
|
+
### Input shake (validation error)
|
|
92
|
+
```css
|
|
93
|
+
@keyframes shake {
|
|
94
|
+
0%, 100% { transform: translateX(0); }
|
|
95
|
+
20% { transform: translateX(-4px); }
|
|
96
|
+
40% { transform: translateX(4px); }
|
|
97
|
+
60% { transform: translateX(-3px); }
|
|
98
|
+
80% { transform: translateX(3px); }
|
|
99
|
+
}
|
|
100
|
+
/* Duration: 320ms — fast, firm, not cartoonish */
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Dropdowns
|
|
104
|
+
- Open: `scaleIn` + `fadeIn`, `150ms ease-out`, origin at trigger
|
|
105
|
+
- Close: `opacity: 1 → 0`, `100ms ease-in` — faster out than in
|
|
106
|
+
|
|
107
|
+
### Toggle switch
|
|
108
|
+
- Thumb: `translateX` from off to on position, `150ms ease`
|
|
109
|
+
- Background: color transition `bg-border-strong → bg-accent`, `150ms ease`
|
|
110
|
+
|
|
111
|
+
### Sidebar collapse (mobile)
|
|
112
|
+
- `translateX(-256px) → translateX(0)`, `250ms ease-out`
|
|
113
|
+
- Backdrop: `opacity: 0 → 0.4`, `200ms ease`
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Stagger
|
|
118
|
+
|
|
119
|
+
When multiple items appear together (card grid, list load, table rows):
|
|
120
|
+
|
|
121
|
+
- Delay per item: `40ms` — faster than warm-craft (60ms) to match efficiency feel
|
|
122
|
+
- Max staggered items: **4** — after 4, all remaining items appear simultaneously
|
|
123
|
+
- Base delay: `0ms` (first item appears immediately)
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
Item 1: 0ms delay
|
|
127
|
+
Item 2: 40ms delay
|
|
128
|
+
Item 3: 80ms delay
|
|
129
|
+
Item 4: 120ms delay
|
|
130
|
+
Item 5+: 120ms delay (same as item 4 — no more stagger)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Page transitions
|
|
136
|
+
|
|
137
|
+
### Route change
|
|
138
|
+
- Old page: `opacity: 1 → 0`, `150ms ease-in`
|
|
139
|
+
- New page: `opacity: 0 → 1`, `200ms ease-out`
|
|
140
|
+
- Optionally: `translateY(4px) → 0` on new page entry
|
|
141
|
+
|
|
142
|
+
### Tab switch
|
|
143
|
+
- Content: `fadeIn` `200ms ease-out` — do NOT slide tabs horizontally (it's disorienting in data-dense apps)
|
|
144
|
+
|
|
145
|
+
### Modal open
|
|
146
|
+
- Backdrop: `opacity: 0 → 0.4`, `200ms ease`
|
|
147
|
+
- Modal: `scaleIn` `200ms ease-out`
|
|
148
|
+
|
|
149
|
+
### Modal close
|
|
150
|
+
- Modal: `scale(1) → scale(0.97)` + `opacity: 1 → 0`, `150ms ease-in`
|
|
151
|
+
- Backdrop: `opacity: 0.4 → 0`, `150ms ease`
|
|
152
|
+
|
|
153
|
+
### Toast
|
|
154
|
+
- Enter: `translateX(calc(100% + 16px)) → translateX(0)`, `250ms ease-out` (slides in from right)
|
|
155
|
+
- Auto-dismiss: after 5s, `opacity: 1 → 0` over `300ms`
|
|
156
|
+
- Manual dismiss: `opacity: 1 → 0` + `scale(0.96)`, `150ms ease-in`
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Loading states
|
|
161
|
+
|
|
162
|
+
### Skeleton pulse
|
|
163
|
+
```css
|
|
164
|
+
@keyframes pulse {
|
|
165
|
+
0%, 100% { opacity: 1; }
|
|
166
|
+
50% { opacity: 0.5; }
|
|
167
|
+
}
|
|
168
|
+
/* Duration: 1.5s — slower than a button transition, rhythmic */
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Spinner
|
|
172
|
+
```css
|
|
173
|
+
@keyframes spin {
|
|
174
|
+
from { transform: rotate(0deg); }
|
|
175
|
+
to { transform: rotate(360deg); }
|
|
176
|
+
}
|
|
177
|
+
/* Duration: 800ms linear infinite — smooth, not jerky */
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Progress bar (indeterminate)
|
|
181
|
+
```css
|
|
182
|
+
@keyframes indeterminate {
|
|
183
|
+
0% { left: -35%; right: 100%; }
|
|
184
|
+
60% { left: 100%; right: -90%; }
|
|
185
|
+
100% { left: 100%; right: -90%; }
|
|
186
|
+
}
|
|
187
|
+
/* Use only for operations with unknown duration (file upload, long request) */
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Scroll animations (marketing pages only)
|
|
193
|
+
|
|
194
|
+
**Zero scroll animations on app pages.** Users in admin panels, dashboards, and forms should never have elements jumping in as they scroll — it breaks focus on data.
|
|
195
|
+
|
|
196
|
+
On **marketing pages** only:
|
|
197
|
+
- `fadeUp` on section entry: `250ms ease-out`, trigger at `20% from bottom`
|
|
198
|
+
- Stagger feature cards on scroll: `60ms` delay per card (slightly more generous than app stagger)
|
|
199
|
+
- Hero screenshot: `fadeIn` with slight `scale(1.02) → scale(1)` for depth, `400ms ease-out`
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Reduced motion
|
|
204
|
+
|
|
205
|
+
**Required.** All motion must respect `prefers-reduced-motion`:
|
|
206
|
+
|
|
207
|
+
```css
|
|
208
|
+
@media (prefers-reduced-motion: reduce) {
|
|
209
|
+
*,
|
|
210
|
+
*::before,
|
|
211
|
+
*::after {
|
|
212
|
+
animation-duration: 0.01ms !important;
|
|
213
|
+
animation-iteration-count: 1 !important;
|
|
214
|
+
transition-duration: 0.01ms !important;
|
|
215
|
+
scroll-behavior: auto !important;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
When reduced motion is active:
|
|
221
|
+
- Transitions still happen but are near-instant
|
|
222
|
+
- State changes (hover, focus, active) remain functional — they just don't animate
|
|
223
|
+
- Spinners and skeletons still render correctly
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## Motion anti-patterns
|
|
228
|
+
|
|
229
|
+
1. `transition: all` — always specify exact properties (`background-color`, `box-shadow`, etc.)
|
|
230
|
+
2. Duration > 300ms for any interactive element in the app
|
|
231
|
+
3. Bounce or spring easing — not this skill; that is warm-craft
|
|
232
|
+
4. Hover that moves the element in XY space (lift, slide) — cards stay grounded in Clean SaaS
|
|
233
|
+
5. Staggering more than 4 items
|
|
234
|
+
6. Scroll animations on any app page (list, dashboard, form, settings)
|
|
235
|
+
7. Animation on focus — focus rings appear instantly, no animation
|