Premium portfolio website built with Next.js 14, TypeScript, Tailwind CSS, and Framer Motion.
# 1. Install dependencies
npm install
# 2. Copy environment template
cp .env.example .env.local
# 3. Start development server
npm run devOpen http://localhost:3000.
portfolio/
├── app/
│ ├── api/
│ │ └── contact/route.ts ← Contact form API (stub, ready to wire)
│ ├── globals.css ← Base styles, fonts, Tailwind
│ ├── layout.tsx ← Root layout + SEO metadata + JSON-LD
│ └── page.tsx ← Main page (assembles all sections)
│
├── components/
│ ├── Navbar.tsx ← Sticky nav with scroll-aware bg
│ ├── Footer.tsx ← Minimal footer
│ └── sections/
│ ├── Hero.tsx ← Animated headline + CTA
│ ├── Metrics.tsx ← Animated counter cards
│ ├── About.tsx ← Narrative + certifications
│ ├── Skills.tsx ← Tabbed skill categories
│ ├── Projects.tsx ← Project cards + detail modal
│ ├── Philosophy.tsx ← 4-principle grid
│ ├── Vision.tsx ← Future goals section
│ └── Contact.tsx ← Email + social + resume CTA
│
├── data/
│ └── index.ts ← ⭐ ALL content lives here. Edit this file.
│
├── lib/
│ ├── utils.ts ← cn(), stagger helpers, color maps
│ ├── firebase.ts ← Firebase stub (ready to activate)
│ └── analytics.ts ← Analytics stub (ready to activate)
│
├── public/
│ └── resume-jestoni-kent-agan.pdf ← DROP YOUR RESUME HERE
│
├── .env.example ← Environment variables template
├── next.config.js
├── tailwind.config.ts
└── tsconfig.json
All text, metrics, projects, and skills are in one file:
data/index.ts
Edit that file to update anything — no need to touch components.
| Token | Value |
|---|---|
| Background | #080b12 |
| Surface | #161d2c |
| Accent Cyan | #22d3ee |
| Accent Blue | #3b82f6 |
| Text Primary | #f0f6ff |
| Text Secondary | #94a3b8 |
| Font Display | Syne |
| Font Body | DM Sans |
| Font Mono | JetBrains Mono |
npm install resend- Add
RESEND_API_KEYto.env.local - Uncomment send logic in
app/api/contact/route.ts
npm install firebase- Fill Firebase vars in
.env.local - Uncomment
lib/firebase.ts
- Vercel Analytics:
npm install @vercel/analytics→ add<Analytics />tolayout.tsx - Plausible: Add script tag to
layout.tsxhead - PostHog: Follow setup in
lib/analytics.ts
npm install -g vercel
vercelThe project is configured for a static export which makes it compatible with GitHub Pages.
On a user‑page repository (<username>.github.io) the default basePath is /.
For project pages, set NEXT_PUBLIC_BASE_PATH and/or NEXT_PUBLIC_ASSET_PREFIX in
.env.local (for example /my-repo) before running the export.
npm run build # creates a production build
npm run export # generates static HTML files in `out/`
# manually push the contents of `out/` to the `gh-pages` branchYou can automate deployment with a GitHub Action or third‑party tool but no additional dependencies are required to keep the repo lean.
Note: server‑side routes (like
app/api/contact/route.ts) are not supported on GitHub Pages. The code remains in the repo for local/dev use and to make it easy to switch to a platform with function support (Vercel, Netlify, etc.). The contact form will degrade gracefully by logging submissions to the console when the email provider is not configured.
The following principles are baked into the system so you can think globally about reliability and safety:
- Errors are caught at boundaries:
- the
app/error.tsxroot boundary displays a friendly message and logs to the console (optionally to a monitoring service). - API routes include try/catch blocks with proper status codes.
- the
- Logging is centralized in
lib/logger.tsso you can swap out the implementation later (send to an external service, mute in production, etc.) without changing every file that writes to console. - Security headers are defined in
next.config.jsand apply to every response. Environment variables are used for host-specific values. - There are no new dependencies; everything works with the existing stack.
Drop your PDF at:
public/resume-jestoni-kent-agan.pdf
The download button is wired automatically.
Update your domain in:
app/layout.tsx→metadataBase.env.local→NEXT_PUBLIC_SITE_URL- JSON-LD in
layout.tsx
Built by Jestoni Kent Agan · jestkent.dev