Personal site for Amir Ranjbar — a bold, dark, motion-led single-page scroller. Built with Vite + React 18 + TypeScript, Tailwind CSS v4 and Framer Motion. See PRD.md for the full product spec.
nvm use # Node 20 (see .nvmrc)
npm install
npm run dev # http://localhost:5173
npm run build # type-check + production build -> dist/
npm run preview # serve the production build locallyThe hero references public/amir.jpg (a treated duotone portrait). A clearly
labelled placeholder is committed so the build works out of the box. To use the
real photo:
-
Drop the source image in the repo root as
amir.jpg. -
Run the optimizer (writes an optimized 4:5 WebP to
public/amir.jpg):python scripts/optimize-portrait.py amir.jpg
- Portrait — replace the placeholder
public/amir.jpg(see above). - GitHub repo count —
GITHUB_REPO_COUNTinsrc/lib/site.ts(currently 56). - OG image —
public/og.pngis an auto-generated typographic placeholder.
src/
components/ one file per section + shared MagneticButton / ScrollProgress
lib/
motion.ts shared Framer Motion variants + reduced-motion sets
site.ts links, email, skill groups, repo count (single source)
index.css Tailwind v4 + design tokens (@theme)
public/ favicon.svg, og.png, amir.jpg
scripts/ optimize-portrait.py
Deploys run via GitHub Actions (.github/workflows/deploy.yml):
- Push to
main→ production deploy. - Open a PR against
main→ unique preview URL.
The workflow installs deps, runs npm run build (output dist/), ensures the
Pages project exists on first run, then deploys with wrangler to the
ranjbar-dev Pages project.
-
Create a Cloudflare API token — dash → My Profile → API Tokens → Create Token → use the "Edit Cloudflare Workers" template (or a custom token with the Account › Cloudflare Pages › Edit permission).
-
Find your Account ID — Cloudflare dashboard → Workers & Pages (right sidebar / URL).
-
Add repo secrets — GitHub repo → Settings → Secrets and variables → Actions → New repository secret:
Secret Value CLOUDFLARE_API_TOKENthe API token from step 1 CLOUDFLARE_ACCOUNT_IDthe Account ID from step 2 (
GITHUB_TOKENis provided automatically — no setup needed.) -
Push to
main. The first run creates theranjbar-devPages project and deploys it.
The Pages project name is
ranjbar-dev(Cloudflare names can't contain dots). If you already created a project under a different name, update the two--project-name/pages project createreferences in the workflow.
In the Pages project → Custom domains, add ranjbar.dev (and www.ranjbar.dev).
Cloudflare manages DNS and SSL automatically.
Note: if you previously enabled Cloudflare's built-in Git integration for this repo, disable it so it doesn't deploy in parallel with this workflow.