Skip to content

Commit 99b910a

Browse files
Merge pull request #105 from sonoflawal/refactor/extract-animation-variants
refactor: extract animation variants into shared constants
2 parents e572ccd + cdd8259 commit 99b910a

8 files changed

Lines changed: 15757 additions & 125 deletions

File tree

app/not-found.tsx

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { motion } from "framer-motion";
66
import { Navbar } from "@/components/organisms/navbar";
77
import { Button } from "@/components/atoms/button";
88
import { GradientText } from "@/components/atoms/gradient-text";
9+
import { slideUp, fadeIn, ANIMATION } from "@/lib/animations";
910

1011
export default function NotFound() {
1112
return (
@@ -15,37 +16,40 @@ export default function NotFound() {
1516
<main className="flex-1 flex items-center justify-center px-6 py-20">
1617
<div className="max-w-2xl w-full text-center">
1718
<motion.h1
18-
initial={{ y: -20, opacity: 0 }}
19-
animate={{ y: 0, opacity: 1 }}
20-
transition={{ duration: 0.6 }}
19+
variants={slideUp}
20+
initial="hidden"
21+
animate="visible"
2122
className="text-8xl md:text-9xl font-bold tracking-tight"
2223
>
2324
<GradientText>404</GradientText>
2425
</motion.h1>
2526

2627
<motion.h2
27-
initial={{ opacity: 0 }}
28-
animate={{ opacity: 1 }}
29-
transition={{ delay: 0.2, duration: 0.6 }}
28+
variants={fadeIn}
29+
initial="hidden"
30+
animate="visible"
31+
transition={{ delay: ANIMATION.DELAY.SHORT }}
3032
className="mt-6 text-2xl md:text-3xl font-semibold"
3133
>
3234
Page not found
3335
</motion.h2>
3436

3537
<motion.p
36-
initial={{ opacity: 0 }}
37-
animate={{ opacity: 1 }}
38-
transition={{ delay: 0.4, duration: 0.6 }}
38+
variants={fadeIn}
39+
initial="hidden"
40+
animate="visible"
41+
transition={{ delay: ANIMATION.DELAY.MEDIUM }}
3942
className="mt-4 text-muted-foreground max-w-md mx-auto"
4043
>
4144
The page you’re looking for doesn’t exist or may have been moved. Let’s get you back to
4245
something useful.
4346
</motion.p>
4447

4548
<motion.div
46-
initial={{ opacity: 0 }}
47-
animate={{ opacity: 1 }}
48-
transition={{ delay: 0.6, duration: 0.6 }}
49+
variants={fadeIn}
50+
initial="hidden"
51+
animate="visible"
52+
transition={{ delay: ANIMATION.DELAY.LONG }}
4953
className="mt-8"
5054
>
5155
<Link href="/">

components/organisms/cta-section.tsx

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
"use client";
22

3+
import { motion } from "framer-motion";
34
import { Button } from "@/components/atoms/button";
45
import { SectionHeader } from "@/components/molecules/section-header";
56
import { Sparkles } from "lucide-react";
67
import { useWaitlist } from "@/components/providers/waitlist-provider";
8+
import { staggerItem, ANIMATION } from "@/lib/animations";
79

810
export function CtaSection() {
911
const { openWaitlist } = useWaitlist();
@@ -13,7 +15,13 @@ export function CtaSection() {
1315
<div className="absolute inset-0 gradient-mesh opacity-70" />
1416
<div className="absolute inset-0 bg-background/40 backdrop-blur-sm" />
1517
<div className="container mx-auto px-4 relative z-10">
16-
<div className="px-6 py-20 text-center md:px-12">
18+
<motion.div
19+
className="px-6 py-20 text-center md:px-12"
20+
initial={{ opacity: 0, y: 20 }}
21+
whileInView={{ opacity: 1, y: 0 }}
22+
transition={{ duration: ANIMATION.DURATION.BASE, ease: ANIMATION.EASING.DEFAULT }}
23+
viewport={{ once: true, amount: 0.3 }}
24+
>
1725
<SectionHeader
1826
badgeText="Early Access"
1927
badgeIcon={<Sparkles className="h-4 w-4" />}
@@ -24,7 +32,11 @@ export function CtaSection() {
2432
}
2533
subtitle="Join 2,000+ early adopters on the waitlist. Be among the first to let an AI agent handle your cross-border payments."
2634
/>
27-
<div className="flex flex-col gap-4 sm:flex-row sm:justify-center">
35+
<motion.div
36+
className="flex flex-col gap-4 sm:flex-row sm:justify-center"
37+
variants={staggerItem}
38+
transition={{ delay: ANIMATION.DELAY.SHORT }}
39+
>
2840
<Button
2941
size="lg"
3042
className="w-full sm:w-auto text-base gap-2 rounded-full px-10 shadow-lg hover:shadow-xl hover:scale-105 transition-all duration-300 glow-sm"
@@ -45,8 +57,8 @@ export function CtaSection() {
4557
Explore Features
4658
</Button>
4759
</a>
48-
</div>
49-
</div>
60+
</motion.div>
61+
</motion.div>
5062
</div>
5163
</section>
5264
);

components/organisms/ecosystem.tsx

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
"use client";
2+
3+
import { motion } from "framer-motion";
14
import { Card } from "@/components/atoms/card";
25
import { SectionHeader } from "@/components/molecules/section-header";
36
import { EcosystemItem } from "@/components/molecules/ecosystem-item";
47
import { Globe, Zap, Shield, Brain } from "lucide-react";
8+
import { staggerContainer, staggerItem } from "@/lib/animations";
59

610
export function Ecosystem() {
711
return (
@@ -20,23 +24,35 @@ export function Ecosystem() {
2024

2125
<div className="mx-auto max-w-4xl">
2226
<Card className="glass-card shimmer-border border-0 p-4 sm:p-8 md:p-10 rounded-3xl">
23-
<div className="space-y-6">
24-
<EcosystemItem
25-
icon={<Zap className="h-7 w-7 text-primary" />}
26-
title="Agent + Stellar = Instant Payments"
27-
description="Your AI agent and Stellar's payment-optimized network work together to deliver near-instant, low-cost cross-border transactions that feel effortless."
28-
/>
29-
<EcosystemItem
30-
icon={<Shield className="h-7 w-7 text-primary" />}
31-
title="Security Your Agent Enforces"
32-
description="Stellar's decentralized, battle-tested network combined with your agent's transaction verification ensures every payment is safe, authenticated, and accounted for."
33-
/>
34-
<EcosystemItem
35-
icon={<Brain className="h-7 w-7 text-primary" />}
36-
title="A Network That Makes Your Agent Smarter"
37-
description="As the Stellar ecosystem grows with new anchors, stablecoin rails, and remittance corridors, your agent gains more routes and better rates to work with."
38-
/>
39-
</div>
27+
<motion.div
28+
className="space-y-6"
29+
variants={staggerContainer}
30+
initial="hidden"
31+
whileInView="visible"
32+
viewport={{ once: true, amount: 0.3 }}
33+
>
34+
<motion.div variants={staggerItem}>
35+
<EcosystemItem
36+
icon={<Zap className="h-7 w-7 text-primary" />}
37+
title="Agent + Stellar = Instant Payments"
38+
description="Your AI agent and Stellar's payment-optimized network work together to deliver near-instant, low-cost cross-border transactions that feel effortless."
39+
/>
40+
</motion.div>
41+
<motion.div variants={staggerItem}>
42+
<EcosystemItem
43+
icon={<Shield className="h-7 w-7 text-primary" />}
44+
title="Security Your Agent Enforces"
45+
description="Stellar's decentralized, battle-tested network combined with your agent's transaction verification ensures every payment is safe, authenticated, and accounted for."
46+
/>
47+
</motion.div>
48+
<motion.div variants={staggerItem}>
49+
<EcosystemItem
50+
icon={<Brain className="h-7 w-7 text-primary" />}
51+
title="A Network That Makes Your Agent Smarter"
52+
description="As the Stellar ecosystem grows with new anchors, stablecoin rails, and remittance corridors, your agent gains more routes and better rates to work with."
53+
/>
54+
</motion.div>
55+
</motion.div>
4056
</Card>
4157
</div>
4258
</section>
Lines changed: 77 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
"use client";
2+
3+
import { motion } from "framer-motion";
14
import { Card } from "@/components/atoms/card";
25
import { SectionHeader } from "@/components/molecules/section-header";
36
import { FeatureChip } from "@/components/molecules/feature-chip";
47
import { Sparkles, Brain, Globe, Shield } from "lucide-react";
8+
import { staggerContainer, staggerItem } from "@/lib/animations";
59

610
export function FeaturesGrid() {
711
return (
@@ -18,73 +22,85 @@ export function FeaturesGrid() {
1822
autonomously"
1923
/>
2024

21-
<div className="grid gap-4 md:grid-cols-3 lg:gap-5">
22-
<Card className="glass-card gradient-border border-0 p-8 md:col-span-2 md:row-span-2 flex flex-col justify-between rounded-3xl group hover:shadow-2xl transition-all duration-500 will-change-transform relative overflow-hidden">
23-
<div className="absolute inset-0 gradient-mesh opacity-40 pointer-events-none" />
24-
<div className="relative z-10">
25-
<div className="mb-6 flex h-14 w-14 items-center justify-center rounded-2xl icon-gradient border border-primary/20 group-hover:scale-110 group-hover:glow-sm transition-all duration-300">
26-
<Brain className="h-7 w-7 text-primary" />
25+
<motion.div
26+
className="grid gap-4 md:grid-cols-3 lg:gap-5"
27+
variants={staggerContainer}
28+
initial="hidden"
29+
whileInView="visible"
30+
viewport={{ once: true, amount: 0.2 }}
31+
>
32+
<motion.div variants={staggerItem}>
33+
<Card className="glass-card gradient-border border-0 p-8 md:col-span-2 md:row-span-2 flex flex-col justify-between rounded-3xl group hover:shadow-2xl transition-all duration-500 will-change-transform relative overflow-hidden">
34+
<div className="absolute inset-0 gradient-mesh opacity-40 pointer-events-none" />
35+
<div className="relative z-10">
36+
<div className="mb-6 flex h-14 w-14 items-center justify-center rounded-2xl icon-gradient border border-primary/20 group-hover:scale-110 group-hover:glow-sm transition-all duration-300">
37+
<Brain className="h-7 w-7 text-primary" />
38+
</div>
39+
<h3 className="mb-3 text-2xl md:text-3xl font-bold">Understands &amp; Learns</h3>
40+
<p className="text-muted-foreground text-base md:text-lg leading-relaxed mb-8">
41+
Say what you need naturally — your agent parses intent, asks smart clarifying
42+
questions, and remembers your patterns over time. Frequent contacts, preferred
43+
currencies, past transactions — it all makes your next request faster.
44+
</p>
2745
</div>
28-
<h3 className="mb-3 text-2xl md:text-3xl font-bold">Understands &amp; Learns</h3>
29-
<p className="text-muted-foreground text-base md:text-lg leading-relaxed mb-8">
30-
Say what you need naturally — your agent parses intent, asks smart clarifying
31-
questions, and remembers your patterns over time. Frequent contacts, preferred
32-
currencies, past transactions — it all makes your next request faster.
33-
</p>
34-
</div>
3546

36-
<div className="relative z-10 grid grid-cols-1 sm:grid-cols-2 gap-3">
37-
<FeatureChip
38-
icon={<Sparkles className="h-4 w-4 text-green-500" />}
39-
label={'"Send rent to landlord"'}
40-
iconBgClass="bg-green-500/20"
41-
/>
42-
<FeatureChip
43-
icon={<Sparkles className="h-4 w-4 text-blue-500" />}
44-
label={'"Best rate for USDC"'}
45-
iconBgClass="bg-blue-500/20"
46-
/>
47-
<FeatureChip
48-
icon={<Sparkles className="h-4 w-4 text-purple-500" />}
49-
label={'"Spending this week?"'}
50-
iconBgClass="bg-purple-500/20"
51-
/>
52-
<FeatureChip
53-
icon={<Sparkles className="h-4 w-4 text-orange-500" />}
54-
label={'"Split dinner, 3 friends"'}
55-
iconBgClass="bg-orange-500/20"
56-
/>
57-
</div>
58-
</Card>
47+
<div className="relative z-10 grid grid-cols-1 sm:grid-cols-2 gap-3">
48+
<FeatureChip
49+
icon={<Sparkles className="h-4 w-4 text-green-500" />}
50+
label={'"Send rent to landlord"'}
51+
iconBgClass="bg-green-500/20"
52+
/>
53+
<FeatureChip
54+
icon={<Sparkles className="h-4 w-4 text-blue-500" />}
55+
label={'"Best rate for USDC"'}
56+
iconBgClass="bg-blue-500/20"
57+
/>
58+
<FeatureChip
59+
icon={<Sparkles className="h-4 w-4 text-purple-500" />}
60+
label={'"Spending this week?"'}
61+
iconBgClass="bg-purple-500/20"
62+
/>
63+
<FeatureChip
64+
icon={<Sparkles className="h-4 w-4 text-orange-500" />}
65+
label={'"Split dinner, 3 friends"'}
66+
iconBgClass="bg-orange-500/20"
67+
/>
68+
</div>
69+
</Card>
70+
</motion.div>
5971

60-
<Card className="glass-card gradient-border border-0 p-6 rounded-3xl group hover:shadow-xl hover:shadow-cyan-500/5 hover:-translate-y-1 transition-all duration-300 will-change-transform relative overflow-hidden">
61-
<div className="absolute top-0 inset-x-0 h-[2px] bg-gradient-to-r from-cyan-500/0 via-cyan-500 to-cyan-500/0" />
62-
<div>
63-
<div className="mb-4 flex h-11 w-11 items-center justify-center rounded-xl icon-gradient border border-primary/20 group-hover:scale-110 transition-transform duration-300">
64-
<Globe className="h-5 w-5 text-primary" />
72+
<motion.div variants={staggerItem}>
73+
<Card className="glass-card gradient-border border-0 p-6 rounded-3xl group hover:shadow-xl hover:shadow-cyan-500/5 hover:-translate-y-1 transition-all duration-300 will-change-transform relative overflow-hidden">
74+
<div className="absolute top-0 inset-x-0 h-[2px] bg-gradient-to-r from-cyan-500/0 via-cyan-500 to-cyan-500/0" />
75+
<div>
76+
<div className="mb-4 flex h-11 w-11 items-center justify-center rounded-xl icon-gradient border border-primary/20 group-hover:scale-110 transition-transform duration-300">
77+
<Globe className="h-5 w-5 text-primary" />
78+
</div>
79+
<h3 className="mb-2 text-lg font-bold">Stellar-Powered Speed</h3>
80+
<p className="text-muted-foreground text-sm leading-relaxed">
81+
Optimal path on Stellar&apos;s network — fastest route, lowest fee, best exchange
82+
rate. Under 5 seconds, less than $0.01.
83+
</p>
6584
</div>
66-
<h3 className="mb-2 text-lg font-bold">Stellar-Powered Speed</h3>
67-
<p className="text-muted-foreground text-sm leading-relaxed">
68-
Optimal path on Stellar&apos;s network — fastest route, lowest fee, best exchange
69-
rate. Under 5 seconds, less than $0.01.
70-
</p>
71-
</div>
72-
</Card>
85+
</Card>
86+
</motion.div>
7387

74-
<Card className="glass-card gradient-border border-0 p-6 rounded-3xl group hover:shadow-xl hover:shadow-green-500/5 hover:-translate-y-1 transition-all duration-300 will-change-transform relative overflow-hidden">
75-
<div className="absolute top-0 inset-x-0 h-[2px] bg-gradient-to-r from-green-500/0 via-green-500 to-green-500/0" />
76-
<div>
77-
<div className="mb-4 flex h-11 w-11 items-center justify-center rounded-xl icon-gradient border border-primary/20 group-hover:scale-110 transition-transform duration-300">
78-
<Shield className="h-5 w-5 text-primary" />
88+
<motion.div variants={staggerItem}>
89+
<Card className="glass-card gradient-border border-0 p-6 rounded-3xl group hover:shadow-xl hover:shadow-green-500/5 hover:-translate-y-1 transition-all duration-300 will-change-transform relative overflow-hidden">
90+
<div className="absolute top-0 inset-x-0 h-[2px] bg-gradient-to-r from-green-500/0 via-green-500 to-green-500/0" />
91+
<div>
92+
<div className="mb-4 flex h-11 w-11 items-center justify-center rounded-xl icon-gradient border border-primary/20 group-hover:scale-110 transition-transform duration-300">
93+
<Shield className="h-5 w-5 text-primary" />
94+
</div>
95+
<h3 className="mb-2 text-lg font-bold">End-to-End Protection</h3>
96+
<p className="text-muted-foreground text-sm leading-relaxed">
97+
Biometric authentication, fully encrypted keys, and an agent that verifies every
98+
transaction before it moves a single cent.
99+
</p>
79100
</div>
80-
<h3 className="mb-2 text-lg font-bold">End-to-End Protection</h3>
81-
<p className="text-muted-foreground text-sm leading-relaxed">
82-
Biometric authentication, fully encrypted keys, and an agent that verifies every
83-
transaction before it moves a single cent.
84-
</p>
85-
</div>
86-
</Card>
87-
</div>
101+
</Card>
102+
</motion.div>
103+
</motion.div>
88104
</section>
89105
);
90106
}

0 commit comments

Comments
 (0)