@@ -94,90 +94,8 @@ const categories = [
9494 </div >
9595 </section >
9696
97- <!-- Features -->
98- <section class =" py-20 px-4 sm:px-6 border-t border-border" >
99- <div class =" max-w-5xl mx-auto" >
100- <div class =" grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6" data-anim-stagger =" 100ms" >
101- <div class =" glass-card p-6" data-anim =" fadeInUp" >
102- <div class =" w-10 h-10 rounded-lg bg-accent/10 flex items-center justify-center mb-4" >
103- <svg width =" 20" height =" 20" viewBox =" 0 0 24 24" fill =" none" stroke =" #6366f1" stroke-width =" 2" >
104- <path d =" M13 2L3 14h9l-1 8 10-12h-9l1-8z" />
105- </svg >
106- </div >
107- <h3 class =" text-lg font-heading font-semibold mb-2" >No JS to Write</h3 >
108- <p class =" text-sm text-text-secondary" >Pure CSS animations triggered by HTML attributes. Just add data attributes.</p >
109- </div >
110-
111- <div class =" glass-card p-6" data-anim =" fadeInUp" >
112- <div class =" w-10 h-10 rounded-lg bg-accent/10 flex items-center justify-center mb-4" >
113- <svg width =" 20" height =" 20" viewBox =" 0 0 24 24" fill =" none" stroke =" #6366f1" stroke-width =" 2" >
114- <path d =" M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" />
115- </svg >
116- </div >
117- <h3 class =" text-lg font-heading font-semibold mb-2" >Anti-FOUC Built-in</h3 >
118- <p class =" text-sm text-text-secondary" >3-layer defense against Flash of Unstyled Content. No manual CSS workarounds needed.</p >
119- </div >
120-
121- <div class =" glass-card p-6" data-anim =" fadeInUp" >
122- <div class =" w-10 h-10 rounded-lg bg-accent/10 flex items-center justify-center mb-4" >
123- <svg width =" 20" height =" 20" viewBox =" 0 0 24 24" fill =" none" stroke =" #6366f1" stroke-width =" 2" >
124- <circle cx =" 12" cy =" 12" r =" 10" />
125- <polyline points =" 12 6 12 12 16 14" />
126- </svg >
127- </div >
128- <h3 class =" text-lg font-heading font-semibold mb-2" >Under 3KB</h3 >
129- <p class =" text-sm text-text-secondary" >Tiny footprint. No dependencies. Loads in under 5ms. Smaller than most favicons.</p >
130- </div >
131-
132- <div class =" glass-card p-6" data-anim =" fadeInUp" >
133- <div class =" w-10 h-10 rounded-lg bg-accent/10 flex items-center justify-center mb-4" >
134- <svg width =" 20" height =" 20" viewBox =" 0 0 24 24" fill =" none" stroke =" #6366f1" stroke-width =" 2" >
135- <path d =" M3 3h18v18H3z M3 9h18 M9 3v18" />
136- </svg >
137- </div >
138- <h3 class =" text-lg font-heading font-semibold mb-2" >TypeScript Support</h3 >
139- <p class =" text-sm text-text-secondary" >Full autocomplete for all data-anim attributes in React and Vue. Just import and go.</p >
140- </div >
141- </div >
142- </div >
143- </section >
144-
145- <!-- Quick Start -->
146- <section class =" py-20 px-4 sm:px-6 border-t border-border" >
147- <div class =" max-w-3xl mx-auto" >
148- <h2 class =" text-3xl font-heading font-bold text-center mb-4" data-anim =" fadeInUp" >
149- Three lines. That's it.
150- </h2 >
151- <p class =" text-center text-text-secondary mb-8" data-anim =" fadeInUp" data-anim-delay =" 100ms" >
152- No config files. No build step. No framework required.
153- </p >
154-
155- <div data-anim =" fadeInUp" data-anim-delay =" 200ms" >
156- <CodeBlock
157- code ={ ` <!-- 1. Add the script -->
158- <script src="https://unpkg.com/data-anim@latest/dist/data-anim.js"></script>
159-
160- <!-- 2. Add the attribute -->
161- <div data-anim="fadeInUp">
162- Your content animates on scroll
163- </div>
164-
165- <!-- 3. There is no step 3 --> ` }
166- lang =" html"
167- filename =" index.html"
168- />
169- </div >
170-
171- <div class =" text-center mt-8" data-anim =" fadeInUp" data-anim-delay =" 300ms" >
172- <a href ={ ` ${import .meta .env .BASE_URL .replace (/ \/ ? $ / , ' /' )}docs/getting-started ` } class =" text-accent-readable hover:text-[#c4b5fd] font-semibold text-lg" >
173- Read the full docs →
174- </a >
175- </div >
176- </div >
177- </section >
178-
17997 <!-- Animation Showcase -->
180- <section class =" py-20 px-4 sm:px-6 border-t border-border" >
98+ <section id = " showcase-section " class =" py-20 px-4 sm:px-6 border-t border-border" >
18199 <div class =" max-w-5xl mx-auto" >
182100 <p class =" text-center text-xs font-semibold tracking-widest text-text-muted uppercase mb-4" data-anim =" fadeInUp" >Animation Library</p >
183101 <h2 class =" text-3xl md:text-4xl font-heading font-bold text-center mb-4" data-anim =" fadeInUp" >
@@ -269,6 +187,88 @@ const categories = [
269187 </div >
270188 </section >
271189
190+ <!-- Features -->
191+ <section class =" py-20 px-4 sm:px-6 border-t border-border" >
192+ <div class =" max-w-5xl mx-auto" >
193+ <div class =" grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6" data-anim-stagger =" 100ms" >
194+ <div class =" glass-card p-6" data-anim =" fadeInUp" >
195+ <div class =" w-10 h-10 rounded-lg bg-accent/10 flex items-center justify-center mb-4" >
196+ <svg width =" 20" height =" 20" viewBox =" 0 0 24 24" fill =" none" stroke =" #6366f1" stroke-width =" 2" >
197+ <path d =" M13 2L3 14h9l-1 8 10-12h-9l1-8z" />
198+ </svg >
199+ </div >
200+ <h3 class =" text-lg font-heading font-semibold mb-2" >No JS to Write</h3 >
201+ <p class =" text-sm text-text-secondary" >Pure CSS animations triggered by HTML attributes. Just add data attributes.</p >
202+ </div >
203+
204+ <div class =" glass-card p-6" data-anim =" fadeInUp" >
205+ <div class =" w-10 h-10 rounded-lg bg-accent/10 flex items-center justify-center mb-4" >
206+ <svg width =" 20" height =" 20" viewBox =" 0 0 24 24" fill =" none" stroke =" #6366f1" stroke-width =" 2" >
207+ <path d =" M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" />
208+ </svg >
209+ </div >
210+ <h3 class =" text-lg font-heading font-semibold mb-2" >Anti-FOUC Built-in</h3 >
211+ <p class =" text-sm text-text-secondary" >3-layer defense against Flash of Unstyled Content. No manual CSS workarounds needed.</p >
212+ </div >
213+
214+ <div class =" glass-card p-6" data-anim =" fadeInUp" >
215+ <div class =" w-10 h-10 rounded-lg bg-accent/10 flex items-center justify-center mb-4" >
216+ <svg width =" 20" height =" 20" viewBox =" 0 0 24 24" fill =" none" stroke =" #6366f1" stroke-width =" 2" >
217+ <circle cx =" 12" cy =" 12" r =" 10" />
218+ <polyline points =" 12 6 12 12 16 14" />
219+ </svg >
220+ </div >
221+ <h3 class =" text-lg font-heading font-semibold mb-2" >Under 3KB</h3 >
222+ <p class =" text-sm text-text-secondary" >Tiny footprint. No dependencies. Loads in under 5ms. Smaller than most favicons.</p >
223+ </div >
224+
225+ <div class =" glass-card p-6" data-anim =" fadeInUp" >
226+ <div class =" w-10 h-10 rounded-lg bg-accent/10 flex items-center justify-center mb-4" >
227+ <svg width =" 20" height =" 20" viewBox =" 0 0 24 24" fill =" none" stroke =" #6366f1" stroke-width =" 2" >
228+ <path d =" M3 3h18v18H3z M3 9h18 M9 3v18" />
229+ </svg >
230+ </div >
231+ <h3 class =" text-lg font-heading font-semibold mb-2" >TypeScript Support</h3 >
232+ <p class =" text-sm text-text-secondary" >Full autocomplete for all data-anim attributes in React and Vue. Just import and go.</p >
233+ </div >
234+ </div >
235+ </div >
236+ </section >
237+
238+ <!-- Quick Start -->
239+ <section class =" py-20 px-4 sm:px-6 border-t border-border" >
240+ <div class =" max-w-3xl mx-auto" >
241+ <h2 class =" text-3xl font-heading font-bold text-center mb-4" data-anim =" fadeInUp" >
242+ Three lines. That's it.
243+ </h2 >
244+ <p class =" text-center text-text-secondary mb-8" data-anim =" fadeInUp" data-anim-delay =" 100ms" >
245+ No config files. No build step. No framework required.
246+ </p >
247+
248+ <div data-anim =" fadeInUp" data-anim-delay =" 200ms" >
249+ <CodeBlock
250+ code ={ ` <!-- 1. Add the script -->
251+ <script src="https://unpkg.com/data-anim@latest/dist/data-anim.js"></script>
252+
253+ <!-- 2. Add the attribute -->
254+ <div data-anim="fadeInUp">
255+ Your content animates on scroll
256+ </div>
257+
258+ <!-- 3. There is no step 3 --> ` }
259+ lang =" html"
260+ filename =" index.html"
261+ />
262+ </div >
263+
264+ <div class =" text-center mt-8" data-anim =" fadeInUp" data-anim-delay =" 300ms" >
265+ <a href ={ ` ${import .meta .env .BASE_URL .replace (/ \/ ? $ / , ' /' )}docs/getting-started ` } class =" text-accent-readable hover:text-[#c4b5fd] font-semibold text-lg" >
266+ Read the full docs →
267+ </a >
268+ </div >
269+ </div >
270+ </section >
271+
272272 <Footer />
273273</BaseLayout >
274274
@@ -466,14 +466,16 @@ const categories = [
466466 } , 2000);
467467 });
468468
469- // Showcase card hover → animate child dots
470- document.querySelectorAll('.showcase-card').forEach(function(card) {
471- var dots = card .querySelectorAll (' [data-gallery-anim]' );
472- if (! dots .length ) return ;
473- var animating = false ;
474- card .addEventListener (' mouseenter' , function () {
475- if (animating ) return ;
476- animating = true ;
469+ // Showcase card continuous auto-play (motion.dev style)
470+ (function() {
471+ var cards = Array .from (document .querySelectorAll (' .showcase-card' ));
472+ if (! cards .length ) return ;
473+
474+ function playCard(card ) {
475+ var dots = card .querySelectorAll (' [data-gallery-anim]' );
476+ if (! dots .length ) return ;
477+ if (card ._animating ) return ;
478+ card ._animating = true ;
477479 var done = 0 ;
478480 dots .forEach (function (dot , i ) {
479481 var name = dot .getAttribute (' data-gallery-anim' );
@@ -484,10 +486,45 @@ const categories = [
484486 dot .addEventListener (' animationend' , function () {
485487 dot .style .animation = ' ' ;
486488 done ++ ;
487- if (done >= dots .length ) animating = false ;
489+ if (done >= dots .length ) card . _animating = false ;
488490 }, { once: true });
489491 }, i * 80 );
490492 });
491- });
492- } );
493+ }
494+
495+ // Each card loops independently with staggered start
496+ var intervals = [];
497+
498+ function startAutoPlay() {
499+ if (intervals .length ) return ;
500+ cards .forEach (function (card , idx ) {
501+ // Stagger initial start so they don't all fire at once
502+ setTimeout (function () {
503+ playCard (card );
504+ var id = setInterval (function () { playCard (card ); }, 1800 );
505+ intervals .push (id );
506+ }, idx * 400 );
507+ });
508+ }
509+
510+ function stopAutoPlay() {
511+ intervals .forEach (function (id ) { clearInterval (id ); });
512+ intervals = [];
513+ }
514+
515+ var showcaseSection = document .getElementById (' showcase-section' );
516+ if (! showcaseSection ) return ;
517+
518+ var observer = new IntersectionObserver (function (entries ) {
519+ entries .forEach (function (entry ) {
520+ if (entry .isIntersecting ) {
521+ startAutoPlay ();
522+ } else {
523+ stopAutoPlay ();
524+ }
525+ });
526+ }, { threshold: 0.1 });
527+
528+ observer .observe (showcaseSection );
529+ } )();
493530</script >
0 commit comments