orchard
mirrorEvery site I host, in one repo, along with the Cloudflare Tunnel and Caddy that front them. It's all Go, Vite, and SQLite, and it runs on a desktop at home with nothing listening on an inbound port.
blogbuncaddycloudflare-tunneldockergogolanghomelabhtml-templatemonorepoself-hostedseosqlitestatic-sitetypstuptime-monitoringviteweb-analytics
1{
2 "_comment": "Which image variants exist. Read by both images.go (embedded, for srcset) and frontend/scripts/images.js (for generation), so the widths that get written into the page and the widths that get generated cannot drift apart.",
3
4 "format": "avif",
5 "_formatNote": "AVIF over WebP after measuring these actual images: same size or smaller at matched accuracy, and AOMedia rather than Google. Support is Chrome 85+, Firefox 93+, Safari 16.4+, Edge 121+. JPEG was the other candidate and costs about 45% more bytes here.",
6
7 "hero": "005",
8 "cardWidths": [480, 960],
9 "lightboxWidth": 1600,
10 "heroWidth": 2400,
11
12 "quality": { "480": 65, "960": 65, "1600": 70, "2400": 40 },
13 "_qualityNote": "2400 is the hero and only the hero: images.js generates that width for spec.hero alone, and the home page is the only thing that requests it. It renders under .index-words, a full-viewport rgba(0,0,0,0.8) layer in mix-blend-mode darken, so it reaches the eye at roughly a fifth of its luminance and quality 40 is indistinguishable from 70 there while costing 240KB instead of 744KB. That also lifts the opening curtain sooner, since the curtain waits on this exact image. Do not extend the same reasoning to 1600: that width is the lightbox, where the art is shown full size with nothing over it, and fidelity is the entire point.",
14
15 "avatar": { "width": 120, "quality": 70 }
16}