body {
  margin: 0;
  padding: 0;
  color: rgba(255, 255, 255, 0.87);
  background-color: #000000;
  /* Ticket #33: the canvas owns every gesture; no scroll, zoom, or
       pull-to-refresh underneath a drag, and no long-press text selection. */
  touch-action: none;
  overscroll-behavior: none;
  -webkit-user-select: none;
  user-select: none;
}

#app {
  width: 100%;
  height: 100vh;
  /* The small viewport, which is the window with the browser's chrome fully
       expanded, less the bottom safe-area inset the entry point reads once at
       boot and writes to --inset-bottom. Small rather than dynamic because a
       dynamic height re-fits the field under the player as the chrome
       retracts, and read once rather than live because the inset itself moves
       with the toolbar on iOS Safari and Chrome Android. The box the renderer
       measures is then clear of the home indicator and never changes again.
       env(safe-area-max-inset-bottom) is the static value this wants and
       Safari does not carry it yet. */
  height: calc(100svh - var(--inset-bottom, 0px));
  overflow: hidden;
  display: flex;
  justify-content: center;
  align-items: center;
}
