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.
92 lines
4.6 KiB
HTML
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}}
|