103 lines
3.5 KiB
TypeScript
103 lines
3.5 KiB
TypeScript
'use client';
|
|
import { motion } from 'framer-motion';
|
|
import { personal } from '@/content/personal';
|
|
import styles from './About.module.scss';
|
|
|
|
export default function About() {
|
|
return (
|
|
<section className={styles.section} id="about">
|
|
<div className={styles.container}>
|
|
<motion.div
|
|
className={styles.wrapper}
|
|
initial={{ opacity: 0, y: 24 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
viewport={{ once: true, margin: '-50px' }}
|
|
transition={{ duration: 0.5 }}
|
|
>
|
|
<header className={styles.header}>
|
|
<h2 className={styles.heading}>
|
|
A bit about me<span className={styles.dot}>.</span>
|
|
</h2>
|
|
</header>
|
|
|
|
<div className={styles.content}>
|
|
<div className={styles.paragraphs}>
|
|
{personal.aboutMe.paragraphs.map((p, i) => (
|
|
<motion.p
|
|
key={i}
|
|
className={styles.para}
|
|
initial={{ opacity: 0, y: 12 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
viewport={{ once: true }}
|
|
transition={{ duration: 0.4, delay: i * 0.08 }}
|
|
>
|
|
{p}
|
|
</motion.p>
|
|
))}
|
|
</div>
|
|
|
|
<motion.div
|
|
className={styles.currently}
|
|
initial={{ opacity: 0, y: 12 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
viewport={{ once: true }}
|
|
transition={{ duration: 0.4, delay: 0.12 }}
|
|
>
|
|
<span className={styles.currentlyLabel}>Right now</span>
|
|
<div className={styles.currentlyTags}>
|
|
{personal.aboutMe.currently.map((item, i) => (
|
|
<motion.span
|
|
key={i}
|
|
className={styles.tag}
|
|
initial={{ opacity: 0, scale: 0.9 }}
|
|
whileInView={{ opacity: 1, scale: 1 }}
|
|
viewport={{ once: true }}
|
|
transition={{ duration: 0.3, delay: 0.1 + i * 0.05 }}
|
|
whileHover={{ scale: 1.05 }}
|
|
>
|
|
{item}
|
|
</motion.span>
|
|
))}
|
|
</div>
|
|
</motion.div>
|
|
|
|
<motion.blockquote
|
|
className={styles.quote}
|
|
initial={{ opacity: 0, y: 12 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
viewport={{ once: true }}
|
|
transition={{ duration: 0.4, delay: 0.18 }}
|
|
>
|
|
{personal.aboutMe.funFact}
|
|
</motion.blockquote>
|
|
|
|
<motion.div
|
|
className={styles.stats}
|
|
initial="hidden"
|
|
whileInView="visible"
|
|
viewport={{ once: true }}
|
|
variants={{ visible: { transition: { staggerChildren: 0.08 } } }}
|
|
>
|
|
{personal.stats.map((s, i) => (
|
|
<motion.div
|
|
key={s.label}
|
|
className={styles.stat}
|
|
variants={{
|
|
hidden: { opacity: 0, y: 14 },
|
|
visible: { opacity: 1, y: 0 },
|
|
}}
|
|
transition={{ duration: 0.4, ease: [0.22, 0.61, 0.36, 1] }}
|
|
whileHover={{ y: -2 }}
|
|
>
|
|
<span className={styles.statValue}>{s.value}</span>
|
|
<span className={styles.statLabel}>{s.label}</span>
|
|
</motion.div>
|
|
))}
|
|
</motion.div>
|
|
</div>
|
|
</motion.div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|