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
1body {
2 min-height: 100vh;
3 display: flex;
4 flex-direction: column;
5 -webkit-font-smoothing: antialiased;
6 -moz-osx-font-smoothing: grayscale;
7 letter-spacing: 0.01em;
8}
9
10.logo {
11 content: "";
12 display: flex;
13 align-items: center;
14 justify-content: center;
15 background-image: linear-gradient(
16 135deg,
17 rgb(14, 63, 180) 0%,
18 rgb(107, 158, 120) 100%
19 );
20 width: 36px;
21 height: 36px;
22 margin-top: auto;
23 margin-bottom: auto;
24 border-radius: 3px;
25 transition: transform 0.25s ease, box-shadow 0.25s ease;
26 position: relative;
27 text-decoration: none !important;
28
29 &::after {
30 content: ">_";
31 font-family: monospace;
32 font-weight: bold;
33 font-size: 14px;
34 color: rgba(255, 255, 255, 0.9);
35 line-height: 1;
36 text-decoration: none;
37 }
38
39 &[style*="width: 20px"]::after {
40 font-size: 8px;
41 }
42
43 &:hover {
44 transform: rotate(12deg) scale(1.08);
45 box-shadow: 0 0 14px rgba(107, 158, 120, 0.3);
46 }
47}
48
49.navbar {
50 border-bottom: 1px solid rgba(107, 158, 120, 0.06);
51
52 .navbar-toggler {
53 color: rgba(221, 215, 205, 0.7);
54 padding: 0.35rem 0.55rem;
55 font-size: 1rem;
56
57 &:focus { box-shadow: none; }
58 }
59
60 .nav-link {
61 font-size: 0.82rem;
62 font-weight: 500;
63 letter-spacing: 0.04em;
64 padding-left: 1rem !important;
65 padding-right: 1rem !important;
66 text-transform: lowercase;
67 position: relative;
68
69 &::after {
70 content: '';
71 position: absolute;
72 bottom: 0;
73 left: 1rem;
74 right: 1rem;
75 height: 1px;
76 background: #6b9e78;
77 box-shadow: 0 0 6px rgba(107, 158, 120, 0.3);
78 transform: scaleX(0);
79 transition: transform 250ms ease;
80 }
81
82 &:hover::after,
83 &.active::after {
84 transform: scaleX(1);
85 }
86 }
87
88 @media (max-width: 767.98px) {
89 .navbar-collapse {
90 width: 100%;
91 border-top: 1px solid rgba(107, 158, 120, 0.08);
92 margin-top: 0.5rem;
93 padding: 0.4rem 0 0.6rem;
94 }
95
96 .navbar-nav {
97 margin-left: 0 !important;
98 width: 100%;
99 }
100
101 .nav-link {
102 padding: 0.65rem 0.75rem !important;
103 border-left: 2px solid transparent;
104 border-radius: 2px;
105 transition: background-color 150ms ease, color 150ms ease, border-color 150ms ease;
106
107 &::after { display: none; }
108
109 &:hover {
110 background: rgba(221, 215, 205, 0.04);
111 color: #ddd7cd;
112 }
113
114 &.active {
115 color: #ddd7cd;
116 border-left-color: #6b9e78;
117 background: rgba(107, 158, 120, 0.08);
118 }
119 }
120 }
121}
122
123.breadcrumb-bar {
124 background: rgba(107, 158, 120, 0.02);
125 border-bottom: 1px solid rgba(107, 158, 120, 0.04);
126}
127
128footer {
129 padding-top: 4rem;
130 position: relative;
131
132 .links {
133 padding-top: 4rem;
134 padding-bottom: 2rem;
135 position: relative;
136 z-index: 20;
137 }
138
139 .h5 {
140 font-size: 0.72rem;
141 letter-spacing: 0.1em;
142 text-transform: uppercase;
143 color: rgba(201, 168, 76, 0.55);
144 font-weight: 600;
145 }
146
147 p {
148 color: rgba(221, 215, 205, 0.5);
149 font-size: 0.88rem;
150 line-height: 1.75;
151
152 a {
153 color: rgba(221, 215, 205, 0.75);
154 text-decoration: underline;
155 text-underline-offset: 2px;
156 transition: color 200ms ease;
157
158 &:hover {
159 color: #ddd7cd;
160 }
161 }
162 }
163}
164
165.footer-bar {
166 background: #070605;
167 border-top: 1px solid rgba(107, 158, 120, 0.05);
168 padding: 1rem 0;
169 color: rgba(221, 215, 205, 0.3);
170 font-size: 0.78rem;
171 letter-spacing: 0.03em;
172 position: relative;
173 z-index: 20;
174
175 small {
176 color: rgba(221, 215, 205, 0.3);
177 }
178
179 &-link {
180 color: rgba(221, 215, 205, 0.3);
181 transition: color 200ms ease;
182
183 &:hover {
184 color: #ddd7cd;
185 }
186 }
187}
188
189.footer-plane {
190 position: relative;
191 width: 100%;
192 height: 300px;
193 overflow: hidden;
194 z-index: 10;
195 perspective: 350px;
196
197 &-overlay {
198 width: 100%;
199 height: 100%;
200 position: absolute;
201 z-index: 11;
202 background: radial-gradient(
203 ellipse at 50% 50%,
204 rgba(9, 8, 6, 0) 0,
205 rgb(9, 8, 6) 80%
206 );
207 }
208
209 @keyframes footer-plane-keyframes {
210 0% {
211 transform: rotateX(45deg) translateY(-50%);
212 }
213
214 to {
215 transform: rotateX(45deg) translateY(0);
216 }
217 }
218
219 &-grid {
220 position: relative;
221 width: 100%;
222 height: 200%;
223 background-image: linear-gradient(
224 90deg,
225 rgba(107, 158, 120, 0.18) 1px,
226 transparent 0
227 ),
228 linear-gradient(180deg, rgba(107, 158, 120, 0.18) 1px, transparent 0);
229 background-size: 40px 30px;
230 background-repeat: repeat;
231 transform-origin: 100% 0 0;
232 animation: footer-plane-keyframes 17s linear infinite;
233 }
234}
235
236.section-label {
237 font-size: 0.72rem;
238 font-weight: 600;
239 letter-spacing: 0.1em;
240 text-transform: uppercase;
241 color: #c9a84c;
242
243 &::before {
244 content: '> ';
245 opacity: 0.5;
246 }
247}
248
249.card {
250 transition: border-color 250ms ease, box-shadow 250ms ease;
251
252 &:hover {
253 border-color: rgba(107, 158, 120, 0.18);
254 box-shadow: 0 0 20px rgba(107, 158, 120, 0.04);
255 }
256}
257
258.search-form {
259 .search-icon {
260 position: absolute;
261 left: 0.85rem;
262 top: 50%;
263 transform: translateY(-50%);
264 color: #665f56;
265 pointer-events: none;
266 z-index: 2;
267 }
268
269 .search-input {
270 padding-left: 2.5rem;
271 font-size: 0.85rem;
272 letter-spacing: 0.02em;
273 border: 1px solid rgba(107, 158, 120, 0.15);
274 background: rgba(19, 18, 14, 0.6);
275 color: #ddd7cd;
276 transition: border-color 200ms ease, box-shadow 200ms ease;
277
278 &::placeholder {
279 color: #665f56;
280 font-style: normal;
281 }
282
283 &:focus {
284 border-color: rgba(107, 158, 120, 0.4);
285 box-shadow: 0 0 0 2px rgba(107, 158, 120, 0.1);
286 background: #13120e;
287 }
288 }
289}
290
291#id_search_results .list-group-item {
292 color: #ddd7cd;
293 border-color: rgba(107, 158, 120, 0.08);
294
295 .fw-bold {
296 color: #ddd7cd;
297 }
298
299 &.active {
300 background: rgba(107, 158, 120, 0.12);
301 border-color: rgba(107, 158, 120, 0.2);
302 color: #ddd7cd;
303 }
304
305 &:hover {
306 background: rgba(107, 158, 120, 0.08);
307 }
308}
309
310.filter-label {
311 font-size: 0.68rem;
312 font-weight: 600;
313 letter-spacing: 0.1em;
314 text-transform: uppercase;
315 color: #c9a84c;
316 opacity: 0.7;
317}
318
319.filter-divider {
320 width: 1px;
321 height: 1.2rem;
322 background: rgba(221, 215, 205, 0.1);
323 margin: 0 0.25rem;
324}
325
326.btn-filter {
327 background: rgba(221, 215, 205, 0.04);
328 color: #a09890;
329 border: 1px solid rgba(221, 215, 205, 0.08);
330 font-size: 0.75rem;
331 line-height: 1;
332 padding: 0.4rem 0.75rem;
333 display: inline-flex;
334 align-items: center;
335 transition: all 200ms ease;
336
337 &:hover {
338 background: rgba(107, 158, 120, 0.1);
339 color: #ddd7cd;
340 border-color: rgba(107, 158, 120, 0.2);
341 }
342}
343
344.btn-filter-active {
345 background: rgba(107, 158, 120, 0.15);
346 color: #7db88c;
347 border: 1px solid rgba(107, 158, 120, 0.3);
348 font-size: 0.75rem;
349 line-height: 1;
350 padding: 0.4rem 0.75rem;
351 display: inline-flex;
352 align-items: center;
353}
354
355.btn-filter-clear {
356 background: rgba(196, 112, 85, 0.1);
357 color: #c47055;
358 border: 1px solid rgba(196, 112, 85, 0.2);
359 font-size: 0.75rem;
360 line-height: 1;
361 padding: 0.4rem 0.75rem;
362 display: inline-flex;
363 align-items: center;
364 transition: all 200ms ease;
365
366 &:hover {
367 background: rgba(196, 112, 85, 0.2);
368 color: #d88a70;
369 border-color: rgba(196, 112, 85, 0.35);
370 }
371}
372
373.vr {
374 background-color: rgba(107, 158, 120, 0.12);
375}