@anubis609/astroanimate-core 0.1.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.
Files changed (78) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +212 -0
  3. package/dist/components/AnimatedBorderButton/AnimatedBorderButton.astro +129 -0
  4. package/dist/components/AnimatedBorderButton/index.js +3 -0
  5. package/dist/components/AnimatedBorderButton/index.js.map +1 -0
  6. package/dist/components/AnimatedButton/AnimatedButton.astro +299 -0
  7. package/dist/components/AnimatedButton/index.js +3 -0
  8. package/dist/components/AnimatedButton/index.js.map +1 -0
  9. package/dist/components/AnimatedCard/AnimatedCard.astro +832 -0
  10. package/dist/components/AnimatedCard/index.js +3 -0
  11. package/dist/components/AnimatedCard/index.js.map +1 -0
  12. package/dist/components/AnimatedTabs/AnimatedTabs.astro +348 -0
  13. package/dist/components/AnimatedTabs/index.js +3 -0
  14. package/dist/components/AnimatedTabs/index.js.map +1 -0
  15. package/dist/components/ArrowCTAButton/ArrowCTAButton.astro +159 -0
  16. package/dist/components/ArticleCard/ArticleCard.astro +208 -0
  17. package/dist/components/CardStack/CardStack.astro +444 -0
  18. package/dist/components/CardStack/index.js +3 -0
  19. package/dist/components/CardStack/index.js.map +1 -0
  20. package/dist/components/CountUp/CountUp.astro +89 -0
  21. package/dist/components/CountUp/index.js +3 -0
  22. package/dist/components/CountUp/index.js.map +1 -0
  23. package/dist/components/Dock/Dock.astro +567 -0
  24. package/dist/components/Dock/DockItem.astro +135 -0
  25. package/dist/components/Dropdown/Dropdown.astro +264 -0
  26. package/dist/components/ExpandableCard/ExpandableCard.astro +402 -0
  27. package/dist/components/ExpandableCard/index.js +3 -0
  28. package/dist/components/ExpandableCard/index.js.map +1 -0
  29. package/dist/components/FadeInText/FadeInText.astro +314 -0
  30. package/dist/components/FadeInText/index.js +3 -0
  31. package/dist/components/FadeInText/index.js.map +1 -0
  32. package/dist/components/FillHoverButton/FillHoverButton.astro +125 -0
  33. package/dist/components/GitHubShineButton/GitHubShineButton.astro +208 -0
  34. package/dist/components/GlassCard/GlassCard.astro +245 -0
  35. package/dist/components/GlassCard/index.js +3 -0
  36. package/dist/components/GlassCard/index.js.map +1 -0
  37. package/dist/components/GridDotsBackground/GridDotsBackground.astro +144 -0
  38. package/dist/components/HighlightText/HighlightText.astro +106 -0
  39. package/dist/components/InfiniteMarquee/InfiniteMarquee.astro +339 -0
  40. package/dist/components/JobCard/JobCard.astro +230 -0
  41. package/dist/components/LiquidGlassCard/LiquidGlassCard.astro +569 -0
  42. package/dist/components/Loader/Loader.astro +156 -0
  43. package/dist/components/Loader/index.js +3 -0
  44. package/dist/components/Loader/index.js.map +1 -0
  45. package/dist/components/NewsletterPopupCard/NewsletterPopupCard.astro +331 -0
  46. package/dist/components/ProductReviewCard/ProductReviewCard.astro +188 -0
  47. package/dist/components/ProgressBar/ProgressBar.astro +137 -0
  48. package/dist/components/ProgressBar/index.js +3 -0
  49. package/dist/components/ProgressBar/index.js.map +1 -0
  50. package/dist/components/RevealImage/RevealImage.astro +160 -0
  51. package/dist/components/RevealImage/index.js +3 -0
  52. package/dist/components/RevealImage/index.js.map +1 -0
  53. package/dist/components/ScaleIn/ScaleIn.astro +231 -0
  54. package/dist/components/ScaleIn/index.js +3 -0
  55. package/dist/components/ScaleIn/index.js.map +1 -0
  56. package/dist/components/SlidingOverlayButton/SlidingOverlayButton.astro +126 -0
  57. package/dist/components/StaggerTextButton/StaggerTextButton.astro +132 -0
  58. package/dist/components/Tooltip/Tooltip.astro +255 -0
  59. package/dist/components/Tooltip/index.js +3 -0
  60. package/dist/components/Tooltip/index.js.map +1 -0
  61. package/dist/components/TypewriterText/TypewriterText.astro +380 -0
  62. package/dist/components/TypewriterText/index.js +3 -0
  63. package/dist/components/TypewriterText/index.js.map +1 -0
  64. package/dist/components/index.js +33 -0
  65. package/dist/components/index.js.map +1 -0
  66. package/dist/index.js +31 -0
  67. package/dist/index.js.map +1 -0
  68. package/dist/internal/countup.js +90 -0
  69. package/dist/internal/countup.js.map +1 -0
  70. package/dist/internal/dropdown.js +166 -0
  71. package/dist/internal/dropdown.js.map +1 -0
  72. package/dist/internal/fadein.js +116 -0
  73. package/dist/internal/fadein.js.map +1 -0
  74. package/dist/internal/guards.js +12 -0
  75. package/dist/internal/guards.js.map +1 -0
  76. package/dist/internal/tabs.js +140 -0
  77. package/dist/internal/tabs.js.map +1 -0
  78. package/package.json +229 -0
@@ -0,0 +1,89 @@
1
+ ---
2
+ interface Props {
3
+ value: number;
4
+ start?: number;
5
+ duration?: number;
6
+ decimals?: number;
7
+ prefix?: string;
8
+ suffix?: string;
9
+ threshold?: number;
10
+ mainClassName?: string;
11
+ enhance?: boolean;
12
+ textColor?: string;
13
+ fontSize?: string;
14
+ fontFamily?: string;
15
+ }
16
+
17
+ const {
18
+ value,
19
+ start = 0,
20
+ duration = 2000,
21
+ decimals = 0,
22
+ prefix = "",
23
+ suffix = "",
24
+ threshold = 0.1,
25
+ mainClassName = "",
26
+ enhance = false,
27
+ textColor = "inherit",
28
+ fontSize = "inherit",
29
+ fontFamily = "inherit",
30
+ } = Astro.props;
31
+
32
+ const baselineValue =
33
+ prefix +
34
+ value.toLocaleString(undefined, {
35
+ minimumFractionDigits: decimals,
36
+ maximumFractionDigits: decimals,
37
+ }) +
38
+ suffix;
39
+ ---
40
+
41
+ <span
42
+ class:list={["count-up", mainClassName]}
43
+ data-countup
44
+ data-value={value}
45
+ data-start={start}
46
+ data-duration={duration}
47
+ data-decimals={decimals}
48
+ data-prefix={prefix}
49
+ data-suffix={suffix}
50
+ data-threshold={threshold}
51
+ data-enhance={enhance ? "true" : "false"}
52
+ style={`--count-up-color: ${textColor}; --count-up-size: ${fontSize}; --count-up-font-family: ${fontFamily};`}
53
+ >
54
+ {baselineValue}
55
+ </span>
56
+
57
+ <style>
58
+ .count-up {
59
+ display: inline-block;
60
+ font-variant-numeric: tabular-nums;
61
+ font-size: var(--count-up-size, 4rem);
62
+ font-weight: 700;
63
+ color: var(--count-up-color, #ff7700);
64
+ font-family: var(--count-up-font-family, system-ui, -apple-system, sans-serif);
65
+ transition: color 0.2s ease;
66
+ }
67
+
68
+ @media (prefers-reduced-motion: reduce) {
69
+ .count-up {
70
+ transition: none !important;
71
+ }
72
+ }
73
+ </style>
74
+
75
+ {
76
+ enhance && (
77
+ <script>
78
+ import { enhanceCountUp } from "../../internal/countup";
79
+
80
+ document
81
+ .querySelectorAll('[data-countup][data-enhance="true"]')
82
+ .forEach((el) => {
83
+ if (el instanceof HTMLElement) {
84
+ enhanceCountUp(el);
85
+ }
86
+ });
87
+ </script>
88
+ )
89
+ }
@@ -0,0 +1,3 @@
1
+ export { default } from './CountUp.astro';
2
+ //# sourceMappingURL=index.js.map
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}
@@ -0,0 +1,567 @@
1
+ ---
2
+ import type { HTMLAttributes } from 'astro/types';
3
+
4
+ interface Props extends HTMLAttributes<'nav'> {
5
+ /**
6
+ * Maximum magnification scale.
7
+ * @default 1.8
8
+ */
9
+ magnification?: number;
10
+ /**
11
+ * Distance in pixels where magnification begins.
12
+ * @default 150
13
+ */
14
+ distance?: number;
15
+ /**
16
+ * Background color of the dock.
17
+ * @default "rgba(20, 20, 20, 0.7)"
18
+ */
19
+ color?: string;
20
+ /**
21
+ * Blur intensity for the glass effect.
22
+ * @default "20px"
23
+ */
24
+ blur?: string;
25
+ /**
26
+ * Opt-in to interactive magnification.
27
+ * @default false
28
+ */
29
+ enhance?: boolean;
30
+ /**
31
+ * Position of the dock on screen.
32
+ * @default "bottom"
33
+ */
34
+ position?: "bottom" | "top";
35
+ /**
36
+ * Size of dock items.
37
+ * @default "md"
38
+ */
39
+ size?: "sm" | "md" | "lg";
40
+ class?: string;
41
+ }
42
+
43
+ const {
44
+ magnification = 1.8,
45
+ distance = 150,
46
+ color = "rgba(20, 20, 20, 0.7)",
47
+ blur = "20px",
48
+ enhance = false,
49
+ position = "bottom",
50
+ size = "md",
51
+ class: className = "",
52
+ ...rest
53
+ } = Astro.props;
54
+ ---
55
+
56
+ <style>
57
+ .astro-dock-container {
58
+ display: flex;
59
+ justify-content: center;
60
+ align-items: center;
61
+ pointer-events: none;
62
+ width: 100%;
63
+ perspective: 1000px;
64
+ }
65
+
66
+ /* Position variants */
67
+ .astro-dock-container[data-position="bottom"] {
68
+ padding-bottom: 1.5rem;
69
+ }
70
+ .astro-dock-container[data-position="top"] {
71
+ padding-top: 1.5rem;
72
+ }
73
+ .astro-dock-container[data-position="left"] {
74
+ padding-left: 1.5rem;
75
+ justify-content: flex-start;
76
+ }
77
+ .astro-dock-container[data-position="right"] {
78
+ padding-right: 1.5rem;
79
+ justify-content: flex-end;
80
+ }
81
+
82
+ .astro-dock {
83
+ display: flex;
84
+ align-items: center;
85
+ padding: 0 var(--dock-padding, 0.4rem);
86
+ background: var(--dock-color);
87
+ backdrop-filter: blur(var(--dock-blur));
88
+ -webkit-backdrop-filter: blur(var(--dock-blur));
89
+ border: 1px solid rgba(255, 255, 255, 0.15);
90
+ border-radius: 1.2rem;
91
+ pointer-events: auto;
92
+ box-shadow:
93
+ 0 10px 40px rgba(0, 0, 0, 0.4),
94
+ 0 0 0 1px rgba(255, 255, 255, 0.05),
95
+ inset 0 1px 0 rgba(255, 255, 255, 0.1);
96
+ height: var(--dock-height, 4.5rem);
97
+ transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
98
+ will-change: width;
99
+ }
100
+
101
+ /* Position-based transforms */
102
+ .astro-dock[data-position="bottom"] {
103
+ --dock-origin: bottom center;
104
+ --tooltip-bottom: calc(100% + 0.75rem);
105
+ --tooltip-top: auto;
106
+ --tooltip-left: 50%;
107
+ --tooltip-right: auto;
108
+ --tooltip-transform: translateX(-50%) translateY(4px);
109
+ --tooltip-transform-hover: translateX(-50%) translateY(0);
110
+ --tooltip-arrow-top: 100%;
111
+ --tooltip-arrow-bottom: auto;
112
+ --tooltip-arrow-left: 50%;
113
+ --tooltip-arrow-right: auto;
114
+ --tooltip-arrow-transform: translateX(-50%);
115
+ --tooltip-arrow-border-color: rgba(0, 0, 0, 0.85) transparent transparent transparent;
116
+ }
117
+ .astro-dock[data-position="top"] {
118
+ --dock-origin: top center;
119
+ --tooltip-bottom: auto;
120
+ --tooltip-top: calc(100% + 0.75rem);
121
+ --tooltip-left: 50%;
122
+ --tooltip-right: auto;
123
+ --tooltip-transform: translateX(-50%) translateY(-4px);
124
+ --tooltip-transform-hover: translateX(-50%) translateY(0);
125
+ --tooltip-arrow-top: auto;
126
+ --tooltip-arrow-bottom: 100%;
127
+ --tooltip-arrow-left: 50%;
128
+ --tooltip-arrow-right: auto;
129
+ --tooltip-arrow-transform: translateX(-50%);
130
+ --tooltip-arrow-border-color: transparent transparent rgba(0, 0, 0, 0.85) transparent;
131
+ }
132
+
133
+
134
+ :global(.dock-item) {
135
+ position: relative;
136
+ width: var(--item-size, 3.2rem);
137
+ height: var(--item-size, 3.2rem);
138
+ border-radius: 0.75rem;
139
+ background: transparent;
140
+ display: flex;
141
+ align-items: center;
142
+ justify-content: center;
143
+ cursor: pointer;
144
+ transform: scale(var(--dock-item-scale, 1)) translateY(var(--dock-item-y, 0px));
145
+ margin: 0 var(--dock-item-margin, 4px);
146
+ transition: transform 0.2s ease-out, margin 0.2s ease-out;
147
+ transform-origin: var(--dock-origin, bottom center);
148
+ will-change: transform, margin;
149
+ flex-shrink: 0;
150
+ overflow: visible;
151
+ transform-style: preserve-3d;
152
+ -webkit-transform-style: preserve-3d;
153
+ }
154
+
155
+ :global(.dock-item img) {
156
+ width: 100%;
157
+ height: 100%;
158
+ object-fit: contain;
159
+ filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.3));
160
+ transition: filter 0.2s ease;
161
+ image-rendering: -webkit-optimize-contrast;
162
+ image-rendering: crisp-edges;
163
+ backface-visibility: hidden;
164
+ -webkit-backface-visibility: hidden;
165
+ transform: translateZ(0) scale(1);
166
+ -webkit-transform: translateZ(0) scale(1);
167
+ transform-style: preserve-3d;
168
+ -webkit-font-smoothing: antialiased;
169
+ }
170
+
171
+ :global(.dock-item:hover img),
172
+ :global(.dock-item.is-active img) {
173
+ image-rendering: -webkit-optimize-contrast;
174
+ filter: drop-shadow(0 6px 12px rgba(0, 0, 0, 0.4));
175
+ }
176
+
177
+ /* Running indicator dot */
178
+ :global(.dock-item.is-active)::after {
179
+ content: '';
180
+ position: absolute;
181
+ bottom: -8px;
182
+ width: 4px;
183
+ height: 4px;
184
+ border-radius: 50%;
185
+ background: rgba(255, 255, 255, 0.6);
186
+ }
187
+
188
+ :global(.dock-item::before) {
189
+ content: '';
190
+ position: absolute;
191
+ inset: 0;
192
+ border-radius: inherit;
193
+ background: linear-gradient(145deg, rgba(255,255,255,0.1) 0%, transparent 50%);
194
+ opacity: 0;
195
+ transition: opacity 0.2s ease;
196
+ pointer-events: none;
197
+ }
198
+
199
+ :global(.dock-item:hover::before) {
200
+ opacity: 1;
201
+ }
202
+
203
+ /* Glow effect */
204
+ :global(.dock-item::after) {
205
+ content: '';
206
+ position: absolute;
207
+ inset: -2px;
208
+ border-radius: 1.1rem;
209
+ background: linear-gradient(145deg, var(--item-glow, transparent), transparent);
210
+ opacity: 0;
211
+ filter: blur(8px);
212
+ z-index: -1;
213
+ transition: opacity 0.3s ease;
214
+ }
215
+
216
+ :global(.dock-item.is-active::after),
217
+ :global(.dock-item:hover::after) {
218
+ opacity: 0.6;
219
+ }
220
+
221
+ /* Selected/Active state */
222
+ :global(.dock-item.is-selected) {
223
+ background: linear-gradient(145deg, #3a3a3a 0%, #2a2a2a 100%);
224
+ box-shadow:
225
+ 0 4px 12px rgba(0, 0, 0, 0.3),
226
+ inset 0 1px 0 rgba(255, 255, 255, 0.15),
227
+ 0 0 0 2px rgba(255, 255, 255, 0.2);
228
+ }
229
+
230
+ :global(.dock-item.is-selected::before) {
231
+ opacity: 1;
232
+ background: linear-gradient(145deg, rgba(255,255,255,0.15) 0%, transparent 50%);
233
+ }
234
+
235
+ /* Size variants */
236
+ .astro-dock[data-size="sm"] {
237
+ --item-size: 2.6rem;
238
+ --dock-height: 3.8rem;
239
+ --dock-gap: 0.5rem;
240
+ --dock-padding: 0.35rem;
241
+ --dock-padding-column: 0.6rem;
242
+ }
243
+ .astro-dock[data-size="lg"] {
244
+ --item-size: 3.8rem;
245
+ --dock-height: 5.2rem;
246
+ --dock-gap: 1rem;
247
+ --dock-padding: 0.45rem;
248
+ --dock-padding-column: 0.7rem;
249
+ }
250
+
251
+ /* Tooltip/Label styling */
252
+ :global(.dock-label) {
253
+ position: absolute;
254
+ bottom: var(--tooltip-bottom, calc(100% + 0.75rem));
255
+ top: var(--tooltip-top, auto);
256
+ left: var(--tooltip-left, 50%);
257
+ right: var(--tooltip-right, auto);
258
+ transform: var(--tooltip-transform, translateX(-50%) translateY(4px)) scale(var(--dock-label-scale, 1));
259
+ transform-origin: inherit;
260
+ background: rgba(0, 0, 0, 0.85);
261
+ color: white;
262
+ padding: 0.4rem 0.9rem;
263
+ border-radius: 0.4rem;
264
+ font-size: 0.8rem;
265
+ font-weight: 500;
266
+ font-family: system-ui, -apple-system, sans-serif;
267
+ border: 1px solid rgba(255, 255, 255, 0.15);
268
+ opacity: 0;
269
+ pointer-events: none;
270
+ transition: opacity 0.15s ease;
271
+ white-space: nowrap;
272
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
273
+ z-index: 100;
274
+ -webkit-font-smoothing: antialiased;
275
+ text-rendering: geometricPrecision;
276
+ backface-visibility: hidden;
277
+ -webkit-backface-visibility: hidden;
278
+ will-change: opacity, transform;
279
+ }
280
+
281
+ /* Tooltip arrow */
282
+ :global(.dock-label::after) {
283
+ content: '';
284
+ position: absolute;
285
+ top: var(--tooltip-arrow-top, 100%);
286
+ bottom: var(--tooltip-arrow-bottom, auto);
287
+ left: var(--tooltip-arrow-left, 50%);
288
+ right: var(--tooltip-arrow-right, auto);
289
+ transform: var(--tooltip-arrow-transform, translateX(-50%));
290
+ border: 5px solid transparent;
291
+ border-color: var(--tooltip-arrow-border-color, rgba(0, 0, 0, 0.85) transparent transparent transparent);
292
+ }
293
+
294
+ /* Icon styling */
295
+ :global(.dock-icon) {
296
+ width: 50%;
297
+ height: 50%;
298
+ display: flex;
299
+ align-items: center;
300
+ justify-content: center;
301
+ font-size: 1.4rem;
302
+ filter: drop-shadow(0 1px 2px rgba(0,0,0,0.3));
303
+ transition: transform 0.2s ease;
304
+ }
305
+
306
+ :global(.dock-item:hover .dock-icon) {
307
+ transform: scale(1.1);
308
+ }
309
+
310
+ /* Click ripple effect container */
311
+ :global(.dock-item-ripple) {
312
+ position: absolute;
313
+ inset: 0;
314
+ border-radius: inherit;
315
+ overflow: hidden;
316
+ pointer-events: none;
317
+ }
318
+
319
+ :global(.dock-ripple) {
320
+ position: absolute;
321
+ border-radius: 50%;
322
+ background: rgba(255, 255, 255, 0.3);
323
+ transform: scale(0);
324
+ animation: dockRipple 0.5s ease-out;
325
+ pointer-events: none;
326
+ }
327
+
328
+ @keyframes dockRipple {
329
+ to {
330
+ transform: scale(4);
331
+ opacity: 0;
332
+ }
333
+ }
334
+
335
+ /* Default hover (CSS fallback if enhance is false) */
336
+ [data-enhance="false"] :global(.dock-item:hover) {
337
+ --dock-item-scale: 1.25;
338
+ --dock-label-scale: 0.8;
339
+ --dock-item-y: -8px;
340
+ --dock-item-margin: 8px;
341
+ }
342
+
343
+ /* FIX (Criterion 6): All animations/transitions neutralized */
344
+ @media (prefers-reduced-motion: reduce) {
345
+ :global(.dock-item) {
346
+ transition: none !important;
347
+ transform: none !important;
348
+ }
349
+ :global(.dock-item img) {
350
+ transition: none !important;
351
+ }
352
+ :global(.dock-item::before) {
353
+ transition: none !important;
354
+ }
355
+ :global(.dock-item::after) {
356
+ transition: none !important;
357
+ }
358
+ :global(.dock-label) {
359
+ transition: none !important;
360
+ }
361
+ :global(.dock-icon) {
362
+ transition: none !important;
363
+ }
364
+ :global(.dock-ripple) {
365
+ animation: none !important;
366
+ }
367
+ .astro-dock {
368
+ transition: none !important;
369
+ backdrop-filter: none;
370
+ }
371
+ }
372
+
373
+ @media (max-width: 640px) {
374
+ .astro-dock {
375
+ --item-size: 2.6rem;
376
+ --dock-height: 3.8rem;
377
+ --dock-gap: 0.5rem;
378
+ --dock-padding: 0.35rem;
379
+ --dock-padding-column: 0.6rem;
380
+ }
381
+ .astro-dock-container[data-position="left"],
382
+ .astro-dock-container[data-position="right"] {
383
+ display: none;
384
+ }
385
+ }
386
+ </style>
387
+
388
+ <div
389
+ class:list={["astro-dock-container", className]}
390
+ data-position={position}
391
+ >
392
+ <nav
393
+ class="astro-dock"
394
+ data-astro-dock
395
+ data-enhance={enhance ? "true" : "false"}
396
+ data-magnification={magnification}
397
+ data-distance={distance}
398
+ data-position={position}
399
+ data-size={size}
400
+ style={`--dock-color: ${color}; --dock-blur: ${blur};`}
401
+ role="toolbar"
402
+ aria-label="Application dock"
403
+ {...rest}
404
+ >
405
+ <slot />
406
+ </nav>
407
+ </div>
408
+
409
+ {enhance && (
410
+ <script is:inline>
411
+ (function() {
412
+ if (typeof window === "undefined") return;
413
+
414
+ function canEnhance() {
415
+ if (typeof window === "undefined") return false;
416
+ if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
417
+ return false;
418
+ }
419
+ return true;
420
+ }
421
+
422
+ var initialized = new WeakMap();
423
+
424
+ function enhanceDock(root) {
425
+ if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
426
+ if (!canEnhance()) return;
427
+ if (initialized.has(root)) return;
428
+
429
+ var items = Array.from(root.querySelectorAll(".dock-item"));
430
+ var rippleTimers = new Map();
431
+
432
+ var updateDock = function (mouseX) {
433
+ var closestIndex = -1;
434
+ var closestDistance = Infinity;
435
+
436
+ items.forEach(function(item, index) {
437
+ var rect = item.getBoundingClientRect();
438
+ var centerX = rect.left + rect.width / 2;
439
+ var distance = Math.abs(mouseX - centerX);
440
+
441
+ if (distance < closestDistance) {
442
+ closestDistance = distance;
443
+ closestIndex = index;
444
+ }
445
+ });
446
+
447
+ items.forEach(function(item) {
448
+ item.style.setProperty("--dock-item-scale", "1");
449
+ item.style.setProperty("--dock-label-scale", "1");
450
+ item.style.setProperty("--dock-item-y", "0px");
451
+ item.style.setProperty("--dock-item-margin", "4px");
452
+ item.classList.remove("is-active");
453
+ });
454
+
455
+ if (closestIndex === -1) return;
456
+
457
+ var transformations = [
458
+ { idx: closestIndex - 2, scale: 1.05, translateY: 0, margin: 4 },
459
+ { idx: closestIndex - 1, scale: 1.15, translateY: -4, margin: 6 },
460
+ { idx: closestIndex, scale: 1.5, translateY: -15, margin: 8 },
461
+ { idx: closestIndex + 1, scale: 1.15, translateY: -4, margin: 6 },
462
+ { idx: closestIndex + 2, scale: 1.05, translateY: 0, margin: 4 },
463
+ ];
464
+
465
+ transformations.forEach(function (t) {
466
+ var idx = t.idx;
467
+ var scale = t.scale;
468
+ var translateY = t.translateY;
469
+ var margin = t.margin;
470
+ if (items[idx]) {
471
+ items[idx].style.setProperty("--dock-item-scale", String(scale));
472
+ items[idx].style.setProperty(
473
+ "--dock-label-scale",
474
+ String(1 / scale),
475
+ );
476
+
477
+ var finalTranslateY = root.dataset.position === "top" ? -translateY : translateY;
478
+ items[idx].style.setProperty("--dock-item-y", finalTranslateY + "px");
479
+ items[idx].style.setProperty("--dock-item-margin", margin + "px");
480
+ }
481
+ });
482
+
483
+ if (items[closestIndex]) {
484
+ items[closestIndex].classList.add("is-active");
485
+ }
486
+ };
487
+
488
+ var handleMouseMove = function (e) {
489
+ updateDock(e.clientX);
490
+ };
491
+
492
+ var handleMouseLeave = function () {
493
+ items.forEach(function(item) {
494
+ item.style.setProperty("--dock-item-scale", "1");
495
+ item.style.setProperty("--dock-label-scale", "1");
496
+ item.style.setProperty("--dock-item-y", "0px");
497
+ item.style.setProperty("--dock-item-margin", "4px");
498
+ item.classList.remove("is-active");
499
+ });
500
+ };
501
+
502
+ var handleClick = function (e) {
503
+ var target = e.currentTarget;
504
+ var ripple = document.createElement("span");
505
+ ripple.className = "dock-ripple";
506
+
507
+ var rect = target.getBoundingClientRect();
508
+ var size = Math.max(rect.width, rect.height);
509
+ ripple.style.width = ripple.style.height = size + "px";
510
+ ripple.style.left = (e.clientX - rect.left - size / 2) + "px";
511
+ ripple.style.top = (e.clientY - rect.top - size / 2) + "px";
512
+
513
+ target.appendChild(ripple);
514
+
515
+ var existing = rippleTimers.get(target);
516
+ if (existing) clearTimeout(existing);
517
+
518
+ var t = setTimeout(function() {
519
+ ripple.remove();
520
+ rippleTimers.delete(target);
521
+ }, 500);
522
+ rippleTimers.set(target, t);
523
+ };
524
+
525
+ items.forEach(function(item) {
526
+ item.addEventListener("click", handleClick);
527
+ });
528
+
529
+ root.addEventListener("mousemove", handleMouseMove, { passive: true });
530
+ root.addEventListener("mouseleave", handleMouseLeave);
531
+
532
+ initialized.set(root, true);
533
+
534
+ var observer = new MutationObserver(function() {
535
+ if (!document.contains(root)) {
536
+ root.removeEventListener("mousemove", handleMouseMove);
537
+ root.removeEventListener("mouseleave", handleMouseLeave);
538
+ items.forEach(function(item) {
539
+ item.removeEventListener("click", handleClick);
540
+ });
541
+ rippleTimers.forEach(function(t) { clearTimeout(t); });
542
+ rippleTimers.clear();
543
+ observer.disconnect();
544
+ initialized.delete(root);
545
+ }
546
+ });
547
+ observer.observe(document.body, { childList: true, subtree: true });
548
+ }
549
+
550
+ var init = function() {
551
+ document.querySelectorAll('[data-astro-dock][data-enhance="true"]:not([data-ready])')
552
+ .forEach(function(el) {
553
+ if (el instanceof HTMLElement) {
554
+ el.dataset.ready = "true";
555
+ enhanceDock(el);
556
+ }
557
+ });
558
+ };
559
+
560
+ if (document.readyState === "loading") {
561
+ document.addEventListener("DOMContentLoaded", init, { once: true });
562
+ } else {
563
+ init();
564
+ }
565
+ })();
566
+ </script>
567
+ )}