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:
@@ -57,6 +57,58 @@ function jpegSize(buf) {
|
||||
|
||||
// skip link: emitted by the shared shell, so its accessibility CSS lives in the shell
|
||||
// too - visually hidden until keyboard focus, visible and prominent when focused.
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Shared masthead: ONE opening treatment for every page on the site. Pages used
|
||||
// to declare their own tokens, type scale and alignment, which is why the three
|
||||
// headers drifted apart. This block owns the family - tokens, the centred
|
||||
// masthead, eyebrow, title, lede and scroll cue - and pages simply use it.
|
||||
// ---------------------------------------------------------------------------
|
||||
const MAST_CSS = `<style>
|
||||
:root{
|
||||
--void:#070b14; --ink:#c9d7ef; --dim:#7286a8; --ink-dim:#7286a8; --line:#1b2740;
|
||||
--cyan:#3fbaf5; --magenta:#e879f9; --amber:#e8b44a;
|
||||
--dur-fast:.2s; --dur-base:.35s; --dur-slow:.6s;
|
||||
--sans:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
|
||||
--mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
|
||||
}
|
||||
.masthead{position:relative;max-width:64ch;margin:0 auto;padding:16vh 24px 9vh;text-align:center}
|
||||
.masthead > :not(.introbg){position:relative}
|
||||
.chapnav{font-family:var(--mono);font-size:.72rem;letter-spacing:.14em;margin:0 0 2.2rem}
|
||||
.chapnav a{color:var(--dim);text-decoration:none;border-bottom:1px solid transparent;
|
||||
padding-bottom:2px;transition:color var(--dur-fast) ease,border-color var(--dur-fast) ease}
|
||||
.chapnav a:hover,.chapnav a:focus-visible{color:var(--cyan);border-color:var(--cyan)}
|
||||
.eyebrow{font-family:var(--mono);font-size:.72rem;letter-spacing:.22em;text-transform:uppercase;
|
||||
color:var(--cyan);margin:0 0 1.5rem}
|
||||
.masthead h1,.thesis{font-size:clamp(1.9rem,4.8vw,3.2rem);line-height:1.1;margin:0 0 1.3rem;
|
||||
font-weight:600;letter-spacing:-.02em;text-wrap:balance;font-family:var(--sans);color:var(--ink)}
|
||||
.masthead h1 em,.thesis em{font-style:normal;color:var(--magenta)}
|
||||
.lede{color:var(--dim);font-size:1.02rem;line-height:1.7;margin:0 auto;max-width:58ch}
|
||||
.scrollcue{font-family:var(--mono);font-size:.7rem;letter-spacing:.2em;text-transform:uppercase;
|
||||
color:var(--dim);margin-top:4.5rem;display:flex;flex-direction:column;align-items:center;gap:.7rem}
|
||||
.scrollcue span{display:block;width:1px;height:46px;background:linear-gradient(var(--cyan),transparent)}
|
||||
.mastfacts{display:flex;flex-wrap:wrap;justify-content:center;gap:0;margin:2.6rem auto 0;
|
||||
border-top:1px solid var(--line);border-bottom:1px solid var(--line);max-width:52ch}
|
||||
.mastfacts div{flex:1 1 8rem;padding:.85rem 1rem;border-right:1px solid var(--line)}
|
||||
.mastfacts div:last-child{border-right:0}
|
||||
.mastfacts dt{font-family:var(--mono);font-size:.64rem;letter-spacing:.16em;text-transform:uppercase;
|
||||
color:var(--dim);margin:0 0 .3rem}
|
||||
.mastfacts dd{margin:0;font-family:var(--mono);font-size:.88rem;color:var(--cyan)}
|
||||
.toc{max-width:760px;margin:0 auto;padding:0 24px 5vh}
|
||||
.toc .kt{font-family:var(--mono);font-size:.68rem;letter-spacing:.16em;
|
||||
text-transform:uppercase;color:var(--dim);text-align:center;margin:0 0 1rem}
|
||||
.toc ol{list-style:none;margin:0;padding:0;counter-reset:toc;display:flex;flex-direction:column;gap:8px}
|
||||
.toc li{counter-increment:toc}
|
||||
.toc a{display:grid;grid-template-columns:34px 110px 1fr;gap:12px;align-items:baseline;
|
||||
border:1px solid var(--line);border-radius:8px;padding:10px 16px;background:#0a1020;text-decoration:none}
|
||||
.toc a::before{content:counter(toc,decimal-leading-zero);font-family:var(--mono);font-size:.68rem;color:var(--dim)}
|
||||
.toc a:hover,.toc a:focus-visible{border-color:var(--cyan)}
|
||||
.toc b{font-family:var(--mono);font-size:.72rem;letter-spacing:.08em;color:var(--cyan);font-weight:600}
|
||||
.toc span{font-size:.82rem;line-height:1.5;color:var(--dim)}
|
||||
@media (max-width:640px){.toc a{grid-template-columns:34px 1fr}.toc span{grid-column:2}}
|
||||
@media (max-width:900px){.masthead{padding:9vh 22px 6vh}}
|
||||
</style>`;
|
||||
|
||||
const SKIP_CSS = `<style>
|
||||
a.skip{position:absolute;left:-9999px;top:0;z-index:99}
|
||||
a.skip:focus{left:1rem;top:1rem;background:#070b14;color:#3fbaf5;
|
||||
@@ -161,6 +213,7 @@ const shell = ({ title, desc, path, ogImg, scripts, bodyHtml }) => `<!doctype ht
|
||||
<meta name="twitter:image" content="${ogImg}">
|
||||
<link rel="icon" href="${favicon}">
|
||||
${SKIP_CSS}
|
||||
${MAST_CSS}
|
||||
</head>
|
||||
<body>
|
||||
<a class="skip" href="#main-content">Skip to content</a>
|
||||
|
||||
Reference in New Issue
Block a user