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{{define "base.html"}}<!doctype html>
2<html lang="en">
3<head>
4<meta charset="utf-8">
5<meta name="viewport" content="width=device-width, initial-scale=1">
6<meta name="color-scheme" content="dark">
7<meta name="theme-color" content="#0d0b09">
8{{/*
9 The market leads, so a tab left open in another window still says what it is
10 doing. live.js rewrites this on every frame and reads the base off the body,
11 rather than keeping its own copy of the wording.
12*/}}
13<title>{{if .Title}}{{.Title}} · {{end}}{{if .State.Market.Ticker}}{{.State.Market.Ticker}} · {{end}}{{.TitleBase}}</title>
14{{if .Description}}<meta name="description" content="{{.Description}}">{{end}}
15{{if .Staging}}<meta name="robots" content="noindex, nofollow">{{end}}
16<link rel="canonical" href="{{.Canonical}}">
17<link rel="icon" href="{{.Favicon}}" type="image/svg+xml">
18{{range .Styles}}<link rel="stylesheet" href="{{.}}">{{end}}
19{{- if .Analytics}}
20<script>
21 (function (m, e, t, r, i, c, s) {
22 m.collectorQueue = m.collectorQueue || r;
23 m.collectorServer = c;
24 m.collectorId = s;
25 m.collectorScript = e.createElement(t);
26 m.collectorScript.src = c + i;
27 e.head.appendChild(m.collectorScript);
28 })(window, document, "script", [], "/static/collector.js",
29 "https://analytics.bythewood.me", "{{.AnalyticsID}}");
30</script>
31{{- end}}
32</head>
33<body data-title-base="{{.TitleBase}}">
34
35{{/*
36 The CRT layer. Two fixed overlays that never take a pointer event: scanlines
37 and grain, then a vignette. All three are drawn in CSS rather than loaded as
38 images, so they cost no request and scale to any viewport.
39*/}}
40<div class="crt" aria-hidden="true"></div>
41<div class="vignette" aria-hidden="true"></div>
42
43<header class="rail">
44 <div class="rail-brand">
45 <span class="mark">◤</span>
46 <span class="wordmark">DASH</span>
47 <span class="rail-sub">BYTHEWOOD / ORCHARD</span>
48 </div>
49
50 <div class="rail-readouts">
51 <div class="readout" data-readout="utc">
52 <span class="readout-key">UTC</span>
53 <span class="readout-val" data-clock-utc>--:--:--</span>
54 </div>
55 <div class="readout" data-readout="local">
56 <span class="readout-key" data-clock-zone>LOCAL</span>
57 <span class="readout-val" data-clock-local>--:--:--</span>
58 </div>
59 <div class="readout" data-readout="date">
60 <span class="readout-key">DATE</span>
61 <span class="readout-val" data-clock-date>----</span>
62 </div>
63 <div class="readout link" data-live data-state="connecting">
64 <span class="readout-key">LINK</span>
65 <span class="readout-val"><span class="pip"></span><span data-live-label>INIT</span></span>
66 </div>
67 </div>
68</header>
69
70<main>
71{{template "content" .}}
72</main>
73
74<footer class="statusline">
75 <span class="seg srcs">SRC {{range $i, $s := .Sources}}{{if $i}}<i>·</i>{{end}}{{$s}}{{end}}</span>
76 <span class="seg" data-guard-line></span>
77 <span class="seg grow"></span>
78 <span class="seg"><a href="{{.SourceURL}}" rel="noopener noreferrer" target="_blank">SOURCE</a></span>
79 <span class="seg">© {{.Year}} {{.AuthorName}}</span>
80</footer>
81
82{{if .Script}}<script type="module" src="{{.Script}}"></script>{{end}}
83</body>
84</html>
85{{end}}