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.
114 lines
5.5 KiB
HTML
114 lines
5.5 KiB
HTML
{{define "title"}}Blackjack · {{.Room.Name}}{{end}}
|
|
|
|
{{define "main"}}
|
|
<div class="space-y-6" data-blackjack>
|
|
|
|
<div class="flex flex-wrap items-center justify-between gap-3">
|
|
<div class="flex items-center gap-3 min-w-0">
|
|
<a href="/games" class="grid h-10 w-10 shrink-0 place-items-center rounded-full bg-[color:var(--card)] shadow-pete border-2 border-[color:var(--ink)]/10 hover:bg-[color:var(--ink)]/5 transition" title="Back to the casino">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="h-5 w-5" aria-hidden="true">
|
|
<path d="M19 12H5"></path><polyline points="12 19 5 12 12 5"></polyline>
|
|
</svg>
|
|
<span class="sr-only">Back to the casino</span>
|
|
</a>
|
|
<h1 class="font-display text-3xl font-bold">Blackjack</h1>
|
|
</div>
|
|
<p class="text-sm text-[color:var(--ink)]/50">Six decks · pays 3:2 · dealer hits soft 17</p>
|
|
</div>
|
|
|
|
{{template "_chipbar" .}}
|
|
|
|
<!-- The felt. -->
|
|
<section class="pete-felt relative overflow-hidden rounded-3xl p-6 sm:p-10 shadow-pete-lg border-2 border-[color:var(--ink)]/10">
|
|
|
|
<!-- The shoe every card flies out of. -->
|
|
<div class="pete-shoe" aria-hidden="true"></div>
|
|
|
|
<div class="relative space-y-8">
|
|
|
|
<!-- Dealer -->
|
|
<div>
|
|
<div class="mb-2 flex items-center gap-2">
|
|
<span class="text-xs font-bold uppercase tracking-wider text-white/60">Dealer</span>
|
|
<span data-dealer-total class="hidden rounded-full bg-black/25 px-2.5 py-0.5 text-xs font-bold tabular-nums text-white"></span>
|
|
</div>
|
|
<div data-dealer class="pete-hand" aria-live="polite"></div>
|
|
</div>
|
|
|
|
<!-- What just happened. -->
|
|
<div class="flex min-h-[2.75rem] items-center justify-center">
|
|
<p data-verdict class="hidden rounded-full bg-white/95 px-5 py-2 font-display text-lg font-bold shadow-pete"></p>
|
|
</div>
|
|
|
|
<!-- Player -->
|
|
<div>
|
|
<div class="mb-2 flex items-center gap-2">
|
|
<span class="text-xs font-bold uppercase tracking-wider text-white/60">You</span>
|
|
<span data-player-total class="hidden rounded-full bg-black/25 px-2.5 py-0.5 text-xs font-bold tabular-nums text-white"></span>
|
|
<span data-bet class="hidden ml-auto rounded-full bg-[color:var(--accent)] px-3 py-0.5 text-xs font-bold tabular-nums text-white"></span>
|
|
</div>
|
|
<div data-player class="pete-hand" aria-live="polite"></div>
|
|
</div>
|
|
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Betting: shown between hands. -->
|
|
<section data-betting class="rounded-3xl bg-[color:var(--card)] p-5 sm:p-6 shadow-pete border-2 border-[color:var(--ink)]/10">
|
|
<div class="flex flex-wrap items-center gap-x-6 gap-y-4">
|
|
<div>
|
|
<div class="text-xs font-semibold uppercase tracking-wider text-[color:var(--ink)]/50">Your bet</div>
|
|
<div class="font-display text-3xl font-bold tabular-nums"><span data-bet-amount>25</span></div>
|
|
</div>
|
|
|
|
<div class="flex flex-wrap items-center gap-2">
|
|
{{range .Denominations}}
|
|
<button type="button" data-chip="{{.}}"
|
|
class="pete-chip h-12 w-12 rounded-full font-display text-sm font-bold text-white shadow-pete
|
|
hover:-translate-y-0.5 active:translate-y-0 transition">{{.}}</button>
|
|
{{end}}
|
|
<button type="button" data-bet-clear
|
|
class="rounded-full px-3 py-2 text-sm font-semibold text-[color:var(--ink)]/50 hover:text-[color:var(--ink)] transition">Clear</button>
|
|
</div>
|
|
|
|
<button type="button" data-deal
|
|
class="ml-auto rounded-full bg-[color:var(--accent)] px-8 py-3 font-display text-lg font-bold text-white shadow-pete
|
|
hover:brightness-105 active:translate-y-px disabled:opacity-40 disabled:pointer-events-none transition">
|
|
Deal
|
|
</button>
|
|
</div>
|
|
<p data-table-msg class="hidden mt-3 rounded-2xl bg-[color:var(--ink)]/5 px-4 py-2 text-sm font-semibold"></p>
|
|
</section>
|
|
|
|
<!-- Playing: shown while a hand is live. -->
|
|
<section data-actions class="hidden rounded-3xl bg-[color:var(--card)] p-5 sm:p-6 shadow-pete border-2 border-[color:var(--ink)]/10">
|
|
<div class="flex flex-wrap items-center justify-center gap-3">
|
|
<button type="button" data-move="hit"
|
|
class="rounded-full bg-[color:var(--accent)] px-8 py-3 font-display text-lg font-bold text-white shadow-pete
|
|
hover:brightness-105 active:translate-y-px disabled:opacity-40 disabled:pointer-events-none transition">
|
|
Hit
|
|
</button>
|
|
<button type="button" data-move="stand"
|
|
class="rounded-full bg-[color:var(--card)] px-8 py-3 font-display text-lg font-bold shadow-pete border-2 border-[color:var(--ink)]/10
|
|
hover:bg-[color:var(--ink)]/5 active:translate-y-px disabled:opacity-40 disabled:pointer-events-none transition">
|
|
Stand
|
|
</button>
|
|
<button type="button" data-move="double"
|
|
class="rounded-full bg-[color:var(--card)] px-8 py-3 font-display text-lg font-bold shadow-pete border-2 border-[color:var(--ink)]/10
|
|
hover:bg-[color:var(--ink)]/5 active:translate-y-px disabled:opacity-40 disabled:pointer-events-none transition">
|
|
Double
|
|
</button>
|
|
</div>
|
|
<p class="mt-3 text-center text-xs text-[color:var(--ink)]/40">
|
|
<kbd>h</kbd> hit · <kbd>s</kbd> stand · <kbd>d</kbd> double
|
|
</p>
|
|
</section>
|
|
|
|
</div>
|
|
{{end}}
|
|
|
|
{{define "scripts"}}
|
|
<script src="/static/js/games.js" defer></script>
|
|
<script src="/static/js/blackjack.js" defer></script>
|
|
{{end}}
|