Run the art to the bottom edge, lift only the rack

The remaining gap was the home-indicator inset being reserved on the canvas
element. Unlike the status bar that is a slim translucent bar, not opaque UI,
so the canvas now runs to the physical bottom edge and the court art fills it —
only the weapon rack and the draw meter lift clear of it, through SAFE.bottom.
The top keeps its element inset, since the scoreboard genuinely has to clear
the status bar.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Opus 5 committed 2026-07-30 18:37:09 +02:00
1 parent 90aefdce27
commit c601035eab
3 files changed
+29 -17

No files matched your search

+7 -5
View File
@@ -182,11 +182,13 @@ zombie (now an occasional opponent, `TUNE.racketEvery`, not the every-game fixtu
because the wave grows with `hordeGrow` while the panic button was a flat 1 s; he chose scaling the
melee over shrinking the horde. **Measure the crowd BEFORE calling `meleeSwipe`** — it kills
everything in reach, so counting after counts the survivors and the cooldown barely moves.
- **The safe area is handled in ONE place: index.html's canvas rule.** The canvas is `position: fixed`
and inset by `env(safe-area-inset-*)`, so the whole game sits inside the safe region — nothing ever
renders under the notch, the status bar or the home indicator. `render.js` does NOT offset the HUD as
well (`SAFE` stays at zero); doing both subtracts the notch twice. Full-bleed with an inset HUD was
tried first and Oliver rejected it twice.
- **The safe area is handled ASYMMETRICALLY, on purpose.** TOP: index.html insets the canvas element
below the status bar, because that is opaque UI the scoreboard must clear - `SAFE.top` stays 0, and
adding a HUD offset there as well subtracts the notch twice. BOTTOM: the canvas deliberately runs to
the PHYSICAL bottom edge so the court art fills the screen (the home indicator is a slim translucent
bar, not opaque UI); only the interactive RACK and the draw meter lift clear of it, via
`SAFE.bottom`, which `measureSafe` reads from the hidden `#safe` probe (env() is CSS-only).
Reserving the bottom inset on the element instead just left a dead band.
- **The canvas is STRETCHED by CSS (100vw x 100dvh minus insets) and `fitViewport` derives the logical
grid from the box it was actually given** — `cv.clientWidth/clientHeight`, never `innerWidth/innerHeight`.
Sizing it the other way round (compute a scale, then set explicit px) laid it out against whatever