* { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { height: 100%; overscroll-behavior: none; }
body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  background: #0b1d3a; color: #e2e8f0;
  display: flex; flex-direction: column;
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
}
#app { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }

#hdr {
  flex: 0 0 auto; display: flex; align-items: center; gap: 4px;
  padding: 6px 8px; font-size: 13px; font-weight: 700;
  background: #0a1730; border-bottom: 1px solid #1e3a5f;
}
#hdr > span { white-space: nowrap; }
/* R17b: the header is navigation only. Four 44px pills and three readouts left
   131px for the readouts and the readouts only grow — adding ⏸️ pushed ❓ 40px
   off a 375 viewport, and Endless's "12.8 mi · Ivory Causeway" in the 67px that
   remained was an ellipsis with a decimal point in front of it. The tap floor
   is not negotiable and the numbers are not shrinkable, so the numbers moved. */
#hdrTitle {
  flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  text-align: center; color: #7dd3fc;
}

/* The instruments, over the road (R17b). Absolutely positioned inside the
   stage wrapper, so they cost the canvas no height and sit in the sky, which
   is the emptiest part of the frame and the part no control occupies.

   pointer-events: none, because everything here is a readout — a swipe that
   starts on the speedometer must still steer (R12e drags on #stageWrap, and a
   child's thumb does not know where the chips are). z-index below #pads (20)
   and below the pause veil (25). */
#instruments {
  position: absolute; inset: 0; z-index: 10; pointer-events: none;
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 8px; padding: 8px 10px;
  font-weight: 800; line-height: 1.15;
}
#instruments > * { pointer-events: none; }
.insRight { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
#hudStage, #hudMain, #hudSpeed {
  background: rgba(7, 20, 39, .55); border-radius: 9px; padding: 4px 8px;
  /* R-C19b: every one of these changes while the player is looking at it. */
  font-variant-numeric: tabular-nums;
}
/* Empty chips must not paint a floating box on the menu screens — the play
   screen clears the text when it is left (show()). */
#hudStage:empty, #hudMain:empty, #hudSpeed:empty { display: none; }
#hudStage { font-size: 13px; max-width: 56%; color: #e2e8f0; white-space: pre-line; }
#hudMain  { font-size: 20px; }
#hudSpeed { font-size: 15px; color: #7dd3fc; }
.pill {
  min-width: 34px; min-height: 34px; font-size: 15px; line-height: 1;
  color: inherit; background: rgba(255,255,255,.08);
  border: 1px solid #1e3a5f; border-radius: 9px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  -webkit-appearance: none; appearance: none;
}
/* R-C5: the 44px floor, which this game had been under since it shipped.
   Scoped to the header so a .pill used elsewhere keeps its own size. */
#hdr .pill { min-width: 44px; min-height: 44px; height: auto; }

.scr { display: none; flex: 1 1 auto; min-height: 0; }
.scr.on { display: flex; flex-direction: column; }
#scr-menu, #scr-how, #scr-table {
  align-items: center; gap: 11px; padding: 16px 14px 26px; overflow-y: auto;
}

/* The Grand Prix stage picker. Two columns of five, so all ten authored stages
   are on screen at once with no scroll of their own — the point of moving this
   into the menu was that you can see the whole season before you commit. */
#gpWrap { width: 100%; max-width: 400px; display: flex; flex-direction: column;
          align-items: center; gap: 7px; }
#gpWrap[hidden] { display: none; }
#gpCount { color: #7dd3fc; font-weight: 700; }
#gpGrid { width: 100%; display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.gpChip {
  display: flex; align-items: center; gap: 6px; min-height: 44px; padding: 7px 8px;
  font: 600 12px/1.2 inherit; text-align: left;
  color: #94a3b8; background: #0f2545;
  border: 2px solid #1e3a5f; border-radius: 10px;
}
.gpChip b { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The order badge holds its width whether it has a number in it or not, so
   selecting a stage does not shuffle every other label sideways. */
.gpChip i {
  flex: 0 0 18px; height: 18px; border-radius: 9px;
  font: 800 11px/18px inherit; font-style: normal; text-align: center;
  background: #16365e; color: #64748b;
}
.gpChip.sel { color: #e2e8f0; background: #16365e; }
.gpChip.sel i { background: #7dd3fc; color: #0b1d3a; }
.linky {
  padding: 6px 12px; font: 700 12px/1 inherit; color: #7dd3fc;
  background: none; border: 1px solid #1e3a5f; border-radius: 999px;
}

/* The championship table. */
#tableRows { width: 100%; max-width: 400px; display: flex; flex-direction: column; gap: 5px; }
.tableRow {
  display: flex; align-items: center; gap: 9px; padding: 10px 12px;
  font: 600 14px/1.2 inherit; color: #cbd5e1;
  background: #0f2545; border: 2px solid #1e3a5f; border-radius: 11px;
}
.tableRow i { font-style: normal; color: #64748b; min-width: 20px; }
.tableRow b { flex: 1; }
.tableRow span { color: #7dd3fc; font-weight: 800; }
.tableRow.me { color: #0b1d3a; background: #7dd3fc; border-color: #7dd3fc; }
.tableRow.me i, .tableRow.me span { color: #0b1d3a; }
h1 { font-size: 27px; letter-spacing: .5px; }
.sub { color: #7dd3fc; font-size: 13px; text-align: center; max-width: 380px; }
.pickLabel { font-size: 12px; color: #94a3b8; margin-top: 4px; }
.pickRow { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; width: 100%; max-width: 400px; }
.pick {
  flex: 1 1 110px; min-height: 66px; padding: 8px 9px;
  font: 700 13px/1.25 inherit; color: #e2e8f0; text-align: center;
  background: #12294c; border: 2px solid #1e3a5f; border-radius: 13px; cursor: pointer;
  -webkit-appearance: none; appearance: none;
}
.pick .te { display: block; font-size: 19px; margin-bottom: 2px; }
.pick small { display: block; font-weight: 400; font-size: 10.5px; color: #94a3b8; margin-top: 2px; }
.pick.sel { border-color: #38bdf8; background: #16365e; }

.big {
  width: 100%; max-width: 320px; min-height: 50px; padding: 12px;
  font: 700 16px/1 inherit; color: #e2e8f0;
  background: #12294c; border: 1px solid #1e3a5f; border-radius: 13px; cursor: pointer;
  -webkit-appearance: none; appearance: none;
}
.big.primary { background: #0284c7; border-color: transparent; color: #f0f9ff; }
#statsLine { font-size: 12px; color: #94a3b8; text-align: center; }
.card {
  background: #12294c; border-radius: 14px; padding: 12px 14px;
  width: 100%; max-width: 380px; font-size: 14px; line-height: 1.5;
}
.card h2 { font-size: 15px; margin-bottom: 5px; }
.hint { font-size: 11.5px; color: #94a3b8; margin-top: 8px; }

/* ---- settings ---- */
#settings { width: 100%; max-width: 380px; background: #12294c; border-radius: 13px; padding: 4px 12px 2px; }
#settings > summary { cursor: pointer; padding: 9px 0; font-weight: 700; font-size: 14px; list-style: none; }
#settings > summary::-webkit-details-marker { display: none; }
#settings[open] > summary { border-bottom: 1px solid rgba(224,242,254,.2); }
.optRow { padding: 10px 0; }
.optRow > .optLabel { font-size: 13px; color: #7dd3fc; margin-bottom: 6px; }
.optChoices { display: flex; gap: 8px; }
.optBtn {
  flex: 1 1 0; min-height: 44px; padding: 7px 8px;
  font: 600 13px/1.25 inherit; color: #e2e8f0; text-align: center;
  background: rgba(255,255,255,.06); border: 1px solid rgba(224,242,254,.3);
  border-radius: 10px; cursor: pointer; -webkit-appearance: none; appearance: none;
}
.optBtn[aria-checked="true"] { background: #0369a1; border-color: #7dd3fc; }
.optBtn small { display: block; font-weight: 400; font-size: 11px; opacity: .8; margin-top: 3px; }

/* ---- the road ---- */
#stageWrap {
  flex: 1 1 auto; min-height: 0; position: relative;
  display: flex; align-items: center; justify-content: center;
  background: #071427; overflow: hidden;
  /* Swipe steering (R12e) drags on this element, so the browser must not treat
     the gesture as a scroll or a pinch. */
  touch-action: none;
}
canvas#stage { display: block; touch-action: none; }

/* Held controls, per R12a: pointer events with capture, never `click`.
   56px because a thumb RESTS on these for a whole stage. */
#pads { position: absolute; inset: 0; z-index: 20; pointer-events: none; }
.padBtn {
  pointer-events: auto; position: absolute;
  bottom: calc(12px + env(safe-area-inset-bottom));
  min-width: 68px; min-height: 68px;
  font: 700 24px/1 inherit; color: #e0f2fe;
  background: rgba(8, 29, 58, .6);
  border: 2px solid rgba(224, 242, 254, .45); border-radius: 18px;
  -webkit-appearance: none; appearance: none;
  touch-action: none; user-select: none; -webkit-user-select: none;
  transition: background-color .08s linear, transform .06s linear;
}
.padBtn:active, .padBtn.on {
  background: rgba(56, 189, 248, .55); border-color: #e0f2fe; transform: scale(.96);
}
/* `hidden` is a style, not a state (docs/offline-pwa.md): the UA rule is
   (0,1,0) and loses to any id rule that sets `display`. Nothing here sets
   display on a pad, but stating it means a later layout tweak cannot silently
   leave a steer button on screen in swipe or tilt mode. */
.padBtn[hidden] { display: none; }
#btnLeft  { left: 12px; }
#btnRight { left: 92px; }
#btnBrake { right: 12px; min-width: 76px; min-height: 76px; font-size: 26px; }
/* ABOVE the brake, not beside it. The brake is a control the thumb RESTS on for
   a whole stage; the boost is a tap. Stacking the tap above the resting
   position means the thumb rolls up and back and the two never compete for the
   same pixels. It is only on screen when there is something banked -- a button
   that does nothing when pressed is the failure mode the catalog's Stop button
   spent three releases teaching us to avoid. */
#btnBoost {
  right: 12px; bottom: calc(96px + env(safe-area-inset-bottom));
  min-width: 64px; min-height: 64px; font-size: 21px; font-weight: 800;
  background: rgba(56, 189, 248, .3); border-color: #7dd3fc; color: #f0f9ff;
}

.ovl {
  position: absolute; inset: 0; z-index: 30;
  display: none; align-items: center; justify-content: center; padding: 18px;
  background: rgba(7, 20, 39, .93);
}
.ovl.on { display: flex; }
.ovlCard {
  background: #12294c; border-radius: 18px; padding: 20px;
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  width: 100%; max-width: 330px; text-align: center;
}
#ovlTitle { font-size: 23px; font-weight: 800; }
#ovlSub { color: #7dd3fc; font-size: 15px; }

/* R-C21, the pause veil. Lighter than .ovl on purpose: the road stays visible
   behind it, because a pause that blacks the world out feels like the run
   ended. z-index above #pads so a paused thumb cannot reach the steer buttons,
   and it eats the swipe gesture #stageWrap would otherwise read as steering.

   R-C15b: flex-start + margin:auto, never align-items:center on a box that can
   scroll. Centring puts the first child above the top edge where scrollTop
   cannot follow, and that is 585px of Word Sleuth's help nobody could read. */
#pauseVeil {
  position: absolute; inset: 0; z-index: 25;
  display: flex; align-items: flex-start; justify-content: center;
  padding: 18px; overflow-y: auto;
  background: rgba(7, 20, 39, .72);
  backdrop-filter: blur(2px);
}
#pauseVeil[hidden] { display: none; }
#pauseCard {
  margin: auto;
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  width: 100%; max-width: 330px; text-align: center;
}
.pauseTitle { font-size: 26px; font-weight: 800; }
.pauseSub { color: #7dd3fc; font-size: 15px; }

.toast-host {
  position: fixed; left: 0; right: 0; z-index: 60;
  bottom: calc(96px + env(safe-area-inset-bottom));
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  pointer-events: none;
}
.toast {
  pointer-events: auto; max-width: 86vw; padding: 8px 13px; border-radius: 11px;
  background: rgba(8, 29, 58, .95); border: 1px solid #1e3a5f;
  font-size: 13px; font-weight: 600; color: #e0f2fe;
  opacity: 0; transform: translateY(6px); transition: opacity .18s, transform .18s;
}
.toast.in { opacity: 1; transform: none; }

/* docs/offline-pwa.md R-C15 — the PAGE must never scroll.
   The product is a fixed frame: header, a named scroll region, footer. If the
   document scrolls too, the header scrolls away, the version chip drifts, and
   a drag that reaches the end of the inner region chains out to the page and
   drags the whole board under the player's thumb. That is the "double scroll".
   `overflow: hidden` stops the second scrollbar; `overscroll-behavior: none`
   stops the chaining, which is the half that is invisible on a desktop mouse
   and obvious on a phone. */
html, body {
    overflow: hidden;
    overscroll-behavior: none;
}
