Terminal-style interactive resume with retro desktop UI, draggable windows, CRT effects, and dual creative/IT personas
  • JavaScript 84.4%
  • CSS 13.8%
  • HTML 1.7%
  • Shell 0.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-08-09 08:35:16 +07:00
dist feat: redesign hero landing, navbar control cluster, skills section, contact section & mobile responsiveness 2026-08-09 08:35:16 +07:00
public feat: redesign hero landing, navbar control cluster, skills section, contact section & mobile responsiveness 2026-08-09 08:35:16 +07:00
scripts feat: dynamic Forgejo repos, CV PDF download, responsive IT windows 2026-06-27 09:27:14 +07:00
src feat: redesign hero landing, navbar control cluster, skills section, contact section & mobile responsiveness 2026-08-09 08:35:16 +07:00
.DS_Store Initial commit 2026-04-19 11:08:18 +07:00
.gitignore feat: update portfolio with Simmonds Ltd design, light/dark theme, improved navigation 2026-04-25 23:03:54 +07:00
index.html feat: redesign hero landing, navbar control cluster, skills section, contact section & mobile responsiveness 2026-08-09 08:35:16 +07:00
llms.txt feat: Add AI agent SEO optimization (llms.txt, JSON-LD, robots.txt) 2026-04-22 13:47:33 +07:00
package-lock.json fix(pdf): add direct html2canvas+jspdf export & resolve mobile print CSS layout hiding 2026-08-02 21:43:00 +07:00
package.json fix(pdf): add direct html2canvas+jspdf export & resolve mobile print CSS layout hiding 2026-08-02 21:43:00 +07:00
postcss.config.js Initial commit 2026-04-19 11:08:18 +07:00
README.md docs: detailed README with architecture, data flow, and project structure 2026-06-27 09:29:12 +07:00
results.txt Initial commit 2026-04-19 11:08:18 +07:00
start.sh fix: PDF print via proper iframe clone, add start script, remove node_modules from git 2026-08-02 19:54:49 +07:00
tailwind.config.js feat: update portfolio with Simmonds Ltd design, light/dark theme, improved navigation 2026-04-25 23:03:54 +07:00
vite.config.js Initial commit 2026-04-19 11:08:18 +07:00

KHOA.VO — Dual Persona Portfolio

A single-page React application showcasing two professional identities — Creative Manager & Design Leader and Full-Stack Developer & DevOps — each with its own dedicated UI, animations, and personality.

Live Site  ·  Forgejo Repo  ·  Creative Works


Personas

Creative Side

A polished, editorial design portfolio targeting agencies and brand clients.

  • Dynamic VNDK Logo — deconstructing/reconstructing letter animation tied to scroll position
  • 3 View Modes — Grid, List, and Minimal gallery layouts
  • Progressive Image Reveal — grayscale + pixelated blur that resolves to full color on hover
  • Live Portfolio Feed — fetches projects from a WordPress REST API (/wp-json/wp/v2/posts)
  • Keyboard Navigation — ESC to close, arrow keys to navigate project modals
  • Dark/Light Theme — toggleable color schemes with system-aware defaults
  • Printable CV — A4-optimized resume rendered via PrintPortfolio component with @media print

IT Side

A retro terminal desktop environment built for developer and recruiter audiences.

  • CRT Screen Effects — scanlines, vignette, flicker via CSS @keyframes
  • Draggable Windows — "About", "Skills", "Projects", "Experience" as desktop windows
  • Boot Loader — simulated terminal boot sequence with typing animation
  • Idle Screensaver — triggers after 10 seconds of inactivity
  • Live Forgejo Sync — projects pulled from git.khoavo.myds.me API at build time, with 5-minute runtime polling
  • Hidden Scrollbarscustom-scrollbar utility scrolls all windows without visible bars
  • Terminal Styling — monospace fonts, phosphor-green (#00FF94) accent, taskbar with prompt

Project Structure

kv-cv/
├── public/
│   ├── resume.pdf            # Downloadable CV
│   ├── robots.txt
│   └── vndk-icon.svg
├── scripts/
│   └── fetch-forgejo-data.mjs # Build-time Forgejo API scraper
├── src/
│   ├── data/
│   │   └── forgejo-repos.json # Generated repo data (build-time)
│   ├── hooks/
│   │   ├── useForgejoRepos.js # Forgejo repo fetch + polling
│   │   └── usePortfolioPosts.js # WordPress post fetch
│   ├── App.jsx               # Main app (1583 lines) — all components + data
│   ├── PrintPortfolio.jsx    # A4 print-optimized CV layout
│   ├── index.css             # Global styles, CRT effects, custom-scrollbar
│   ├── print.css             # Print-only media rules
│   └── main.jsx              # React entry point
├── package.json
├── vite.config.js
├── tailwind.config.js
└── README.md

~3,110 lines across all source files.


Tech Stack

Layer Technology
Framework React 18
Build Vite 6
Styling Tailwind CSS 3 + PostCSS + Autoprefixer
Animation Framer Motion 12
Icons Lucide React
Data Sources WordPress REST API · Forgejo REST API · JSON build data
Runtime Browser SPA (no SSR, no backend)

Data Flow

Creative Portfolio (WordPress)

usePortfolioPosts → fetch("https://portfolio.khoavo.myds.me/wp-json/wp/v2/posts")
                    → transformToProject → Grid/List/Minimal gallery

IT Projects (Forgejo)

npm run build → scripts/fetch-forgejo-data.mjs
                → fetch("git.khoavo.myds.me/api/v1/users/vndangkhoa/repos")
                → write src/data/forgejo-repos.json

useForgejoRepos → import build data (instant, no loading state)
                   → 5-min polling fallback for live updates

The build script runs automatically via Forgejo CI/CD on every push, ensuring the deployed site always has fresh repo data. Runtime polling attempts live updates; on CORS failure it silently keeps the build-time data.


Getting Started

# Install dependencies
npm install

# Development server (hot reload)
npm run dev

# Production build (includes Forgejo data fetch)
npm run build

# Preview production build
npm run preview

Deployment

The site is deployed at khoavo.myds.me via Forgejo CI/CD on every push to main. The pipeline:

  1. Runs npm run build (triggers Forgejo data fetch)
  2. Deploys the dist/ directory to the web server

Configuration

File Purpose
tailwind.config.js Custom colors (#00FF94, dark mode), fonts
vite.config.js React plugin, base path
postcss.config.js Tailwind + Autoprefixer pipeline

License

MIT — Vo Nguyen Dang Khoa