:root {
  --sand: #d8b384;
  --rust: #8c4a2f;
  --ink: #241a14;

  /* Overwritten from the live view size on boot: the PC build is a 1.6 landscape
     box and the mobile one a 19.5:9 upright slab, and the letterboxing has to
     follow whichever is running. */
  --aspect: 1.6;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: #120d0a;
  color: #f4e6d2;
  font-family: "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  overflow: hidden;
  overscroll-behavior: none;
  touch-action: none;
}

/* ---- the swipe is ours, not the browser's -------------------------------

   `touch-action` is not an inherited property. Declaring it on html and body
   above says nothing at all about the two elements a finger actually lands
   on -- the stage, and the canvas inside it -- which were left at the initial
   `auto`, and `auto` means "this might be a scroll".

   So every lane-change swipe was offered to the browser first, and on Android
   that is both expensive and visible. Chrome holds the pointer stream back
   while it decides whether the gesture is a pan, which is the stutter; and it
   runs its address-bar show/hide against the same gesture, which resizes the
   viewport in the middle of the swipe. Each of those resizes used to
   re-allocate the canvas and wipe it -- see `resize` in main.js, which no
   longer does -- and what the player saw was the HUD and its text blinking
   out for a frame, every time they changed lane.

   Declared here on the elements that receive the touches. The rules above
   stay as they are: they are still right for the document, and they are what
   stops the document itself scrolling.

   The other three are the same idea said three more ways. A slow drag across
   a canvas is otherwise a text selection, a held finger is a long-press
   callout, and a tap on Android paints a grey box over whatever was tapped --
   all of them the browser answering a gesture the game has already answered. */
#stage, #game {
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}

#stage {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    radial-gradient(ellipse at 50% 30%, #2b1f17 0%, #120d0a 70%);
}

#game {
  display: block;

  /* The box to fit the canvas into: the viewport less anything the hardware
     has taken out of it. The page head no longer asks for "viewport-fit=cover"
     -- see the note there -- so on most browsers these now resolve to zero and
     the subtraction is a no-op, the browser having already kept us out of the
     notch and the button row. They stay because a browser that does report an
     inset is telling us something true, and because the day the cover flag
     comes back this is what makes it safe. The 0px fallbacks matter -- an
     env() a browser does not know, with no fallback, invalidates the whole
     declaration. */
  --inset-x: calc(env(safe-area-inset-left, 0px) + env(safe-area-inset-right, 0px));
  --inset-y: calc(env(safe-area-inset-top, 0px) + env(safe-area-inset-bottom, 0px));
  --fit-w: calc(100vw - var(--inset-x));
  --fit-h: calc(100vh - var(--inset-y));

  width: min(var(--fit-w), calc(var(--fit-h) * var(--aspect)));
  height: min(var(--fit-h), calc(var(--fit-w) / var(--aspect)));
  image-rendering: auto;
  background: #7cb4e2;
  box-shadow: 0 0 0 2px #3d2a1d, 0 18px 60px rgba(0, 0, 0, .75);
  cursor: default;
}

/* ---- the one text box ----------------------------------------------------

   The email address and the code on the profile card. Everything else in the
   game is drawn into the canvas, and this is drawn there too -- the box, its
   border, the gold when it is chosen -- so the input itself is transparent
   and contributes only what a canvas cannot: a caret, the characters, a
   phone's keyboard, a password manager's autofill and iOS offering the code
   straight out of Mail. src/render/profile.js moves it over the drawn box on
   every frame and sets its size and font size from the canvas's scale.

   The stage above says `user-select: none` and `-webkit-touch-callout: none`
   for everything a finger lands on, which in here would mean a box you could
   not select text in or paste into. They are put back. `touch-action` goes to
   manipulation rather than none, so a tap focuses it at once instead of
   waiting to see whether it was the start of a double tap. */
.dl-field {
  position: absolute;
  z-index: 2;
  margin: 0;
  border: 0;
  border-radius: 0;
  outline: none;
  background: transparent;
  box-shadow: none;
  color: #fff3d6;
  caret-color: #ffd24a;
  font-family: "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  font-weight: 700;
  -webkit-appearance: none;
  appearance: none;
  touch-action: manipulation;
  user-select: text;
  -webkit-user-select: text;
  -webkit-touch-callout: default;
}

.dl-field::placeholder {
  color: #6f6557;
  opacity: 1;
}

.dl-field:disabled {
  color: #8d8172;
}

/* A browser that fills the address in from its own memory paints the box pale
   blue or yellow to say so, straight over the card. The paint is a background
   that cannot be overridden, only delayed -- for about a week. */
.dl-field:-webkit-autofill,
.dl-field:-webkit-autofill:hover,
.dl-field:-webkit-autofill:focus {
  -webkit-text-fill-color: #fff3d6;
  caret-color: #ffd24a;
  transition: background-color 600000s 0s, color 600000s 0s;
}

/* ---- the mobile viewport, which is not the height it claims to be ----------

   On a phone, 100vh is the height the page would have if the browser's toolbar
   were hidden, while a percentage height resolves against what is actually on
   screen. The two disagree by the depth of the toolbar, and the canvas was
   sized by the larger of them -- so its bottom, which is where the whole HUD
   band lives, was pushed under the fold and clipped by `overflow: hidden`.

   dvh is the unit that means what it says. It is overridden here rather than
   written above so that a browser without it keeps the vh version and still
   gets something sensible. */
@supports (height: 100dvh) {
  html, body { height: 100dvh; }
  #game { --fit-h: calc(100dvh - var(--inset-y)); }
}
