Serves Pete's classified-story archive over HTTP alongside the Matrix
bot. Three sections (gaming/tech/politics), Animal-Crossing-vibe Tailwind
templates, day/night palette driven by the visitor's browser clock.
Web port configurable via web.listen_addr and ${PETE_WEB_PORT} in
docker-compose. Tailwind built in a node stage in the Dockerfile so
deployments don't need node at runtime.
78 lines
3.5 KiB
HTML
78 lines
3.5 KiB
HTML
{{define "layout"}}<!doctype html>
|
|
<html lang="en" data-phase="day">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>{{block "title" .}}{{.SiteTitle}}{{end}}</title>
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;500;600;700&family=Nunito:wght@400;600;700&display=swap" rel="stylesheet">
|
|
<link rel="stylesheet" href="/static/css/output.css">
|
|
<link rel="icon" href="/static/img/leaf.svg" type="image/svg+xml">
|
|
<script>
|
|
// Pick a palette phase from the browser clock and update it each minute.
|
|
(function () {
|
|
function phase(h) {
|
|
if (h >= 5 && h < 8) return "dawn";
|
|
if (h >= 8 && h < 17) return "day";
|
|
if (h >= 17 && h < 20) return "dusk";
|
|
return "night";
|
|
}
|
|
function apply() {
|
|
document.documentElement.dataset.phase = phase(new Date().getHours());
|
|
}
|
|
apply();
|
|
setInterval(apply, 60000);
|
|
})();
|
|
</script>
|
|
</head>
|
|
<body class="min-h-screen bg-[color:var(--bg)] text-[color:var(--ink)] transition-colors duration-1000">
|
|
<div class="pointer-events-none fixed inset-0 -z-10 bg-[color:var(--bg-grad)] transition-colors duration-1000"></div>
|
|
|
|
<header class="mx-auto max-w-6xl px-4 pt-8 pb-4 sm:pt-12">
|
|
<div class="flex items-center justify-between gap-4">
|
|
<a href="/" class="flex items-center gap-3 group">
|
|
<span class="inline-flex h-12 w-12 items-center justify-center rounded-2xl bg-[color:var(--card)] shadow-pete border-2 border-[color:var(--ink)]/10 text-2xl group-hover:-rotate-6 transition-transform">🌿</span>
|
|
<span class="font-display text-3xl font-bold tracking-tight">{{.SiteTitle}}</span>
|
|
<span class="hidden sm:inline rounded-full bg-[color:var(--accent)]/20 px-3 py-1 text-xs font-semibold uppercase tracking-wider text-[color:var(--ink)]/70" data-phase-label>day</span>
|
|
</a>
|
|
<nav class="flex items-center gap-1 sm:gap-2 rounded-full bg-[color:var(--card)] p-1 shadow-pete border-2 border-[color:var(--ink)]/10">
|
|
{{$active := .Active}}
|
|
{{range .Channels}}
|
|
<a href="/{{.Slug}}"
|
|
class="rounded-full px-3 py-2 text-sm font-semibold transition
|
|
{{if eq $active .Slug}}bg-theme-{{.Theme}} text-white shadow-sm{{else}}hover:bg-[color:var(--ink)]/5{{end}}">
|
|
<span aria-hidden="true" class="mr-1">{{.Emoji}}</span><span class="hidden sm:inline">{{.Title}}</span>
|
|
</a>
|
|
{{end}}
|
|
</nav>
|
|
</div>
|
|
</header>
|
|
|
|
<main class="mx-auto max-w-6xl px-4 pb-24">
|
|
{{block "main" .}}{{end}}
|
|
</main>
|
|
|
|
<footer class="mx-auto max-w-6xl px-4 pb-10 text-center text-sm text-[color:var(--ink)]/50">
|
|
served by <span class="font-semibold">Pete</span> · also a Matrix bot · <span data-clock>—</span>
|
|
</footer>
|
|
|
|
<script>
|
|
// Tiny clock + phase label updater for the header pill / footer.
|
|
(function () {
|
|
function tick() {
|
|
var now = new Date();
|
|
var hh = String(now.getHours()).padStart(2, "0");
|
|
var mm = String(now.getMinutes()).padStart(2, "0");
|
|
var el = document.querySelector("[data-clock]");
|
|
if (el) el.textContent = hh + ":" + mm;
|
|
var label = document.querySelector("[data-phase-label]");
|
|
if (label) label.textContent = document.documentElement.dataset.phase;
|
|
}
|
|
tick();
|
|
setInterval(tick, 30000);
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html>{{end}}
|