Files
casino/cmd/arcade/static/index.html
drjones 48a9120fe4 feat: auto cash-out targets, 1% house edge, terminal aesthetic
Auto cash-out closes a position at exactly the chosen target rather than
the next tick's multiplier, and fires whenever the target is at or below
the crash point. This is the feature that makes the game playable over a
network, where manual timing is at the mercy of latency.

House edge drops from 2% to 1% across crash and scratch. Scratch prize
tables retuned so the published 99% RTP is exact.

Adds docs/API.md: the client uses no private endpoints, so anyone can
write a bot against the same API.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 16:24:31 +00:00

147 lines
5.0 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<title>QUANTUM ARCADE</title>
<link rel="stylesheet" href="/style.css">
</head>
<body>
<!-- Ornate background filigree, drawn once as an SVG pattern and tiled. -->
<svg class="filigree" aria-hidden="true">
<defs>
<pattern id="orn" width="60" height="52" patternUnits="userSpaceOnUse">
<g fill="none" stroke="currentColor" stroke-width="0.7">
<path d="M15 0 L45 0 L60 26 L45 52 L15 52 L0 26 Z"/>
<path d="M30 26 L60 26 M30 26 L15 0 M30 26 L15 52"/>
<circle cx="30" cy="26" r="1.6"/>
<circle cx="0" cy="26" r="1.2"/>
<circle cx="60" cy="26" r="1.2"/>
</g>
</pattern>
</defs>
<rect width="100%" height="100%" fill="url(#orn)"/>
</svg>
<header class="topbar">
<div class="brand">QUANTUM<span>ARCADE</span></div>
<div class="balance" id="balance-wrap" hidden>
<span class="label">balance</span>
<span class="value" id="balance"></span>
</div>
<button class="sound" id="sound-toggle" title="Ambient sound"></button>
</header>
<!-- Sign-in: a nickname and nothing else. -->
<section class="panel center" id="signin">
<h1>ACCESS TERMINAL</h1>
<p class="muted small">
No account. No email. No password. This device generated a keypair that
<em>is</em> your identity. Keep the device, keep the balance.
</p>
<input id="nickname" maxlength="20" placeholder="handle" autocomplete="off">
<button class="primary" id="enter">Connect</button>
<p class="fineprint" id="keynote"></p>
</section>
<main id="app" hidden>
<nav class="tabs">
<button class="tab active" data-view="crash">Crash</button>
<button class="tab" data-view="scratch">Scratchers</button>
<button class="tab" data-view="wallet">Wallet</button>
<button class="tab" data-view="verify">Verify</button>
</nav>
<!-- ============ CRASH ============ -->
<section class="view" id="view-crash">
<div class="gamepick" id="gamepick"></div>
<div class="stage">
<canvas id="canvas"></canvas>
<div class="readout">
<div class="multiplier" id="multiplier">1.00×</div>
<div class="state" id="state">connecting…</div>
</div>
</div>
<div class="controls">
<div class="stakerow">
<button class="chip" data-stake="1000">1</button>
<button class="chip" data-stake="5000">5</button>
<button class="chip" data-stake="25000">25</button>
<button class="chip" data-stake="100000">100</button>
<span class="unit">sats</span>
</div>
<div class="autorow" id="autorow">
<label for="auto-target">auto&nbsp;out</label>
<input id="auto-target" type="number" min="1.01" step="0.1"
inputmode="decimal" placeholder="off">
<span class="x">×</span>
</div>
<button class="primary big" id="action">Place bet</button>
<div class="hint" id="hint"></div>
</div>
<div class="players" id="players"></div>
<details class="proof">
<summary>Fairness for this round</summary>
<div class="kv"><span>commitment</span><code id="commitment"></code></div>
<div class="kv"><span>revealed seed</span><code id="revealed">sealed until the round ends</code></div>
<p class="muted small">
The commitment is published before betting opens. The crash point is
derived from that seed combined with every player's key — so it cannot
be chosen after seeing who joined.
</p>
</details>
</section>
<!-- ============ SCRATCH ============ -->
<section class="view" id="view-scratch" hidden>
<div id="tickets"></div>
</section>
<!-- ============ WALLET ============ -->
<section class="view" id="view-wallet" hidden>
<div class="card">
<h2>Your key</h2>
<p class="muted small">Share this so friends can send you sats.</p>
<code class="pubkey" id="pubkey"></code>
<button id="copykey">Copy</button>
</div>
<div class="card">
<h2>Send sats</h2>
<input id="to-key" placeholder="recipient key" autocomplete="off">
<input id="send-amt" type="number" min="1" placeholder="amount in sats">
<button class="primary" id="send">Send</button>
<div class="hint" id="send-hint"></div>
</div>
<div class="card">
<h2>Every change to your balance</h2>
<div id="history" class="history"></div>
</div>
</section>
<!-- ============ VERIFY ============ -->
<section class="view" id="view-verify" hidden>
<div class="card">
<h2>Check any round</h2>
<p class="muted small">
Enter a round number. Your phone recomputes the outcome from the
published seeds — it does not take the server's word for anything.
</p>
<input id="verify-id" type="number" min="1" placeholder="round number">
<button class="primary" id="do-verify">Verify</button>
<div id="verify-out" class="verify-out"></div>
</div>
</section>
</main>
<script src="/app.js"></script>
</body>
</html>