Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1ba748a8e7 | |||
| ad0cd8ee25 | |||
| deccd91a17 | |||
| 1a591040cb | |||
| d1b516580b | |||
| bba3582e04 | |||
| 3e3c5d663f | |||
| 192fd930a5 | |||
| 06c55e3eac | |||
| f8be5a84da |
1367
src/app/layout.tsx
1367
src/app/layout.tsx
File diff suppressed because it is too large
Load Diff
@@ -2,15 +2,17 @@
|
|||||||
|
|
||||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||||
import NavbarLayoutFloatingOverlay from '@/components/navbar/NavbarLayoutFloatingOverlay/NavbarLayoutFloatingOverlay';
|
import NavbarLayoutFloatingOverlay from '@/components/navbar/NavbarLayoutFloatingOverlay/NavbarLayoutFloatingOverlay';
|
||||||
import HeroBillboard from '@/components/sections/hero/HeroBillboard';
|
import { HeroCarouselLogo } from '@/components/sections/hero/HeroCarouselLogo';
|
||||||
import TextSplitAbout from '@/components/sections/about/TextSplitAbout';
|
import { TextImageAbout } from '@/components/sections/about/TextImageAbout';
|
||||||
import FeatureCardTwentyFive from '@/components/sections/feature/FeatureCardTwentyFive';
|
import { FeatureCardTwenty } from '@/components/sections/feature/FeatureCardTwenty';
|
||||||
import MetricCardOne from '@/components/sections/metrics/MetricCardOne';
|
import MetricCardTwo from '@/components/sections/metrics/MetricCardTwo';
|
||||||
import TestimonialCardOne from '@/components/sections/testimonial/TestimonialCardOne';
|
import TestimonialCardTwo from '@/components/sections/testimonial/TestimonialCardTwo';
|
||||||
import ContactSplitForm from '@/components/sections/contact/ContactSplitForm';
|
import ContactSplitForm from '@/components/sections/contact/ContactSplitForm';
|
||||||
import FooterSimple from '@/components/sections/footer/FooterSimple';
|
import FooterSimple from '@/components/sections/footer/FooterSimple';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { Sparkles, CheckCircle, ArrowRight, Brain, Code, BookOpen, Users, Trophy, TrendingUp, Shield } from 'lucide-react';
|
import { Sparkles, CheckCircle, ArrowRight, Brain, Code, BookOpen, Users, Trophy, TrendingUp, Shield } from 'lucide-react';
|
||||||
|
import TestimonialCardOne from "@/components/sections/testimonial/TestimonialCardOne";
|
||||||
|
import HeroLogo from '@/components/sections/hero/HeroLogo';
|
||||||
|
|
||||||
export default function HomePage() {
|
export default function HomePage() {
|
||||||
return (
|
return (
|
||||||
@@ -44,40 +46,23 @@ export default function HomePage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="hero-section" data-section="hero-section">
|
<div id="hero-section" data-section="hero-section">
|
||||||
<HeroBillboard
|
<HeroLogo
|
||||||
title="Where Innovation Meets Community"
|
logoText="Computer Club"
|
||||||
description="Join our vibrant computer club and explore the latest in technology, collaborate on exciting projects, and connect with fellow tech enthusiasts aged 16-25."
|
description="Join our vibrant community of tech enthusiasts. Explore cutting-edge projects, attend workshops, and connect with fellow innovators."
|
||||||
background={{ variant: "radial-gradient" }}
|
|
||||||
tag="Tech Enthusiasts Welcome"
|
|
||||||
tagIcon={Sparkles}
|
|
||||||
tagAnimation="slide-up"
|
|
||||||
buttons={[
|
buttons={[
|
||||||
{ text: "Explore Events", href: "/events" },
|
{ label: "Join Us", href: "/join", dataWebildId: "hero_logo_join_btn" },
|
||||||
{ text: "View Projects", href: "/projects" }
|
{ label: "View Events", href: "/events", dataWebildId: "hero_logo_events_btn" }
|
||||||
]}
|
]}
|
||||||
buttonAnimation="slide-up"
|
buttonAnimation="none"
|
||||||
avatars={[
|
imageSrc="https://img.b2bpic.net/free-photo/abstract-luxury-gradient-blue-background_53876-120942.jpg"
|
||||||
{ src: "http://img.b2bpic.net/free-photo/three-students-working-together-laptops_23-2152025161.jpg", alt: "Club member" },
|
imageAlt="Computer Club community"
|
||||||
{ src: "http://img.b2bpic.net/free-photo/two-teenage-friends-playing-video-games-together-home_23-2149332883.jpg", alt: "Club member" },
|
showDimOverlay={true}
|
||||||
{ src: "http://img.b2bpic.net/free-photo/group-people-discussing-business-issues_53876-22915.jpg", alt: "Club member" }
|
ariaLabel="Computer Club hero section with logo"
|
||||||
]}
|
|
||||||
avatarText="150+ Members"
|
|
||||||
imageSrc="http://img.b2bpic.net/free-photo/group-young-people-doing-experiments-robotics-laboratory-girls-protective-glasses_1268-24389.jpg?_wi=1"
|
|
||||||
imageAlt="Students collaborating on tech projects"
|
|
||||||
mediaAnimation="slide-up"
|
|
||||||
marqueeItems={[
|
|
||||||
{ type: "text", text: "Weekly Workshops" },
|
|
||||||
{ type: "text", text: "Project Showcases" },
|
|
||||||
{ type: "text", text: "Guest Speaker Series" }
|
|
||||||
]}
|
|
||||||
marqueeSpeed={30}
|
|
||||||
showMarqueeCard={true}
|
|
||||||
ariaLabel="Hero section"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="about-section" data-section="about-section">
|
<div id="about-section" data-section="about-section">
|
||||||
<TextSplitAbout
|
<TextImageAbout
|
||||||
title="About Our Tech Club"
|
title="About Our Tech Club"
|
||||||
description={[
|
description={[
|
||||||
"We're a vibrant community of students passionate about technology, innovation, and collaboration. Our club provides a welcoming space for learners of all levels to explore coding, robotics, cybersecurity, and emerging tech trends.",
|
"We're a vibrant community of students passionate about technology, innovation, and collaboration. Our club provides a welcoming space for learners of all levels to explore coding, robotics, cybersecurity, and emerging tech trends.",
|
||||||
@@ -89,11 +74,13 @@ export default function HomePage() {
|
|||||||
]}
|
]}
|
||||||
buttonAnimation="slide-up"
|
buttonAnimation="slide-up"
|
||||||
useInvertedBackground={false}
|
useInvertedBackground={false}
|
||||||
|
imageSrc="https://img.b2bpic.net/free-photo/group-young-people-doing-experiments-robotics-laboratory-girls-protective-glasses_1268-24389.jpg"
|
||||||
|
imageAlt="Computer Club members collaborating"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="events-section" data-section="events-section">
|
<div id="events-section" data-section="events-section">
|
||||||
<FeatureCardTwentyFive
|
<FeatureCardTwenty
|
||||||
title="Upcoming Tech Events"
|
title="Upcoming Tech Events"
|
||||||
description="Join our community for hands-on workshops, guest lectures, and networking opportunities. Stay updated with our calendar of events designed to spark curiosity and build skills."
|
description="Join our community for hands-on workshops, guest lectures, and networking opportunities. Stay updated with our calendar of events designed to spark curiosity and build skills."
|
||||||
animationType="slide-up"
|
animationType="slide-up"
|
||||||
@@ -136,7 +123,7 @@ export default function HomePage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="projects-section" data-section="projects-section">
|
<div id="projects-section" data-section="projects-section">
|
||||||
<MetricCardOne
|
<MetricCardTwo
|
||||||
metrics={[
|
metrics={[
|
||||||
{
|
{
|
||||||
id: "metric-1",
|
id: "metric-1",
|
||||||
@@ -167,7 +154,7 @@ export default function HomePage() {
|
|||||||
icon: Trophy
|
icon: Trophy
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
gridVariant="bento-grid"
|
gridVariant="uniform-all-items-equal"
|
||||||
animationType="slide-up"
|
animationType="slide-up"
|
||||||
title="Our Impact"
|
title="Our Impact"
|
||||||
description="Discover how our club drives innovation and empowers tech enthusiasts through collaborative projects and learning opportunities."
|
description="Discover how our club drives innovation and empowers tech enthusiasts through collaborative projects and learning opportunities."
|
||||||
|
|||||||
134
src/components/sections/about/TextImageAbout.tsx
Normal file
134
src/components/sections/about/TextImageAbout.tsx
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
interface Button {
|
||||||
|
text: string;
|
||||||
|
href: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TextImageAboutProps {
|
||||||
|
title: string;
|
||||||
|
description: string[];
|
||||||
|
buttons: Button[];
|
||||||
|
buttonAnimation?: "slide-up" | "fade-in" | "none";
|
||||||
|
useInvertedBackground?: boolean;
|
||||||
|
imageSrc: string;
|
||||||
|
imageAlt: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function TextImageAbout({
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
buttons,
|
||||||
|
buttonAnimation = "slide-up",
|
||||||
|
useInvertedBackground = false,
|
||||||
|
imageSrc,
|
||||||
|
imageAlt,
|
||||||
|
}: TextImageAboutProps) {
|
||||||
|
const bgClass = useInvertedBackground ? "bg-gray-900" : "bg-white";
|
||||||
|
const textClass = useInvertedBackground ? "text-white" : "text-gray-900";
|
||||||
|
const descTextClass = useInvertedBackground ? "text-gray-300" : "text-gray-600";
|
||||||
|
|
||||||
|
const getButtonAnimationClass = () => {
|
||||||
|
switch (buttonAnimation) {
|
||||||
|
case "slide-up":
|
||||||
|
return "animate-slide-up";
|
||||||
|
case "fade-in":
|
||||||
|
return "animate-fade-in";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className={`${bgClass} py-16 md:py-24 lg:py-32 transition-colors duration-300`}>
|
||||||
|
<div className="container mx-auto px-4 md:px-6 lg:px-8">
|
||||||
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8 lg:gap-12 items-center">
|
||||||
|
{/* Text Content */}
|
||||||
|
<div className="flex flex-col justify-center space-y-6">
|
||||||
|
<div>
|
||||||
|
<h2 className={`text-4xl md:text-5xl font-bold ${textClass} mb-6 leading-tight`}>
|
||||||
|
{title}
|
||||||
|
</h2>
|
||||||
|
<div className="space-y-4">
|
||||||
|
{description.map((paragraph, index) => (
|
||||||
|
<p
|
||||||
|
key={index}
|
||||||
|
className={`text-lg ${descTextClass} leading-relaxed`}
|
||||||
|
>
|
||||||
|
{paragraph}
|
||||||
|
</p>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Buttons */}
|
||||||
|
<div className="flex flex-wrap gap-4 pt-4">
|
||||||
|
{buttons.map((button, index) => (
|
||||||
|
<a
|
||||||
|
key={index}
|
||||||
|
href={button.href}
|
||||||
|
className={`inline-block px-8 py-3 rounded-lg font-semibold transition-all duration-300 ${
|
||||||
|
index === 0
|
||||||
|
? "bg-blue-600 text-white hover:bg-blue-700 shadow-lg hover:shadow-xl"
|
||||||
|
: "border-2 border-blue-600 text-blue-600 hover:bg-blue-50"
|
||||||
|
} ${getButtonAnimationClass()}`}
|
||||||
|
style={{
|
||||||
|
animationDelay: `${index * 100}ms`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{button.text}
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Image */}
|
||||||
|
<div className="flex justify-center lg:justify-end">
|
||||||
|
<div className="relative w-full max-w-md lg:max-w-lg">
|
||||||
|
<div className="absolute inset-0 bg-gradient-to-br from-blue-400 to-blue-600 rounded-2xl transform rotate-3 opacity-20"></div>
|
||||||
|
<img
|
||||||
|
src={imageSrc}
|
||||||
|
alt={imageAlt}
|
||||||
|
className="relative w-full h-auto rounded-2xl shadow-2xl object-cover"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style jsx>{`
|
||||||
|
@keyframes slide-up {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(20px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade-in {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-slide-up {
|
||||||
|
animation: slide-up 0.6s ease-out forwards;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-fade-in {
|
||||||
|
animation: fade-in 0.6s ease-out forwards;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
207
src/components/sections/feature/FeatureCardTwenty.tsx
Normal file
207
src/components/sections/feature/FeatureCardTwenty.tsx
Normal file
@@ -0,0 +1,207 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import { LucideIcon } from 'lucide-react';
|
||||||
|
|
||||||
|
interface MediaItem {
|
||||||
|
imageSrc: string;
|
||||||
|
imageAlt: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Feature {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
icon: LucideIcon;
|
||||||
|
mediaItems: MediaItem[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FeatureCardTwentyProps {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
animationType?: 'slide-up' | 'fade-in' | 'slide-left';
|
||||||
|
textboxLayout?: 'default' | 'centered' | 'compact';
|
||||||
|
useInvertedBackground?: boolean;
|
||||||
|
features: Feature[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function FeatureCardTwenty({
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
animationType = 'slide-up',
|
||||||
|
textboxLayout = 'default',
|
||||||
|
useInvertedBackground = false,
|
||||||
|
features,
|
||||||
|
}: FeatureCardTwentyProps) {
|
||||||
|
const [activeFeatureIndex, setActiveFeatureIndex] = useState(0);
|
||||||
|
const [isVisible, setIsVisible] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setIsVisible(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const getAnimationClass = () => {
|
||||||
|
if (!isVisible) {
|
||||||
|
switch (animationType) {
|
||||||
|
case 'slide-up':
|
||||||
|
return 'opacity-0 translate-y-8';
|
||||||
|
case 'slide-left':
|
||||||
|
return 'opacity-0 -translate-x-8';
|
||||||
|
case 'fade-in':
|
||||||
|
default:
|
||||||
|
return 'opacity-0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (animationType) {
|
||||||
|
case 'slide-up':
|
||||||
|
return 'opacity-100 translate-y-0 transition-all duration-700 ease-out';
|
||||||
|
case 'slide-left':
|
||||||
|
return 'opacity-100 translate-x-0 transition-all duration-700 ease-out';
|
||||||
|
case 'fade-in':
|
||||||
|
default:
|
||||||
|
return 'opacity-100 transition-opacity duration-700 ease-out';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getTextboxLayoutClass = () => {
|
||||||
|
switch (textboxLayout) {
|
||||||
|
case 'centered':
|
||||||
|
return 'text-center';
|
||||||
|
case 'compact':
|
||||||
|
return 'text-left max-w-2xl';
|
||||||
|
case 'default':
|
||||||
|
default:
|
||||||
|
return 'text-left';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const bgClass = useInvertedBackground ? 'bg-slate-900 text-white' : 'bg-white text-slate-900';
|
||||||
|
const activeFeature = features[activeFeatureIndex];
|
||||||
|
const IconComponent = activeFeature.icon;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className={`${bgClass} py-16 md:py-24 px-4 md:px-8 transition-colors duration-300`}>
|
||||||
|
<div className="max-w-7xl mx-auto">
|
||||||
|
{/* Header Section */}
|
||||||
|
<div className={`mb-12 md:mb-16 ${getTextboxLayoutClass()} ${getAnimationClass()}`}>
|
||||||
|
<h2 className="text-3xl md:text-4xl lg:text-5xl font-bold mb-4 leading-tight">
|
||||||
|
{title}
|
||||||
|
</h2>
|
||||||
|
<p className={`text-lg md:text-xl ${useInvertedBackground ? 'text-slate-300' : 'text-slate-600'} max-w-3xl`}>
|
||||||
|
{description}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Features Grid and Detail View */}
|
||||||
|
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8 md:gap-12">
|
||||||
|
{/* Feature Cards */}
|
||||||
|
<div className="lg:col-span-1 space-y-4">
|
||||||
|
{features.map((feature, index) => {
|
||||||
|
const CardIcon = feature.icon;
|
||||||
|
const isActive = index === activeFeatureIndex;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
key={index}
|
||||||
|
onClick={() => setActiveFeatureIndex(index)}
|
||||||
|
className={`w-full p-4 md:p-6 rounded-lg transition-all duration-300 text-left ${
|
||||||
|
isActive
|
||||||
|
? useInvertedBackground
|
||||||
|
? 'bg-blue-600 text-white shadow-lg'
|
||||||
|
: 'bg-blue-50 border-2 border-blue-600 text-slate-900'
|
||||||
|
: useInvertedBackground
|
||||||
|
? 'bg-slate-800 text-slate-300 hover:bg-slate-700'
|
||||||
|
: 'bg-slate-50 text-slate-700 hover:bg-slate-100 border-2 border-transparent'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div className="flex items-start gap-3">
|
||||||
|
<CardIcon className="w-6 h-6 flex-shrink-0 mt-1" />
|
||||||
|
<div className="flex-1">
|
||||||
|
<h3 className="font-semibold text-base md:text-lg mb-1">
|
||||||
|
{feature.title}
|
||||||
|
</h3>
|
||||||
|
<p className={`text-sm ${isActive ? '' : useInvertedBackground ? 'text-slate-400' : 'text-slate-600'}`}>
|
||||||
|
{feature.description}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Active Feature Detail */}
|
||||||
|
<div className="lg:col-span-2">
|
||||||
|
<div className={`rounded-lg overflow-hidden ${useInvertedBackground ? 'bg-slate-800' : 'bg-slate-50'} p-6 md:p-8 transition-all duration-500`}>
|
||||||
|
{/* Feature Header */}
|
||||||
|
<div className="flex items-center gap-4 mb-6">
|
||||||
|
<div className={`p-3 rounded-lg ${useInvertedBackground ? 'bg-blue-600' : 'bg-blue-100'}`}>
|
||||||
|
<IconComponent className={`w-8 h-8 ${useInvertedBackground ? 'text-white' : 'text-blue-600'}`} />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 className="text-2xl md:text-3xl font-bold">
|
||||||
|
{activeFeature.title}
|
||||||
|
</h3>
|
||||||
|
<p className={`text-base ${useInvertedBackground ? 'text-slate-400' : 'text-slate-600'} mt-1`}>
|
||||||
|
{activeFeature.description}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Media Gallery */}
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
|
{activeFeature.mediaItems.map((media, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className="relative overflow-hidden rounded-lg aspect-video bg-slate-200 animate-fade-in"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={media.imageSrc}
|
||||||
|
alt={media.imageAlt}
|
||||||
|
className="w-full h-full object-cover hover:scale-105 transition-transform duration-300"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Indicator Dots */}
|
||||||
|
<div className="flex justify-center gap-2 mt-6">
|
||||||
|
{features.map((_, index) => (
|
||||||
|
<button
|
||||||
|
key={index}
|
||||||
|
onClick={() => setActiveFeatureIndex(index)}
|
||||||
|
className={`w-2 h-2 rounded-full transition-all duration-300 ${
|
||||||
|
index === activeFeatureIndex
|
||||||
|
? useInvertedBackground
|
||||||
|
? 'bg-blue-400 w-8'
|
||||||
|
: 'bg-blue-600 w-8'
|
||||||
|
: useInvertedBackground
|
||||||
|
? 'bg-slate-600'
|
||||||
|
: 'bg-slate-300'
|
||||||
|
}`}
|
||||||
|
aria-label={`Go to feature ${index + 1}`}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style jsx>{`
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-fade-in {
|
||||||
|
animation: fadeIn 0.5s ease-out;
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user