Animated about

This commit is contained in:
2026-01-21 12:30:49 +01:00
parent ede059581a
commit 611d51765d
2 changed files with 203 additions and 90 deletions
+116 -83
View File
@@ -1,3 +1,5 @@
"use client";
import { import {
Github, Github,
Linkedin, Linkedin,
@@ -21,6 +23,16 @@ import {
SiLinux, SiLinux,
} from "@icons-pack/react-simple-icons"; } from "@icons-pack/react-simple-icons";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { motion } from "framer-motion";
import {
staggerContainer,
fadeInUp,
fadeIn,
cardReveal,
timelineItemLeft,
timelineItemRight,
slowFloat,
} from "@/lib/animations";
const timeline = [ const timeline = [
{ {
@@ -122,52 +134,78 @@ export default function About() {
return ( return (
<> <>
{/* Hero */} {/* Hero */}
<section className="pt-24 pb-16 bg-background relative overflow-hidden"> <motion.section
<div className="absolute top-1/4 right-1/4 w-96 h-96 bg-accent/5 rounded-full blur-3xl" /> className="pt-24 pb-16 bg-background relative overflow-hidden"
variants={staggerContainer}
initial="hidden"
animate="visible"
>
<motion.div
className="absolute top-1/4 right-1/4 w-96 h-96 bg-accent/5 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="grid grid-cols-1 lg:grid-cols-2 gap-16 items-center"> <div className="grid grid-cols-1 lg:grid-cols-2 gap-16 items-center">
{/* Image/Avatar */} {/* Image/Avatar */}
<div className="relative"> <motion.div variants={fadeInUp}>
<div className="aspect-square max-w-md mx-auto rounded-3xl overflow-hidden glass-card p-2"> <div className="relative">
<div className="w-full h-full rounded-2xl bg-gradient-to-br from-accent/20 to-accent/5 flex items-center justify-center"> <div className="aspect-square max-w-md mx-auto rounded-3xl overflow-hidden glass-card p-2">
<img <div className="w-full h-full rounded-2xl bg-gradient-to-br from-accent/20 to-accent/5 flex items-center justify-center">
src="https://avatars.githubusercontent.com/u/103524696?v=4" <img
alt="Klesti Selimaj" src="https://avatars.githubusercontent.com/u/103524696?v=4"
className="w-full h-full object-cover rounded-2xl" alt="Klesti Selimaj"
/> className="w-full h-full object-cover rounded-2xl"
/>
</div>
</div> </div>
{/* Floating badges */}
<motion.div
className="absolute -bottom-4 -right-4 glass-card rounded-xl px-4 py-2 flex items-center gap-2"
variants={fadeInUp}
transition={{ delay: 0.6, type: "spring" }}
>
<span className="w-2 h-2 rounded-full bg-accent animate-pulse" />
<span className="text-sm text-foreground">Available</span>
</motion.div>
</div> </div>
{/* Floating badges */} </motion.div>
<div className="absolute -bottom-4 -right-4 glass-card rounded-xl px-4 py-2 flex items-center gap-2">
<span className="w-2 h-2 rounded-full bg-accent animate-pulse" />
<span className="text-sm text-foreground">Available</span>
</div>
</div>
{/* Content */} {/* Content */}
<div> <motion.div variants={staggerContainer}>
<span className="text-accent text-sm font-medium uppercase tracking-wider"> <span className="text-accent text-sm font-medium uppercase tracking-wider">
About Me About Me
</span> </span>
<h1 className="text-4xl md:text-5xl font-bold text-foreground mt-2 mb-6"> <motion.h1
variants={fadeInUp}
className="text-4xl md:text-5xl font-bold text-foreground mt-2 mb-6"
>
Hey, I'm{" "} Hey, I'm{" "}
<span className="text-gradient-gold">Klesti Selimaj</span> <span className="text-gradient-gold">Klesti Selimaj</span>
</h1> </motion.h1>
<p className="text-lg text-muted-foreground mb-6"> <motion.p
variants={fadeInUp}
className="text-lg text-muted-foreground mb-6"
>
A 16-year-old software engineer from Albania with 6+ years of A 16-year-old software engineer from Albania with 6+ years of
experience. I'm passionate about building things that matter, experience. I'm passionate about building things that matter,
from low-level systems to beautiful user interfaces. from low-level systems to beautiful user interfaces.
</p> </motion.p>
<p className="text-muted-foreground mb-8"> <motion.p
variants={fadeInUp}
className="text-muted-foreground mb-8"
>
My journey started at age 10 when I had my first laptop (a Asus My journey started at age 10 when I had my first laptop (a Asus
with pre installed endless linux), and since then I've been with pre installed endless linux), and since then I've been
hooked on computers, but i didn't exactly know what programming hooked on computers, but i didn't exactly know what programming
was but i was doing it unconsciously, making winforms apps in c# was but i was doing it unconsciously, making winforms apps in c#
with visual studio. with visual studio.
</p> </motion.p>
{/* Quick Info */} {/* Quick Info */}
<div className="flex flex-wrap gap-4 mb-8"> <motion.div
variants={fadeInUp}
className="flex flex-wrap gap-4 mb-8"
>
<div className="flex items-center gap-2 text-muted-foreground"> <div className="flex items-center gap-2 text-muted-foreground">
<MapPin className="w-4 h-4 text-accent" /> <MapPin className="w-4 h-4 text-accent" />
<span>Albania</span> <span>Albania</span>
@@ -180,55 +218,30 @@ export default function About() {
<Crown className="w-4 h-4 text-accent" /> <Crown className="w-4 h-4 text-accent" />
<span>@orus-dev</span> <span>@orus-dev</span>
</div> </div>
</div> </motion.div>
{/* Social Links */} {/* Social Links */}
<div className="flex items-center gap-4"> <motion.div
<a variants={fadeInUp}
href="https://github.com/selimaj-dev" className="flex items-center gap-4"
target="_blank" >
rel="noopener noreferrer" {[Github, Linkedin, Youtube, Instagram, ExternalLink].map(
className="glass-card p-3 rounded-xl hover:ring-1 hover:ring-accent/30 transition-all" (Icon, i) => (
> <motion.a
<Github className="w-5 h-5 text-foreground" /> key={i}
</a> whileHover={{ y: -4, scale: 1.05 }}
<a whileTap={{ scale: 0.95 }}
href="https://www.linkedin.com/in/klesti-selimaj-7a0162343/" className="glass-card p-3 rounded-xl hover:ring-1 hover:ring-accent/30 transition-all"
target="_blank" >
rel="noopener noreferrer" <Icon className="w-5 h-5 text-foreground" />
className="glass-card p-3 rounded-xl hover:ring-1 hover:ring-accent/30 transition-all" </motion.a>
> ),
<Linkedin className="w-5 h-5 text-foreground" /> )}
</a> </motion.div>
<a </motion.div>
href="https://www.youtube.com/@0xkleo"
target="_blank"
rel="noopener noreferrer"
className="glass-card p-3 rounded-xl hover:ring-1 hover:ring-accent/30 transition-all"
>
<Youtube className="w-5 h-5 text-foreground" />
</a>
<a
href="https://www.instagram.com/selimaj.dev/"
target="_blank"
rel="noopener noreferrer"
className="glass-card p-3 rounded-xl hover:ring-1 hover:ring-accent/30 transition-all"
>
<Instagram className="w-5 h-5 text-foreground" />
</a>
<a
href="https://dev.to/selimaj"
target="_blank"
rel="noopener noreferrer"
className="glass-card p-3 rounded-xl hover:ring-1 hover:ring-accent/30 transition-all"
>
<ExternalLink className="w-5 h-5 text-foreground" />
</a>
</div>
</div>
</div> </div>
</div> </div>
</section> </motion.section>
{/* Tech Stack */} {/* Tech Stack */}
<section className="py-24 bg-card/50"> <section className="py-24 bg-card/50">
@@ -246,12 +259,18 @@ export default function About() {
</p> </p>
</div> </div>
<div className="grid grid-cols-2 md:grid-cols-4 gap-4"> <motion.div
className="grid grid-cols-2 md:grid-cols-4 gap-4"
variants={staggerContainer}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
>
{techStack.map((tech, index) => ( {techStack.map((tech, index) => (
<div <motion.div
key={tech.name} key={tech.name}
variants={cardReveal}
className="glass-card rounded-2xl p-6 text-center hover-lift group" className="glass-card rounded-2xl p-6 text-center hover-lift group"
style={{ animationDelay: `${index * 50}ms` }}
> >
<div className={cn("text-4xl mb-3 mx-auto w-max", tech.color)}> <div className={cn("text-4xl mb-3 mx-auto w-max", tech.color)}>
{tech.icon} {tech.icon}
@@ -259,9 +278,9 @@ export default function About() {
<h3 className="font-semibold text-foreground group-hover:text-accent transition-colors"> <h3 className="font-semibold text-foreground group-hover:text-accent transition-colors">
{tech.name} {tech.name}
</h3> </h3>
</div> </motion.div>
))} ))}
</div> </motion.div>
</div> </div>
</section> </section>
@@ -280,12 +299,18 @@ export default function About() {
</p> </p>
</div> </div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6"> <motion.div
className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6"
variants={staggerContainer}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
>
{achievements.map((achievement, index) => ( {achievements.map((achievement, index) => (
<div <motion.div
key={achievement.title} key={achievement.title}
variants={cardReveal}
className="glass-card rounded-2xl p-6 text-center hover-lift" className="glass-card rounded-2xl p-6 text-center hover-lift"
style={{ animationDelay: `${index * 100}ms` }}
> >
<div className="text-4xl mb-4">{achievement.icon}</div> <div className="text-4xl mb-4">{achievement.icon}</div>
<h3 className="font-semibold text-foreground mb-2"> <h3 className="font-semibold text-foreground mb-2">
@@ -294,9 +319,9 @@ export default function About() {
<p className="text-sm text-muted-foreground"> <p className="text-sm text-muted-foreground">
{achievement.description} {achievement.description}
</p> </p>
</div> </motion.div>
))} ))}
</div> </motion.div>
</div> </div>
</section> </section>
@@ -318,10 +343,15 @@ export default function About() {
<div className="max-w-3xl mx-auto"> <div className="max-w-3xl mx-auto">
{timeline.map((item, index) => ( {timeline.map((item, index) => (
<div <motion.div
key={item.year} key={item.year}
variants={
index % 2 === 0 ? timelineItemLeft : timelineItemRight
}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
className="relative flex gap-6 pb-12 last:pb-0" className="relative flex gap-6 pb-12 last:pb-0"
style={{ animationDelay: `${index * 100}ms` }}
> >
{/* Line */} {/* Line */}
{index !== timeline.length - 1 && ( {index !== timeline.length - 1 && (
@@ -351,7 +381,7 @@ export default function About() {
{item.description} {item.description}
</p> </p>
</div> </div>
</div> </motion.div>
))} ))}
</div> </div>
</div> </div>
@@ -359,7 +389,10 @@ export default function About() {
{/* Philosophy */} {/* Philosophy */}
<section className="py-24 bg-background relative overflow-hidden"> <section className="py-24 bg-background relative overflow-hidden">
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[600px] h-[600px] bg-accent/5 rounded-full blur-3xl" /> <motion.div
className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[600px] h-[600px] bg-accent/5 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-3xl mx-auto text-center"> <div className="max-w-3xl mx-auto text-center">
<span className="text-accent text-sm font-medium uppercase tracking-wider"> <span className="text-accent text-sm font-medium uppercase tracking-wider">
+87 -7
View File
@@ -1,22 +1,102 @@
import { Variant } from "framer-motion"; import { Variants } from "framer-motion";
type AnimationVariants = Record<string, Variant>; /**
* Container
*/
export const staggerContainer: Variants = {
hidden: {},
visible: {
transition: {
staggerChildren: 0.15,
delayChildren: 0.05,
},
},
};
export const fadeInUp: AnimationVariants = { /**
hidden: { opacity: 0, y: 30 }, * Basic entrances
*/
export const fadeInUp: Variants = {
hidden: { opacity: 0, y: 24 },
visible: { visible: {
opacity: 1, opacity: 1,
y: 0, y: 0,
transition: {
duration: 0.6,
ease: [0.22, 1, 0.36, 1], // premium easeOut
},
},
};
export const fadeInDown: Variants = {
hidden: { opacity: 0, y: -24 },
visible: {
opacity: 1,
y: 0,
transition: {
duration: 0.6,
ease: [0.22, 1, 0.36, 1],
},
},
};
export const fadeIn: Variants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: { duration: 0.6, ease: "easeOut" }, transition: { duration: 0.6, ease: "easeOut" },
}, },
}; };
export const staggerContainer: AnimationVariants = { /**
hidden: { opacity: 0 }, * Cards
*/
export const cardReveal: Variants = {
hidden: { opacity: 0, y: 30, scale: 0.96 },
visible: { visible: {
opacity: 1, opacity: 1,
y: 0,
scale: 1,
transition: { transition: {
staggerChildren: 0.15, duration: 0.5,
ease: [0.22, 1, 0.36, 1],
},
},
};
/**
* Timeline
*/
export const timelineItemLeft: Variants = {
hidden: { opacity: 0, x: -40 },
visible: {
opacity: 1,
x: 0,
transition: { duration: 0.5, ease: "easeOut" },
},
};
export const timelineItemRight: Variants = {
hidden: { opacity: 0, x: 40 },
visible: {
opacity: 1,
x: 0,
transition: { duration: 0.5, ease: "easeOut" },
},
};
/**
* Decorative / ambient
*/
export const slowFloat: Variants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
y: [0, -10, 0],
transition: {
duration: 6,
repeat: Infinity,
ease: "easeInOut",
}, },
}, },
}; };