Amr Elshabrawy
Elshabrawy
HomeAboutServicesWorkContact
Download CV
Amr Elshabrawy
Elshabrawy

Β© 2026 Amr Elshabrawy. All rights reserved.

Amrelshabrawydev.github.io

Amrelshabrawydev.github.io

No description available.

View Code
0 stars
0 forks
Created Feb 18, 2026
16.7 MB

Technologies

TypeScript

Languages

TypeScript90%
CSS9%
JavaScript0%

README

Amr Elshabrawy Logo

Amr Elshabrawy β€” Portfolio

A modern, high-performance developer portfolio built with Next.js 16, React 19 & Tailwind CSS v4

Live Demo Next.js React TypeScript Tailwind CSS


πŸ“– Table of Contents

  • Overview
  • Live Demo
  • Tech Stack & Why
  • Project Structure
  • How It Works
  • Data Fetching Strategy
  • Styling & Design System
  • Components Architecture
  • SEO & Performance
  • Deployment
  • Getting Started
  • Environment Variables
  • Scripts
  • License

🌟 Overview

A fully static, blazing-fast developer portfolio that automatically syncs with GitHub to showcase projects. No CMS, no database β€” just push to GitHub and your portfolio updates itself on the next build.

✨ Key Features

FeatureDescription
Auto-Synced ProjectsFetches all repositories from GitHub API at build time β€” no manual data entry
Dynamic Project PagesEach repo gets its own detail page with full README rendering
Contact FormFunctional email form powered by EmailJS β€” no backend needed
Responsive DesignPixel-perfect on every device, from 320px to 4K
Dark Cosmic ThemeCustom dark theme with glassmorphism, gradients, and glow effects
Smooth AnimationsPage transitions, scroll-triggered reveals, and micro-interactions
Full SEOStructured data (JSON-LD), Open Graph, Twitter Cards, sitemap, robots.txt
Static ExportPre-rendered to pure HTML/CSS/JS β€” deploys anywhere

πŸ”— Live Demo

πŸ‘‰ amrelshabrawydev.github.io


πŸ› οΈ Tech Stack & Why

Core Framework

TechnologyVersionWhy We Use It
Next.js16.0.10App Router, static export (output: "export"), file-based routing, built-in image optimization, and Turbopack for fast builds
React19.2.0Latest concurrent features, server components, improved performance with automatic batching
TypeScript5.xType safety across the entire codebase β€” catches bugs at compile time, improves DX with autocomplete

Styling

TechnologyWhy We Use It
Tailwind CSS v4Utility-first CSS with the new @theme directive for design tokens. Zero runtime CSS β€” everything is compiled at build time
tailwind-mergeIntelligently merges conflicting Tailwind classes (e.g., px-4 + px-6 β†’ px-6)
class-variance-authorityType-safe component variant APIs (used by shadcn/ui Button, Badge, etc.)
clsxConditional class name composition β€” cleaner than template literals

UI Components

TechnologyWhy We Use It
shadcn/uiPre-built, accessible, customizable components (Button, Card, Tabs, Dialog, Tooltip, Badge, Input, Textarea). Not a dependency β€” components are copied into components/ui/ for full control
Radix UIHeadless, accessible primitives that power shadcn/ui (Dialog, Tabs, Tooltip, Slot)
Lucide ReactBeautiful, consistent SVG icon set with tree-shaking β€” only imports icons we use
Framer MotionDeclarative animations: page transitions, scroll-triggered reveals, layout animations, and hover micro-interactions

Data & Communication

TechnologyWhy We Use It
GitHub REST API v3Fetches all public repositories, language stats, and README content at build time
EmailJSSends contact form emails directly from the browser β€” no backend, no server functions needed for static export

Markdown Rendering

TechnologyWhy We Use It
react-markdownRenders GitHub README files as React components
remark-gfmGitHub Flavored Markdown support (tables, strikethrough, task lists, autolinks)
rehype-rawAllows raw HTML in markdown (for badges, images, etc.)
rehype-sanitizeSanitizes HTML to prevent XSS attacks
react-syntax-highlighterSyntax highlighting for code blocks inside READMEs

DevOps & Deployment

TechnologyWhy We Use It
gh-pagesPublishes the out/ directory to the gh-pages branch with one command
GitHub PagesFree, reliable static hosting with HTTPS and custom domain support
ESLintCode quality and consistency enforcement
pnpmFast, disk-efficient package manager

πŸ“ Project Structure

amrelshabrawydev/
β”œβ”€β”€ app/                          # Next.js App Router
β”‚   β”œβ”€β”€ layout.tsx                # Root layout (fonts, metadata, navbar, footer)
β”‚   β”œβ”€β”€ page.tsx                  # Home page β†’ HeroSection
β”‚   β”œβ”€β”€ globals.css               # Design system (theme tokens, utilities, animations)
β”‚   β”œβ”€β”€ robots.ts                 # Dynamic robots.txt generation
β”‚   β”œβ”€β”€ sitemap.ts                # Dynamic sitemap.xml generation
β”‚   β”œβ”€β”€ about/page.tsx            # About page β†’ AboutSection
β”‚   β”œβ”€β”€ services/page.tsx         # Services page β†’ ServicesSection
β”‚   β”œβ”€β”€ work/
β”‚   β”‚   β”œβ”€β”€ page.tsx              # Work page β†’ GitHubProjectsSection
β”‚   β”‚   └── [slug]/page.tsx       # Dynamic project detail pages
β”‚   β”œβ”€β”€ contact/page.tsx          # Contact page β†’ ContactSection
β”‚   └── api/
β”‚       └── github-projects/route.ts  # API route for client-side project fetching
β”‚
β”œβ”€β”€ components/
β”‚   β”œβ”€β”€ Layout/
β”‚   β”‚   β”œβ”€β”€ Footer.tsx            # Site footer with social links
β”‚   β”‚   └── PageTransition.tsx    # Framer Motion animation variants
β”‚   β”œβ”€β”€ Navigation/
β”‚   β”‚   └── Navbar.tsx            # Responsive navbar with mobile menu
β”‚   β”œβ”€β”€ Sections/
β”‚   β”‚   β”œβ”€β”€ HeroSection.tsx       # Hero with typewriter animation
β”‚   β”‚   β”œβ”€β”€ AboutSection.tsx      # Skills, experience, and bio
β”‚   β”‚   β”œβ”€β”€ ServicesSection.tsx   # Services offered
β”‚   β”‚   β”œβ”€β”€ ContactSection.tsx    # EmailJS-powered contact form
β”‚   β”‚   β”œβ”€β”€ GitHubProjectsSection.tsx  # Project grid (client-side fetch)
β”‚   β”‚   └── GitHubProjects/
β”‚   β”‚       β”œβ”€β”€ ProjectCard.tsx   # Individual project card
β”‚   β”‚       └── ProjectSkeleton.tsx  # Loading skeleton
β”‚   └── ui/                       # shadcn/ui components
β”‚       β”œβ”€β”€ button.tsx, badge.tsx, card.tsx, dialog.tsx
β”‚       β”œβ”€β”€ input.tsx, textarea.tsx, tabs.tsx, tooltip.tsx
β”‚       β”œβ”€β”€ glass-card.tsx        # Custom glassmorphic card
β”‚       β”œβ”€β”€ markdown-components.tsx  # Custom markdown renderers
β”‚       └── type-animation.tsx    # Typewriter effect component
β”‚
β”œβ”€β”€ lib/
β”‚   β”œβ”€β”€ github.ts                 # GitHub API service (fetch repos, READMEs)
β”‚   β”œβ”€β”€ metadata.ts               # Centralized SEO metadata & JSON-LD schemas
β”‚   └── utils.ts                  # Utilities (cn, formatDate, generateSlug)
β”‚
β”œβ”€β”€ data/
β”‚   └── index.tsx                 # Static data (personal info, skills, services, social links)
β”‚
β”œβ”€β”€ types/
β”‚   └── github.ts                 # TypeScript interfaces (Project, Language)
β”‚
β”œβ”€β”€ public/                       # Static assets
β”‚   β”œβ”€β”€ .nojekyll                 # Tells GitHub Pages to serve _next/ directory
β”‚   β”œβ”€β”€ logo.svg, profile.png     # Branding
β”‚   β”œβ”€β”€ og-*.png, twitter-card.png  # Social sharing images
β”‚   β”œβ”€β”€ favicon.*, apple-touch-icon.png  # Favicons
β”‚   └── site.webmanifest          # PWA manifest
β”‚
β”œβ”€β”€ next.config.ts                # Next.js config (static export, image patterns)
β”œβ”€β”€ tsconfig.json                 # TypeScript strict configuration
β”œβ”€β”€ postcss.config.mjs            # PostCSS with Tailwind plugin
β”œβ”€β”€ eslint.config.mjs             # ESLint configuration
└── package.json                  # Dependencies & scripts

βš™οΈ How It Works

Build Pipeline

graph LR
    A[pnpm build] --> B[Next.js Turbopack]
    B --> C[Fetch GitHub API]
    C --> D[Generate Static Pages]
    D --> E[out/ directory]
    E --> F[gh-pages deploys to GitHub Pages]
  1. pnpm build triggers Next.js static export (output: "export")
  2. Turbopack compiles TypeScript and bundles assets
  3. generateStaticParams() in app/work/[slug]/page.tsx calls getAllProjects() which fetches all repos from GitHub API
  4. Each repo gets its own static HTML page at /work/{slug}
  5. Output is a fully static out/ directory (HTML, CSS, JS, images)
  6. pnpm run deploy pushes out/ to the gh-pages branch via gh-pages --nojekyll

Runtime Behavior

  • Project listing page (/work): Fetches projects client-side via /api/github-projects route for fresh data
  • Project detail pages (/work/[slug]): Pre-rendered at build time with full README content
  • Contact form: Sends emails client-side via EmailJS SDK β€” no server roundtrip
  • Navigation: Client-side routing via Next.js App Router with Framer Motion page transitions

πŸ”„ Data Fetching Strategy

1. GitHub Projects (Build-Time + Client-Side Hybrid)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    lib/github.ts                            β”‚
β”‚                                                             β”‚
β”‚  fetchWithToken(url)                                        β”‚
β”‚  β”œβ”€β”€ Adds Bearer token if GITHUB_TOKEN is set               β”‚
β”‚  β”œβ”€β”€ Uses next: { revalidate: 3600 } (1-hour cache)         β”‚
β”‚  └── Handles rate limiting gracefully                       β”‚
β”‚                                                             β”‚
β”‚  getAllProjects()                                           β”‚
β”‚  β”œβ”€β”€ GET /users/{username}/repos?sort=updated&per_page=100  β”‚
β”‚  β”œβ”€β”€ Filters out forked repos                               β”‚
β”‚  β”œβ”€β”€ Fetches language stats per repo                        β”‚
β”‚  β”œβ”€β”€ Generates OG image URL from GitHub                     β”‚
β”‚  └── Returns Project[] with title, description, etc.        β”‚
β”‚                                                             β”‚
β”‚  getProjectReadme(fullName, branch)                         β”‚
β”‚  β”œβ”€β”€ GET /repos/{fullName}/readme?ref={branch}              β”‚
β”‚  β”œβ”€β”€ Decodes Base64 content                                 β”‚
β”‚  └── Extracts preview text for meta descriptions            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Why hybrid?

  • Build time (generateStaticParams): Pre-renders all project detail pages with README content for instant loading and SEO
  • Client side (GitHubProjectsSection): Fetches fresh project data on the /work page so visitors always see the latest repos without rebuilding

2. Contact Form (Client-Side via EmailJS)

User submits form β†’ EmailJS SDK β†’ EmailJS Service β†’ Your Gmail inbox
  • No backend required β€” perfect for static deployment
  • Template variables: {{from_name}}, {{from_email}}, {{message}}
  • Success/error states with loading spinner

3. Static Data (data/index.tsx)

All personal info, skills, services, and social links are defined as typed constants:

export const personalInfo: PersonalInfo = { name, role, tagline, ... }
export const skills: Skill[] = [...]
export const services: Service[] = [...]
export const socialLinks: SocialLink[] = [...]

Why? Single source of truth. Change your bio in one file β†’ every page updates.


🎨 Styling & Design System

Theme Architecture

The design system is defined in app/globals.css using Tailwind CSS v4's @theme directive:

@theme {
  /* Background Layers */
  --color-bg-base: #0a0e27; /* Deep dark blue */
  --color-bg-elevated: #111827; /* Cards, footer */
  --color-bg-overlay: #1f2937; /* Modals, popovers */

  /* Brand Colors */
  --color-primary-500: #3b82f6; /* Blue β€” CTAs, links */
  --color-accent-500: #8b5cf6; /* Purple β€” gradients, highlights */

  /* Text Hierarchy */
  --color-text-primary: #e0e7ff; /* Headings */
  --color-text-secondary: #94a3b8; /* Body text */
  --color-text-tertiary: #64748b; /* Captions */
}

Visual Effects

EffectImplementation
Glassmorphism.glass-card β€” rgba background + backdrop-filter: blur(12px)
Gradient Text.gradient-text — background-clip: text with primary→accent gradient
Glow Effects.glow-subtle/medium/strong β€” Layered box-shadow with brand colors
Grid Pattern.bg-grid-pattern β€” CSS linear-gradient creating a subtle grid
Mesh Gradient--gradient-mesh β€” Multiple radial-gradient layers for depth
Float Animation@keyframes float β€” Gentle Y-axis oscillation on the hero image

Typography

  • Headings: Space Grotesk β€” Geometric, modern feel
  • Body: Inter β€” Highly legible at all sizes
  • Loaded via next/font/google for zero layout shift (FOUT-free)

🧩 Components Architecture

Page Sections

graph TD
    A[Layout - layout.tsx] --> B[Navbar]
    A --> C[Page Content]
    A --> D[Footer]

    C --> E[HeroSection]
    C --> F[AboutSection]
    C --> G[ServicesSection]
    C --> H[GitHubProjectsSection]
    C --> I[ContactSection]
    C --> J["ProjectDetail [slug]"]

    H --> K[ProjectCard]
    H --> L[ProjectSkeleton]
    J --> M[ReactMarkdown + remark-gfm]

UI Component Library (shadcn/ui)

All components live in components/ui/ β€” they are not installed as dependencies but copied directly for full customization:

ComponentPurpose
ButtonPrimary CTAs with variants (default, outline, ghost) via CVA
CardContent containers with header/content/footer slots
BadgeTechnology tags, status indicators
DialogModal overlays (accessible, focus-trapped)
TabsContent tabbing (e.g., skills categories)
TooltipHover information overlays
Input / TextareaForm fields with consistent styling
GlassCardCustom glassmorphic card with hover effects
TypeAnimationTypewriter effect for hero section role titles
MarkdownComponentsCustom renderers for README code blocks, images, links

πŸ” SEO & Performance

SEO Features

  • Metadata in lib/metadata.ts: Centralized Open Graph, Twitter Card, and description for every page
  • JSON-LD Structured Data: Person, ProfessionalService, and ItemList schemas
  • Dynamic Sitemap (app/sitemap.ts): Auto-generated with all routes
  • Dynamic Robots (app/robots.ts): Proper crawl directives
  • Canonical URLs: Prevent duplicate content
  • Semantic HTML: Proper heading hierarchy, landmarks, and ARIA labels

Performance

  • Static Export: Zero server overhead β€” served directly from CDN
  • Turbopack: Up to 10x faster builds than Webpack
  • Image Optimization: next/image with unoptimized: true for static export (images served as-is)
  • Font Optimization: next/font/google with display: swap and preloading
  • Code Splitting: Automatic per-route JavaScript bundles
  • Tree Shaking: Only imported icons/components are bundled

πŸš€ Deployment

GitHub Pages (Current Setup)

The project deploys to GitHub Pages via the gh-pages package:

# Build + Deploy (runs predeploy β†’ build automatically)
pnpm run deploy

This command:

  1. Runs next build β†’ generates out/ directory
  2. Pushes out/ to the gh-pages branch with --nojekyll flag
  3. GitHub Pages serves the static files from that branch

Important Notes

  • .nojekyll file in public/ tells GitHub Pages to serve the _next/ directory (which starts with an underscore and would normally be ignored by Jekyll)
  • output: "export" in next.config.ts enables fully static HTML generation
  • images.unoptimized: true is required because GitHub Pages doesn't support Next.js image optimization API
  • generateStaticParams() in app/work/[slug]/page.tsx pre-renders all project detail pages

🏁 Getting Started

Prerequisites

  • Node.js β‰₯ 18
  • pnpm (recommended) or npm

Installation

# Clone the repository
git clone https://github.com/AmrElshabrawyDev/amrelshabrawydev.github.io.git
cd amrelshabrawydev.github.io

# Install dependencies
pnpm install

# Set up environment variables
cp .env.example .env.local
# Edit .env.local with your values (see below)

# Start development server
pnpm dev

Open http://localhost:3000 in your browser.


πŸ” Environment Variables

Create a .env.local file in the project root:

# GitHub API
GITHUB_USERNAME=YourGitHubUsername
GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxx   # Optional: increases API rate limit from 60 to 5000 req/hr

# EmailJS (for contact form)
NEXT_PUBLIC_EMAILJS_SERVICE_ID=service_xxxxxxx
NEXT_PUBLIC_EMAILJS_TEMPLATE_ID=template_xxxxxxx
NEXT_PUBLIC_EMAILJS_PUBLIC_KEY=xxxxxxxxxxxxxxx
VariableRequiredDescription
GITHUB_USERNAMEβœ…Your GitHub username for fetching repositories
GITHUB_TOKEN❌Personal access token β€” raises rate limit from 60 to 5,000 requests/hour
NEXT_PUBLIC_EMAILJS_SERVICE_IDβœ…EmailJS service ID (get from emailjs.com)
NEXT_PUBLIC_EMAILJS_TEMPLATE_IDβœ…EmailJS email template ID
NEXT_PUBLIC_EMAILJS_PUBLIC_KEYβœ…EmailJS public key for browser-side sends

πŸ“œ Scripts

ScriptCommandDescription
devpnpm devStart development server with Turbopack HMR
buildpnpm buildCreate optimized static production build in out/
startpnpm startStart production server (for testing, not used with static export)
lintpnpm lintRun ESLint for code quality checks
deploypnpm run deployBuild + push to gh-pages branch

πŸ“„ License

This project is open source and available under the MIT License.


Built with ❀️ by Amr Elshabrawy