@getvitops/core 0.1.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 (57) hide show
  1. package/README.md +29 -0
  2. package/css/animation.css +526 -0
  3. package/css/global.css +17 -0
  4. package/css/index.css +58 -0
  5. package/css/layout.css +723 -0
  6. package/css/patterns/anchor-link.css +66 -0
  7. package/css/patterns/banner.css +64 -0
  8. package/css/patterns/carousel.css +269 -0
  9. package/css/patterns/cluster.css +64 -0
  10. package/css/patterns/code.css +17 -0
  11. package/css/patterns/combobox.css +97 -0
  12. package/css/patterns/comment.css +88 -0
  13. package/css/patterns/copy.css +82 -0
  14. package/css/patterns/details.css +87 -0
  15. package/css/patterns/dialog.css +99 -0
  16. package/css/patterns/drawer.css +108 -0
  17. package/css/patterns/dropdown.css +45 -0
  18. package/css/patterns/forms.css +335 -0
  19. package/css/patterns/grouped.css +86 -0
  20. package/css/patterns/horizontal-scroll.css +40 -0
  21. package/css/patterns/icon.css +72 -0
  22. package/css/patterns/lightbox.css +156 -0
  23. package/css/patterns/list.css +272 -0
  24. package/css/patterns/marquee.css +68 -0
  25. package/css/patterns/masonry.css +40 -0
  26. package/css/patterns/media.css +70 -0
  27. package/css/patterns/nav.css +241 -0
  28. package/css/patterns/notification.css +114 -0
  29. package/css/patterns/overlay.css +28 -0
  30. package/css/patterns/popover.css +68 -0
  31. package/css/patterns/pull-quote.css +71 -0
  32. package/css/patterns/scroll-based.css +227 -0
  33. package/css/patterns/scroll-target.css +124 -0
  34. package/css/patterns/separator.css +130 -0
  35. package/css/patterns/sitenav.css +582 -0
  36. package/css/patterns/split-link.css +113 -0
  37. package/css/patterns/splitter.css +212 -0
  38. package/css/patterns/stack.css +67 -0
  39. package/css/patterns/sticky.css +127 -0
  40. package/css/patterns/subgrid.css +178 -0
  41. package/css/patterns/svg.css +166 -0
  42. package/css/patterns/table.css +106 -0
  43. package/css/patterns/tag.css +75 -0
  44. package/css/patterns/text-effects.css +317 -0
  45. package/css/patterns/tooltip.css +68 -0
  46. package/css/patterns/tree.css +126 -0
  47. package/css/utilities.css +351 -0
  48. package/dist/deferred.js +1 -0
  49. package/dist/elements.js +887 -0
  50. package/dist/polyfills/adoptedStyleSheets.js +1 -0
  51. package/dist/polyfills/css-anchor-positioning-fn.js +17 -0
  52. package/dist/polyfills/global.esm.js +1 -0
  53. package/dist/polyfills/popover.js +63 -0
  54. package/dist/polyfills/template-shadowroot.js +24 -0
  55. package/dist/polyfills/webcomponents-bundle.js +27 -0
  56. package/dist/polyfills.js +1 -0
  57. package/package.json +33 -0
@@ -0,0 +1,166 @@
1
+ /**
2
+ * SVG — sizing/styling utilities and decorative helpers migrated from
3
+ * old-css-lib. Pure CSS. The bare-<svg> reset is kept intentionally light
4
+ * (no forced 1em sizing) so it doesn't fight component-owned icon sizing.
5
+ */
6
+
7
+ svg {
8
+ flex-shrink: 0;
9
+ fill: currentColor;
10
+ }
11
+
12
+ .svg-container {
13
+ --_svg-size: var(--svg-size, 1.5rem);
14
+
15
+ display: inline-flex;
16
+ align-items: center;
17
+ justify-content: center;
18
+ inline-size: var(--_svg-size);
19
+ block-size: var(--_svg-size);
20
+
21
+ > svg {
22
+ inline-size: 100%;
23
+ block-size: 100%;
24
+ }
25
+ }
26
+
27
+ .svg-stroke > svg {
28
+ fill: none;
29
+ stroke: var(--svg-stroke-color, currentColor);
30
+ stroke-width: var(--svg-stroke-width, 2);
31
+ stroke-linecap: var(--svg-stroke-linecap, round);
32
+ stroke-linejoin: var(--svg-stroke-linejoin, round);
33
+ }
34
+
35
+ /* ── Animated SVG ─────────────────────────────────────────────────────────── */
36
+ .svg-animated {
37
+ &.svg-animated--spin > svg {
38
+ animation: svg-spin 1s linear infinite;
39
+ }
40
+ &.svg-animated--pulse > svg {
41
+ animation: svg-pulse 1.5s ease-in-out infinite;
42
+ }
43
+ &.svg-animated--bounce > svg {
44
+ animation: svg-bounce 1s ease infinite;
45
+ }
46
+ &.svg-animated--draw > svg {
47
+ stroke-dasharray: var(--svg-dash-length, 100);
48
+ stroke-dashoffset: var(--svg-dash-length, 100);
49
+ animation: svg-draw 1.5s ease forwards;
50
+
51
+ @media (prefers-reduced-motion: reduce) {
52
+ stroke-dashoffset: 0;
53
+ animation: none;
54
+ }
55
+ }
56
+
57
+ @media (prefers-reduced-motion: reduce) {
58
+ &.svg-animated--spin > svg,
59
+ &.svg-animated--pulse > svg,
60
+ &.svg-animated--bounce > svg {
61
+ animation: none;
62
+ }
63
+ }
64
+ }
65
+
66
+ /* ── Background patterns ──────────────────────────────────────────────────── */
67
+ .svg-pattern {
68
+ --_pattern-size: var(--svg-pattern-size, 20px);
69
+ --_pattern-color: var(--svg-pattern-color, currentColor);
70
+
71
+ background-size: var(--_pattern-size) var(--_pattern-size);
72
+
73
+ &.svg-pattern--dots {
74
+ background-image: radial-gradient(var(--_pattern-color) 1px, transparent 1px);
75
+ }
76
+
77
+ &.svg-pattern--grid {
78
+ background-image:
79
+ linear-gradient(var(--_pattern-color) 1px, transparent 1px),
80
+ linear-gradient(90deg, var(--_pattern-color) 1px, transparent 1px);
81
+ }
82
+
83
+ &.svg-pattern--diagonal {
84
+ background-image: repeating-linear-gradient(
85
+ 45deg,
86
+ var(--_pattern-color),
87
+ var(--_pattern-color) 1px,
88
+ transparent 1px,
89
+ transparent 10px
90
+ );
91
+ }
92
+
93
+ &.svg-pattern--cross {
94
+ background-image:
95
+ linear-gradient(var(--_pattern-color) 1px, transparent 1px),
96
+ linear-gradient(90deg, var(--_pattern-color) 1px, transparent 1px);
97
+ background-position: center center;
98
+ }
99
+ }
100
+
101
+ /* ── Decorative shapes / dividers ─────────────────────────────────────────── */
102
+ .svg-shape {
103
+ display: block;
104
+ inline-size: 100%;
105
+ block-size: auto;
106
+
107
+ &.svg-shape--flip-x {
108
+ transform: scaleX(-1);
109
+ }
110
+ &.svg-shape--flip-y {
111
+ transform: scaleY(-1);
112
+ }
113
+ &.svg-shape--top {
114
+ position: absolute;
115
+ inset-block-start: 0;
116
+ inset-inline: 0;
117
+ }
118
+ &.svg-shape--bottom {
119
+ position: absolute;
120
+ inset-block-end: 0;
121
+ inset-inline: 0;
122
+ }
123
+ }
124
+
125
+ .svg-use {
126
+ display: inline-block;
127
+ vertical-align: middle;
128
+
129
+ > svg {
130
+ display: block;
131
+ inline-size: 100%;
132
+ block-size: 100%;
133
+ }
134
+ }
135
+
136
+ @keyframes svg-spin {
137
+ from {
138
+ transform: rotate(0deg);
139
+ }
140
+ to {
141
+ transform: rotate(360deg);
142
+ }
143
+ }
144
+ @keyframes svg-pulse {
145
+ 0%,
146
+ 100% {
147
+ opacity: 1;
148
+ }
149
+ 50% {
150
+ opacity: 0.5;
151
+ }
152
+ }
153
+ @keyframes svg-bounce {
154
+ 0%,
155
+ 100% {
156
+ transform: translateY(0);
157
+ }
158
+ 50% {
159
+ transform: translateY(-25%);
160
+ }
161
+ }
162
+ @keyframes svg-draw {
163
+ to {
164
+ stroke-dashoffset: 0;
165
+ }
166
+ }
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Table — pattern partial migrated from old-css-lib.
3
+ * Consumes the generated token cascade (src/css/generated/tokens.css).
4
+ */
5
+
6
+ /* ── Table — bare <table> or .table, with variants ────────────────────────── */
7
+ table,
8
+ .table {
9
+ --_b: var(--b-table, var(--b-table-group, var(--b-default)));
10
+ --_br: var(--br-table, var(--br-table-group, var(--br-default)));
11
+ --_fs: var(--fs-table, var(--fs-table-group, var(--fs-default)));
12
+ --_cell: var(--table-cell-padding, 0.75em 1em);
13
+
14
+ inline-size: 100%;
15
+ border-collapse: collapse;
16
+ border-spacing: 0;
17
+ font-size: var(--_fs);
18
+ text-align: start;
19
+
20
+ > caption {
21
+ caption-side: bottom;
22
+ padding-block-start: var(--table-caption-gap, 0.75em);
23
+ font-size: var(--table-caption-fs, 0.875em);
24
+ opacity: 0.7;
25
+ text-align: start;
26
+ }
27
+
28
+ > thead {
29
+ text-align: start;
30
+
31
+ > tr > th {
32
+ padding: var(--_cell);
33
+ font-weight: 600;
34
+ text-align: inherit;
35
+ border-block-end: var(--_b);
36
+ }
37
+ }
38
+
39
+ > tbody > tr > td {
40
+ padding: var(--_cell);
41
+ border-block-end: var(--_b);
42
+ vertical-align: baseline;
43
+ }
44
+
45
+ > tbody > tr:last-child > td {
46
+ border-block-end: none;
47
+ }
48
+
49
+ > tfoot > tr > td,
50
+ > tfoot > tr > th {
51
+ padding: var(--_cell);
52
+ font-weight: 600;
53
+ border-block-start: var(--_b);
54
+ }
55
+
56
+ &.table--bordered {
57
+ border: var(--_b);
58
+ border-radius: var(--_br);
59
+ overflow: hidden;
60
+
61
+ > thead > tr > th,
62
+ > tbody > tr > td,
63
+ > tfoot > tr > td,
64
+ > tfoot > tr > th {
65
+ border: var(--_b);
66
+ }
67
+ }
68
+
69
+ &.table--striped > tbody > tr:nth-child(even) {
70
+ background: oklch(0 0 0 / var(--table-stripe-opacity, 0.04));
71
+ }
72
+
73
+ &.table--hover > tbody > tr:hover {
74
+ background: oklch(0 0 0 / var(--table-hover-opacity, 0.08));
75
+ }
76
+
77
+ &.table--compact {
78
+ --_cell: var(--table-compact-padding, 0.375em 0.75em);
79
+ }
80
+
81
+ [data-numeric] {
82
+ text-align: end;
83
+ font-variant-numeric: tabular-nums;
84
+ }
85
+
86
+ &.table--fixed {
87
+ table-layout: fixed;
88
+ }
89
+
90
+ &.table--sticky-header > thead > tr > th {
91
+ position: sticky;
92
+ inset-block-start: 0;
93
+ z-index: var(--z-tier-raised);
94
+ background: inherit;
95
+ }
96
+ }
97
+
98
+ .table-wrapper {
99
+ overflow-x: auto;
100
+ -webkit-overflow-scrolling: touch;
101
+
102
+ > table,
103
+ > .table {
104
+ min-inline-size: var(--table-min-inline-size, 100%);
105
+ }
106
+ }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Tag — pattern partial migrated from old-css-lib.
3
+ * Consumes the generated token cascade (src/css/generated/tokens.css).
4
+ */
5
+
6
+ /* ── Tag sub-parts — pair with generated .tag / .tag-<role> ───────────────── */
7
+ .tag__icon {
8
+ flex-shrink: 0;
9
+ inline-size: 1em;
10
+ block-size: 1em;
11
+ }
12
+
13
+ .tag__remove {
14
+ flex-shrink: 0;
15
+ margin-inline-start: 0.25em;
16
+ padding: 0.125em;
17
+ background: transparent;
18
+ border: none;
19
+ cursor: pointer;
20
+ opacity: 0.6;
21
+ line-height: 1;
22
+ transition: opacity 0.15s ease;
23
+
24
+ &:hover {
25
+ opacity: 1;
26
+ }
27
+ }
28
+
29
+ /* ── Badge indicator — numeric notification bubble (distinct from .badge) ──── */
30
+ .badge-indicator {
31
+ --_size: var(--badge-size, 1.25rem);
32
+ --_br: var(--br-badge, var(--br-badge-group, var(--br-default)));
33
+
34
+ display: inline-flex;
35
+ align-items: center;
36
+ justify-content: center;
37
+ min-inline-size: var(--_size);
38
+ block-size: var(--_size);
39
+ padding-inline: 0.25em;
40
+ font-size: var(--fs-badge, var(--fs-badge-group, var(--fs-default)));
41
+ font-weight: 600;
42
+ line-height: 1;
43
+ border-radius: var(--br-badge-indicator, var(--br-pill, 999px));
44
+ background: var(--color-danger-d);
45
+ color: #fff;
46
+
47
+ &.badge-indicator--dot {
48
+ --_size: 0.5rem;
49
+ padding: 0;
50
+ }
51
+
52
+ &.badge-indicator--positioned {
53
+ position: absolute;
54
+ inset-block-start: 0;
55
+ inset-inline-end: 0;
56
+ translate: 50% -50%;
57
+ }
58
+ }
59
+
60
+ /* ── Status dot pulse — modifier + keyframe over the generated .status-dot ─── */
61
+ .status-dot--pulse {
62
+ animation: status-pulse 2s ease-in-out infinite;
63
+ }
64
+
65
+ @keyframes status-pulse {
66
+ 0%,
67
+ 100% {
68
+ box-shadow: 0 0 0 0 currentColor;
69
+ opacity: 1;
70
+ }
71
+ 50% {
72
+ box-shadow: 0 0 0 4px currentColor;
73
+ opacity: 0.5;
74
+ }
75
+ }
@@ -0,0 +1,317 @@
1
+ /**
2
+ * Text effects — typewriter, flip, rotate, gradient, highlight and stagger text
3
+ * animations migrated from old-css-lib. Pure-CSS value + keyframe layers; each
4
+ * degrades under prefers-reduced-motion. `.text-scramble` is a CSS shell — the
5
+ * per-character randomisation arrives with its Lit component.
6
+ */
7
+
8
+ /* ── Typing — typewriter reveal with blinking caret ───────────────────────── */
9
+ .typing {
10
+ --_typing-speed: var(--typing-speed, 3s);
11
+ --_typing-steps: var(--typing-steps, 20);
12
+ --_cursor-color: var(--typing-cursor-color, currentColor);
13
+ --_cursor-width: var(--typing-cursor-width, 2px);
14
+
15
+ display: inline-block;
16
+ overflow: hidden;
17
+ white-space: nowrap;
18
+ border-inline-end: var(--_cursor-width) solid var(--_cursor-color);
19
+ animation:
20
+ typing-text var(--_typing-speed) steps(var(--_typing-steps)) forwards,
21
+ typing-cursor 0.75s step-end infinite;
22
+
23
+ @media (prefers-reduced-motion: reduce) {
24
+ border-inline-end: none;
25
+ animation: none;
26
+ }
27
+
28
+ &.typing--loop {
29
+ animation:
30
+ typing-text var(--_typing-speed) steps(var(--_typing-steps)) infinite alternate,
31
+ typing-cursor 0.75s step-end infinite;
32
+ }
33
+
34
+ &.typing--no-cursor {
35
+ animation: typing-text var(--_typing-speed) steps(var(--_typing-steps)) forwards;
36
+ border-inline-end: none;
37
+ }
38
+ }
39
+
40
+ @keyframes typing-text {
41
+ from {
42
+ inline-size: 0;
43
+ }
44
+ to {
45
+ inline-size: 100%;
46
+ }
47
+ }
48
+ @keyframes typing-cursor {
49
+ 50% {
50
+ border-color: transparent;
51
+ }
52
+ }
53
+
54
+ /* ── Text flip — 3D rotating word list ────────────────────────────────────── */
55
+ .text-flip {
56
+ --_flip-duration: var(--text-flip-duration, 3s);
57
+ --_flip-items: var(--text-flip-items, 3);
58
+
59
+ display: inline-block;
60
+ position: relative;
61
+ perspective: 1000px;
62
+ overflow: hidden;
63
+ vertical-align: bottom;
64
+
65
+ .text-flip__item {
66
+ display: block;
67
+ animation: text-flip-rotate calc(var(--_flip-duration) * var(--_flip-items)) infinite;
68
+ backface-visibility: hidden;
69
+
70
+ @media (prefers-reduced-motion: reduce) {
71
+ animation: none;
72
+
73
+ &:not(:first-child) {
74
+ display: none;
75
+ }
76
+ }
77
+ }
78
+
79
+ .text-flip__item:nth-child(1) {
80
+ animation-delay: 0s;
81
+ }
82
+ .text-flip__item:nth-child(2) {
83
+ animation-delay: var(--_flip-duration);
84
+ }
85
+ .text-flip__item:nth-child(3) {
86
+ animation-delay: calc(var(--_flip-duration) * 2);
87
+ }
88
+ .text-flip__item:nth-child(4) {
89
+ animation-delay: calc(var(--_flip-duration) * 3);
90
+ }
91
+ .text-flip__item:nth-child(5) {
92
+ animation-delay: calc(var(--_flip-duration) * 4);
93
+ }
94
+
95
+ .text-flip__item:not(:first-child) {
96
+ position: absolute;
97
+ inset: 0;
98
+ }
99
+ }
100
+
101
+ @keyframes text-flip-rotate {
102
+ 0%,
103
+ 20% {
104
+ opacity: 1;
105
+ transform: rotateX(0);
106
+ }
107
+ 25%,
108
+ 100% {
109
+ opacity: 0;
110
+ transform: rotateX(-90deg);
111
+ }
112
+ }
113
+
114
+ /* ── Text rotate — fade/slide word list ───────────────────────────────────── */
115
+ .text-rotate {
116
+ --_rotate-duration: var(--text-rotate-duration, 2s);
117
+ --_rotate-items: var(--text-rotate-items, 3);
118
+
119
+ display: inline-block;
120
+ position: relative;
121
+ overflow: hidden;
122
+ vertical-align: bottom;
123
+
124
+ .text-rotate__item {
125
+ display: block;
126
+ opacity: 0;
127
+ animation: text-rotate-fade calc(var(--_rotate-duration) * var(--_rotate-items)) infinite;
128
+
129
+ @media (prefers-reduced-motion: reduce) {
130
+ opacity: 1;
131
+ animation: none;
132
+
133
+ &:not(:first-child) {
134
+ display: none;
135
+ }
136
+ }
137
+ }
138
+
139
+ .text-rotate__item:nth-child(1) {
140
+ animation-delay: 0s;
141
+ }
142
+ .text-rotate__item:nth-child(2) {
143
+ animation-delay: var(--_rotate-duration);
144
+ }
145
+ .text-rotate__item:nth-child(3) {
146
+ animation-delay: calc(var(--_rotate-duration) * 2);
147
+ }
148
+ .text-rotate__item:nth-child(4) {
149
+ animation-delay: calc(var(--_rotate-duration) * 3);
150
+ }
151
+ .text-rotate__item:nth-child(5) {
152
+ animation-delay: calc(var(--_rotate-duration) * 4);
153
+ }
154
+
155
+ .text-rotate__item:not(:first-child) {
156
+ position: absolute;
157
+ inset: 0;
158
+ }
159
+ }
160
+
161
+ @keyframes text-rotate-fade {
162
+ 0%,
163
+ 5% {
164
+ opacity: 0;
165
+ transform: translateY(100%);
166
+ }
167
+ 10%,
168
+ 30% {
169
+ opacity: 1;
170
+ transform: translateY(0);
171
+ }
172
+ 35%,
173
+ 100% {
174
+ opacity: 0;
175
+ transform: translateY(-100%);
176
+ }
177
+ }
178
+
179
+ /* ── Text scramble — CSS shell; randomisation lands via Lit ───────────────── */
180
+ .text-scramble {
181
+ display: inline-block;
182
+ font-family: var(--font-mono, monospace);
183
+
184
+ .text-scramble__char {
185
+ display: inline-block;
186
+ transition: opacity 0.1s ease;
187
+ }
188
+
189
+ .text-scramble__char--scrambled {
190
+ opacity: 0.3;
191
+ }
192
+ }
193
+
194
+ /* ── Animated gradient text ───────────────────────────────────────────────── */
195
+ .text-gradient-animate {
196
+ --_gradient-speed: var(--text-gradient-speed, 3s);
197
+ --_gradient-colors: var(
198
+ --text-gradient-colors,
199
+ oklch(0.7 0.25 0),
200
+ oklch(0.7 0.25 60),
201
+ oklch(0.7 0.25 120),
202
+ oklch(0.7 0.25 180),
203
+ oklch(0.7 0.25 240),
204
+ oklch(0.7 0.25 300),
205
+ oklch(0.7 0.25 360)
206
+ );
207
+
208
+ background: linear-gradient(90deg, var(--_gradient-colors));
209
+ background-size: 200% auto;
210
+ background-clip: text;
211
+ -webkit-background-clip: text;
212
+ -webkit-text-fill-color: transparent;
213
+ animation: text-gradient-shift var(--_gradient-speed) linear infinite;
214
+
215
+ @media (prefers-reduced-motion: reduce) {
216
+ animation: none;
217
+ }
218
+ }
219
+
220
+ @keyframes text-gradient-shift {
221
+ to {
222
+ background-position: 200% center;
223
+ }
224
+ }
225
+
226
+ /* ── Highlight sweep ──────────────────────────────────────────────────────── */
227
+ .text-highlight {
228
+ --_highlight-color: var(--text-highlight-color, var(--color-warning-l));
229
+ --_highlight-duration: var(--text-highlight-duration, 0.5s);
230
+ --_highlight-pad-block: var(--text-highlight-pad-block, 0.1em);
231
+ --_highlight-pad-inline: var(--text-highlight-pad-inline, 0);
232
+ --_highlight-radius: var(--text-highlight-radius, 0);
233
+ --_highlight-skew: var(--text-highlight-skew, 0deg);
234
+
235
+ background: linear-gradient(to right, var(--_highlight-color) 50%, transparent 50%);
236
+ background-size: 200% 100%;
237
+ background-position: 100% 0;
238
+ border-radius: var(--_highlight-radius);
239
+ /* Extend the sweep slightly past the glyphs so the band doesn't sit flush to
240
+ the characters; keep line layout intact by clawing the padding back. */
241
+ padding-block: var(--_highlight-pad-block);
242
+ padding-inline: var(--_highlight-pad-inline);
243
+ margin-block: calc(-1 * var(--_highlight-pad-block));
244
+ margin-inline: calc(-1 * var(--_highlight-pad-inline));
245
+ box-decoration-break: clone;
246
+ /* skew is a no-op on pure inline boxes; opt in with inline-block when the
247
+ phrase stays on one line and a slanted marker look is wanted. */
248
+ transform: skewX(var(--_highlight-skew));
249
+ transition: background-position var(--_highlight-duration) ease;
250
+
251
+ @media (prefers-reduced-motion: reduce) {
252
+ background-position: 0 0;
253
+ }
254
+
255
+ &.text-highlight--active,
256
+ &:hover {
257
+ background-position: 0 0;
258
+ }
259
+ }
260
+
261
+ /* ── Character stagger pop-in ─────────────────────────────────────────────── */
262
+ .text-stagger {
263
+ display: inline-flex;
264
+
265
+ .text-stagger__char {
266
+ display: inline-block;
267
+ animation: text-stagger-pop 0.5s ease backwards;
268
+ }
269
+
270
+ .text-stagger__char:nth-child(1) {
271
+ animation-delay: 0s;
272
+ }
273
+ .text-stagger__char:nth-child(2) {
274
+ animation-delay: 0.05s;
275
+ }
276
+ .text-stagger__char:nth-child(3) {
277
+ animation-delay: 0.1s;
278
+ }
279
+ .text-stagger__char:nth-child(4) {
280
+ animation-delay: 0.15s;
281
+ }
282
+ .text-stagger__char:nth-child(5) {
283
+ animation-delay: 0.2s;
284
+ }
285
+ .text-stagger__char:nth-child(6) {
286
+ animation-delay: 0.25s;
287
+ }
288
+ .text-stagger__char:nth-child(7) {
289
+ animation-delay: 0.3s;
290
+ }
291
+ .text-stagger__char:nth-child(8) {
292
+ animation-delay: 0.35s;
293
+ }
294
+ .text-stagger__char:nth-child(9) {
295
+ animation-delay: 0.4s;
296
+ }
297
+ .text-stagger__char:nth-child(10) {
298
+ animation-delay: 0.45s;
299
+ }
300
+
301
+ @media (prefers-reduced-motion: reduce) {
302
+ .text-stagger__char {
303
+ animation: none;
304
+ }
305
+ }
306
+ }
307
+
308
+ @keyframes text-stagger-pop {
309
+ from {
310
+ opacity: 0;
311
+ transform: translateY(20px) scale(0.8);
312
+ }
313
+ to {
314
+ opacity: 1;
315
+ transform: translateY(0) scale(1);
316
+ }
317
+ }