The Teaching Lab (learn.bztmon.com)

A static learning site documenting infrastructure I operate in my homelab - the decisions, the failures, and the validation still outstanding. Dark engineering-dossier aesthetic (void #070b14, cyan #3fbaf5, magenta #e879f9), dependency-light by design, strict security posture.

Pages

Route Page Source
/ The Teaching Lab - chapter directory pilot/index.tpl.html
/cluster Chapter 01: The Exploded Cluster - eleven-course container-platform teardown pilot/arc.tpl.html + pilot/manifest-*.json
/mirror Chapter 02: The Mirror - a zot pull-through registry, its failure modes and operations pilot/mirror.tpl.html + pilot/mirror.js

Build

bash build.sh -> dist/. The assembler (pilot/assemble-arc.mjs, plain node, no dependencies) wraps each page in a shared document shell (canonical/OG metadata, build revision, skip link), content-fingerprints every file under /assets/ (immutable-cached by nginx), splits page scripts into external fingerprinted files, injects intrinsic image dimensions (WebP and JPEG parsed from the actual bytes) with deliberate lazy/eager loading, and runs per-page preflight gates: no inline scripts (CSP script-src 'self' with no exceptions), exactly one h1, unique ids, no dangling anchors, no unresolved placeholders, and page-specific content assertions. A failed gate fails the build.

Ship: podman build (multi-stage: node builds dist/, nginx-unprivileged serves it, both digest-pinned) -> push to the estate registry -> digest-pinned deploy via GitOps. nginx/ carries the runtime config: strict CSP, HSTS, no-cache HTML with immutable fingerprinted assets, security headers on every location.

Accessibility and performance

Skip link on every page (hidden until keyboard focus), one h1 per page, stable section anchors, reduced-motion honoured live (effects also pause when the tab is hidden or the scene is off screen), intrinsic image dimensions to prevent layout shift, below-fold images lazy-loaded, system font stacks (CSP permits no third-party fonts).

Layout

Path What
pilot/ page templates, page scripts, scene manifests, the assembler
assets/dist/ production heroes and diagrams for /cluster
assets/mirror/ plates for /mirror
content/ course source notes
nginx/ runtime config baked into the image
tools/slicer.html slice editor: load a hero, tune cut lines, export a scene manifest
prompts/ image prompt contract for the house visual style
exploded-cluster.html, ec2-part*.html v2 (parked, superseded by /cluster)
gsap.min.js / st.min.js GSAP 3.13 + ScrollTrigger, fingerprinted at assemble time

The slicing rule (load-bearing - read before touching the arc engine)

Parts occlude each other in 2D, so every slice carries a hidden notch where the part in front covers it. Animating collapsed -> hero only ever increases occlusion, so notches stay buried. Never overshoot past the hero layout and never fan parts sideways - either exposes the tears. Region boundaries overlap upward by EPS; expanding downward would ghost.

S
Description
No description provided
Readme 27 MiB
Languages
HTML 92.4%
JavaScript 5.6%
Python 1.2%
Shell 0.5%
Dockerfile 0.3%