/* ------------------------------------------------------------ viewport lock
   Everything here exists to stop the page itself from moving while a small
   finger drags across it: no scroll, no bounce, no pinch, no pull-to-refresh,
   no text selection, no long-press callout. */

:root {
  /* Taken from the scene itself, so the chrome belongs to the same world:
     forest floor, canopy, sunlit leaf, warm sky, the truck's own brass. */
  --bg:        #16241d;
  --forest:    #1d3a2c;
  --moss:      #2f6b4f;
  --leaf:      #4f9d70;
  --leaf-lit:  #8ecb8a;
  --line:      #2c5642;
  --ink:       #eef6ee;
  --ink-soft:  #9fc3ad;
  --brass:     #c99a2e;
  --brass-dim: rgba(201, 154, 46, .17);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
  background: var(--bg);
}

body {
  position: fixed;
  inset: 0;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
  color: var(--ink);
  font: 500 16px/1.4 ui-rounded, "SF Pro Rounded", system-ui, -apple-system,
        "Segoe UI", Roboto, sans-serif;
}

/* ------------------------------------------------- the instruction line, and
   the board it sits over. Nothing here is a permanent floating button beyond
   the two round ones: there is deliberately nothing else on screen for him to
   press by accident.

   Edge to edge. The framebuffer is resized to the viewport's aspect, so
   filling the box never stretches a pixel. */

#board {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  background: var(--bg);
  image-rendering: pixelated;
  touch-action: none;
}

.hint {
  position: fixed;
  left: 50%;
  /* Along the top, out of the scene. At the bottom it sat over the pond,
     which is exactly where he is playing. Clears the menu button on the
     left and the readout on the right. */
  top: calc(env(safe-area-inset-top) + 14px);
  transform: translateX(-50%);
  max-width: 46%;
  padding: 8px 16px;
  border-radius: 9px;
  background: rgba(13, 19, 24, .62);
  backdrop-filter: blur(6px);
  font-size: 14px;
  pointer-events: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 1;
  transition: opacity .35s ease;
}
.hint[hidden] { display: none; }
.hint.spent { opacity: 0; }

/* ------------------------------------------------- the truck's own controls
   Two round buttons along the top: which truck, and which way round. They are
   floating controls, unlike the game switcher — pressing either by accident
   changes the truck or turns it, and both are things he might want anyway.

   Along the top rather than the bottom because the bottom of the screen is
   where the driving happens, and a button there is under his hand all game. */

.controls {
  position: fixed;
  top: calc(env(safe-area-inset-top) + 12px);
  right: calc(env(safe-area-inset-right) + 14px);
  display: flex;
  gap: 10px;
  z-index: 4;
}

.round {
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  padding: 0;
  border-radius: 50%;
  border: 1px solid rgba(201, 154, 46, .30);
  background: rgba(18, 24, 30, .38);
  backdrop-filter: blur(4px);
  color: rgba(201, 154, 46, .86);
  cursor: pointer;
  touch-action: manipulation;
  transition: transform .12s ease, color .25s ease, border-color .25s ease;
}
.round[hidden] { display: none; }
.round:active { background: var(--brass-dim); transform: scale(.92); }

/* The mode button wears the colour of the truck it will give you, so the
   answer to "what does this do" is the button itself. */
.mode { color: rgba(201, 154, 46, .9); }
.mode.gomi { color: #79a8e8; border-color: rgba(121, 168, 232, .40); }
.mode.gomi:active { background: rgba(121, 168, 232, .18); }
.mode.bus { color: #f0c04a; border-color: rgba(240, 192, 74, .42); }
.mode.bus:active { background: rgba(240, 192, 74, .18); }
.controls[hidden] { display: none; }

/* The two bus buttons. They only exist on the school run, and they wear the
   colour of the bus he currently has rather than of the one they will give
   him: unlike the vehicle button, these do not point somewhere — they say
   "this is yours, press to change it". Their colour is written from Rust's
   own palette so the two can never drift apart. */
.shape, .paint { color: rgba(240, 192, 74, .9); border-color: rgba(240, 192, 74, .34); }
.shape:active, .paint:active { background: rgba(240, 192, 74, .18); }
.round .ic { width: 27px; height: 17px; fill: currentcolor; }
.round .ic[hidden] { display: none; }

#turn .stroke { width: 22px; height: 22px; fill: none; stroke: currentcolor;
                stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
                transition: transform .42s cubic-bezier(.34,1.3,.5,1); }
#turn.spun .stroke { transform: rotate(180deg); }

@media (orientation: landscape) and (max-height: 520px) {
  .controls { top: 8px; right: 10px; gap: 8px; }
  .round { width: 42px; height: 42px; }
  .round .ic { width: 24px; height: 15px; }
  #turn .stroke { width: 19px; height: 19px; }
}

/* ----------------------------------------------------------------- the menu
   A real button now, but the quietest one on the screen: small, translucent,
   and tucked into the corner. */

.menu-btn {
  position: fixed;
  top: calc(env(safe-area-inset-top) + 12px);
  left: calc(env(safe-area-inset-left) + 12px);
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid rgb(255 255 255 / 12%);
  border-radius: 12px;
  background: rgb(18 24 30 / 30%);
  backdrop-filter: blur(4px);
  color: rgb(230 237 233 / 55%);
  cursor: pointer;
  touch-action: manipulation;
  z-index: 5;
}
.menu-btn svg { width: 20px; height: 20px; fill: currentcolor; }
.menu-btn:active { background: var(--brass-dim); color: var(--brass); }

/* ------------------------------------------------------- landscape, or ask
   A side-on driving game in a tall frame is a band along the bottom of a
   screenful of nothing. Rather than build a second layout nobody wants, the
   page asks to be turned — and everything behind this is written for a wide
   frame only. */

.turnme {
  /* Orientation is a CSS question, so CSS answers it. Gating this in
     JavaScript meant a portrait device showed a blank canvas for as long as
     the module took to arrive. */
  display: none;
  position: fixed;
  inset: 0;
  z-index: 30;
  place-content: center;
  justify-items: center;
  gap: 8px;
  padding: 24px;
  text-align: center;
  background: linear-gradient(160deg, #2b6ea8 0%, #6fa8c4 46%, #cbd9a8 100%);
  color: #14301f;
}

@media (orientation: portrait) {
  .turnme { display: grid; }
}
.turnme p {
  margin: 12px 0 0;
  font-size: 21px;
  font-weight: 800;
  letter-spacing: .01em;
}
.turnme span { font-size: 15px; font-weight: 700; color: #2f5c3f; }
.turnme .tablet {
  width: 132px;
  height: 132px;
  transform-origin: 60px 60px;
  animation: tip 2.6s ease-in-out infinite;
}
.turnme .slab  { fill: #2f6b4f; }
.turnme .glass { fill: #cfe6d2; }
.turnme .arrow {
  fill: none;
  stroke: #14301f;
  stroke-width: 6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

@keyframes tip {
  0%, 42%  { transform: rotate(0deg); }
  62%, 88% { transform: rotate(-90deg); }
  100%     { transform: rotate(0deg); }
}

/* -------------------------------------------------------------- the switcher */

.sheet {
  position: fixed;
  inset: 0;
  z-index: 10;
  display: grid;
  place-items: center;
  padding: 20px;
  background: radial-gradient(120% 90% at 50% 0%,
              rgb(47 107 79 / 92%) 0%, rgb(22 36 29 / 96%) 78%);
  backdrop-filter: blur(10px);
  opacity: 0;
  pointer-events: none;
  transition: opacity .16s;
}
.sheet.open { opacity: 1; pointer-events: auto; }

.sheet-inner {
  width: min(460px, 100%);
  display: grid;
  gap: 12px;
}

/* The one piece of prose in the game. It is for the parent, it appears only
   when asked for, and it is never on screen while the child is playing. */
.how {
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink);
  background: rgb(12 20 16 / 55%);
  border: 2px solid var(--line);
  border-radius: 18px;
  padding: 14px 16px;
  text-align: left;
}
.how[hidden] { display: none; }
.how b { color: var(--brass); }
.how ol { margin: 6px 0 0; padding-left: 20px; }
.how li { margin: 4px 0; }

/* Four big soft targets, not a row of small words. A grown-up opening this
   with a child in their lap should be able to hit any of them without
   looking, and there should be nothing here to read out loud. */
.sheet .minor {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: 12px;
}
.sheet .minor button {
  display: grid;
  gap: 5px;
  justify-items: center;
  font: inherit;
  font-size: 15px;
  font-weight: 700;
  color: var(--ink);
  background: var(--forest);
  border: 2px solid var(--line);
  border-radius: 18px;
  padding: 16px 10px;
  cursor: pointer;
  touch-action: manipulation;
  transition: transform .12s ease, background .18s ease;
}
.sheet .minor button i { font-size: 25px; font-style: normal; line-height: 1; }
.sheet .minor button:active {
  background: var(--moss);
  border-color: var(--leaf);
  transform: scale(.95);
}
.sheet .minor button[hidden] { display: none; }
.sheet .minor button.off { color: var(--ink-soft); }
.sheet .minor button.off i { opacity: .45; }

#close {
  font: inherit;
  font-size: 17px;
  font-weight: 800;
  color: #16241d;
  background: var(--leaf-lit);
  border: 0;
  border-radius: 18px;
  padding: 17px;
  margin-top: 2px;
  cursor: pointer;
  touch-action: manipulation;
}
#close:active { background: var(--leaf); }

:focus-visible { outline: 2px solid var(--brass); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
}
