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:
npm run devshows a complete single-page portfolio- Navbar links jump to About, Skills, Projects, and Contact
- Layout works on a phone width and a desktop width
- Dark / light toggle works and survives a refresh
- 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.