# jasonwoltje.com — Professional Website

Personal brand + portfolio site for Jason Woltje. Payload CMS 3 on Next.js 16, Postgres 17, deployed to Docker Swarm (`w-docker0`) behind Traefik.

## Stack

| Layer | Choice |
|---|---|
| Framework | Next.js 16 (App Router) |
| CMS | Payload 3 (Next-integrated, admin at `/admin`) |
| DB | PostgreSQL 17 |
| Styling | Tailwind v3 (ported from stitch design tokens) |
| Fonts | Space Grotesk (display/labels) + Inter (body), self-hosted via `next/font` |
| Media | Local volume (migratable to S3/MinIO via Payload adapter) |
| Analytics | Umami (self-hosted) |
| CAPTCHA | Cloudflare Turnstile |
| Registry | `git.mosaicstack.dev` container packages (immutable `sha-*` tags) |
| CI | Woodpecker CI + Kaniko |
| Deploy | Portainer stack on `w-docker0` (Swarm) |
| Ingress | Edge Traefik (TLS) → per-swarm Traefik (`entrypoints=web`) |

## Repository layout

```
professional-website/
├── src/                     # Next.js app + Payload config
├── public/                  # static assets
├── design-samples/          # stitch design reference (HTML + DESIGN.md)
├── images/                  # source headshots (pre-upload originals)
├── docs/
│   ├── PRD.md               # product requirements
│   ├── TASKS.md             # execution tracking
│   └── scratchpads/         # per-task working notes
├── Dockerfile               # multi-stage build
├── docker-compose.swarm.yml # Portainer stack (prod)
├── .woodpecker/web.yml      # CI pipeline
└── .env.example
```

## Local dev

```bash
pnpm install
cp .env.example .env        # fill in local values
pnpm dev                    # Next + Payload on http://localhost:3000
```

Payload admin: http://localhost:3000/admin

## Documentation

- [`docs/PRD.md`](docs/PRD.md) — product requirements, scope, architecture decisions
- [`docs/TASKS.md`](docs/TASKS.md) — milestone + task tracking
- [`design-samples/stitch_jasonwoltje.com/silicon_ethos/DESIGN.md`](design-samples/stitch_jasonwoltje.com/silicon_ethos/DESIGN.md) — design system reference

## Deployment

Container images are built by Woodpecker and pushed to `git.mosaicstack.dev/jason.woltje/professional-website:sha-<short>`. The Portainer stack references immutable tags — `latest` is never used as a deploy reference.

See `docs/PRD.md` §Infrastructure for the full deploy runbook.
