Files
portifolio-evandrodevbr/app/components/Skills.tsx
T
Evandro Fonseca JuniorandClaude Sonnet 5 d76bbf5974 feat: revamp portfolio with case studies, curriculo page, and local SEO
Adds dynamic case study and curriculo routes, project health monitoring
for live demo status, and strengthens local SEO (structured data,
service-area targeting for Garuva/Joinville/Curitiba, a dedicated
"criação de sites" service page) so search results better match the
professional title (Engenheiro da Computação) and experience (5 anos).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-07-15 01:31:46 -03:00

90 lines
2.5 KiB
TypeScript

"use client";
import type { PortfolioSkillCategory } from "@/lib/portfolio-data";
import { motion, type Variants, useReducedMotion } from "framer-motion";
import { Section } from "./Section";
import { DrawLine } from "./animations/DrawLine";
export default function Skills({
categories,
}: {
categories: PortfolioSkillCategory[];
}) {
const shouldReduceMotion = useReducedMotion();
const gridVariants: Variants = {
hidden: {},
visible: {
transition: {
delayChildren: 0.06,
staggerChildren: 0.08,
},
},
};
const cardVariants: Variants = {
hidden: shouldReduceMotion
? { opacity: 0 }
: { opacity: 0, y: 20, clipPath: "inset(100% 0 0 0)" },
visible: {
opacity: 1,
y: 0,
clipPath: "inset(0% 0 0 0)",
transition: shouldReduceMotion
? { duration: 0.25 }
: { duration: 0.8, ease: [0.16, 1, 0.3, 1] },
},
};
return (
<Section
id="skills"
eyebrow="Core stack"
title="Next.js, Tauri, Rust e stack para produtos criticos"
description="Tecnologias e fundamentos que uso em engenharia de software, arquitetura de software, IoT e integracoes complexas."
dark
disableChildrenAnimation
>
<motion.div
className="ds-grid-2"
initial="hidden"
whileInView="visible"
viewport={{ once: true, amount: 0.2 }}
variants={gridVariants}
>
{categories.map((category) => (
<motion.article
key={category.category}
className="ds-card h-full"
variants={cardVariants}
whileHover={
shouldReduceMotion
? undefined
: {
y: -4,
boxShadow: "0 20px 40px rgba(0, 0, 0, 0.35)",
}
}
whileTap={shouldReduceMotion ? undefined : { scale: 0.99 }}
transition={{ type: "spring", stiffness: 180, damping: 18 }}
>
<h3 className="ds-card-title !mt-0">{category.category}</h3>
<DrawLine delay={0.05} />
<p className="ds-copy !mt-sp-4">
Ferramentas que uso para construir com clareza tecnica e ritmo de
entrega.
</p>
<ul className="ds-tags">
{category.skills.map((skill) => (
<li key={skill} className="ds-tag">
{skill}
</li>
))}
</ul>
</motion.article>
))}
</motion.div>
</Section>
);
}