This is a single-page portfolio site built with React and Vite. It is designed as a content-driven personal site rather than a CMS-backed app: profile details, experience, education, links, and featured work are maintained directly in the source code.
The site combines a structured portfolio layout with a Three.js globe hero, grouped experience cards, and a light/dark theme that follows the user's device or browser preference.
- React 18 for the UI and section composition
- Vite for local development and production builds
- Three.js for the hero globe
- GSAP for globe motion
- Plain CSS for layout, theming, and responsive behavior
- React Context for portfolio content and profile data
src/main.jsxmounts the React appsrc/App.jsxcomposes the page sections and applies reveal-on-scroll behaviorsrc/context/DataContext.jsxstores the portfolio content modelsrc/components/sections/contains the main page sections:NavbarHomeAboutWorkCredentialsFooter
src/components/ThreeEarth.jsxrenders the globe used in the heropublic/contains static assets such as logos, favicon, social icons, and profile imagery
The site content is driven from src/context/DataContext.jsx.
This includes:
- profile headline, summaries, links, and hero highlights
- grouped work experience entries and company metadata
- certifications and education
- featured public links
- skill tags and focus areas
If you want to update role history, hero text, public links, or company logos, that is the main file to change.
src/index.cssdefines the global design tokens and the light/dark theme variables- the site uses
prefers-color-schemeto switch automatically between light and dark mode src/App.cssprovides the shared shell, card, button, pill, and reveal styles- each section has its own CSS file for layout-specific styling
The current visual direction uses:
- a cool-toned grid background
- glass-like cards with soft borders and shadows
- a restrained defense-tech inspired palette
- responsive layouts for desktop and mobile
The hero section lazy-loads ThreeEarth so the main page content does not depend on the rendering bundle loading first.
The globe implementation uses:
- Three.js scene/camera/renderer setup
- GSAP-based rotation animation
- a separate rendering chunk configured in
vite.config.js
Install dependencies:
npm installStart the local dev server:
npm run devCreate a production build:
npm run buildPreview the production build locally:
npm run previewvite.config.js uses:
@vitejs/plugin-reactfor React supportvite-plugin-stringfor loading shader strings- manual chunking so
threeandgsapare split into a dedicatedrenderingbundle
This keeps the main app bundle smaller and isolates the heavier visual code.
- update portfolio content in
src/context/DataContext.jsx - update section layout/styling in the matching file under
src/components/sections/ - update global theme behavior in
src/index.cssandsrc/App.css - update static assets such as logos and favicon in
public/
- single-page portfolio experience
- sticky top navigation with section jump links
- grouped company experience cards
- responsive first-fold hero with globe backdrop
- public-facing links to LinkedIn, GitHub, and selected work
- system-based light and dark mode