The engine, the escrow and the wire were all in place; nothing had a browser on the end of it. This is that end: a lobby, a table, and the five endpoints between them. The browser holds no game. It sends intents and gets back a view — the cards it is entitled to see, and the script of how they arrived, one event per card off the shoe. The dealer's hole card is not in the payload at all until the reveal, because a field the client is told to ignore is a field somebody reads in devtools. The shoe lives in game_live_hands, which also means a redeploy mid-hand no longer costs a player their stake: the hand is still there when they come back. The money is ordered so nothing can be spent twice. The stake leaves the stack in the same statement that checks it exists, before a card is dealt. Every new hand is seated with a plain INSERT, so a double-clicked Deal is decided by the primary key rather than by a read that raced — it loses, gets its chips back, and the hand in progress is untouched. A double takes its raise up front and hands it straight back if the engine refuses the move. Cards are dealt rather than swapped in — they fly out of the shoe and turn over, which was a requirement and not a flourish. The faces and the chips are still plain; that's next.
46 lines
2.5 KiB
HTML
46 lines
2.5 KiB
HTML
{{define "_chipbar"}}
|
|
<section data-chipbar
|
|
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 class="min-w-0">
|
|
<div class="text-xs font-semibold uppercase tracking-wider text-[color:var(--ink)]/50">Chips in front of you</div>
|
|
<div class="flex items-baseline gap-2">
|
|
<span data-chips class="font-display text-3xl font-bold tabular-nums">—</span>
|
|
<span data-pending class="hidden text-sm font-semibold text-[color:var(--ink)]/60 animate-pulse"></span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="min-w-0">
|
|
<div class="text-xs font-semibold uppercase tracking-wider text-[color:var(--ink)]/50">Your wallet</div>
|
|
<div class="flex items-baseline gap-1.5">
|
|
<span data-euros class="font-display text-2xl font-bold tabular-nums text-[color:var(--ink)]/70">—</span>
|
|
<span class="text-sm text-[color:var(--ink)]/40" title="Pete reads this off the game box every couple of minutes, so it lags a little.">€, give or take</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="ml-auto flex flex-wrap items-center gap-2">
|
|
<div class="flex items-center gap-1.5 rounded-full bg-[color:var(--ink)]/5 p-1.5">
|
|
<label for="buyin-amount" class="sr-only">How many chips?</label>
|
|
<input id="buyin-amount" data-buyin-amount type="number" min="1" step="1" value="100"
|
|
inputmode="numeric" enterkeyhint="go"
|
|
class="w-24 rounded-full bg-[color:var(--card)] px-3 py-1.5 text-sm font-semibold tabular-nums
|
|
border-2 border-[color:var(--ink)]/10 focus:outline-none focus:border-[color:var(--accent)]">
|
|
<button type="button" data-buyin
|
|
class="rounded-full bg-[color:var(--accent)] px-4 py-1.5 text-sm font-bold text-white shadow-pete
|
|
hover:brightness-105 active:translate-y-px disabled:opacity-40 disabled:pointer-events-none transition">
|
|
Buy chips
|
|
</button>
|
|
</div>
|
|
<button type="button" data-cashout
|
|
class="rounded-full bg-[color:var(--card)] px-4 py-2 text-sm 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">
|
|
Cash out
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<p data-chipbar-msg class="hidden mt-3 rounded-2xl bg-[color:var(--ink)]/5 px-4 py-2 text-sm font-semibold"></p>
|
|
</section>
|
|
{{end}}
|