Skip to content

Commit 8d1dfd5

Browse files
feat: Add subtle bounce animation to the emojis in the hero headline.
1 parent 9900ce5 commit 8d1dfd5

1 file changed

Lines changed: 170 additions & 126 deletions

File tree

Lines changed: 170 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -1,137 +1,181 @@
1-
"use client";
1+
'use client';
22

3-
import { motion } from "framer-motion";
4-
import Image from "next/image";
5-
import { useEffect, useState } from "react";
6-
import GitHubModal from "../github-modal/client";
7-
import { Info, Github, GitFork } from "lucide-react";
8-
import Counter from "../counter";
3+
import { motion } from 'framer-motion';
4+
import Image from 'next/image';
5+
import { useEffect, useState } from 'react';
6+
import GitHubModal from '../github-modal/client';
7+
import { Info, Github, GitFork } from 'lucide-react';
8+
import Counter from '../counter';
99

1010
export default function AnimatedHeroClient() {
11-
const [showGithubModal, setShowGithubModal] = useState(false);
11+
const [showGithubModal, setShowGithubModal] = useState(false);
1212

13-
useEffect(() => {
14-
// Check if URL has modal=true parameter
15-
const searchParams = new URLSearchParams(window.location.search);
16-
const shouldShowModal = searchParams.get("modal") === "true";
13+
useEffect(() => {
14+
// Check if URL has modal=true parameter
15+
const searchParams = new URLSearchParams(window.location.search);
16+
const shouldShowModal = searchParams.get('modal') === 'true';
1717

18-
if (shouldShowModal) {
19-
setShowGithubModal(true);
20-
}
21-
}, []);
18+
if (shouldShowModal) {
19+
setShowGithubModal(true);
20+
}
21+
}, []);
2222

23-
return (
24-
<section className="w-full flex flex-col items-center justify-center pb-16 md:pb-24">
25-
{/* Trusted badge */}
26-
<motion.div
27-
initial={{ opacity: 0, y: 20 }}
28-
animate={{ opacity: 1, y: 0 }}
29-
transition={{ duration: 0.5 }}
30-
className="flex items-center mb-10"
31-
>
32-
<Image src="/images/leaf-l.png" alt="Laurel left" width={28} height={52} className="w-auto h-12 opacity-80" />
33-
<div className="flex items-center gap-3">
34-
<div className="flex -space-x-3">
35-
<Image
36-
src="https://avatars.githubusercontent.com/u/63339782?v=4"
37-
alt="Customer 1"
38-
width={36} height={36}
39-
priority
40-
className="w-9 h-9 rounded-full border-2 border-white object-cover shadow-sm relative z-0"
41-
/>
42-
<Image
43-
src="https://avatars.githubusercontent.com/u/93549213?v=4"
44-
alt="Customer 2"
45-
width={36} height={36}
46-
priority
47-
className="w-9 h-9 rounded-full border-2 border-white object-cover shadow-sm relative z-10"
48-
/>
49-
<Image
50-
src="https://avatars.githubusercontent.com/u/135146135?v=4"
51-
alt="Customer 3"
52-
width={36} height={36}
53-
priority
54-
className="w-9 h-9 rounded-full border-2 border-white bg-purple-100 object-cover shadow-sm relative z-20"
55-
/>
56-
</div>
57-
<span className="text-[17px] font-medium text-[#7a7a7a] tracking-tight">
58-
Trusted by 2k+ Customers
59-
</span>
60-
</div>
61-
<Image src="/images/leaf-r.png" alt="Laurel right" width={28} height={52} className="w-auto h-12 opacity-80" />
62-
</motion.div>
23+
return (
24+
<section className="w-full flex flex-col items-center justify-center pb-16 md:pb-24">
25+
{/* Trusted badge */}
26+
<motion.div
27+
initial={{ opacity: 0, y: 20 }}
28+
animate={{ opacity: 1, y: 0 }}
29+
transition={{ duration: 0.5 }}
30+
className="flex items-center mb-10"
31+
>
32+
<Image
33+
src="/images/leaf-l.png"
34+
alt="Laurel left"
35+
width={28}
36+
height={52}
37+
className="w-auto h-12 opacity-80"
38+
/>
39+
<div className="flex items-center gap-3">
40+
<div className="flex -space-x-3">
41+
<Image
42+
src="https://avatars.githubusercontent.com/u/63339782?v=4"
43+
alt="Customer 1"
44+
width={36}
45+
height={36}
46+
priority
47+
className="w-9 h-9 rounded-full border-2 border-white object-cover shadow-sm relative z-0"
48+
/>
49+
<Image
50+
src="https://avatars.githubusercontent.com/u/93549213?v=4"
51+
alt="Customer 2"
52+
width={36}
53+
height={36}
54+
priority
55+
className="w-9 h-9 rounded-full border-2 border-white object-cover shadow-sm relative z-10"
56+
/>
57+
<Image
58+
src="https://avatars.githubusercontent.com/u/135146135?v=4"
59+
alt="Customer 3"
60+
width={36}
61+
height={36}
62+
priority
63+
className="w-9 h-9 rounded-full border-2 border-white bg-purple-100 object-cover shadow-sm relative z-20"
64+
/>
65+
</div>
66+
<span className="text-[17px] font-medium text-[#7a7a7a] tracking-tight">
67+
Trusted by 2k+ Customers
68+
</span>
69+
</div>
70+
<Image
71+
src="/images/leaf-r.png"
72+
alt="Laurel right"
73+
width={28}
74+
height={52}
75+
className="w-auto h-12 opacity-80"
76+
/>
77+
</motion.div>
6378

64-
{/* Main Headline */}
65-
<motion.h1
66-
initial={{ opacity: 0, y: 20 }}
67-
animate={{ opacity: 1, y: 0 }}
68-
transition={{ duration: 0.5, delay: 0.1 }}
69-
className="text-5xl md:text-[76px] font-semibold text-[#111] leading-[1.1] tracking-tight text-center max-w-5xl"
70-
>
71-
Effortless <span className="inline-flex relative -top-1 md:-top-2 items-center justify-center bg-indigo-50 w-12 h-12 md:w-20 md:h-20 rounded-xl md:rounded-2xl mx-1 md:mx-3 shadow-inner text-2xl md:text-4xl translate-y-2">👨‍💻</span> Portfolios <br className="hidden md:block" />
72-
for <span className="inline-flex relative -top-1 md:-top-2 items-center justify-center bg-rose-50 w-12 h-12 md:w-20 md:h-20 rounded-xl md:rounded-2xl mx-1 md:mx-3 shadow-inner text-2xl md:text-4xl translate-y-2">🚀</span> Developers <span className="inline-flex relative -top-1 md:-top-2 items-center justify-center bg-amber-50 w-12 h-12 md:w-20 md:h-20 rounded-xl md:rounded-2xl mx-1 md:mx-3 shadow-inner text-2xl md:text-4xl translate-y-2"></span>
73-
</motion.h1>
79+
{/* Main Headline */}
80+
<motion.h1
81+
initial={{ opacity: 0, y: 20 }}
82+
animate={{ opacity: 1, y: 0 }}
83+
transition={{ duration: 0.5, delay: 0.1 }}
84+
className="text-5xl md:text-[76px] font-semibold text-[#111] leading-[1.1] tracking-tight text-center max-w-5xl"
85+
>
86+
Effortless{' '}
87+
<motion.span
88+
animate={{ y: [4, -8, 4] }}
89+
transition={{ repeat: Infinity, duration: 4, ease: "easeInOut" }}
90+
className="inline-flex relative -top-1 md:-top-2 border-3 border-white rotate-8 items-center justify-center bg-indigo-50 size-8 md:size-16 rounded-xl md:rounded-2xl mx-1 md:mx-3 shadow-inner text-2xl md:text-3xl shadow-md"
91+
>
92+
👨‍💻
93+
</motion.span>{' '}
94+
Portfolios <br className="hidden md:block" />
95+
for{' '}
96+
<motion.span
97+
animate={{ y: [4, -10, 4] }}
98+
transition={{ repeat: Infinity, duration: 3.5, ease: "easeInOut", delay: 0.5 }}
99+
className="inline-flex relative -top-1 md:-top-2 border-3 border-white -rotate-6 items-center justify-center bg-rose-50 size-8 md:size-16 rounded-xl md:rounded-2xl mx-1 md:mx-3 shadow-inner text-2xl md:text-3xl shadow-md"
100+
>
101+
💻️
102+
</motion.span>{' '}
103+
Developers{' '}
104+
<motion.span
105+
animate={{ y: [4, -6, 4] }}
106+
transition={{ repeat: Infinity, duration: 4.5, ease: "easeInOut", delay: 1 }}
107+
className="inline-flex relative -top-1 md:-top-2 border-3 border-white -rotate-10 items-center justify-center bg-amber-50 size-8 md:size-16 rounded-xl md:rounded-2xl mx-1 md:mx-3 shadow-inner text-2xl md:text-3xl shadow-md"
108+
>
109+
📁
110+
</motion.span>
111+
</motion.h1>
74112

75-
{/* Subhead */}
76-
<motion.p
77-
initial={{ opacity: 0, y: 20 }}
78-
animate={{ opacity: 1, y: 0 }}
79-
transition={{ duration: 0.5, delay: 0.2 }}
80-
className="text-lg md:text-xl text-gray-500 mt-8 max-w-2xl text-center px-4"
81-
>
82-
Automatic portfolio generation powered by your GitHub profile.
83-
<br className="hidden md:block" />
84-
Zero maintenance required. Setup once, let it narrate your story.
85-
</motion.p>
113+
{/* Subhead */}
114+
<motion.p
115+
initial={{ opacity: 0, y: 20 }}
116+
animate={{ opacity: 1, y: 0 }}
117+
transition={{ duration: 0.5, delay: 0.2 }}
118+
className="text-lg md:text-xl text-gray-500 mt-8 max-w-2xl text-center px-4"
119+
>
120+
Automatic portfolio generation powered by your GitHub profile.
121+
<br className="hidden md:block" />
122+
Zero maintenance required. Setup once, let it narrate your story.
123+
</motion.p>
86124

87-
{/* Buttons */}
88-
<motion.div
89-
initial={{ opacity: 0, y: 20 }}
90-
animate={{ opacity: 1, y: 0 }}
91-
transition={{ duration: 0.5, delay: 0.3 }}
92-
className="flex flex-col sm:flex-row items-center gap-4 mt-10"
93-
>
94-
<button
95-
onClick={() => setShowGithubModal(true)}
96-
className="bg-black text-white px-8 py-3.5 rounded-full text-base font-medium hover:bg-gray-800 transition-colors flex items-center gap-2 shadow-lg"
97-
>
98-
<Github className="w-5 h-5" /> Generate Portfolio
99-
</button>
100-
<button className="bg-white border text-gray-700 border-gray-200 px-8 py-3.5 rounded-full text-base font-medium hover:bg-gray-50 transition-colors flex items-center justify-center gap-2 shadow-sm">
101-
<GitFork className="w-4 h-4 text-black" /> Contribute
102-
</button>
103-
</motion.div>
104-
{/* Metrics Section */}
105-
<motion.div
106-
initial={{ opacity: 0, y: 20 }}
107-
animate={{ opacity: 1, y: 0 }}
108-
transition={{ duration: 0.5, delay: 0.4 }}
109-
className="mt-20 w-full max-w-4xl border-t border-gray-100 pt-12"
110-
>
111-
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 md:gap-4 divide-y md:divide-y-0 md:divide-x divide-gray-100">
112-
<div className="flex flex-col items-center justify-center pt-4 md:pt-0">
113-
<span className="text-4xl md:text-5xl font-bold tracking-tight text-[#111] mb-2 flex items-center">
114-
<Counter from={0} to={6010} duration={2} />+
115-
</span>
116-
<span className="text-xs md:text-sm font-medium text-gray-500 uppercase tracking-widest text-center">Profiles Generated</span>
117-
</div>
118-
<div className="flex flex-col items-center justify-center pt-8 md:pt-0">
119-
<span className="text-4xl md:text-5xl font-bold tracking-tight text-[#111] mb-2 flex items-baseline">
120-
<Counter from={0} to={8} duration={2} /><span className="text-3xl font-semibold text-gray-300 ml-1">mo</span>
121-
</span>
122-
<span className="text-xs md:text-sm font-medium text-gray-500 uppercase tracking-widest text-center">Continuously Active</span>
123-
</div>
124-
<div className="flex flex-col items-center justify-center pt-8 md:pt-0">
125-
<span className="text-4xl md:text-5xl font-bold tracking-tight text-[#111] mb-2">Global</span>
126-
<span className="text-xs md:text-sm font-medium text-gray-500 uppercase tracking-widest text-center">Developer Reach</span>
127-
</div>
128-
</div>
129-
</motion.div>
125+
{/* Buttons */}
126+
<motion.div
127+
initial={{ opacity: 0, y: 20 }}
128+
animate={{ opacity: 1, y: 0 }}
129+
transition={{ duration: 0.5, delay: 0.3 }}
130+
className="flex flex-col sm:flex-row items-center gap-4 mt-10"
131+
>
132+
<button
133+
onClick={() => setShowGithubModal(true)}
134+
className="bg-black text-white px-8 py-3.5 rounded-full text-base font-medium hover:bg-gray-800 transition-colors flex items-center gap-2 shadow-lg"
135+
>
136+
<Github className="w-5 h-5" /> Generate Portfolio
137+
</button>
138+
<button className="bg-white border text-gray-700 border-gray-200 px-8 py-3.5 rounded-full text-base font-medium hover:bg-gray-50 transition-colors flex items-center justify-center gap-2 shadow-sm">
139+
<GitFork className="w-4 h-4 text-black" /> Contribute
140+
</button>
141+
</motion.div>
142+
{/* Metrics Section */}
143+
<motion.div
144+
initial={{ opacity: 0, y: 20 }}
145+
animate={{ opacity: 1, y: 0 }}
146+
transition={{ duration: 0.5, delay: 0.4 }}
147+
className="mt-20 w-full max-w-4xl border-t border-gray-100 pt-12"
148+
>
149+
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 md:gap-4 divide-y md:divide-y-0 md:divide-x divide-gray-100">
150+
<div className="flex flex-col items-center justify-center pt-4 md:pt-0">
151+
<span className="text-4xl md:text-5xl font-bold tracking-tight text-[#111] mb-2 flex items-center">
152+
<Counter from={0} to={6010} duration={2} />+
153+
</span>
154+
<span className="text-xs md:text-sm font-medium text-gray-500 uppercase tracking-widest text-center">
155+
Profiles Generated
156+
</span>
157+
</div>
158+
<div className="flex flex-col items-center justify-center pt-8 md:pt-0">
159+
<span className="text-4xl md:text-5xl font-bold tracking-tight text-[#111] mb-2 flex items-baseline">
160+
<Counter from={0} to={8} duration={2} />
161+
<span className="text-3xl font-semibold text-gray-300 ml-1">mo</span>
162+
</span>
163+
<span className="text-xs md:text-sm font-medium text-gray-500 uppercase tracking-widest text-center">
164+
Continuously Active
165+
</span>
166+
</div>
167+
<div className="flex flex-col items-center justify-center pt-8 md:pt-0">
168+
<span className="text-4xl md:text-5xl font-bold tracking-tight text-[#111] mb-2">
169+
Global
170+
</span>
171+
<span className="text-xs md:text-sm font-medium text-gray-500 uppercase tracking-widest text-center">
172+
Developer Reach
173+
</span>
174+
</div>
175+
</div>
176+
</motion.div>
130177

131-
132-
{showGithubModal && (
133-
<GitHubModal onClose={() => setShowGithubModal(false)} />
134-
)}
135-
</section>
136-
);
178+
{showGithubModal && <GitHubModal onClose={() => setShowGithubModal(false)} />}
179+
</section>
180+
);
137181
}

0 commit comments

Comments
 (0)