*{margin:0;padding:0;box-sizing:border-box}
html,body{
  width:100%;height:100%;overflow:hidden;background:#07060d;
  -webkit-user-select:none;user-select:none;
  -webkit-tap-highlight-color:transparent;
  touch-action:none;
  overscroll-behavior:none;
  /* iOS rubber-bands the page behind a canvas game and hands the address bar
     back mid-swipe; pinning the body kills both. */
  position:fixed;inset:0;
  -webkit-text-size-adjust:100%;
}
/* The OS pointer is hidden everywhere, because the game draws its own pixel
   cursor everywhere. That is only true now that the canvas spans the whole
   viewport and drawCursorLayer() runs in canvas space (js/core.js tick()) —
   there is no longer any pixel on the page with neither an OS cursor nor a
   drawn one. An earlier revision scoped this to #screen alone to stop the
   pointer vanishing over the letterbox; the letterbox is now part of the
   canvas, so that workaround would just re-introduce an OS arrow on top of
   the pixel one. Do not narrow this back down. */
body{cursor:none}
#screen{cursor:none}
/* Only hide the pointer where there IS one. On a touch device the game draws
   no cursor at all, and forcing cursor:none there breaks nothing but also
   helps nothing — it just confuses a plugged-in mouse. */
@media (hover:none) and (pointer:coarse){
  body,#boot,#screen{cursor:auto}
}
#stage{
  /* Sized from JS, not from inset:0. On iOS the LAYOUT viewport keeps counting
     the space under the collapsing toolbars while the VISUAL viewport does not,
     and the canvas is measured against the visual one — so centring the canvas
     inside a layout-viewport-sized stage pushes it partly under the chrome.
     core.js drives top/left/width/height from the same measurement it uses for
     the canvas. On desktop the two viewports agree and this is inset:0. */
  position:fixed;top:0;left:0;width:100%;height:100%;
  /* LOAD-BEARING: the canvas is sized to cover the viewport and then rounded
     UP to a multiple of 8 virtual px, so it overhangs the stage by a few
     device px on one axis. This clips that overhang. */
  overflow:hidden;
  line-height:0;
  /* Only ever visible for the frame or two before the canvas paints, and
     behind the clipped overhang above. The letterbox itself is no longer a
     CSS concern at all — it's inside the canvas now, drawn as pixel art by
     js/border.js. Kept dark so the first paint doesn't flash. */
  background-color:#0a0813;
}
#screen{
  display:block;
  position:absolute;top:50%;left:50%;
  transform:translate(-50%,-50%);
  image-rendering:pixelated;
  image-rendering:-moz-crisp-edges;
  image-rendering:crisp-edges;
  background:#0b0a12;
  /* No CSS framing here any more. Three attempts at dressing the letterbox
     from OUTSIDE the canvas (a repeating dot grid, a vignette + bloom, then a
     flat bezel) all read as wrong beside the pixel art, and none of them could
     ever satisfy the harder requirement: the game's own cursor has to stay
     visible out there, and the game cannot draw outside its canvas. So the
     canvas grew to cover the whole viewport and the border is now pixel art,
     baked by js/border.js from the same palette and the same warehouse. */
}

/* ---- boot overlay: a transparent layer that exists only for its fade. The
       visible splash is canvas pixel art, and the first-gesture handler that
       unlocks WebAudio now lives on the window (js/main.js).
       pointer-events:none from the start is what lets it stay full-viewport
       without owning the CSS `cursor` for the whole page: while it was
       hit-testable it sat on top of both the canvas and the letterbox bars,
       so its own cursor rule beat the scoped ones below and the pointer went
       invisible over the bars during boot. ---- */
#boot{
  position:fixed;inset:0;z-index:50;
  background:transparent;
  pointer-events:none;
  transition:opacity .35s ease;
}
#boot.hide{opacity:0}

/* ---- safe-area probe: env() is unreadable from JS, so hang the four insets
       on a zero-size element's padding and let core.js read them back. ---- */
#safe{
  position:fixed;top:0;left:0;width:0;height:0;
  visibility:hidden;pointer-events:none;
  padding:env(safe-area-inset-top) env(safe-area-inset-right)
          env(safe-area-inset-bottom) env(safe-area-inset-left);
}

