# cameleer-website

Marketing site for [cameleer.io](https://www.cameleer.io) — zero-code observability for Apache Camel.

This is a **static** Astro 5 site. Hosted on Hetzner Webhosting L, fronted by Cloudflare, deployed via Gitea Actions.

## Development

```bash
npm ci
npm run dev       # http://localhost:4321
npm run test      # vitest — auth config + middleware header tests
npm run build     # produces dist/
npm run preview   # serves dist/
```

## Quality gates (run in CI)

```bash
npm run lint:html     # html-validate on dist/
npm run lint:links    # linkinator on dist/
npm run lh            # Lighthouse CI (>=0.95 on all 4 categories)
```

## Environment variables

See `.env.example`. All are `PUBLIC_*` (build-time, embedded in HTML).

| Var | Purpose |
|-----|---------|
| `PUBLIC_AUTH_SIGNIN_URL` | Logto sign-in URL (redirected to by "Sign in" buttons) |
| `PUBLIC_AUTH_SIGNUP_URL` | Logto sign-up URL (redirected to by "Start free trial") |
| `PUBLIC_SALES_EMAIL` | Sales email (`mailto:` target for "Talk to sales") |

## Deployment

**Manual trigger only.** Merging to `main` does NOT auto-deploy. To ship: Gitea → **Actions → deploy → Run workflow** on `main`. The workflow runs tests, builds, then `rsync`s `dist/` to Hetzner over SSH (ed25519 key on port 222, host-key-pinned), and post-deploy curls the live site to verify security headers.

Rollback: trigger the deploy workflow on the previous `main` commit (Actions UI lets you pick a ref).

**Security headers** (HSTS, CSP, X-Frame-Options, etc.) are owned by **Cloudflare Transform Rules**, not by anything in this repo. Hetzner Webhosting L ignores file-based `.htaccess` (`AllowOverride None`), so origin-side header config is impossible from code. See `OPERATOR-CHECKLIST.md` §2.

See [`OPERATOR-CHECKLIST.md`](./OPERATOR-CHECKLIST.md) for the one-time Hetzner + Cloudflare setup.

## Design & plan

- `docs/superpowers/specs/2026-04-24-cameleer-website-design.md` — the approved spec.
- `docs/superpowers/plans/2026-04-24-cameleer-website.md` — the implementation plan that built this repo.
