Files
Pete/internal/web/templates/games_layout.html
prosolis 8ec13eab5b games: the casino moves out, and gets a clock of its own
The tables were living in the news app's shell: Pete's face in the header
and the footer, the channel nav, search, the reader, the weather canvas,
the PWA. A casino is not a news page with a felt on it.

So it gets its own layout. What carries over is the design language — the
four palette vars, Fredoka/Nunito, the fat rounded cards, the dropped
shadow. What doesn't is every control it has no use for. gamesPage stops
embedding the news pageData, which is what keeps the furniture from
drifting back one convenient field at a time.

It keeps a clock, but tells a different joke with it: Casinopolis by day,
Casino Night Zone from six, palette and felt and the sign over the door all
changing together. The rule lives in roomAt() for the first paint and again
in the browser, so a player abroad gets their own evening.

And the cards are cards now — corner indices in both corners, the bottom
one upside down as printed, pips on the three-by-seven grid every real deck
has used for four hundred years, courts as a letter with the suit over each
shoulder. Driven in a real browser, both rooms, dealt through to a payout.
2026-07-13 23:40:33 -07:00

92 lines
4.6 KiB
HTML

{{define "layout"}}<!doctype html>
<html lang="en" data-room="{{.Room.Slug}}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{block "title" .}}{{.Room.Name}}{{end}}</title>
<meta name="robots" content="noindex">
<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="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cpolygon points='16,3 27,9.5 27,22.5 16,29 5,22.5 5,9.5' fill='%23f2b53d' stroke='%232b2118' stroke-width='2.5' stroke-linejoin='round'/%3E%3C/svg%3E" type="image/svg+xml">
<meta name="theme-color" content="#17231d">
<script>
// Which room you're standing in, from your clock rather than the server's:
// Casinopolis in daylight, Casino Night Zone once the lights come on at six.
// Same rule as roomAt() in games_pages.go — keep the two in step.
//
// The server already painted its best guess into the markup, so this only
// corrects a player whose evening isn't the server's.
(function () {
var ROOMS = {
"casinopolis": "Casinopolis",
"casino-night": "Casino Night Zone",
};
function roomAt(h) { return (h >= 6 && h < 18) ? "casinopolis" : "casino-night"; }
function apply() {
var slug = roomAt(new Date().getHours());
// The palette can be set from <head> — the sign can't: this script runs
// before the header exists. So set the attribute now (no flash of the
// wrong room) and always re-stamp the name, which is a no-op until the
// header is there to stamp. Bailing out early when the slug already
// matches would leave the server's name under the browser's palette.
document.documentElement.dataset.room = slug;
document.querySelectorAll("[data-room-name]").forEach(function (el) {
el.textContent = ROOMS[slug];
});
}
apply();
document.addEventListener("DOMContentLoaded", apply);
setInterval(apply, 60000);
})();
</script>
</head>
<body class="min-h-screen bg-[color:var(--bg)] text-[color:var(--ink)]">
<div class="pointer-events-none fixed inset-0 -z-10 cs-room" aria-hidden="true"></div>
<header class="mx-auto max-w-5xl px-4 pt-6 pb-4 sm:pt-10">
<div class="flex items-center justify-between gap-3">
<a href="/games" class="group flex min-w-0 items-center gap-3">
{{template "_comb" .}}
<span class="min-w-0">
<span data-room-name class="block font-display text-2xl sm:text-3xl font-bold leading-none tracking-tight">{{.Room.Name}}</span>
<span class="mt-1 block text-xs font-semibold uppercase tracking-[0.18em] text-[color:var(--ink)]/45">Chips are euros</span>
</span>
</a>
{{if .User}}
<a href="/auth/logout" title="Signed in as {{.User.Display}} — sign out"
class="inline-flex shrink-0 items-center gap-2 rounded-full bg-[color:var(--card)] px-2.5 py-1.5 text-sm font-semibold shadow-pete border-2 border-[color:var(--ink)]/10 hover:bg-[color:var(--ink)]/5 transition">
<span class="grid h-6 w-6 place-items-center rounded-full bg-[color:var(--accent)] text-xs font-bold text-[#20180c]">{{.User.Initial}}</span>
<span class="hidden sm:inline max-w-[7rem] truncate">{{.User.Display}}</span>
</a>
{{end}}
</div>
</header>
<main class="mx-auto max-w-5xl px-4 pb-20">
{{block "main" .}}{{end}}
</main>
<footer class="mx-auto max-w-5xl px-4 pb-10 text-center text-xs text-[color:var(--ink)]/40">
Play for what you can lose. Cash out whenever you like.
</footer>
{{block "scripts" .}}{{end}}
</body>
</html>{{end}}
{{/* The house mark: a honeycomb cell struck like a chip. Stands in for a logo,
and deliberately isn't a face — nobody is watching you play. */}}
{{define "_comb"}}
<span class="cs-comb grid h-11 w-11 shrink-0 place-items-center transition-transform group-hover:-rotate-6" aria-hidden="true">
<svg viewBox="0 0 32 32" class="h-11 w-11">
<polygon points="16,2.5 27.5,9.25 27.5,22.75 16,29.5 4.5,22.75 4.5,9.25"
fill="var(--accent)" stroke="var(--ink)" stroke-width="2.5" stroke-linejoin="round"/>
<polygon points="16,9 21.5,12.25 21.5,18.75 16,22 10.5,18.75 10.5,12.25"
fill="none" stroke="var(--ink)" stroke-width="1.75" stroke-linejoin="round" opacity="0.5"/>
</svg>
</span>
{{end}}