Every run gets a door out: the quit chip and the LEAVE THE MATCH? ask

"all tennis screens are missing the ability to exit the game and return to
the menu — right now I need to force close the app." A quiet x chip rides the
top-right corner of every run (the scoreboard owns the left; the desktop key
hint shifts inboard). Tapping it — or Escape on desktop — freezes the world
with the existing paused flag and asks LEAVE THE MATCH?: BACK TO THE MENU in
the menu's crimson, PLAY ON underneath. Quitting is the death path minus the
death — restartRun, refreshSplash, splash — and banks nothing: an abandoned
run never happened, statistically. Verified live both ways: PLAY ON resumes
the frozen rally, quitting lands on the splash with the chip retired.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Fable 5 committed 2026-08-14 12:07:10 +02:00
1 parent 1facc954e2
commit 11ca935ad0
2 files changed
+46 -3

No files matched your search

+24 -3
View File
@@ -78,9 +78,22 @@ if (location.hostname !== 'splatter-tennis.wuwi.one') {
html { height: 100vh; }
canvas { height: calc(100vh - env(safe-area-inset-top, 0px)); }
}
/* desktop key hint — up in the empty top-right corner now that the rack owns the bottom edge */
#hint { position: fixed; top: 6px; right: 10px; text-align: right;
/* desktop key hint — top-right, shifted left of the quit chip that owns the corner now */
#hint { position: fixed; top: 6px; right: 52px; text-align: right;
font: 400 10px Silkscreen, monospace; color: #6b7688; }
/* THE DOOR OUT (Oliver: every tennis screen lacked an exit — force-closing the app was the only
way back to the menu). A quiet chip during play; tapping it freezes the world and asks. */
#quit { position: fixed; top: calc(env(safe-area-inset-top, 0px) + 8px); right: 8px; z-index: 5; }
#quit button { width: 34px; height: 34px; background: rgba(14,23,20,0.72); border: 2px solid var(--line);
color: var(--dim); font: 400 15px Silkscreen, monospace; cursor: pointer;
-webkit-tap-highlight-color: transparent; }
#qAsk { position: fixed; inset: 0; z-index: 6; background: rgba(0,0,0,0.55);
display: flex; align-items: center; justify-content: center; }
#quit[hidden], #qAsk[hidden] { display: none; }
.qBox { background: var(--solid); border: 2px solid var(--line); padding: 18px 16px;
width: min(320px, 84vw); display: flex; flex-direction: column; gap: 10px; }
.qBox p { margin: 0 0 6px; font: 400 12px Silkscreen, monospace; color: var(--cream);
text-align: center; letter-spacing: 1px; }
@media (pointer: coarse) { #hint { display: none; } }
/* ---- THE MENU PALETTE. The canvas HUD keeps its own blue-grey and gold; the menus are
deliberately a different room — dark court green, one acid accent, and one crimson reserved for
@@ -355,6 +368,14 @@ if (location.hostname !== 'splatter-tennis.wuwi.one') {
<canvas id="c" width="480" height="270"></canvas>
<div id="safe"></div>
<div id="hint">move: WASD/arrows &nbsp;·&nbsp; serve/swing: SPACE &nbsp;·&nbsp; aim: hold a direction while swinging &nbsp;·&nbsp; T: tuning panel</div>
<div id="quit" hidden><button id="qChip">&#10005;</button></div>
<div id="qAsk" hidden>
<div class="qBox">
<p>LEAVE THE MATCH?</p>
<button class="btn big" id="qYes">BACK TO THE MENU</button>
<button class="btn sec" id="qNo">PLAY ON</button>
</div>
</div>
<div id="intro" data-stage="splash">
<div class="card">
<!-- The title screen IS the menu. A separate menu stage behind it was the same logo over the
@@ -471,6 +492,6 @@ if (location.hostname !== 'splatter-tennis.wuwi.one') {
</div>
</div>
</div>
<script type="module" src="src/main.js?v=237"></script>
<script type="module" src="src/main.js?v=238"></script>
</body>
</html>