Header slot: random reading highlight per page view
Pulled client-side from /highlights/random (max_len=280); attribution from the API's parsed title/author; hidden when the API is unreachable. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -33,6 +33,10 @@ const showToc = headings.filter((h) => h.depth <= 3).length >= 2;
|
|||||||
<div class="content-col">
|
<div class="content-col">
|
||||||
<header>
|
<header>
|
||||||
{!isHome && <nav><a href="/">← home</a></nav>}
|
{!isHome && <nav><a href="/">← home</a></nav>}
|
||||||
|
<div id="hq" class="header-quote" hidden>
|
||||||
|
<span id="hq-text"></span>
|
||||||
|
<span id="hq-attr" class="hq-attr"></span>
|
||||||
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
<slot />
|
<slot />
|
||||||
@@ -72,6 +76,25 @@ const showToc = headings.filter((h) => h.depth <= 3).length >= 2;
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Header quote: one random reading highlight per page view.
|
||||||
|
// Fail-closed: any error leaves the slot hidden.
|
||||||
|
try {
|
||||||
|
const res = await fetch(
|
||||||
|
'https://api.c0smere.net/highlights/random?max_len=280',
|
||||||
|
);
|
||||||
|
if (!res.ok) throw new Error(String(res.status));
|
||||||
|
const q = await res.json();
|
||||||
|
document.getElementById('hq-text')!.textContent = `“${q.text}”`;
|
||||||
|
document.getElementById('hq-attr')!.textContent = q.author
|
||||||
|
? `— ${q.author}, ${q.book}`
|
||||||
|
: `— ${q.book}`;
|
||||||
|
document.getElementById('hq')!.hidden = false;
|
||||||
|
} catch {
|
||||||
|
/* API down or blocked: slot stays hidden */
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Odometer: fetch totals once, then animate forward at the lifetime
|
// Odometer: fetch totals once, then animate forward at the lifetime
|
||||||
// average rate. Looks live, but deliberately never exposes current
|
// average rate. Looks live, but deliberately never exposes current
|
||||||
@@ -321,6 +344,20 @@ const showToc = headings.filter((h) => h.depth <= 3).length >= 2;
|
|||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
|
.header-quote {
|
||||||
|
margin-bottom: 1.75rem;
|
||||||
|
padding-bottom: 0.75rem;
|
||||||
|
border-bottom: 1px solid var(--faint);
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-style: italic;
|
||||||
|
color: var(--muted);
|
||||||
|
}
|
||||||
|
.header-quote .hq-attr {
|
||||||
|
font-style: normal;
|
||||||
|
white-space: nowrap;
|
||||||
|
margin-left: 0.4rem;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
footer {
|
footer {
|
||||||
margin-top: 3rem;
|
margin-top: 3rem;
|
||||||
padding-top: 1rem;
|
padding-top: 1rem;
|
||||||
|
|||||||
Reference in New Issue
Block a user