Skip to main content

Overview

The SkillsSection component displays areas of expertise in a responsive grid layout. Each skill card features an icon, title, and description with smooth hover interactions.

Features

  • Responsive grid layout (1/2/3 columns)
  • Icon-based visual hierarchy
  • Staggered card animations
  • Hover state transitions
  • Background color differentiation
  • Lucide React icons integration

Component Structure

import { motion } from "framer-motion";
import { Brain, Code, Shield, Workflow, Cloud, Users } from "lucide-react";

const skills = [
  {
    icon: Brain,
    title: "IA Generativa",
    description: "Implementación de soluciones de IA Generativa privada para empresas...",
  },
  // ... more skills
];

const SkillsSection = () => {
  return (
    <section id="skills" className="py-24 md:py-32 bg-card/50">
      {/* Content */}
    </section>
  );
};

Data Structure

Skills are defined as an array of objects:
interface Skill {
  icon: LucideIcon;    // Icon component from lucide-react
  title: string;       // Skill name
  description: string; // Detailed description
}

Default Skills Data

const skills = [
  {
    icon: Brain,
    title: "IA Generativa",
    description: "Implementación de soluciones de IA Generativa privada para empresas, garantizando seguridad y personalización.",
  },
  {
    icon: Code,
    title: "Desarrollo de Software",
    description: "Arquitectura y desarrollo de soluciones a medida con tecnologías de vanguardia y metodologías ágiles.",
  },
  {
    icon: Workflow,
    title: "Transformación Digital",
    description: "Estrategia e implementación de procesos de digitalización y modernización tecnológica empresarial.",
  },
  {
    icon: Users,
    title: "Liderazgo Técnico",
    description: "Gestión de equipos de alto rendimiento con más de 100 consultores e ingenieros de software.",
  },
  {
    icon: Shield,
    title: "Consultoría IT",
    description: "Asesoramiento estratégico en tecnología, alineando soluciones técnicas con objetivos de negocio.",
  },
  {
    icon: Cloud,
    title: "Cloud & DevOps",
    description: "Diseño de infraestructuras cloud escalables y procesos de entrega continua para máxima eficiencia.",
  },
];

Grid Layout

Responsive Breakpoints

<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
  {/* Cards */}
</div>
Single column layout - grid with no column specification

Skill Card Implementation

{skills.map((skill, i) => (
  <motion.div
    key={skill.title}
    initial={{ opacity: 0, y: 20 }}
    whileInView={{ opacity: 1, y: 0 }}
    viewport={{ once: true }}
    transition={{ delay: i * 0.1, duration: 0.5 }}
    className="bg-background border border-border rounded-lg p-6 
               hover:border-primary/30 transition-all group"
  >
    <div className="w-11 h-11 rounded-lg bg-primary/10 
                    flex items-center justify-center mb-4 
                    group-hover:bg-primary/20 transition-colors">
      <skill.icon className="w-5 h-5 text-primary" />
    </div>
    <h3 className="font-heading text-lg font-semibold mb-2">
      {skill.title}
    </h3>
    <p className="text-muted-foreground text-sm leading-relaxed">
      {skill.description}
    </p>
  </motion.div>
))}

Card Anatomy

1

Icon Container

11x11 rounded square with primary background at 10% opacity
2

Title

Large heading font with semibold weight
3

Description

Muted text color with relaxed line height for readability

Animation Details

Staggered Card Entrance

Each card animates in sequence with a 0.1s delay increment:
transition={{ delay: i * 0.1, duration: 0.5 }}
  • Card 0: 0.0s delay
  • Card 1: 0.1s delay
  • Card 2: 0.2s delay
  • Card 3: 0.3s delay
  • Card 4: 0.4s delay
  • Card 5: 0.5s delay

Hover Effects

Two hover transitions occur simultaneously:
hover:border-primary/30
Border color transitions to primary at 30% opacity

Section Background

Unlike other sections, SkillsSection has a subtle background:
<section className="py-24 md:py-32 bg-card/50">
This creates visual separation and hierarchy in the page layout.

Section Header

<motion.div
  initial={{ opacity: 0, y: 30 }}
  whileInView={{ opacity: 1, y: 0 }}
  viewport={{ once: true }}
  transition={{ duration: 0.6 }}
  className="text-center mb-16"
>
  <p className="text-primary font-heading text-sm tracking-[0.2em] uppercase mb-3">
    Competencias
  </p>
  <h2 className="font-heading text-3xl md:text-5xl font-bold">
    Áreas de especialización
  </h2>
</motion.div>

Full Component Code

import { motion } from "framer-motion";
import { Brain, Code, Shield, Workflow, Cloud, Users } from "lucide-react";

const skills = [
  {
    icon: Brain,
    title: "IA Generativa",
    description: "Implementación de soluciones de IA Generativa privada para empresas, garantizando seguridad y personalización.",
  },
  {
    icon: Code,
    title: "Desarrollo de Software",
    description: "Arquitectura y desarrollo de soluciones a medida con tecnologías de vanguardia y metodologías ágiles.",
  },
  {
    icon: Workflow,
    title: "Transformación Digital",
    description: "Estrategia e implementación de procesos de digitalización y modernización tecnológica empresarial.",
  },
  {
    icon: Users,
    title: "Liderazgo Técnico",
    description: "Gestión de equipos de alto rendimiento con más de 100 consultores e ingenieros de software.",
  },
  {
    icon: Shield,
    title: "Consultoría IT",
    description: "Asesoramiento estratégico en tecnología, alineando soluciones técnicas con objetivos de negocio.",
  },
  {
    icon: Cloud,
    title: "Cloud & DevOps",
    description: "Diseño de infraestructuras cloud escalables y procesos de entrega continua para máxima eficiencia.",
  },
];

const SkillsSection = () => {
  return (
    <section id="skills" className="py-24 md:py-32 bg-card/50">
      <div className="container px-6">
        <div className="max-w-5xl mx-auto">
          <motion.div
            initial={{ opacity: 0, y: 30 }}
            whileInView={{ opacity: 1, y: 0 }}
            viewport={{ once: true }}
            transition={{ duration: 0.6 }}
            className="text-center mb-16"
          >
            <p className="text-primary font-heading text-sm tracking-[0.2em] uppercase mb-3">
              Competencias
            </p>
            <h2 className="font-heading text-3xl md:text-5xl font-bold">
              Áreas de especialización
            </h2>
          </motion.div>

          <div className="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
            {skills.map((skill, i) => (
              <motion.div
                key={skill.title}
                initial={{ opacity: 0, y: 20 }}
                whileInView={{ opacity: 1, y: 0 }}
                viewport={{ once: true }}
                transition={{ delay: i * 0.1, duration: 0.5 }}
                className="bg-background border border-border rounded-lg p-6 hover:border-primary/30 transition-all group"
              >
                <div className="w-11 h-11 rounded-lg bg-primary/10 flex items-center justify-center mb-4 group-hover:bg-primary/20 transition-colors">
                  <skill.icon className="w-5 h-5 text-primary" />
                </div>
                <h3 className="font-heading text-lg font-semibold mb-2">{skill.title}</h3>
                <p className="text-muted-foreground text-sm leading-relaxed">{skill.description}</p>
              </motion.div>
            ))}
          </div>
        </div>
      </div>
    </section>
  );
};

export default SkillsSection;

Customization

1

Add New Skill

Import a new icon from lucide-react and add an object to the skills array
2

Change Grid Layout

Modify lg:grid-cols-3 to lg:grid-cols-4 for four columns on large screens
3

Adjust Card Spacing

Change gap-6 to increase or decrease space between cards
4

Customize Hover Effects

Modify hover:border-primary/30 and group-hover:bg-primary/20 values

Icon Options

Popular Lucide icons for skills:
  • Brain - AI/ML
  • Code - Development
  • Shield - Security
  • Workflow - Automation
  • Cloud - Cloud services
  • Users - Team management
  • Database - Data management
  • Lock - Cybersecurity
  • Zap - Performance
  • Layers - Architecture

Usage Example

import SkillsSection from '@/components/SkillsSection';

function App() {
  return (
    <>
      <AboutSection />
      <SkillsSection />
      <ExperienceSection />
    </>
  );
}

Build docs developers (and LLMs) love