Goal

Create Skills: a responsive card grid that lists your skills by category.

Skills.jsx

function Skills() {
  return (
    <section id="skills" className="bg-white py-20 dark:bg-slate-900">
      <div className="mx-auto max-w-5xl px-6">
        <h2 className="mb-2 text-3xl font-bold text-slate-900 dark:text-slate-100">
          Skills
        </h2>
        <p className="mb-10 max-w-2xl text-slate-600 dark:text-slate-400">
          Tools I use to design, build, and ship full stack applications.
        </p>

        <div className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
          {[
            {
              title: "Frontend",
              items: "HTML, CSS, JavaScript, React, Tailwind CSS",
            },
            {
              title: "Backend",
              items: "Node.js, Express, REST APIs, authentication",
            },
            {
              title: "Data",
              items: "SQL, MongoDB, Prisma, data modeling",
            },
            {
              title: "Tooling",
              items: "Git, Vite, npm, ESLint, VS Code",
            },
            {
              title: "Soft skills",
              items: "Communication, debugging, pair programming",
            },
            {
              title: "Currently learning",
              items: "TypeScript, testing, cloud deployment",
            },
          ].map((skill) => (
            <article
              key={skill.title}
              className="rounded-2xl border border-slate-200 bg-white p-6 shadow-sm dark:border-slate-700 dark:bg-slate-900"
            >
              <h3 className="mb-2 text-lg font-semibold text-slate-900 dark:text-slate-100">
                {skill.title}
              </h3>
              <p className="text-sm leading-relaxed text-slate-600 dark:text-slate-400">
                {skill.items}
              </p>
            </article>
          ))}
        </div>
      </div>
    </section>
  );
}

export default Skills;

Edit the skill groups so they match what you actually know.

Tailwind chunks explained: section chrome

Class Meaning
id="skills" Target for #skills nav links
bg-white / dark:bg-slate-900 Alternate band vs the surface-colored hero
py-20 Tall section padding
mx-auto max-w-5xl px-6 Same content rail as Hero and Navbar
mb-2 / mb-10 Tight heading gap, then space before the grid
max-w-2xl Keep the intro paragraph from stretching too wide
text-3xl font-bold Section heading scale

Tailwind chunks explained: responsive grid

Class Meaning
grid CSS Grid container
grid-cols-1 One column by default (phones)
sm:grid-cols-2 Two columns from sm (640px) up
lg:grid-cols-3 Three columns from lg (1024px) up
gap-6 Consistent gap between cards

Mental model: write the mobile layout first, then add breakpoint prefixes for larger screens.

Tailwind chunks explained: skill cards

Class Meaning
rounded-2xl Large corner radius for a soft card
border Visible edge
border-slate-200 / dark:border-slate-700 Theme-aware outline
bg-white / dark:bg-slate-900 Card surface
p-6 Inner padding
shadow-sm Light elevation
text-lg font-semibold Card title weight
text-sm leading-relaxed Comfortable description type

Wire into App.jsx

import Navbar from "./components/Navbar";
import Hero from "./components/Hero";
import Skills from "./components/Skills";

function App() {
  return (
    <div className="min-h-screen bg-surface font-sans text-ink antialiased dark:bg-slate-950 dark:text-slate-100">
      <Navbar />

      <main>
        <Hero />
        <Skills />
      </main>
    </div>
  );
}

export default App;

Check

  • 1 column on a narrow phone width
  • 2 columns around tablet width
  • 3 columns on a wide desktop
  • Cards stay readable in dark mode
  • Navbar Skills jumps to this section

Next: build the Projects cards with hover motion.