- TypeScript 75.5%
- Just 11.9%
- CSS 9.4%
- Dockerfile 2.5%
- JavaScript 0.7%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
The heading read "Selected projects" while every entry is a side project, so name the section for what it holds. Re-render public/resume.pdf from the updated copy. |
||
| .forgejo/workflows | ||
| public | ||
| src | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| AGENTS.md | ||
| CLAUDE.md | ||
| Dockerfile | ||
| eslint.config.mjs | ||
| justfile | ||
| next.config.ts | ||
| package.json | ||
| pnpm-lock.yaml | ||
| pnpm-workspace.yaml | ||
| postcss.config.mjs | ||
| README.md | ||
| SPECS.md | ||
| tsconfig.json | ||
Portfolio homepage
Single-page portfolio for a software engineer / tech lead. Next.js App Router, TypeScript, Tailwind CSS v4, Motion for the scroll-driven sections, deployed as a Docker container.
Quick start
just install
just dev # http://localhost:3000
just with no arguments lists every task.
Editing content
All copy lives in typed data files under src/content/ — nothing is fetched at
runtime, so a content change is "edit one file, redeploy":
| File | What it holds |
|---|---|
src/content/site.ts |
Name, title, tagline, bio, email, SEO defaults |
src/content/experience.ts |
Reverse-chronological roles |
src/content/projects.ts |
Curated project cards |
src/content/interests.ts |
Off-the-clock interests |
src/content/stack.ts |
Tech-stack groups shown in About |
src/content/socials.ts |
Social links |
Everything currently in those files is placeholder content. A dev-only badge
sits at the bottom of the page until site.isPlaceholderContent is set to
false. public/resume.pdf is a placeholder too.
Configuration
NEXT_PUBLIC_SITE_URL is read at build time for canonical URLs, the
sitemap, and Open Graph tags — see .env.example. Pass it as a Docker build
arg, not a runtime env var.
Docker
NEXT_PUBLIC_SITE_URL=https://your-domain.com just docker-build
just docker-run # foreground, Ctrl-C to stop
just docker-up # detached, waits for the healthcheck
just docker-logs # tail it
just docker-down # stop and remove it
The image uses Next's standalone output, runs as a non-root user, and exposes port 3000. Reverse proxy, domain, and TLS are handled outside this repo.
Checks
just check # build, then typecheck and lint
just typecheck needs a build first: Next generates the route types that tsc
reads.
Notes
- Theme: dark by default, honours
prefers-color-schemeon a first visit, toggled from the header. The theme class is written by a blocking inline script, so there is no flash and no layout shift. - Motion: all animation is disabled under
prefers-reduced-motion.