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 "content" }}
2<div class="art-background"></div>
3
4<h1 class="art-heading">Acrylic Pours</h1>
5<p class="art-paragraph">
6 A bit more traditional than my usual art. Each piece starts as a mix of
7 acrylic paint, water, glue, and silicone oil poured onto canvas, then
8 manipulated with a heat gun to bring out cells and organic patterns. No two
9 pours come out the same and the process is as much about letting go of
10 control as it is about technique.
11</p>
12<div class="art-artGrid">
13 {{- range .Pours }}
14 <div
15 class="art-artItem"
16 data-lightbox="{{ .LightboxSrc }}"
17 data-lightbox-alt="{{ .Title }}"
18 >
19 <span class="art-cardImage">
20 <img
21 src="{{ .CardSrc }}"
22 srcset="{{ .CardSrcset }}"
23 {{/* Two columns above 768px inside the centre grid area, one below.
24 Roughly 30vw on a desktop, 40vw on a tablet, 80vw on a phone. */}}
25 sizes="(max-width: 767.98px) 80vw, (max-width: 1023.98px) 40vw, 30vw"
26 alt="{{ .Title }}"
27 width="960"
28 height="540"
29 class="mouse-activate"
30 {{ if .Priority }}fetchpriority="high"{{ else }}loading="lazy"{{ end }}
31 decoding="async"
32 />
33 </span>
34 <h2 class="art-artItemHeader">{{ .Title }} <span>{{ .Number }}</span></h2>
35 </div>
36 {{- end }}
37</div>
38
39<h1 class="art-heading">Emergent Generative Art</h1>
40<p class="art-paragraph">
41 Code as a creative medium. These pieces are built entirely in JavaScript on
42 HTML canvas, each one a small system of simple rules that produces complex,
43 unpredictable behavior. The art emerges from the interaction of autonomous
44 entities rather than being explicitly drawn.
45</p>
46
47{{- range .Generative }}
48<h2 class="art-subheading"><span>{{ .Number }}</span> {{ .Title }}</h2>
49<p class="art-paragraph">{{ .Description }}</p>
50<div class="art-artContainer">
51 <canvas class="canvas" data-art-canvas="{{ .Slug }}"></canvas>
52 <button
53 class="art-playButton"
54 type="button"
55 data-art-toggle="{{ .Slug }}"
56 data-active="false"
57 {{ if .Autoplay }}data-autoplay="true"{{ end }}
58 aria-label="Play or pause {{ .Title }}"
59 >▶</button>
60</div>
61<a class="art-artItemButton" href="{{ .Source }}" rel="noopener noreferrer" target="_blank">See the Code</a>
62{{- end }}
63
64<!-- One lightbox, reused by every card. -->
65<div class="art-lightboxOverlay" hidden>
66 <span class="art-lightboxImageWrapper">
67 <div class="art-lightboxLoading">Loading...</div>
68 <img class="art-lightboxImage" alt="" />
69 <button class="art-lightboxClose" type="button" aria-label="Close">✕</button>
70 </span>
71</div>
72{{ end }}