/* mobilescroll.css — the outpost and the garage scroll on a phone (2026-08-26, lane ANIM/a7)
 *
 * THE OWNER, flagged priority: "In the mobile UI, when you are in the outpost, garage, etc. You
 * can't scroll down to see your vehicles or the bottom of pages."
 *
 * WHY THIS IS ITS OWN FILE AND NOT FOUR LINES IN style.css. style.css is CLAIMED by a13-lamplight
 * and they are mid-batch; the radio rule is that a claimed file is not edited, and an urgent bug
 * does not suspend it. This sheet is linked immediately AFTER style.css, so it is a pure cascade
 * override with no specificity tricks: every rule below restates the same selector weight the
 * original used and wins on order alone. WHOEVER OWNS style.css NEXT SHOULD FOLD THESE IN AND
 * DELETE THIS FILE — it is a coordination artifact, not an architecture.
 *
 * TWO INDEPENDENT BUGS. Both were found by reading style.css against game3d.js's own adoption
 * contract, and each is a different way for content to become unreachable.
 */

/* ------------------------------------------------------------------ 1. THE CENTRED DIALOG
 *
 * `#garage3d` and `#outpost3d` are full-bleed flex containers with `align-items: center` and no
 * overflow. A box SHORTER than the viewport centres, which is what was wanted. A box TALLER than
 * the viewport overflows EQUALLY IN BOTH DIRECTIONS — and the overflow above the container's top
 * edge is unreachable by any scroll, because scrolling only ever reveals content below the start
 * edge. On a 390x844 phone the garage's twelve-stat vehicle cards clear that height easily, so
 * the bottom of the list was simply gone.
 *
 * THE FIX IS `margin: auto` ON THE BOX, NOT CENTRING ON THE CONTAINER. `align-items: center` and
 * `justify-content: center` are the trap; `auto` margins on a flex CHILD centre it while it fits
 * and collapse to zero the moment it does not, so a tall box starts flush at the top edge and
 * every pixel of it is inside the scrollable area. This is the standard remedy and it needs no
 * media query: the desktop behaviour at every size where the box fits is byte-identical.
 */
body.wrecker3d #garage3d,
body.wrecker3d #outpost3d,
body.wrecker3d #shop3d {
  align-items: flex-start;
  justify-content: flex-start;
  overflow-y: auto;
  /* Momentum scrolling on iOS, and a scroll chain that stops at the dialog rather than dragging
     the page behind it. `contain` and not `none`: the dialog should still bounce at its own
     ends, which is the feedback that tells a thumb it has reached the bottom. */
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}
body.wrecker3d #garage3d > .shop-box,
body.wrecker3d #garage3d > .garage-box,
body.wrecker3d #outpost3d > .shop-box,
body.wrecker3d #shop3d > .shop-box {
  margin: auto;
  /* A flex child may not shrink below its content by default, but it MAY be told not to grow
     past it either; without this the box can stretch to the container and re-create the clip it
     was just freed from. */
  flex: 0 0 auto;
}

/* ------------------------------------------------------------------ 2. THE ADOPTION WHITELIST
 *
 * The hub does not build its body — it ADOPTS one. game3d.js states the set in its own contract
 * (game3d.js, "IT ADOPTS, IT DOES NOT COPY"): #garage-panel3d, #shop-grid3d, #shop-repair3d and
 * #shop-fence3d are moved into the one content slot and handed back on close. adoptBay() also
 * appends roadBody(), built at runtime, and whereStrip().
 *
 * style.css grants the scroll to THREE selectors — #shop-grid3d, #garage-panel3d and .pk-body —
 * under a blanket `body.wrecker3d .op-body > * { flex: 0 0 auto; }` and an `.op-body` that is
 * `overflow: hidden`. So #shop-fence3d and roadBody() are pinned at their natural height inside a
 * clipping parent: THE FENCE AND THE ROAD BAYS COULD NOT SCROLL AT ALL, and nothing below the
 * fold in them was reachable by any gesture.
 *
 * A WHITELIST OF ADOPTABLE BODIES IS THE WRONG SHAPE and that is the real finding. The list lives
 * in two files that cannot see each other, so every panel adopted from here on is one edit away
 * from being silently unscrollable — which is exactly how these two got missed. The rule below is
 * therefore stated as "the LAST element child of .op-body is the body, and the body scrolls",
 * which is true by construction of adoptBay(): the pinned furniture (FIELD REPAIR, the WHERE
 * strip, the rig-cost plate) is appended BEFORE the body in every branch. It cannot miss a panel
 * that does not exist yet.
 *
 * `:last-child` and not `:has()`: it is supported everywhere this game runs, including the iOS
 * versions the svh fallback at the top of style.css is written for. EXACTLY ONE SCROLLER is
 * preserved — this grants it to one child and the named three keep it, and no child is ever
 * granted it twice.
 */
body.wrecker3d .op-body > :last-child {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}
/* ...but never the pinned furniture, even when it lands last (an empty bay, a hidden grid). Those
   are pinned BY NAME in style.css and they stay pinned; a plate that grew a scrollbar because it
   happened to be last would be a new bug in place of the old one. */
body.wrecker3d .op-body > #shop-repair3d:last-child,
body.wrecker3d .op-body > .op-where:last-child,
body.wrecker3d .op-body > #op-rigcost3d:last-child {
  flex: 0 0 auto;
  overflow-y: visible;
}

/* ------------------------------------------------------------------ 3. THE FLOOR UNDER BOTH
 *
 * Whatever else is true, a dialog must never be taller than the space it is given while hiding
 * the rest. `.shop-box` is content-sized under a max-height in style.css; this restates the max
 * against the SMALL viewport unit so a phone's collapsing address bar cannot push the footer out
 * of reach — the same reason the body at the top of style.css carries `min-height: 100svh` with a
 * vh fallback ahead of it. Order matters: the fallback is first, so a browser without svh keeps
 * the vh value instead of dropping the declaration.
 */
@media (pointer: coarse) {
  body.wrecker3d .shop-box,
  body.wrecker3d .garage-box {
    max-height: 92vh;
    max-height: 92svh;
  }
}
