Skip to content

Commit b4f665e

Browse files
Add fade-in animation and scroll indicator
Implement a fade-in animation for landing page elements and add a scroll indicator.
1 parent c4ed699 commit b4f665e

File tree

2 files changed

+73
-25
lines changed

2 files changed

+73
-25
lines changed

src/components/landing/HeroSection.tsx

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
import { Button } from "@/components/ui/button";
3-
import { ArrowRight, CheckCircle, Star, DollarSign, TrendingUp, Zap, Globe } from "lucide-react";
3+
import { ArrowRight, CheckCircle, Star, DollarSign, TrendingUp, Zap, Globe, ChevronDown } from "lucide-react";
44
import { useTranslation } from 'react-i18next';
55

66
interface HeroSectionProps {
@@ -19,56 +19,56 @@ export const HeroSection = ({ scrollY, onRedirectToDashboard }: HeroSectionProps
1919
{/* Floating Icons */}
2020
<div className="absolute inset-0 pointer-events-none">
2121
<DollarSign
22-
className="absolute top-1/4 left-1/4 w-8 h-8 text-green-500/20 animate-bounce"
23-
style={{ animationDelay: '0s', animationDuration: '3s' }}
22+
className="absolute top-1/4 left-1/4 w-8 h-8 text-green-500/20 animate-bounce opacity-0 animate-fade-in"
23+
style={{ animationDelay: '2s', animationDuration: '3s' }}
2424
/>
2525
<TrendingUp
26-
className="absolute top-1/3 right-1/3 w-6 h-6 text-blue-500/20 animate-bounce"
27-
style={{ animationDelay: '1s', animationDuration: '4s' }}
26+
className="absolute top-1/3 right-1/3 w-6 h-6 text-blue-500/20 animate-bounce opacity-0 animate-fade-in"
27+
style={{ animationDelay: '2.5s', animationDuration: '4s' }}
2828
/>
2929
<Zap
30-
className="absolute bottom-1/3 left-1/5 w-7 h-7 text-purple-500/20 animate-bounce"
31-
style={{ animationDelay: '2s', animationDuration: '3.5s' }}
30+
className="absolute bottom-1/3 left-1/5 w-7 h-7 text-purple-500/20 animate-bounce opacity-0 animate-fade-in"
31+
style={{ animationDelay: '3s', animationDuration: '3.5s' }}
3232
/>
3333
<Globe
34-
className="absolute top-1/5 right-1/5 w-9 h-9 text-indigo-500/20 animate-bounce"
35-
style={{ animationDelay: '0.5s', animationDuration: '4.5s' }}
34+
className="absolute top-1/5 right-1/5 w-9 h-9 text-indigo-500/20 animate-bounce opacity-0 animate-fade-in"
35+
style={{ animationDelay: '2.2s', animationDuration: '4.5s' }}
3636
/>
3737
</div>
3838

3939
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center relative z-10">
40-
<div className="animate-fade-in space-y-12">
40+
<div className="space-y-12">
4141
{/* Badge */}
42-
<div className="inline-flex items-center gap-2 bg-gradient-to-r from-blue-100 to-purple-100 text-blue-800 px-6 py-3 rounded-full text-sm font-medium border border-blue-200/50 backdrop-blur-sm animate-scale-in">
42+
<div className="inline-flex items-center gap-2 bg-gradient-to-r from-blue-100 to-purple-100 text-blue-800 px-6 py-3 rounded-full text-sm font-medium border border-blue-200/50 backdrop-blur-sm opacity-0 animate-fade-in" style={{ animationDelay: '0.2s' }}>
4343
<CheckCircle className="w-4 h-4" />
4444
{t('hero.badge')}
4545
<Star className="w-4 h-4 text-yellow-500" />
4646
</div>
4747

48-
<h1 className="text-5xl md:text-7xl lg:text-8xl font-bold text-slate-900 leading-tight">
48+
<h1 className="text-5xl md:text-7xl lg:text-8xl font-bold text-slate-900 leading-tight opacity-0 animate-fade-in" style={{ animationDelay: '0.4s' }}>
4949
{t('hero.title.part1')}
5050
<br />
51-
<span className="bg-gradient-to-r from-blue-600 via-purple-600 to-blue-800 bg-clip-text text-transparent animate-pulse">
51+
<span className="bg-gradient-to-r from-blue-600 via-purple-600 to-blue-800 bg-clip-text text-transparent">
5252
{t('hero.title.part2')}
5353
</span>
5454
</h1>
5555

56-
<p className="text-lg md:text-xl lg:text-2xl text-slate-600 max-w-4xl mx-auto leading-relaxed" style={{ animationDelay: '0.2s' }}>
56+
<p className="text-lg md:text-xl lg:text-2xl text-slate-600 max-w-4xl mx-auto leading-relaxed opacity-0 animate-fade-in" style={{ animationDelay: '0.6s' }}>
5757
<strong>{t('hero.subtitle.bold')}</strong>
5858
<br />
5959
<span className="text-slate-900 font-semibold">{t('hero.subtitle.normal')}</span>
6060
</p>
6161

62-
{/* Value props with animations */}
62+
{/* Value props with staggered animations */}
6363
<div className="flex flex-wrap justify-center gap-4 lg:gap-6">
6464
{[
65-
{ text: t('hero.features.noSetupFee'), delay: "0.3s" },
66-
{ text: t('hero.features.noMonthlyFee'), delay: "0.4s" },
67-
{ text: t('hero.features.fullAccess'), delay: "0.5s" }
65+
{ text: t('hero.features.noSetupFee'), delay: "0.8s" },
66+
{ text: t('hero.features.noMonthlyFee'), delay: "1.0s" },
67+
{ text: t('hero.features.fullAccess'), delay: "1.2s" }
6868
].map((item, index) => (
6969
<div
7070
key={index}
71-
className="flex items-center gap-2 bg-white/80 backdrop-blur-sm px-4 py-2 lg:px-6 lg:py-3 rounded-full border border-slate-200 hover:scale-105 transition-all animate-fade-in shadow-lg"
71+
className="flex items-center gap-2 bg-white/80 backdrop-blur-sm px-4 py-2 lg:px-6 lg:py-3 rounded-full border border-slate-200 hover:scale-105 transition-all shadow-lg opacity-0 animate-fade-in"
7272
style={{ animationDelay: item.delay }}
7373
>
7474
<CheckCircle className="w-4 h-4 lg:w-5 lg:h-5 text-green-600" />
@@ -77,7 +77,7 @@ export const HeroSection = ({ scrollY, onRedirectToDashboard }: HeroSectionProps
7777
))}
7878
</div>
7979

80-
<div className="flex flex-col sm:flex-row gap-4 lg:gap-6 justify-center" style={{ animationDelay: '0.6s' }}>
80+
<div className="flex flex-col sm:flex-row gap-4 lg:gap-6 justify-center opacity-0 animate-fade-in" style={{ animationDelay: '1.4s' }}>
8181
<Button
8282
size="lg"
8383
className="text-lg px-8 py-4 lg:px-12 lg:py-6 bg-gradient-to-r from-blue-600 to-purple-600 hover:from-blue-700 hover:to-purple-700 shadow-2xl hover:shadow-3xl transition-all hover:scale-105 border-0 text-white"
@@ -96,8 +96,8 @@ export const HeroSection = ({ scrollY, onRedirectToDashboard }: HeroSectionProps
9696
</Button>
9797
</div>
9898

99-
{/* Social proof with animation */}
100-
<div className="pt-12 border-t border-slate-200/50" style={{ animationDelay: '0.8s' }}>
99+
{/* Social proof with delayed animation */}
100+
<div className="pt-12 border-t border-slate-200/50 opacity-0 animate-fade-in" style={{ animationDelay: '1.6s' }}>
101101
<p className="text-slate-500 text-sm mb-6">{t('hero.socialProof.text')}</p>
102102
<div className="flex justify-center items-center gap-6 lg:gap-8 opacity-70">
103103
<div className="text-2xl lg:text-3xl font-bold text-slate-600 hover:text-blue-600 transition-colors">{t('hero.socialProof.revenue')}</div>
@@ -111,6 +111,17 @@ export const HeroSection = ({ scrollY, onRedirectToDashboard }: HeroSectionProps
111111
</div>
112112
</div>
113113
</div>
114+
115+
{/* Scroll Indicator */}
116+
<div className="absolute bottom-8 left-1/2 transform -translate-x-1/2 opacity-0 animate-fade-in" style={{ animationDelay: '2s' }}>
117+
<div className="flex flex-col items-center gap-2 animate-bounce">
118+
<span className="text-slate-500 text-sm font-medium">Scroll</span>
119+
<div className="w-6 h-10 border-2 border-slate-300 rounded-full flex justify-center">
120+
<div className="w-1 h-3 bg-slate-400 rounded-full mt-2 animate-pulse"></div>
121+
</div>
122+
<ChevronDown className="w-5 h-5 text-slate-400" />
123+
</div>
124+
</div>
114125
</section>
115126
);
116127
};

src/index.css

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,57 @@ body {
2424
text-rendering: optimizeLegibility;
2525
}
2626

27-
/* Amélioration des animations */
27+
/* Amélioration des animations avec fade-in progressif */
2828
@keyframes fade-in {
2929
from {
3030
opacity: 0;
31-
transform: translateY(10px);
31+
transform: translateY(20px);
3232
}
3333
to {
3434
opacity: 1;
3535
transform: translateY(0);
3636
}
3737
}
3838

39+
@keyframes fade-in-scale {
40+
from {
41+
opacity: 0;
42+
transform: translateY(20px) scale(0.95);
43+
}
44+
to {
45+
opacity: 1;
46+
transform: translateY(0) scale(1);
47+
}
48+
}
49+
50+
@keyframes bounce-in {
51+
0% {
52+
opacity: 0;
53+
transform: scale(0.3);
54+
}
55+
50% {
56+
opacity: 1;
57+
transform: scale(1.05);
58+
}
59+
70% {
60+
transform: scale(0.9);
61+
}
62+
100% {
63+
opacity: 1;
64+
transform: scale(1);
65+
}
66+
}
67+
3968
.animate-fade-in {
40-
animation: fade-in 0.5s ease-out forwards;
69+
animation: fade-in 0.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
70+
}
71+
72+
.animate-fade-in-scale {
73+
animation: fade-in-scale 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards;
74+
}
75+
76+
.animate-bounce-in {
77+
animation: bounce-in 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55) forwards;
4178
}
4279

4380
/* Optimisation pour les focus states */

0 commit comments

Comments
 (0)