@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,314 @@
1
+ ---
2
+ /**
3
+ * FadeInText — Fades in with blur + vertical translate.
4
+ *
5
+ * enhance=false (default): Pure CSS @keyframes plays on every page load / refresh.
6
+ * No JavaScript involved. Works with JS disabled.
7
+ *
8
+ * enhance=true: IntersectionObserver delays the animation until the element
9
+ * scrolls into view. Animation fires once (or repeatedly if once=false).
10
+ */
11
+
12
+ interface Props {
13
+ /**
14
+ * Opt-in to JS-powered scroll-triggered animation (IntersectionObserver).
15
+ * When false (default), CSS @keyframes plays on every page load automatically.
16
+ * @default false
17
+ */
18
+ enhance?: boolean;
19
+
20
+ /**
21
+ * Animation duration in seconds.
22
+ * @default 0.6
23
+ */
24
+ duration?: number;
25
+
26
+ /**
27
+ * Delay before animation starts in seconds.
28
+ * CSS animation: applied as animation-delay.
29
+ * JS-enhanced: applied as transition-delay once element is in view.
30
+ * @default 0
31
+ */
32
+ delay?: number;
33
+
34
+ /**
35
+ * CSS easing / timing function.
36
+ * @default "cubic-bezier(0.4, 0, 0.2, 1)"
37
+ */
38
+ easing?: string;
39
+
40
+ /**
41
+ * Initial blur amount. Must include a CSS unit (e.g. "6px", "4px").
42
+ * @default "6px"
43
+ */
44
+ blur?: string;
45
+
46
+ /**
47
+ * Vertical distance (px) the element travels upward during the animation.
48
+ * @default 20
49
+ */
50
+ yOffset?: number;
51
+
52
+ /**
53
+ * [enhance=true only] Play the animation only once (true) or reset and
54
+ * re-animate every time the element re-enters the viewport (false).
55
+ * Has no effect when enhance=false.
56
+ * @default true
57
+ */
58
+ once?: boolean;
59
+
60
+ /**
61
+ * [enhance=true only] IntersectionObserver bottom rootMargin.
62
+ * A negative value (e.g. "-50px") means the element must be this far
63
+ * inside the viewport before the animation fires.
64
+ * Has no effect when enhance=false.
65
+ * @default "-50px"
66
+ */
67
+ inViewMargin?: string;
68
+
69
+ /**
70
+ * CSS class name applied to the root element.
71
+ */
72
+ class?: string;
73
+
74
+ /**
75
+ * HTML element rendered as the root wrapper.
76
+ * @default "div"
77
+ */
78
+ as?:
79
+ | "div"
80
+ | "section"
81
+ | "article"
82
+ | "aside"
83
+ | "main"
84
+ | "header"
85
+ | "footer"
86
+ | "nav"
87
+ | "span"
88
+ | "p"
89
+ | "h1"
90
+ | "h2"
91
+ | "h3"
92
+ | "h4"
93
+ | "h5"
94
+ | "h6"
95
+ | "li"
96
+ | "ul"
97
+ | "ol"
98
+ | "a"
99
+ | "button";
100
+
101
+ /**
102
+ * Any additional HTML attributes (id, aria-label, role, tabindex, data-*, …)
103
+ * are forwarded directly to the root element.
104
+ */
105
+ [key: string]: unknown;
106
+ }
107
+
108
+ const {
109
+ enhance = false,
110
+ duration = 0.6,
111
+ delay = 0,
112
+ easing = "cubic-bezier(0.4, 0, 0.2, 1)",
113
+ blur = "6px",
114
+ yOffset = 20,
115
+ once = true,
116
+ inViewMargin = "-50px",
117
+ class: className = "",
118
+ as: Tag = "div",
119
+ ...rest
120
+ } = Astro.props as Props;
121
+ ---
122
+
123
+ <style>
124
+ /*
125
+ * Separate CSS paths for enhance=false vs enhance=true.
126
+ *
127
+ * CSS animation ONLY fires on data-enhance="false" elements.
128
+ * enhance=true elements start statically hidden — JS owns their animation.
129
+ * A 2s CSS fallback animation on enhance=true ensures content is never
130
+ * permanently invisible if JS fails to load.
131
+ */
132
+
133
+ /* ✅ C1 + C7: CSS-only path for enhance=false.
134
+ Plays automatically on every page load and page refresh.
135
+ fill-mode "both": element starts in "from" state during delay,
136
+ and stays in "to" state permanently after the animation ends. */
137
+ [data-astro-fade-in-text][data-enhance="false"]:not([data-ready]) {
138
+ animation: fadeInText var(--fit-duration) var(--fit-easing) var(--fit-delay) both;
139
+ }
140
+
141
+ /* ✅ C1: Static hidden state for enhance=true, before JS runs.
142
+ CSS animation is intentionally suppressed here — JS will control it.
143
+ The 2s fallback animation is a safety net: if JS fails or is blocked,
144
+ content becomes visible after 2s instead of staying hidden forever. */
145
+ [data-astro-fade-in-text][data-enhance="true"]:not([data-ready]) {
146
+ opacity: 0;
147
+ filter: blur(var(--fit-blur));
148
+ transform: translateY(var(--fit-y-offset));
149
+ animation: fadeInText var(--fit-duration) var(--fit-easing) 2s both;
150
+ }
151
+
152
+ @keyframes fadeInText {
153
+ from {
154
+ opacity: 0;
155
+ filter: blur(var(--fit-blur));
156
+ transform: translateY(var(--fit-y-offset));
157
+ }
158
+ to {
159
+ opacity: 1;
160
+ filter: blur(0px);
161
+ transform: translateY(0);
162
+ }
163
+ }
164
+
165
+ /* ── JS-enhanced states ─────────────────────────────────────────────────
166
+ Activated once JS sets data-ready="true". All visual changes are
167
+ driven purely by data-state attribute — JS never writes element.style.
168
+ ──────────────────────────────────────────────────────────────────────── */
169
+
170
+ /* ✅ C7: Waiting for viewport entry */
171
+ [data-astro-fade-in-text][data-ready="true"][data-state="hidden"] {
172
+ opacity: 0;
173
+ filter: blur(var(--fit-blur));
174
+ transform: translateY(var(--fit-y-offset));
175
+ }
176
+
177
+ /* ✅ C7: Element is in viewport — CSS transition to fully visible */
178
+ [data-astro-fade-in-text][data-ready="true"][data-state="animate"] {
179
+ opacity: 1;
180
+ filter: blur(0px);
181
+ transform: translateY(0);
182
+ transition:
183
+ opacity var(--fit-duration) var(--fit-easing) var(--fit-delay),
184
+ filter var(--fit-duration) var(--fit-easing) var(--fit-delay),
185
+ transform var(--fit-duration) var(--fit-easing) var(--fit-delay);
186
+ }
187
+
188
+ /* ✅ C6: ALL CSS motion neutralised for prefers-reduced-motion.
189
+ Covers both the CSS-only path and the JS-enhanced path.
190
+ Content is shown immediately regardless of animation state. */
191
+ @media (prefers-reduced-motion: reduce) {
192
+ [data-astro-fade-in-text]:not([data-ready]) {
193
+ animation: none !important;
194
+ opacity: 1 !important;
195
+ filter: none !important;
196
+ transform: none !important;
197
+ }
198
+ [data-astro-fade-in-text][data-ready="true"] {
199
+ opacity: 1 !important;
200
+ filter: none !important;
201
+ transform: none !important;
202
+ transition: none !important;
203
+ }
204
+ }
205
+ </style>
206
+
207
+ <!-- ✅ C1: Slot content always present in HTML — meaningful without JS.
208
+ ✅ C4: No import.meta.env.DEV — identical in dev, build, and preview.
209
+ ✅ C5: No astro:* events. Standard data attributes only.
210
+ {...rest} forwards id, aria-label, role, tabindex, data-*, etc.
211
+ Style is a single inline string — no stray newlines in HTML output. -->
212
+ <Tag
213
+ {...rest}
214
+ class:list={["astro-fade-in-text", className]}
215
+ data-astro-fade-in-text
216
+ data-enhance={enhance ? "true" : "false"}
217
+ data-once={once ? "true" : "false"}
218
+ data-margin={inViewMargin}
219
+ style={`--fit-duration:${duration}s;--fit-delay:${delay}s;--fit-easing:${easing};--fit-blur:${blur};--fit-y-offset:${yOffset}px`}
220
+ >
221
+ <!-- ✅ C8: Slot always rendered. JS only adds timing/trigger control. -->
222
+ <slot />
223
+ </Tag>
224
+
225
+ <!-- ✅ C2: Script emitted ONLY when enhance=true. No unconditional scripts.
226
+ is:inline is required — Astro does NOT bundle <script> tags sourced
227
+ from node_modules. is:inline embeds the script verbatim in HTML output,
228
+ guaranteeing it ships regardless of the consumer's build configuration. -->
229
+ {enhance && (
230
+ <script is:inline>
231
+ (function () {
232
+ // ✅ C6: SSR guard — bail immediately if not in a browser context
233
+ if (typeof window === "undefined") return;
234
+
235
+ // ✅ C6: Reduced motion check BEFORE any initialisation
236
+ if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
237
+
238
+ // ✅ C3: WeakMap stores IntersectionObserver per element for cleanup.
239
+ var initialized = new WeakMap();
240
+
241
+ function enhanceFadeInText(root) {
242
+ /*
243
+ * Cross-IIFE initialisation guard via DOM attribute.
244
+ *
245
+ * With N enhance=true FadeInText components on the page,
246
+ * N IIFEs execute. Each IIFE creates its own fresh WeakMap. Each IIFE's
247
+ * querySelectorAll finds ALL N elements. Since each WeakMap is always
248
+ * empty at that moment, initialized.has(root) is always false, so every
249
+ * IIFE enhances every element. N elements × N IIFEs = N² observers.
250
+ * Animations race; cleanup fires multiple times per element.
251
+ *
252
+ * AFTER (fix): data-ready is set directly on the DOM element, which is
253
+ * shared state across all IIFEs. The first IIFE to run sets
254
+ * data-ready="true"; every subsequent IIFE exits immediately on this
255
+ * check. Exactly one IntersectionObserver + one MutationObserver per
256
+ * element, regardless of how many components are on the page.
257
+ */
258
+ if (root.dataset.ready === "true") return;
259
+
260
+ var isOnce = root.dataset.once === "true";
261
+ var margin = root.dataset.margin || "-50px";
262
+
263
+ // ✅ C7: JS sets data attributes only — never element.style.
264
+ //
265
+ // Setting data-ready="true" does three things simultaneously:
266
+ // 1. Acts as the cross-IFFE initialisation guard (see above).
267
+ // 2. Switches CSS from the static-hidden path to the data-state path.
268
+ // 3. Cancels the 2s CSS fallback animation (selector no longer matches).
269
+ root.dataset.ready = "true";
270
+ root.dataset.state = "hidden";
271
+
272
+ // ✅ C3: IntersectionObserver — tracked in WeakMap for cleanup
273
+ var observer = new IntersectionObserver(
274
+ function (entries) {
275
+ entries.forEach(function (entry) {
276
+ if (entry.isIntersecting) {
277
+ root.dataset.state = "animate"; // ✅ C7: attribute-only transition
278
+ if (isOnce) {
279
+ // once=true: stop observing after first intersection —
280
+ // no further callbacks, no unnecessary CPU work.
281
+ observer.unobserve(root);
282
+ }
283
+ } else if (!isOnce) {
284
+ // once=false: element scrolled back out — reset for re-animation.
285
+ root.dataset.state = "hidden";
286
+ }
287
+ });
288
+ },
289
+ { threshold: 0.1, rootMargin: "0px 0px " + margin + " 0px" }
290
+ );
291
+
292
+ observer.observe(root);
293
+ initialized.set(root, observer); // ✅ C3: store ref for guaranteed cleanup
294
+
295
+ // ✅ C3: MutationObserver guarantees both observers are disconnected
296
+ // when the root element is removed from the DOM (SPA navigation,
297
+ // conditional rendering, island teardown, etc.).
298
+ var cleanupObserver = new MutationObserver(function () {
299
+ if (!document.contains(root)) {
300
+ observer.disconnect(); // ✅ C3: IntersectionObserver disconnected
301
+ cleanupObserver.disconnect(); // ✅ C3: MutationObserver disconnected
302
+ initialized.delete(root);
303
+ }
304
+ });
305
+
306
+ cleanupObserver.observe(document.body, { childList: true, subtree: true });
307
+ }
308
+
309
+ document
310
+ .querySelectorAll('[data-astro-fade-in-text][data-enhance="true"]')
311
+ .forEach(function (el) { enhanceFadeInText(el); });
312
+ })();
313
+ </script>
314
+ )}
@@ -0,0 +1,3 @@
1
+ export { default } from './FadeInText.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,125 @@
1
+ ---
2
+ interface Props {
3
+ as?: "button" | "a";
4
+ href?: string;
5
+ type?: "button" | "submit" | "reset";
6
+ class?: string;
7
+ }
8
+
9
+ const {
10
+ as = "button",
11
+ href,
12
+ type = "button",
13
+ class: className = "",
14
+ } = Astro.props;
15
+ ---
16
+
17
+ <style>
18
+ /* ✅ CRITERION 7: CSS-FIRST */
19
+
20
+ [data-fhb] {
21
+ position: relative;
22
+
23
+ display: inline-flex;
24
+ align-items: center;
25
+ justify-content: center;
26
+
27
+ padding: 1em 1.5em;
28
+
29
+ border: none;
30
+ background: transparent;
31
+
32
+ color: #ffc506;
33
+
34
+ font-size: 1.0625rem;
35
+ text-transform: uppercase;
36
+ text-decoration: none;
37
+
38
+ cursor: pointer;
39
+
40
+ overflow: hidden;
41
+ isolation: isolate;
42
+
43
+ transition: color 500ms ease;
44
+ }
45
+
46
+ /* Underline */
47
+ [data-fhb]::before {
48
+ content: "";
49
+
50
+ position: absolute;
51
+ left: 0;
52
+ bottom: 0;
53
+
54
+ width: 0;
55
+ height: 2px;
56
+
57
+ background: #ffc506;
58
+
59
+ transition: width 500ms ease;
60
+ }
61
+
62
+ /* Fill layer */
63
+ [data-fhb]::after {
64
+ content: "";
65
+
66
+ position: absolute;
67
+ inset: auto 0 0 0;
68
+
69
+ width: 100%;
70
+ height: 0;
71
+
72
+ background: #ffc506;
73
+
74
+ z-index: -1;
75
+
76
+ transition: height 400ms ease;
77
+ }
78
+
79
+ [data-fhb]:hover {
80
+ color: #1e1e2b;
81
+ transition-delay: 500ms;
82
+ }
83
+
84
+ [data-fhb]:hover::before {
85
+ width: 100%;
86
+ }
87
+
88
+ [data-fhb]:hover::after {
89
+ height: 100%;
90
+ transition-delay: 400ms;
91
+ }
92
+
93
+ /* Accessibility */
94
+ [data-fhb]:focus-visible {
95
+ outline: 2px solid #ffc506;
96
+ outline-offset: 4px;
97
+ }
98
+
99
+ /* ✅ CRITERION 6: REDUCED MOTION */
100
+ @media (prefers-reduced-motion: reduce) {
101
+ [data-fhb],
102
+ [data-fhb]::before,
103
+ [data-fhb]::after {
104
+ transition: none !important;
105
+ }
106
+ }
107
+ </style>
108
+
109
+ {as === "a" ? (
110
+ <a
111
+ data-fhb
112
+ href={href}
113
+ class={className}
114
+ >
115
+ <slot />
116
+ </a>
117
+ ) : (
118
+ <button
119
+ data-fhb
120
+ type={type}
121
+ class={className}
122
+ >
123
+ <slot />
124
+ </button>
125
+ )}
@@ -0,0 +1,208 @@
1
+ ---
2
+ interface Props {
3
+ as?: "button" | "a";
4
+ href?: string;
5
+ stars?: number | string;
6
+ showStars?: boolean;
7
+ type?: "button" | "submit" | "reset";
8
+ class?: string;
9
+ fontFamily?: string;
10
+ }
11
+
12
+ const {
13
+ as = "button",
14
+ href,
15
+ stars = 0,
16
+ showStars = true,
17
+ type = "button",
18
+ class: className = "",
19
+ fontFamily = "Inter, sans-serif",
20
+ } = Astro.props;
21
+ ---
22
+
23
+ <style>
24
+ /* ✅ CRITERION 7: CSS-FIRST */
25
+
26
+ [data-ghsb] {
27
+ position: relative;
28
+ overflow: hidden;
29
+ display: inline-flex;
30
+ align-items: center;
31
+ justify-content: center;
32
+ gap: 0.75rem;
33
+
34
+ height: 2.6rem;
35
+ padding-inline: 1rem;
36
+
37
+ border-radius: 0.5rem;
38
+ background: black;
39
+ color: white;
40
+
41
+ font-size: 0.875rem;
42
+ font-weight: 500;
43
+ text-decoration: none;
44
+ white-space: nowrap;
45
+
46
+ transition:
47
+ background-color 300ms ease,
48
+ box-shadow 300ms ease,
49
+ transform 300ms ease;
50
+ }
51
+
52
+ /* Shine */
53
+ [data-ghsb]::before {
54
+ content: "";
55
+ position: absolute;
56
+ top: -4rem;
57
+ right: 0;
58
+
59
+ width: 2rem;
60
+ height: 8rem;
61
+
62
+ transform: translateX(3rem) rotate(12deg);
63
+
64
+ background: rgba(255,255,255,0.1);
65
+
66
+ transition: transform 1000ms ease;
67
+ }
68
+
69
+ [data-ghsb]:hover::before {
70
+ transform: translateX(-10rem) rotate(12deg);
71
+ }
72
+
73
+ [data-ghsb]:hover {
74
+ background: rgba(0,0,0,0.9);
75
+ box-shadow: 0 0 0 2px white;
76
+ }
77
+
78
+ .main,
79
+ .stats {
80
+ position: relative;
81
+ z-index: 1;
82
+
83
+ display: inline-flex;
84
+ align-items: center;
85
+ gap: 0.35rem;
86
+ }
87
+
88
+ .github-icon,
89
+ .star-icon {
90
+ width: 1rem;
91
+ height: 1rem;
92
+ fill: currentColor;
93
+ flex-shrink: 0;
94
+ }
95
+
96
+ .star-icon {
97
+ color: #a3a3a3;
98
+ transition: color 300ms ease;
99
+ }
100
+
101
+ [data-ghsb]:hover .star-icon {
102
+ color: #fde047;
103
+ }
104
+
105
+ .count {
106
+ font-variant-numeric: tabular-nums;
107
+ letter-spacing: 0.04em;
108
+ }
109
+
110
+ /* Accessibility */
111
+ [data-ghsb]:focus-visible {
112
+ outline: 2px solid white;
113
+ outline-offset: 4px;
114
+ }
115
+
116
+ /* ✅ CRITERION 6: REDUCED MOTION */
117
+ @media (prefers-reduced-motion: reduce) {
118
+ [data-ghsb],
119
+ [data-ghsb] * {
120
+ transition: none !important;
121
+ transform: none !important;
122
+ }
123
+ }
124
+ </style>
125
+
126
+ {as === "a" ? (
127
+ <a
128
+ data-ghsb
129
+ href={href}
130
+ class={className}
131
+ style={`font-family: ${fontFamily};`}
132
+ >
133
+ <span class="main">
134
+ <svg
135
+ class="github-icon"
136
+ aria-hidden="true"
137
+ viewBox="0 0 24 24"
138
+ >
139
+ <path
140
+ fill="currentColor"
141
+ d="M12 .5C5.648.5.5 5.648.5 12a11.5 11.5 0 0 0 7.863 10.923c.575.106.787-.25.787-.556 0-.275-.012-1.188-.018-2.156-3.2.694-3.877-1.544-3.877-1.544-.525-1.337-1.282-1.694-1.282-1.694-1.05-.719.081-.706.081-.706 1.162.081 1.775 1.194 1.775 1.194 1.031 1.769 2.706 1.258 3.369.962.106-.75.406-1.256.737-1.544-2.556-.288-5.244-1.281-5.244-5.706 0-1.262.45-2.294 1.188-3.106-.119-.288-.519-1.45.112-3.019 0 0 .969-.31 3.175 1.188A11.06 11.06 0 0 1 12 6.094c.975.006 1.956.131 2.875.381 2.206-1.5 3.175-1.188 3.175-1.188.631 1.569.231 2.731.112 3.019.738.812 1.188 1.844 1.188 3.106 0 4.438-2.694 5.413-5.256 5.694.419.362.794 1.075.794 2.169 0 1.569-.013 2.831-.013 3.219 0 .306.206.669.794.556A11.503 11.503 0 0 0 23.5 12C23.5 5.648 18.352.5 12 .5Z"
142
+ />
143
+ </svg>
144
+
145
+ <span>
146
+ <slot />
147
+ </span>
148
+ </span>
149
+
150
+ {showStars && (
151
+ <span class="stats">
152
+ <svg
153
+ class="star-icon"
154
+ aria-hidden="true"
155
+ viewBox="0 0 24 24"
156
+ >
157
+ <path
158
+ fill="currentColor"
159
+ d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"
160
+ />
161
+ </svg>
162
+
163
+ <span class="count">{stars}</span>
164
+ </span>
165
+ )}
166
+ </a>
167
+ ) : (
168
+ <button
169
+ data-ghsb
170
+ type={type}
171
+ class={className}
172
+ style={`font-family: ${fontFamily};`}
173
+ >
174
+ <span class="main">
175
+ <svg
176
+ class="github-icon"
177
+ aria-hidden="true"
178
+ viewBox="0 0 24 24"
179
+ >
180
+ <path
181
+ fill="currentColor"
182
+ d="M12 .5C5.648.5.5 5.648.5 12a11.5 11.5 0 0 0 7.863 10.923c.575.106.787-.25.787-.556 0-.275-.012-1.188-.018-2.156-3.2.694-3.877-1.544-3.877-1.544-.525-1.337-1.282-1.694-1.282-1.694-1.05-.719.081-.706.081-.706 1.162.081 1.775 1.194 1.775 1.194 1.031 1.769 2.706 1.258 3.369.962.106-.75.406-1.256.737-1.544-2.556-.288-5.244-1.281-5.244-5.706 0-1.262.45-2.294 1.188-3.106-.119-.288-.519-1.45.112-3.019 0 0 .969-.31 3.175 1.188A11.06 11.06 0 0 1 12 6.094c.975.006 1.956.131 2.875.381 2.206-1.5 3.175-1.188 3.175-1.188.631 1.569.231 2.731.112 3.019.738.812 1.188 1.844 1.188 3.106 0 4.438-2.694 5.413-5.256 5.694.419.362.794 1.075.794 2.169 0 1.569-.013 2.831-.013 3.219 0 .306.206.669.794.556A11.503 11.503 0 0 0 23.5 12C23.5 5.648 18.352.5 12 .5Z"
183
+ />
184
+ </svg>
185
+
186
+ <span>
187
+ <slot />
188
+ </span>
189
+ </span>
190
+
191
+ {showStars && (
192
+ <span class="stats">
193
+ <svg
194
+ class="star-icon"
195
+ aria-hidden="true"
196
+ viewBox="0 0 24 24"
197
+ >
198
+ <path
199
+ fill="currentColor"
200
+ d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"
201
+ />
202
+ </svg>
203
+
204
+ <span class="count">{stars}</span>
205
+ </span>
206
+ )}
207
+ </button>
208
+ )}