Goal

Add the Footer, assemble the final App, and verify the whole portfolio works end to end.

1. Footer.jsx

function Footer() {
  return (
    <footer className="border-t border-slate-200 py-8 text-center text-sm text-slate-500 dark:border-slate-700 dark:text-slate-400">
      © {new Date().getFullYear()} Your Name.
    </footer>
  );
}

export default Footer;

Tailwind chunks explained

Class Meaning
border-t Top edge that separates footer from content
border-slate-200 / dark:border-slate-700 Theme-aware divider
py-8 Vertical breathing room
text-center Center the copyright line
text-sm Smaller footer type
text-slate-500 / dark:text-slate-400 Muted, secondary text

Optional stretch: add a flex row of social links with flex justify-center gap-4 above the copyright line.

2. Final App.jsx

import Contact from "./components/Contact";
import Footer from "./components/Footer";
import Hero from "./components/Hero";
import Navbar from "./components/Navbar";
import Projects from "./components/Projects";
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 />
        <Projects />
        <Contact />
      </main>

      <Footer />
    </div>
  );
}

export default App;

Page shell reminder

Class Role on the whole site
min-h-screen Full-height page canvas
bg-surface / dark:bg-slate-950 Global background
font-sans Theme font everywhere
text-ink / dark:text-slate-100 Default text color
antialiased Cleaner type rendering

3. Final folder check

src/
├── main.jsx
├── style.css
├── App.jsx
└── components/
    ├── Navbar.jsx
    ├── ThemeToggle.jsx
    ├── Hero.jsx
    ├── Skills.jsx
    ├── Projects.jsx
    ├── Contact.jsx
    └── Footer.jsx

4. Definition of done

You are finished when:

  1. npm run dev shows a complete single-page portfolio
  2. Navbar links jump to About, Skills, Projects, and Contact
  3. Layout works on a phone width and a desktop width
  4. Dark / light toggle works and survives a refresh
  5. Someone can tell who you are, what you know, and how to reach you

What you practiced

Building section by section, you used the Tailwind tools you will reach for daily:

Concept Where it showed up
Theme tokens (@theme) Setup: brand, surface, ink, fonts
Flexbox Navbar row, hero split, CTA / tag rows
Grid Skills and projects layouts, form stacks
Responsive prefixes Mobile menu, column counts, hero direction
Borders / radius / shadows Cards, inputs, nav chrome
State variants hover:, focus:, focus-visible:, active:, group-hover:
Transitions / transforms Buttons, project cards
Dark mode (dark: + class strategy) Whole page + theme toggle

Ship it. Put your name on it. Then keep replacing placeholder copy and project links with real work.