# Technical Kiwi Limited — Website A small business site built with **Go**, [**templ**](https://templ.guide/) (server-side HTML templates), and [**HTMX**](https://htmx.org/) for gallery interactions. ## Requirements - [Docker](https://docs.docker.com/get-docker/) and Docker Compose ## Quick start ```bash cp .env.example .env # optional SMTP settings make dev # live reload → http://localhost:7331 ``` ## Make targets | Target | Description | |--------|-------------| | `make dev` | Dev with Air + templ browser live reload (default) | | `make build` | Build production `website` image | | `make up` | Run production `website` service | | `make down` | Stop compose services | | `make generate` | Run `templ generate` in dev container | | `make tidy` | Run `go mod tidy` in dev container | | `make logs` | Follow dev container logs | ## Features - Single-page layout: hero, services, gallery, contact - Gallery loads via HTMX (`hx-get="/gallery"`) - Year filters without full page reload - Lightbox modal with previous/next navigation - Contact form with SMTP relay (HTMX submit, no page reload) - Serves photos from `app/images/` ## Contact form (SMTP) Set relay details in `.env`: | Variable | Description | |----------|-------------| | `SMTP_HOST` | Relay hostname (required) | | `SMTP_PORT` | Port (default `587`) | | `SMTP_USER` / `SMTP_PASSWORD` | Auth if your relay requires it | | `SMTP_FROM` | Envelope/header From address (required) | | `SMTP_TO` | Where contact messages are delivered (required) | | `SMTP_TLS` | `auto`, `tls` (465), or `plain` (25/local relay) | If SMTP is not configured, the page shows a mailto fallback instead of the form. ## Dev container `make dev` mounts `./app` and your host Go caches (`~/go/pkg/mod`, `~/.cache/go-build` by default). Override with `GOMODCACHE` / `GOCACHE` in `.env`. **Use [http://localhost:7331](http://localhost:7331)** in the browser — the templ proxy injects live reload on `.templ`, `.go`, and `.css` changes. Port 8080 hits the app directly without auto-reload. Only run **`dev`** or **`website`** at a time if you map both to the same host ports. Production `website` joins the external `caddy` Docker network for reverse proxy labels. ## Project layout ``` app/ cmd/server/ HTTP server entrypoint internal/gallery/ Scan and sort images from disk internal/contact/ Form validation internal/mail/ SMTP relay internal/handlers/ Routes and HTMX partials templates/ templ components (.templ → generated Go) static/ CSS images/ Gallery photos (served at /images/) Dockerfile Production image Dockerfile.dev Dev image (Go + templ + Air) docker-compose.yaml .env.example ``` ## Gallery images On startup the server builds JPEG thumbnails in `app/images/thumbs/` (max 480px edge) for the grid and hero. The lightbox still loads full-resolution originals. Thumbnails are gitignored and regenerated when source photos change. ## Deploy notes First request after deploy may take a moment while thumbnails are generated if they are not baked into the image yet.