learn site: one shared masthead for every page

The three pages had each grown their own tokens, type scale and alignment, so
the openings looked like three different sites. The document shell now owns the
masthead family - tokens, centred masthead, eyebrow, title, lede, fact strip,
scroll cue and the index component - and the pages carry only their content.
The Mirror gains the section index the arc has, drops its duplicate technical
footer, and its title now uses the same magenta accent instead of a one-off
gradient.
This commit is contained in:
2026-08-25 19:07:48 +10:00
parent ff2b8dabdc
commit f6616a5863
3 changed files with 83 additions and 85 deletions
+21 -54
View File
@@ -1,11 +1,4 @@
<style>
:root{
--void:#070b14; --void-2:#0a0f1b; --ink:#dfe6f0; --ink-dim:#98a2b4;
--cyan:#3fbaf5; --magenta:#e879f9; --amber:#e8b44a; --line:#1c2434; --card:#0d1424;
--good:#7fe0a7; --bad:#ff8fa3;
--mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
--sans:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;background:var(--void);color:var(--ink);
@@ -17,12 +10,9 @@
grid-template-columns:[full-start] minmax(1.25rem,1fr) [main-start] min(46rem,calc(100% - 2.5rem)) [main-end] minmax(1.25rem,1fr) [full-end]}
.layout>*{grid-column:main}
.layout>.scene{grid-column:full}
header.hero{min-height:70vh;display:flex;flex-direction:column;justify-content:center;padding:4.5rem 0 1.5rem;position:relative}
.eyebrow{font-family:var(--mono);font-size:.78rem;letter-spacing:.22em;color:var(--cyan);text-transform:uppercase}
h1{font-family:var(--sans);font-weight:750;font-size:clamp(2.8rem,8vw,4.6rem);
line-height:.98;margin:.5rem 0 1rem;text-wrap:balance;letter-spacing:-.01em}
.outcome{max-width:36rem;color:var(--ink-dim);font-size:1.12rem}
.outcome b{color:var(--ink);font-weight:600}
.chapnav{font-family:var(--mono);font-size:.72rem;letter-spacing:.14em;margin:0 0 2.4rem}
.chapnav a{color:var(--ink-dim);text-decoration:none;border-bottom:1px solid transparent;
padding-bottom:2px;transition:color .2s ease,border-color .2s ease}
@@ -31,16 +21,6 @@
-webkit-background-clip:text;background-clip:text;color:transparent;padding-bottom:.12em}
.standfirst{font-size:clamp(1.15rem,2.4vw,1.5rem);color:var(--ink);font-weight:600;
margin:.2rem 0 1rem;letter-spacing:-.01em;max-width:34rem}
.herostats{display:flex;flex-wrap:wrap;gap:0;margin:2.4rem 0 0;border-top:1px solid var(--line);
border-bottom:1px solid var(--line)}
.herostats div{flex:1 1 8rem;padding:.85rem 1.1rem .85rem 0;border-right:1px solid var(--line)}
.herostats div:last-child{border-right:0}
.herostats dt{font-family:var(--mono);font-size:.66rem;letter-spacing:.16em;
text-transform:uppercase;color:var(--ink-dim);margin:0 0 .25rem}
.herostats dd{margin:0;font-family:var(--mono);font-size:.92rem;color:var(--cyan)}
.scrollcue{font-family:var(--mono);font-size:.7rem;letter-spacing:.2em;text-transform:uppercase;
color:var(--ink-dim);margin-top:3rem;display:flex;flex-direction:column;gap:.7rem}
.scrollcue span{display:block;width:1px;height:46px;background:linear-gradient(var(--cyan),transparent)}
h2{font-family:var(--sans);font-weight:700;font-size:1.85rem;letter-spacing:0;
margin:4.2rem 0 1rem;text-wrap:balance;scroll-margin-top:2.5rem}
h2 .n{color:var(--cyan);font-family:var(--mono);font-weight:500;font-size:1rem;vertical-align:.35em;margin-right:.65rem;letter-spacing:.1em}
@@ -89,13 +69,6 @@
.facts dl{display:grid;grid-template-columns:max-content 1fr;gap:.35rem 1.2rem;margin:0}
.facts dt{font-family:var(--mono);font-size:.72rem;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-dim);padding-top:.15rem}
.facts dd{margin:0}
.toc{border:1px solid var(--line);border-radius:.55rem;padding:1rem 1.3rem;margin:2rem 0;background:var(--void-2)}
.toc .k{font-family:var(--mono);font-size:.72rem;letter-spacing:.18em;color:var(--cyan);text-transform:uppercase}
.toc ol{margin:.6rem 0 0;padding-left:1.4rem;columns:2;column-gap:2.5rem;font-size:.92rem}
.toc li{margin:.3rem 0;break-inside:avoid}
.toc a{color:var(--ink);text-decoration:none}
.toc a:hover{color:var(--cyan)}
@media (max-width:640px){.toc ol{columns:1}}
ol{padding-left:1.3rem} ol li{margin:.6rem 0}
ul{padding-left:1.2rem} ul li{margin:.5rem 0}
em{color:#fff}
@@ -125,16 +98,15 @@
<div class="layout">
<header class="hero">
<header class="masthead">
<nav class="chapnav" aria-label="Site"><a href="/">&larr; The Teaching Lab</a></nav>
<p class="eyebrow">Chapter 02 &middot; Dossier 005 &middot; operations</p>
<h1>The <em>Mirror</em></h1>
<p class="standfirst">A pull-through OCI registry, taken apart.</p>
<p class="outcome">What the deployed version guarantees, the retention behaviour that
evicts digest-pinned content, and how each lesson translates to production. Every claim
carries an evidence label &mdash; and the corrections to my own first draft are on the
page, not quietly edited out.</p>
<dl class="herostats">
<p class="eyebrow">Chapter 02 &middot; The Mirror &middot; Dossier 005</p>
<h1>The cache was the easy part.<br><em>Now watch what it quietly throws away.</em></h1>
<p class="lede">A pull-through registry, taken apart: what the deployed version actually
guarantees, the retention behaviour that evicts digest-pinned content, and how each lesson
translates to production. Every claim carries an evidence label - including the corrections
to my own first draft. Scroll, and the machinery comes apart.</p>
<dl class="mastfacts">
<div><dt>Registry</dt><dd>zot v2.1.17</dd></div>
<div><dt>Upstreams</dt><dd>5, on-demand</dd></div>
<div><dt>Platform</dt><dd>Talos / containerd</dd></div>
@@ -163,19 +135,19 @@
<span class="st prop">proposed</span> not deployed &middot; <span class="st open">open</span> not yet run</p>
</div>
<nav class="toc" aria-labelledby="toc-h">
<p class="k" id="toc-h">Contents</p>
<nav class="toc" aria-label="Section index">
<p class="kt">Index</p>
<ol>
<li><a href="#incident">The build that "hung"</a></li>
<li><a href="#anatomy">What the mirror actually does</a></li>
<li><a href="#routing">Request routing and five upstreams</a></li>
<li><a href="#bootstrap">Bootstrap, fallback and failure modes</a></li>
<li><a href="#digests">Digests, manifests and supply chain</a></li>
<li><a href="#retention">Retention, GC and the digest-only trap</a></li>
<li><a href="#auth">The authentication migration</a></li>
<li><a href="#observability">Observability that means something</a></li>
<li><a href="#production">The production translation</a></li>
<li><a href="#verified">Verified, open and references</a></li>
<li><a href="#incident"><b>Section 01</b><span>The build that "hung"</span></a></li>
<li><a href="#anatomy"><b>Section 02</b><span>What the mirror does</span></a></li>
<li><a href="#routing"><b>Section 03</b><span>Routing and five upstreams</span></a></li>
<li><a href="#bootstrap"><b>Section 04</b><span>Bootstrap, fallback, failure</span></a></li>
<li><a href="#digests"><b>Section 05</b><span>Digests and supply chain</span></a></li>
<li><a href="#retention"><b>Section 06</b><span>Retention and the digest trap</span></a></li>
<li><a href="#auth"><b>Section 07</b><span>The authentication migration</span></a></li>
<li><a href="#observability"><b>Section 08</b><span>Observability that means something</span></a></li>
<li><a href="#production"><b>Section 09</b><span>The production translation</span></a></li>
<li><a href="#verified"><b>Section 10</b><span>Verified, open, references</span></a></li>
</ol>
</nav>
@@ -849,12 +821,7 @@ cache re-warm cost.</li>
<li>Docker Hub <a href="https://docs.docker.com/docker-hub/usage/">usage and limits</a> &middot; buildah <a href="https://github.com/containers/buildah/blob/main/docs/buildah-build.1.md">build --retry semantics</a></li>
</ul>
<footer>
DOSSIER / 005 &middot; last reviewed 2026-08-25 against the running estate and the
sources above &middot; corrections in this revision: retention/GC semantics, warm-cache
behaviour, retry arithmetic, upstream namespace routing &middot;
<a href="/">The Teaching Lab</a> &middot; <a href="https://git.bztmon.com/jwright/exploded-cluster">source</a>
</footer>
<footer class="outro">
<p>&copy; 2026 Jonathon Wright &middot; <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a>