# bztmon-site The source for **[www.bztmon.com](https://www.bztmon.com)** — Jonathon Wright's portfolio / résumé site. A fast, animated, security-hardened static site for a platform / infrastructure engineer. > This repo is **public**. It lives on a self-hosted public Gitea (`git.bztmon.com`), > isolated from the private homelab GitOps. **Never commit secrets** — the static > site needs none. ## Stack - **Astro** (static output) + **TypeScript** + **Tailwind v4** - Zero JS by default; tiny islands for the theme toggle + scroll reveals - Content & config are data-driven (`src/data/`) — adding a project never touches a component ## Develop ```bash npm install npm run dev # http://localhost:4321 npm run check # astro check (types + diagnostics) npm run build # static build → dist/ npm run preview # serve the build locally npm run gen:og # regenerate the social-preview image (public/og.png) ``` ## Project layout ``` src/ data/ site.ts, socials.ts, skills.ts, projects.ts, experience.ts components/ Hero, Nav, ThemeToggle, ProjectCard, SkillGroup, ... layouts/ Layout.astro (SEO/OG, theme bootstrap) pages/ index.astro, projects/, 404.astro styles/ tokens.css (theme), global.css lib/ build-time helpers (cv detection) scripts/ gen-og.mjs, build-image.sh nginx/ default.conf (security headers, caching) baked into the image Dockerfile Debian build stage → nginx-unprivileged runtime ``` ## Content TODOs (Jonathon) - Drop a real CV at `public/cv.pdf` — the **Download CV** button appears automatically. - Fill the `TODO(Jonathon)` markers in `src/data/experience.ts`, `projects.ts`, `socials.ts` (employer names, dates, GitHub/LinkedIn handles). ## Deploy Built into a container image, served by nginx-unprivileged on a homelab Kubernetes cluster, exposed via Cloudflare Tunnel. The image is pinned by digest in the private `home-ops` repo and rolled out by ArgoCD. See `scripts/build-image.sh`.