@vamos-ui/react 0.2.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.
Files changed (82) hide show
  1. package/dist/blocks/site/_kit-1.d.ts +1 -0
  2. package/dist/blocks/site/_kit-1.js +2 -0
  3. package/dist/blocks/site/cta.js +2 -1
  4. package/dist/blocks/site/faq.js +2 -1
  5. package/dist/blocks/site/feature-grid.js +2 -1
  6. package/dist/blocks/site/gallery-section.js +3 -2
  7. package/dist/blocks/site/hero.js +12 -6
  8. package/dist/blocks/site/logo-strip.d.ts +5 -3
  9. package/dist/blocks/site/logo-strip.js +8 -7
  10. package/dist/blocks/site/media-text.js +2 -1
  11. package/dist/blocks/site/pricing-table.js +2 -1
  12. package/dist/blocks/site/process.js +2 -1
  13. package/dist/blocks/site/site-shell.d.ts +11 -0
  14. package/dist/blocks/site/site-shell.js +43 -16
  15. package/dist/blocks/site/stats-band.d.ts +3 -1
  16. package/dist/blocks/site/stats-band.js +11 -7
  17. package/dist/blocks/site/testimonials.js +2 -1
  18. package/dist/business/index.d.ts +1 -0
  19. package/dist/business/index.js +2 -0
  20. package/dist/business/signer-status.d.ts +53 -0
  21. package/dist/business/signer-status.js +76 -0
  22. package/dist/charts/bar-chart.js +5 -1
  23. package/dist/charts/combo-chart.js +1 -1
  24. package/dist/components/_qr-core.d.ts +26 -0
  25. package/dist/components/_qr-core.js +376 -0
  26. package/dist/components/backup-codes.d.ts +42 -0
  27. package/dist/components/backup-codes.js +67 -0
  28. package/dist/components/breadcrumb.d.ts +2 -2
  29. package/dist/components/breadcrumb.js +1 -1
  30. package/dist/components/command.d.ts +8 -2
  31. package/dist/components/command.js +7 -2
  32. package/dist/components/input.d.ts +1 -1
  33. package/dist/components/input.js +1 -1
  34. package/dist/components/pin-map.d.ts +58 -0
  35. package/dist/components/pin-map.js +167 -0
  36. package/dist/components/qr-code.d.ts +36 -0
  37. package/dist/components/qr-code.js +27 -0
  38. package/dist/components/record-detail-layout.d.ts +2 -2
  39. package/dist/components/record-detail-layout.js +1 -1
  40. package/dist/components/sidebar.js +8 -8
  41. package/dist/components/sla-timer.d.ts +75 -0
  42. package/dist/components/sla-timer.js +142 -0
  43. package/dist/components/slug-input.js +1 -1
  44. package/dist/components/tour.d.ts +60 -0
  45. package/dist/components/tour.js +139 -0
  46. package/dist/index.d.ts +5 -0
  47. package/dist/index.js +5 -0
  48. package/dist/lib/public.d.ts +1 -0
  49. package/dist/lib/public.js +1 -0
  50. package/dist/locale-data/core/holidays.d.ts +1 -1
  51. package/dist/locale-data/core/holidays.js +1 -1
  52. package/dist/media/gallery.js +3 -1
  53. package/dist/motion/core.d.ts +32 -0
  54. package/dist/motion/core.js +77 -0
  55. package/dist/motion/count-up.d.ts +29 -0
  56. package/dist/motion/count-up.js +92 -0
  57. package/dist/motion/index.d.ts +11 -0
  58. package/dist/motion/index.js +13 -0
  59. package/dist/motion/motion-scope.d.ts +17 -0
  60. package/dist/motion/motion-scope.js +16 -0
  61. package/dist/motion/page-transition.d.ts +33 -0
  62. package/dist/motion/page-transition.js +61 -0
  63. package/dist/motion/parallax.d.ts +37 -0
  64. package/dist/motion/parallax.js +90 -0
  65. package/dist/motion/pointer.d.ts +38 -0
  66. package/dist/motion/pointer.js +117 -0
  67. package/dist/motion/reveal.d.ts +72 -0
  68. package/dist/motion/reveal.js +133 -0
  69. package/dist/motion/scroll-shrink.d.ts +18 -0
  70. package/dist/motion/scroll-shrink.js +47 -0
  71. package/dist/motion/skeleton-swap.d.ts +17 -0
  72. package/dist/motion/skeleton-swap.js +43 -0
  73. package/dist/motion/text-reveal.d.ts +30 -0
  74. package/dist/motion/text-reveal.js +29 -0
  75. package/dist/motion/ticker.d.ts +35 -0
  76. package/dist/motion/ticker.js +16 -0
  77. package/dist/sortable/sortable-tree.d.ts +4 -0
  78. package/dist/sortable/sortable-tree.js +16 -4
  79. package/dist/styles/blocks.css +3 -3
  80. package/dist/styles/motion.css +389 -0
  81. package/dist/styles.css +2 -1
  82. package/package.json +5 -1
@@ -0,0 +1,389 @@
1
+ /* ------------------------------------------------------------------ */
2
+ /* Motion kit (@vamos-ui/react/motion) */
3
+ /* */
4
+ /* Levels: data-motion="full | subtle | off" on any ancestor (SiteShell */
5
+ /* sets it); "off" on <html> beats every scope. No attribute = subtle. */
6
+ /* Every hidden or moving state below sits behind */
7
+ /* @media screen and (prefers-reduced-motion: no-preference) */
8
+ /* and the ON guard :where(:not([data-motion="off"], [data-motion="off"] *))
9
+ /* so reduced motion, motion-off and print always get the final state. */
10
+ /* Transform / opacity / filter / clip-path only: no layout shift. */
11
+ /* ------------------------------------------------------------------ */
12
+
13
+ :root {
14
+ --motion-fast: 140ms;
15
+ --motion-base: 240ms;
16
+ --motion-slow: 420ms;
17
+ --motion-reveal: 680ms;
18
+ --ease-out-quint: cubic-bezier(0.22, 1, 0.36, 1);
19
+ --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
20
+ --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
21
+ /* A damped spring: ~4% overshoot, settles by 70%. */
22
+ --ease-spring: linear(0, 0.034 1.6%, 0.135 3.4%, 0.474 8.5%, 0.73 13%, 0.896 17.8%, 0.988 22.9%, 1.033 28.6%, 1.045 34.2%, 1.039 40.4%, 1.014 52.8%, 0.999 68.4%, 1);
23
+ --motion-distance: 14px;
24
+ --motion-blur: 6px;
25
+ --motion-stagger: 60ms;
26
+ /* Density factor: compact moves shorter and quicker, spacious a touch slower. */
27
+ --motion-k: 1;
28
+ }
29
+ [data-motion="subtle"] {
30
+ --motion-reveal: 680ms;
31
+ --motion-distance: 14px;
32
+ --motion-blur: 6px;
33
+ --motion-stagger: 60ms;
34
+ }
35
+ [data-motion="full"] {
36
+ --motion-reveal: 960ms;
37
+ --motion-distance: 32px;
38
+ --motion-blur: 12px;
39
+ --motion-stagger: 90ms;
40
+ }
41
+ [data-density="compact"] { --motion-k: 0.8; }
42
+ [data-density="comfortable"] { --motion-k: 1; }
43
+ [data-density="spacious"] { --motion-k: 1.12; }
44
+
45
+ @keyframes vm-fade-in { from { opacity: 0; } }
46
+ @keyframes vm-fade-out { to { opacity: 0; } }
47
+ @keyframes vm-enter { from { opacity: 0; transform: translate3d(0, calc(var(--motion-distance) * var(--motion-k)), 0); } }
48
+ @keyframes vm-enter-title {
49
+ from { opacity: 0; transform: translate3d(0, 0.3em, 0); clip-path: inset(0 -0.2em 100% -0.2em); }
50
+ to { clip-path: inset(-0.2em -0.2em -0.3em -0.2em); }
51
+ }
52
+ @keyframes vm-enter-media { from { opacity: 0; clip-path: inset(10% 0 0 0); } to { clip-path: inset(0 0 0 0); } }
53
+ @keyframes vm-enter-zoom { from { transform: scale(1.06); } }
54
+ @keyframes vm-page-in { from { opacity: 0; transform: translate3d(0, 10px, 0); } }
55
+ @keyframes vm-vt-in { from { opacity: 0; transform: translate3d(0, 10px, 0); } }
56
+ @keyframes vm-marquee { to { transform: translate3d(calc(-50% * var(--dir, 1)), 0, 0); } }
57
+ @keyframes vm-parallax {
58
+ from { transform: translate3d(0, var(--vm-parallax-shift), 0); }
59
+ to { transform: translate3d(0, calc(var(--vm-parallax-shift) * -1), 0); }
60
+ }
61
+ @keyframes vm-grow-x { from { transform: scaleX(0); } to { transform: scaleX(1); } }
62
+
63
+ /* ------------------------------------------------------- Reveal states */
64
+ /* useReveal flips data-reveal-state: pending → in → done. */
65
+
66
+ [data-reveal] { --_from: translate3d(0, calc(var(--motion-distance) * var(--motion-k)), 0); }
67
+ [data-reveal="fade"] { --_from: none; }
68
+ [data-reveal="scale"] { --_from: scale(0.94); }
69
+ [data-reveal="blur"] { --_from: translate3d(0, calc(var(--motion-distance) * 0.5 * var(--motion-k)), 0); }
70
+ [data-reveal="clip"] { --_from: translate3d(0, calc(var(--motion-distance) * 0.6 * var(--motion-k)), 0); }
71
+
72
+ /* Stagger: --vm-i per child, capped at 12 so long lists never drag. */
73
+ [data-reveal-stagger] > :nth-child(2) { --vm-i: 1; }
74
+ [data-reveal-stagger] > :nth-child(3) { --vm-i: 2; }
75
+ [data-reveal-stagger] > :nth-child(4) { --vm-i: 3; }
76
+ [data-reveal-stagger] > :nth-child(5) { --vm-i: 4; }
77
+ [data-reveal-stagger] > :nth-child(6) { --vm-i: 5; }
78
+ [data-reveal-stagger] > :nth-child(7) { --vm-i: 6; }
79
+ [data-reveal-stagger] > :nth-child(8) { --vm-i: 7; }
80
+ [data-reveal-stagger] > :nth-child(9) { --vm-i: 8; }
81
+ [data-reveal-stagger] > :nth-child(10) { --vm-i: 9; }
82
+ [data-reveal-stagger] > :nth-child(11) { --vm-i: 10; }
83
+ [data-reveal-stagger] > :nth-child(12) { --vm-i: 11; }
84
+ [data-reveal-stagger] > :nth-child(n + 13) { --vm-i: 12; }
85
+
86
+ /* Text reveal structure (also without motion: plain inline text). */
87
+ .vm-tr-mask { display: inline-block; vertical-align: top; }
88
+ .vm-tr-unit { display: inline-block; }
89
+ [data-text-reveal="line"] .vm-tr-mask { display: block; }
90
+ [data-reveal="text"] .vm-tr-mask { overflow: clip; overflow-clip-margin: 0.1em; padding-block-end: 0.12em; margin-block-end: -0.12em; }
91
+
92
+ @media screen and (prefers-reduced-motion: no-preference) {
93
+ /* Hidden (pending) */
94
+ [data-reveal][data-reveal-state="pending"]:not([data-reveal-stagger], [data-text-reveal]):where(:not([data-motion="off"], [data-motion="off"] *)),
95
+ [data-reveal-stagger][data-reveal-state="pending"]:where(:not([data-motion="off"], [data-motion="off"] *)) > * {
96
+ opacity: 0;
97
+ transform: var(--_from);
98
+ }
99
+ [data-reveal="blur"][data-reveal-state="pending"]:not([data-reveal-stagger], [data-text-reveal]):where(:not([data-motion="off"], [data-motion="off"] *)),
100
+ [data-reveal="blur"][data-reveal-stagger][data-reveal-state="pending"]:where(:not([data-motion="off"], [data-motion="off"] *)) > * {
101
+ filter: blur(var(--motion-blur));
102
+ }
103
+ [data-reveal="clip"][data-reveal-state="pending"]:not([data-reveal-stagger], [data-text-reveal]):where(:not([data-motion="off"], [data-motion="off"] *)),
104
+ [data-reveal="clip"][data-reveal-stagger][data-reveal-state="pending"]:where(:not([data-motion="off"], [data-motion="off"] *)) > * {
105
+ opacity: 1;
106
+ clip-path: inset(0 0 100% 0);
107
+ }
108
+
109
+ /* Revealing (in) */
110
+ [data-reveal][data-reveal-state="in"]:not([data-reveal-stagger], [data-text-reveal]):where(:not([data-motion="off"], [data-motion="off"] *)),
111
+ [data-reveal-stagger][data-reveal-state="in"]:where(:not([data-motion="off"], [data-motion="off"] *)) > * {
112
+ --_d: calc(var(--vm-duration, var(--motion-reveal)) * var(--motion-k));
113
+ transition-property: opacity, transform, filter, clip-path;
114
+ transition-duration: calc(var(--_d) * 0.6), var(--_d), var(--_d), var(--_d);
115
+ transition-timing-function: linear, var(--ease-out-quint), var(--ease-out-quint), var(--ease-out-expo);
116
+ transition-delay: var(--vm-delay, 0ms);
117
+ }
118
+ [data-reveal-stagger][data-reveal-state="in"]:where(:not([data-motion="off"], [data-motion="off"] *)) > * {
119
+ transition-delay: calc(var(--vm-delay, 0ms) + var(--vm-i, 0) * var(--vm-step, var(--motion-stagger)) * var(--motion-k));
120
+ }
121
+
122
+ /* TextReveal: units hide inside their masks; the heading box never moves. */
123
+ [data-text-reveal][data-reveal-state="pending"]:where(:not([data-motion="off"], [data-motion="off"] *)) .vm-tr-unit { transform: translate3d(0, 108%, 0); }
124
+ [data-text-reveal][data-reveal="fade"][data-reveal-state="pending"]:where(:not([data-motion="off"], [data-motion="off"] *)) .vm-tr-unit { transform: none; opacity: 0; }
125
+ [data-text-reveal][data-reveal="blur"][data-reveal-state="pending"]:where(:not([data-motion="off"], [data-motion="off"] *)) .vm-tr-unit { transform: translate3d(0, 0.2em, 0); opacity: 0; filter: blur(var(--motion-blur)); }
126
+ [data-text-reveal]:is([data-reveal-state="in"], [data-reveal-state="done"]):where(:not([data-motion="off"], [data-motion="off"] *)) .vm-tr-unit {
127
+ transition:
128
+ transform calc(var(--vm-duration, var(--motion-reveal)) * var(--motion-k)) var(--ease-out-quint),
129
+ opacity calc(var(--vm-duration, var(--motion-reveal)) * 0.6 * var(--motion-k)) linear,
130
+ filter calc(var(--vm-duration, var(--motion-reveal)) * var(--motion-k)) var(--ease-out-quint);
131
+ transition-delay: calc(var(--vm-delay, 0ms) + var(--vm-i, 0) * var(--vm-step, 45ms) * var(--motion-k));
132
+ }
133
+
134
+ /* ------------------------------------------------ Enter (CSS only) */
135
+ /* Plays from the first paint — no JavaScript involved — so hero copy */
136
+ /* is never held back by hydration. Opt in with .vm-enter + --vm-i. */
137
+ .vm-enter:where(:not([data-motion="off"], [data-motion="off"] *)) {
138
+ animation: vm-enter calc(var(--motion-reveal) * var(--motion-k)) var(--ease-out-quint) backwards;
139
+ animation-delay: calc(60ms + var(--vm-i, 0) * var(--motion-stagger) * 1.3 * var(--motion-k));
140
+ }
141
+ [data-motion="full"] .vm-enter-title:where(:not([data-motion="off"] *)) { animation-name: vm-enter-title; }
142
+ .vm-enter-media:where(:not([data-motion="off"], [data-motion="off"] *)) { animation-name: vm-enter-media; animation-timing-function: var(--ease-out-expo); }
143
+ [data-motion="full"] .vm-enter-media:where(:not([data-motion="off"] *)) :is(img, video) {
144
+ animation: vm-enter-zoom calc(var(--motion-reveal) * 1.8 * var(--motion-k)) var(--ease-out-quint) backwards;
145
+ }
146
+
147
+ /* --------------------------------------------------- Page switches */
148
+ .vm-page[data-page-enter]:where(:not([data-motion="off"], [data-motion="off"] *)),
149
+ [data-site-page][data-page-enter]:where(:not([data-motion="off"] *)) > * {
150
+ animation: vm-page-in calc(var(--motion-slow) * var(--motion-k)) var(--ease-out-quint) backwards;
151
+ }
152
+
153
+ /* ---------------------------------------------------- Ticker / marquee */
154
+ .vm-marquee:where(:not([data-motion="off"], [data-motion="off"] *)) .vm-marquee-track {
155
+ animation: vm-marquee var(--vm-marquee-duration, 40s) linear infinite;
156
+ }
157
+ .vm-marquee[data-direction="end"] .vm-marquee-track { animation-direction: reverse; }
158
+ .vm-marquee-track:hover,
159
+ .vm-marquee-track:focus-within,
160
+ .vm-marquee:has(.vm-marquee-pause:checked) .vm-marquee-track { animation-play-state: paused; }
161
+
162
+ /* --------------------------------------------------------- Parallax */
163
+ @supports (animation-timeline: view()) {
164
+ .vm-parallax { view-timeline: --vm-parallax block; }
165
+ .vm-parallax:where(:not([data-motion="off"], [data-motion="off"] *)) > .vm-parallax-layer {
166
+ animation: vm-parallax linear both;
167
+ animation-timeline: --vm-parallax;
168
+ }
169
+ }
170
+ .vm-parallax[data-js]:where(:not([data-motion="off"], [data-motion="off"] *)) > .vm-parallax-layer {
171
+ transform: translate3d(0, calc((0.5 - var(--vm-progress, 0.5)) * 2 * var(--vm-parallax-shift)), 0);
172
+ }
173
+
174
+ /* ---------------------------------------------- Pointer: tilt, magnetic */
175
+ .vm-tilt:where(:not([data-motion="off"], [data-motion="off"] *)) {
176
+ transition: transform var(--motion-slow) var(--ease-out-quint);
177
+ }
178
+ .vm-tilt[data-pointer]:where(:not([data-motion="off"], [data-motion="off"] *)) {
179
+ transform: perspective(60rem) rotateX(var(--vm-tilt-x, 0deg)) rotateY(var(--vm-tilt-y, 0deg));
180
+ transition-duration: 120ms;
181
+ }
182
+ .vm-magnetic:where(:not([data-motion="off"], [data-motion="off"] *)) {
183
+ transition: translate calc(var(--motion-slow) * 1.4) var(--ease-spring);
184
+ }
185
+ .vm-magnetic[data-pointer]:where(:not([data-motion="off"], [data-motion="off"] *)) {
186
+ translate: var(--vm-mag-x, 0px) var(--vm-mag-y, 0px);
187
+ transition: translate 140ms var(--ease-out-quint);
188
+ }
189
+
190
+ /* --------------------------------------------- Micro-interactions */
191
+ .vm-press:where(:not([data-motion="off"], [data-motion="off"] *)) { transition: scale var(--motion-fast) var(--ease-out-quint); }
192
+ .vm-press:where(:not([data-motion="off"], [data-motion="off"] *)):active:not(:disabled, [aria-disabled="true"]) { scale: 0.97; }
193
+ @media (hover: hover) and (pointer: fine) {
194
+ .vm-lift:where(:not([data-motion="off"], [data-motion="off"] *)) {
195
+ transition: translate var(--motion-base) var(--ease-out-quint), box-shadow var(--motion-base) var(--ease-out-quint);
196
+ }
197
+ .vm-lift:where(:not([data-motion="off"], [data-motion="off"] *)):hover { translate: 0 -2px; box-shadow: var(--popover-shadow); }
198
+ .vm-nudge:where(:not([data-motion="off"], [data-motion="off"] *)) > svg:last-child { transition: translate var(--motion-base) var(--ease-out-quint); }
199
+ .vm-nudge:where(:not([data-motion="off"], [data-motion="off"] *)):hover > svg:last-child { translate: calc(3px * var(--dir, 1)) 0; }
200
+ }
201
+ .vm-underline:where(:not([data-motion="off"], [data-motion="off"] *)) { transition: background-size var(--motion-slow) var(--ease-out-quint); }
202
+
203
+ /* -------------------------------------------- Skeleton → content */
204
+ .vm-swap-skeleton[data-leaving]:where(:not([data-motion="off"], [data-motion="off"] *)) {
205
+ animation: vm-fade-out calc(var(--motion-slow) * var(--motion-k)) var(--ease-out-quint) forwards;
206
+ }
207
+ .vm-swap-content[data-entering]:where(:not([data-motion="off"], [data-motion="off"] *)) {
208
+ animation: vm-fade-in calc(var(--motion-slow) * var(--motion-k)) var(--ease-out-quint) backwards;
209
+ }
210
+
211
+ /* ------------------------------------------- Expand / accordion height */
212
+ .vm-expand:where(:not([data-motion="off"], [data-motion="off"] *)) {
213
+ transition: grid-template-rows calc(var(--motion-slow) * var(--motion-k)) var(--ease-out-quint);
214
+ }
215
+ @supports selector(::details-content) {
216
+ details.vm-details:where(:not([data-motion="off"], [data-motion="off"] *))::details-content {
217
+ transition:
218
+ block-size calc(var(--motion-slow) * var(--motion-k)) var(--ease-out-quint),
219
+ content-visibility calc(var(--motion-slow) * var(--motion-k)) allow-discrete;
220
+ }
221
+ }
222
+
223
+ /* -------------------------------------------- Sticky header shrink */
224
+ .vm-shrink:where(:not([data-motion="off"], [data-motion="off"] *))::before { transition: transform var(--motion-base) var(--ease-out-quint), border-color var(--motion-base) ease; }
225
+ .vm-shrink:where(:not([data-motion="off"], [data-motion="off"] *)) > * { transition: translate var(--motion-base) var(--ease-out-quint); }
226
+ }
227
+
228
+ /* -------------------------------------------------- View transitions */
229
+ /* startPageTransition names the switching element "vm-page" for the */
230
+ /* length of the transition; the rest of the page does not cross-fade. */
231
+ ::view-transition-group(vm-page) { animation-duration: 0s; }
232
+ ::view-transition-old(vm-page) { animation: vm-fade-out 140ms var(--ease-in-out) both; }
233
+ ::view-transition-new(vm-page) { animation: vm-vt-in 340ms var(--ease-out-quint) 60ms both; }
234
+ html[data-vm-transition]::view-transition-old(root),
235
+ html[data-vm-transition]::view-transition-new(root) { animation: none; }
236
+ @media (prefers-reduced-motion: reduce) {
237
+ ::view-transition-old(vm-page),
238
+ ::view-transition-new(vm-page) { animation: none; }
239
+ }
240
+
241
+ /* -------------------------------------------------------- CountUp */
242
+ .vm-count { display: inline-grid; font-variant-numeric: tabular-nums; }
243
+ .vm-count::before { content: attr(data-ghost); grid-area: 1 / 1; visibility: hidden; }
244
+ .vm-count > :not(.sr-only) { grid-area: 1 / 1; }
245
+
246
+ /* --------------------------------------------------- Ticker / marquee */
247
+ .vm-marquee { --vm-marquee-gap: clamp(2.5rem, 6cqi, 4.5rem); position: relative; }
248
+ .vm-marquee-viewport { overflow: hidden; }
249
+ .vm-marquee[data-fade] .vm-marquee-viewport {
250
+ -webkit-mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
251
+ mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
252
+ }
253
+ .vm-marquee-track { display: flex; width: max-content; }
254
+ .vm-marquee-group {
255
+ display: flex;
256
+ flex-shrink: 0;
257
+ align-items: center;
258
+ gap: var(--vm-marquee-gap);
259
+ margin: 0;
260
+ padding: 0;
261
+ padding-inline-end: var(--vm-marquee-gap);
262
+ list-style: none;
263
+ }
264
+ .vm-marquee-toggle {
265
+ position: absolute;
266
+ inset-inline-end: 0;
267
+ inset-block-start: 50%;
268
+ translate: 0 -50%;
269
+ display: grid;
270
+ place-items: center;
271
+ width: 1.75rem;
272
+ height: 1.75rem;
273
+ border-radius: 999px;
274
+ border: 1px solid var(--surface-border);
275
+ background: var(--surface);
276
+ color: var(--fg-muted);
277
+ cursor: pointer;
278
+ opacity: 0.7;
279
+ transition: opacity var(--motion-fast) ease, color var(--motion-fast) ease;
280
+ }
281
+ .vm-marquee-toggle:hover,
282
+ .vm-marquee-toggle:has(:focus-visible) { opacity: 1; color: var(--fg); }
283
+ .vm-marquee-toggle:has(:focus-visible) { outline: 2px solid var(--ring); outline-offset: 2px; }
284
+ .vm-marquee-toggle svg { width: 0.75rem; height: 0.75rem; fill: currentColor; }
285
+ .vm-marquee-icon-play,
286
+ .vm-marquee:has(.vm-marquee-pause:checked) .vm-marquee-icon-pause { display: none; }
287
+ .vm-marquee:has(.vm-marquee-pause:checked) .vm-marquee-icon-play { display: block; }
288
+
289
+ /* ------------------------------------------------- Parallax frame */
290
+ .vm-parallax[data-clip] { position: relative; overflow: clip; }
291
+ .vm-parallax[data-clip] > .vm-parallax-layer { position: absolute; inset: calc(var(--vm-parallax-shift) * -1) 0; }
292
+ .vm-parallax[data-clip] > .vm-parallax-layer > :is(img, video, picture) { display: block; width: 100%; height: 100%; object-fit: cover; }
293
+
294
+ /* ------------------------------------------------- Scroll progress */
295
+ .vm-scroll-progress { height: 2px; overflow: hidden; pointer-events: none; }
296
+ .vm-scroll-progress[data-fixed] { position: fixed; inset-inline: 0; inset-block-start: 0; z-index: var(--z-sticky, 20); }
297
+ .vm-scroll-progress-bar { height: 100%; background: var(--accent); transform-origin: left center; transform: scaleX(var(--vm-progress, 0)); }
298
+ [dir="rtl"] .vm-scroll-progress-bar { transform-origin: right center; }
299
+ @supports (animation-timeline: scroll()) {
300
+ .vm-scroll-progress:not([data-js]) .vm-scroll-progress-bar { animation: vm-grow-x linear both; animation-timeline: scroll(root block); }
301
+ }
302
+
303
+ /* ----------------------------------------------------- Tilt glare */
304
+ .vm-tilt[data-glare] { position: relative; }
305
+ .vm-tilt[data-glare]::after {
306
+ content: "";
307
+ position: absolute;
308
+ inset: 0;
309
+ border-radius: inherit;
310
+ pointer-events: none;
311
+ background: radial-gradient(circle at var(--vm-glare-x, 50%) var(--vm-glare-y, 50%), color-mix(in oklch, var(--fg) 7%, transparent), transparent 60%);
312
+ opacity: 0;
313
+ transition: opacity var(--motion-base) ease;
314
+ }
315
+ .vm-tilt[data-glare][data-pointer]::after { opacity: 1; }
316
+ .vm-magnetic { display: inline-block; }
317
+
318
+ /* --------------------------------------------- Micro-interactions */
319
+ /* A quiet resting underline (links stay recognisable without colour), drawn over in full on hover. */
320
+ .vm-underline {
321
+ text-decoration: none;
322
+ background-image: linear-gradient(currentColor, currentColor), linear-gradient(color-mix(in oklch, currentColor 28%, transparent), color-mix(in oklch, currentColor 28%, transparent));
323
+ background-repeat: no-repeat;
324
+ background-position: 0 100%, 0 100%;
325
+ background-size: 0% 1px, 100% 1px;
326
+ }
327
+ [dir="rtl"] .vm-underline { background-position: 100% 100%, 100% 100%; }
328
+ .vm-underline:hover,
329
+ .vm-underline:focus-visible,
330
+ .vm-underline[aria-current="page"] { background-size: 100% 1px, 100% 1px; }
331
+
332
+ /* ------------------------------------------------ Skeleton swap */
333
+ .vm-swap { display: grid; }
334
+ .vm-swap > * { grid-area: 1 / 1; min-width: 0; }
335
+ .vm-swap-skeleton[data-leaving] { pointer-events: none; }
336
+
337
+ /* ------------------------------------------ Expand / accordion height */
338
+ .vm-expand { display: grid; grid-template-rows: 0fr; }
339
+ .vm-expand > * { min-height: 0; overflow: hidden; }
340
+ .vm-expand:is([data-state="open"], [data-open]) { grid-template-rows: 1fr; }
341
+ @supports selector(::details-content) {
342
+ details.vm-details { interpolate-size: allow-keywords; }
343
+ details.vm-details::details-content { block-size: 0; overflow: clip; }
344
+ details.vm-details[open]::details-content { block-size: auto; }
345
+ }
346
+
347
+ /* ---------------------------------------- Sticky header shrink */
348
+ /* The bar's background is a pseudo-element that slides up; the content */
349
+ /* moves up half as much. Transforms only, the header box keeps its size. */
350
+ .vm-shrink { --vm-shrink-by: 0.625rem; isolation: isolate; }
351
+ .vm-shrink::before {
352
+ content: "";
353
+ position: absolute;
354
+ inset: calc(var(--vm-shrink-by) * -2) 0 0;
355
+ z-index: -1;
356
+ background: var(--vm-shrink-bg, var(--scene));
357
+ border-block-end: 1px solid transparent;
358
+ }
359
+ .vm-shrink[data-scrolled]::before { transform: translate3d(0, calc(var(--vm-shrink-by) * -2), 0); border-block-end-color: var(--line); }
360
+ .vm-shrink[data-scrolled] > * { translate: 0 calc(var(--vm-shrink-by) * -1); }
361
+
362
+ /* ----------------------------------------------- Motion off / reduced */
363
+ /* data-motion="off" also stills the kit's other built-in motion. */
364
+ [data-motion="off"] :is(.vb-reveal, .vb-marquee-track, .vui-marquee-track, .vb-feature-panel, .vb-form-success, .vb-sticky-frame),
365
+ html[data-motion="off"] :is(.ui-fade, .ui-pop, .ui-dialog, .ui-sheet-end, .ui-sheet-start, .ui-sheet-bottom, .ui-sheet-top, .ui-collapse, .ui-rise) {
366
+ animation: none !important;
367
+ }
368
+ [data-motion="off"] .vb-arrow { transition: none !important; }
369
+ [data-motion="off"] .vb-faq-marker::before,
370
+ [data-motion="off"] .vb-faq-marker::after,
371
+ [data-motion="off"] .vb-faq-item::details-content { transition: none !important; }
372
+ [data-motion="off"] .vb-marquee-track > [data-dup],
373
+ [data-motion="off"] .vui-marquee-track[aria-hidden] { display: none; }
374
+ [data-motion="off"] .vb-marquee { -webkit-mask-image: none; mask-image: none; }
375
+ [data-motion="off"] .vb-marquee-track { width: auto; flex-wrap: wrap; justify-content: center; row-gap: 1.5rem; padding-inline: var(--gutter); }
376
+
377
+ /* Static ticker: one wrapped, centred row, no copy, no pause control. */
378
+ .vm-marquee:is([data-motion="off"], [data-motion="off"] *) :is(.vm-marquee-toggle, [data-marquee-copy]) { display: none; }
379
+ .vm-marquee:is([data-motion="off"], [data-motion="off"] *) .vm-marquee-viewport { -webkit-mask-image: none; mask-image: none; }
380
+ .vm-marquee:is([data-motion="off"], [data-motion="off"] *) .vm-marquee-track { width: auto; }
381
+ .vm-marquee:is([data-motion="off"], [data-motion="off"] *) .vm-marquee-group { flex: 1; flex-wrap: wrap; justify-content: center; row-gap: 1.5rem; padding-inline: 0; }
382
+ @media (prefers-reduced-motion: reduce) {
383
+ .vm-marquee :is(.vm-marquee-toggle, [data-marquee-copy]) { display: none; }
384
+ .vm-marquee .vm-marquee-viewport { -webkit-mask-image: none; mask-image: none; }
385
+ .vm-marquee .vm-marquee-track { width: auto; }
386
+ .vm-marquee .vm-marquee-group { flex: 1; flex-wrap: wrap; justify-content: center; row-gap: 1.5rem; padding-inline: 0; }
387
+ .vm-shrink::before,
388
+ .vm-shrink > * { transition: none; }
389
+ }
package/dist/styles.css CHANGED
@@ -27,6 +27,7 @@
27
27
  @import "./styles/editors.css";
28
28
  @import "./styles/media.css";
29
29
  @import "./styles/blocks.css";
30
+ @import "./styles/motion.css";
30
31
 
31
32
  @source "./";
32
33
 
@@ -118,7 +119,7 @@
118
119
  --nav-popover-border: rgba(255, 255, 255, 0.09);
119
120
 
120
121
 
121
- --success: #0f8a5f;
122
+ --success: #0b7d55;
122
123
  --warning: #c26a00;
123
124
  --danger: #d0303c;
124
125
  /* solid danger fill behind white text (destructive buttons); stays >= 4.5:1 in both themes */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vamos-ui/react",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Themeable component kit for admin panels and websites — theme × material × accent × density × font.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -57,6 +57,10 @@
57
57
  "types": "./dist/blocks/schema/index.d.ts",
58
58
  "default": "./dist/blocks/schema/index.js"
59
59
  },
60
+ "./motion": {
61
+ "types": "./dist/motion/index.d.ts",
62
+ "default": "./dist/motion/index.js"
63
+ },
60
64
  "./form": {
61
65
  "types": "./dist/form/index.d.ts",
62
66
  "default": "./dist/form/index.js"