Animated home page

This commit is contained in:
2026-01-21 12:49:27 +01:00
parent 4154ebc6b8
commit ad2ebc8de9
4 changed files with 116 additions and 44 deletions
+2 -2
View File
@@ -14,8 +14,8 @@ export function CTASection() {
<span className="text-gradient-gold">extraordinary</span>? <span className="text-gradient-gold">extraordinary</span>?
</h2> </h2>
<p className="text-lg text-muted-foreground mb-10 max-w-xl mx-auto"> <p className="text-lg text-muted-foreground mb-10 max-w-xl mx-auto">
Whether you need a complex system, a modern web application, or specialized tooling, Whether you need a complex system, a modern web application, or
I'm here to bring your vision to life. specialized tooling, I'm here to bring your vision to life.
</p> </p>
<div className="flex flex-col sm:flex-row items-center justify-center gap-4"> <div className="flex flex-col sm:flex-row items-center justify-center gap-4">
<Link <Link
+59 -18
View File
@@ -1,43 +1,76 @@
"use client";
import { ArrowRight, Github, Linkedin, Youtube } from "lucide-react"; import { ArrowRight, Github, Linkedin, Youtube } from "lucide-react";
import Link from "next/link"; import Link from "next/link";
import { motion } from "framer-motion";
import { staggerContainer, fadeInUp, slowFloat } from "@/lib/animations";
export function HeroSection() { export function HeroSection() {
return ( return (
<section className="relative min-h-[90vh] flex items-center justify-center overflow-hidden"> <motion.section
className="relative min-h-svh flex items-center justify-center overflow-hidden"
variants={staggerContainer}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
>
{/* Background Effects */} {/* Background Effects */}
<div className="absolute inset-0 bg-gradient-to-b from-background via-background to-card" /> <div className="absolute inset-0 bg-gradient-to-b from-background via-background to-card" />
<div className="absolute top-1/4 left-1/4 w-96 h-96 bg-accent/5 rounded-full blur-3xl" /> <motion.div
<div className="absolute bottom-1/4 right-1/4 w-96 h-96 bg-accent/10 rounded-full blur-3xl" /> className="absolute top-1/4 left-1/4 w-96 h-96 bg-accent/5 rounded-full blur-3xl"
variants={slowFloat}
/>
<motion.div
className="absolute bottom-1/4 right-1/4 w-96 h-96 bg-accent/10 rounded-full blur-3xl"
variants={slowFloat}
/>
<div className="container mx-auto px-6 relative z-10"> <div className="container mx-auto px-6 relative z-10">
<div className="max-w-4xl mx-auto text-center"> <motion.div
className="max-w-4xl mx-auto text-center"
variants={staggerContainer}
>
{/* Status Badge */} {/* Status Badge */}
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full glass-card mb-8 animate-fade-in"> <motion.div
className="inline-flex items-center gap-2 px-4 py-2 rounded-full glass-card mb-8"
variants={fadeInUp}
>
<span className="w-2 h-2 rounded-full bg-accent animate-pulse" /> <span className="w-2 h-2 rounded-full bg-accent animate-pulse" />
<span className="text-sm text-muted-foreground"> <span className="text-sm text-muted-foreground">
Available for new projects Available for new projects
</span> </span>
</div> </motion.div>
{/* Main Heading */} {/* Main Heading */}
<h1 className="text-4xl md:text-6xl lg:text-7xl font-bold mb-6 animate-fade-in-up"> <motion.h1
className="text-4xl md:text-6xl lg:text-7xl font-bold mb-6"
variants={fadeInUp}
>
<span className="text-foreground">Building</span>{" "} <span className="text-foreground">Building</span>{" "}
<span className="text-gradient-gold">exceptional</span> <span className="text-gradient-gold">exceptional</span>
<br /> <br />
<span className="text-foreground">digital experiences</span> <span className="text-foreground">digital experiences</span>
</h1> </motion.h1>
{/* Subheading */} {/* Subheading */}
<p className="text-lg md:text-xl text-muted-foreground max-w-2xl mx-auto mb-10 animate-fade-in-delay-1"> <motion.p
className="text-lg md:text-xl text-muted-foreground max-w-2xl mx-auto mb-10"
variants={fadeInUp}
custom={0.2}
>
I'm{" "} I'm{" "}
<span className="text-foreground font-medium">Klesti Selimaj</span>, <span className="text-foreground font-medium">Klesti Selimaj</span>,
a 16-year-old software engineer with 6+ years of experience. a 16-year-old software engineer with 6+ years of experience.
Passionate about low-level systems, modern web apps, and crafting Passionate about low-level systems, modern web apps, and crafting
tools that make a difference. tools that make a difference.
</p> </motion.p>
{/* CTA Buttons */} {/* CTA Buttons */}
<div className="flex flex-col sm:flex-row items-center justify-center gap-4 mb-12 animate-fade-in-delay-2"> <motion.div
className="flex flex-col sm:flex-row items-center justify-center gap-4 mb-12"
variants={fadeInUp}
custom={0.4}
>
<Link <Link
href="/pricing" href="/pricing"
className="group flex items-center gap-2 bg-accent text-accent-foreground px-8 py-4 rounded-xl font-medium hover:bg-accent/90 transition-all hover:gap-3" className="group flex items-center gap-2 bg-accent text-accent-foreground px-8 py-4 rounded-xl font-medium hover:bg-accent/90 transition-all hover:gap-3"
@@ -54,10 +87,14 @@ export function HeroSection() {
<Github className="w-4 h-4" /> <Github className="w-4 h-4" />
View GitHub View GitHub
</a> </a>
</div> </motion.div>
{/* Social Links */} {/* Social Links */}
<div className="flex items-center justify-center gap-6 animate-fade-in-delay-3"> <motion.div
className="flex items-center justify-center gap-6"
variants={fadeInUp}
custom={0.6}
>
<a <a
href="https://github.com/selimaj-dev" href="https://github.com/selimaj-dev"
target="_blank" target="_blank"
@@ -82,16 +119,20 @@ export function HeroSection() {
> >
<Youtube className="w-5 h-5" /> <Youtube className="w-5 h-5" />
</a> </a>
</div> </motion.div>
</div> </motion.div>
</div> </div>
{/* Scroll Indicator */} {/* Scroll Indicator */}
<div className="absolute bottom-8 left-1/2 -translate-x-1/2 animate-bounce"> <motion.div
className="absolute bottom-8 left-1/2 -translate-x-1/2 mb-14"
animate={{ y: [0, 10, 0] }}
transition={{ repeat: Infinity, duration: 1.5 }}
>
<div className="w-6 h-10 border-2 border-muted-foreground/30 rounded-full flex items-start justify-center p-2"> <div className="w-6 h-10 border-2 border-muted-foreground/30 rounded-full flex items-start justify-center p-2">
<div className="w-1 h-2 bg-accent rounded-full animate-pulse" /> <div className="w-1 h-2 bg-accent rounded-full animate-pulse" />
</div> </div>
</div> </motion.div>
</section> </motion.section>
); );
} }
+24 -9
View File
@@ -1,4 +1,8 @@
"use client";
import { ExternalLink, Github, Star } from "lucide-react"; import { ExternalLink, Github, Star } from "lucide-react";
import { motion } from "framer-motion";
import { fadeInUp, staggerContainer } from "@/lib/animations";
const projects = [ const projects = [
{ {
@@ -56,10 +60,16 @@ const projects = [
export function ProjectsSection() { export function ProjectsSection() {
return ( return (
<section className="py-24 bg-card/50"> <motion.section
className="py-24 bg-card/50"
variants={staggerContainer}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
>
<div className="container mx-auto px-6"> <div className="container mx-auto px-6">
{/* Section Header */} {/* Section Header */}
<div className="max-w-2xl mb-16"> <motion.div className="max-w-2xl mb-16" variants={fadeInUp}>
<span className="text-accent text-sm font-medium uppercase tracking-wider"> <span className="text-accent text-sm font-medium uppercase tracking-wider">
Portfolio Portfolio
</span> </span>
@@ -71,15 +81,16 @@ export function ProjectsSection() {
showcase my skills in systems programming, web development, and showcase my skills in systems programming, web development, and
tooling. tooling.
</p> </p>
</div> </motion.div>
{/* Projects Grid */} {/* Projects Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{projects.map((project, index) => ( {projects.map((project, index) => (
<article <motion.article
key={project.name} key={project.name}
className={"group glass-card rounded-2xl p-6 hover-lift"} className={"group glass-card rounded-2xl p-6 hover-lift"}
style={{ animationDelay: `${index * 100}ms` }} variants={fadeInUp}
custom={index * 0.1}
> >
{/* Header */} {/* Header */}
<div className="flex items-start justify-between mb-4"> <div className="flex items-start justify-between mb-4">
@@ -137,12 +148,16 @@ export function ProjectsSection() {
View View
</a> </a>
</div> </div>
</article> </motion.article>
))} ))}
</div> </div>
{/* View All CTA */} {/* View All CTA */}
<div className="text-center mt-12"> <motion.div
className="text-center mt-12"
variants={fadeInUp}
custom={0.8}
>
<a <a
href="https://github.com/selimaj-dev?tab=repositories" href="https://github.com/selimaj-dev?tab=repositories"
target="_blank" target="_blank"
@@ -152,8 +167,8 @@ export function ProjectsSection() {
View all projects on GitHub View all projects on GitHub
<ExternalLink className="w-4 h-4" /> <ExternalLink className="w-4 h-4" />
</a> </a>
</div> </motion.div>
</div> </div>
</section> </motion.section>
); );
} }
+29 -13
View File
@@ -1,3 +1,8 @@
"use client";
import { motion } from "framer-motion";
import { fadeInUp, staggerContainer } from "@/lib/animations";
const skills = [ const skills = [
{ {
category: "Languages", category: "Languages",
@@ -39,26 +44,33 @@ const stats = [
export function SkillsSection() { export function SkillsSection() {
return ( return (
<section className="py-24 bg-background"> <motion.section
className="py-24 bg-background"
variants={staggerContainer}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
>
<div className="container mx-auto px-6"> <div className="container mx-auto px-6">
{/* Stats */} {/* Stats */}
<div className="grid grid-cols-2 md:grid-cols-4 gap-6 mb-20"> <div className="grid grid-cols-2 md:grid-cols-4 gap-6 mb-20">
{stats.map((stat, index) => ( {stats.map((stat, index) => (
<div <motion.div
key={stat.label} key={stat.label}
className="text-center p-6 glass-card rounded-2xl hover-lift" className="text-center p-6 glass-card rounded-2xl hover-lift"
style={{ animationDelay: `${index * 100}ms` }} variants={fadeInUp}
custom={index * 0.1}
> >
<div className="text-3xl md:text-4xl font-bold text-gradient-gold mb-2"> <div className="text-3xl md:text-4xl font-bold text-gradient-gold mb-2">
{stat.value} {stat.value}
</div> </div>
<div className="text-sm text-muted-foreground">{stat.label}</div> <div className="text-sm text-muted-foreground">{stat.label}</div>
</div> </motion.div>
))} ))}
</div> </div>
{/* Section Header */} {/* Section Header */}
<div className="max-w-2xl mb-16"> <motion.div className="max-w-2xl mb-16" variants={fadeInUp}>
<span className="text-accent text-sm font-medium uppercase tracking-wider"> <span className="text-accent text-sm font-medium uppercase tracking-wider">
Expertise Expertise
</span> </span>
@@ -69,15 +81,16 @@ export function SkillsSection() {
From low-level systems programming to modern web development, I From low-level systems programming to modern web development, I
bring a diverse skill set to every project. bring a diverse skill set to every project.
</p> </p>
</div> </motion.div>
{/* Skills Grid */} {/* Skills Grid */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-8"> <div className="grid grid-cols-1 md:grid-cols-3 gap-8">
{skills.map((category, categoryIndex) => ( {skills.map((category, categoryIndex) => (
<div <motion.div
key={category.category} key={category.category}
className="glass-card rounded-2xl p-6" className="glass-card rounded-2xl p-6"
style={{ animationDelay: `${categoryIndex * 150}ms` }} variants={fadeInUp}
custom={categoryIndex * 0.15}
> >
<h3 className="text-lg font-semibold text-foreground mb-6 flex items-center gap-2"> <h3 className="text-lg font-semibold text-foreground mb-6 flex items-center gap-2">
<span className="w-2 h-2 rounded-full bg-accent" /> <span className="w-2 h-2 rounded-full bg-accent" />
@@ -95,18 +108,21 @@ export function SkillsSection() {
</span> </span>
</div> </div>
<div className="h-1.5 bg-secondary rounded-full overflow-hidden"> <div className="h-1.5 bg-secondary rounded-full overflow-hidden">
<div <motion.div
className="h-full bg-accent rounded-full transition-all duration-1000 ease-out" className="h-full bg-accent rounded-full"
style={{ width: `${skill.level}%` }} initial={{ width: 0 }}
whileInView={{ width: `${skill.level}%` }}
transition={{ duration: 1, ease: "easeOut" }}
viewport={{ once: true }}
/> />
</div> </div>
</div> </div>
))} ))}
</div> </div>
</div> </motion.div>
))} ))}
</div> </div>
</div> </div>
</section> </motion.section>
); );
} }