* { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { height: 100%; }
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: linear-gradient(180deg, #0f172a 0%, #1e1b4b 55%, #0f172a 100%);
  color: #e2e8f0; user-select: none; -webkit-user-select: none;
  touch-action: none; overflow: hidden;
}
#app { height: 100%; display: flex; flex-direction: column; max-width: min(100%, 860px); margin: 0 auto; }

#hdr { display: flex; align-items: center; gap: 8px; padding: 8px 12px; padding-top: max(8px, env(safe-area-inset-top)); }
#hdr .pill { background: rgba(0,0,0,0.24); border: 2px solid rgba(255,255,255,0.14); border-radius: 999px; padding: 6px 11px; font-weight: 800; font-size: 15px; min-width: 44px; min-height: 44px; display: flex; align-items: center; cursor: pointer; justify-content: center; color: inherit; font-family: inherit; }
#hdrHome { border: none; background: #fbbf24; color: #0f172a; font-size: 18px; }
#hdrStatus { flex: 1; min-width: 0; text-align: center; font-weight: 800; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: #c7d2fe; }

.scr { flex: 1; display: none; flex-direction: column; overflow-y: auto; padding: 6px 14px 18px; }
#scr-play { padding: 6px 4px 6px; }
.scr.on { display: flex; }

#scr-menu { align-items: center; text-align: center; gap: 12px; justify-content: center; }
#scr-menu h1 { font-size: clamp(30px, 8.5vw, 44px); color: #f8fafc; }
#scr-menu .sub { color: #c7d2fe; font-weight: 600; margin-bottom: 4px; }
#tierRow { display: flex; gap: 8px; width: 100%; }
.tierCard { flex: 1; background: rgba(0,0,0,0.22); border: 3px solid rgba(255,255,255,0.13); border-radius: 16px; padding: 10px 4px; font-weight: 800; font-size: 14px; line-height: 1.35; cursor: pointer; color: #e2e8f0; font-family: inherit; }
.tierCard small { display: block; color: #c7d2fe; font-weight: 700; font-size: 11.5px; }
.tierCard .te { font-size: 26px; display: block; }
.tierCard.sel { border-color: #fbbf24; background: rgba(56,189,248,0.14); }

button.big { width: 100%; border-radius: 16px; min-height: 56px; font-size: 19px; font-weight: 800; background: rgba(0,0,0,0.22); color: #e2e8f0; border: 3px solid rgba(255,255,255,0.13); cursor: pointer; font-family: inherit; }
button.big:active { transform: translateY(2px); }
button.big.primary { background: #fbbf24; border-color: #f59e0b; color: #0f172a; min-height: 44px;}
#statsLine { color: #c7d2fe; font-weight: 700; font-size: 13px; }

/* ⚙️ Settings — the shared disclosure shape (R-C23). */
#custom { width: 100%; background: rgba(0,0,0,0.22); border: 3px solid rgba(255,255,255,0.12); border-radius: 16px; padding: 10px 12px; text-align: left; }
#custom summary { font-weight: 800; font-size: 16px; cursor: pointer; list-style: none; }
#custom summary::-webkit-details-marker { display: none; }
.field { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.field .lbl { flex: 1; font-weight: 700; font-size: 14px; color: #cbd5e1; }
.seg { display: flex; gap: 4px; background: rgba(0,0,0,0.3); border-radius: 12px; padding: 3px; }
.seg button { min-height: 44px; min-width: 58px; border: none; border-radius: 9px; background: transparent; color: #94a3b8; font-weight: 800; font-size: 13px; font-family: inherit; cursor: pointer; }
.seg button.on { background: #fbbf24; color: #0f172a; min-height: 44px;}
.blurb { color: #c7d2fe; font-weight: 700; font-size: 12.5px; margin-top: 10px; line-height: 1.45; }

/* play */
#playTop { display: flex; align-items: center; justify-content: space-between; font-weight: 800; padding: 2px 6px 6px; font-size: 15px; min-height: 22px; }
#ballOut { color: #f8fafc; }
#midOut { color: #fbbf24; font-weight: 800; font-size: 13px; letter-spacing: 0.5px; }
#scoreOut { color: #c7d2fe; font-variant-numeric: tabular-nums; min-width: 48px; text-align: right; }

/* The mission strip. Two lines, fixed height, so the table never jumps when a
   mission starts or ends -- a playfield that resizes mid-ball is worse than no
   information at all. */
#mission { flex: none; padding: 0 6px 5px; }
#mHead { display: flex; align-items: baseline; gap: 8px; font-size: 12.5px; font-weight: 800; line-height: 1.2; }
#mRank { color: #fbbf24; white-space: nowrap; }
#mName { flex: 1; min-width: 0; color: #e2e8f0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#mProg { color: #22d3ee; font-variant-numeric: tabular-nums; white-space: nowrap; }
#mBars { display: flex; gap: 6px; margin-top: 4px; }
.bar { flex: 1; position: relative; height: 10px; border-radius: 6px; background: rgba(0,0,0,0.35); overflow: hidden; }
.bar i { position: absolute; inset: 0 100% 0 0; display: block; border-radius: 6px; transition: right 0.12s linear; }
.bar b { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 8px; letter-spacing: 1.2px; color: #94a3b8; font-weight: 800; }
#barTime i { background: linear-gradient(90deg, #f59e0b, #fbbf24); }
#barFuel i { background: linear-gradient(90deg, #0891b2, #22d3ee); }
#mission.off .bar i { right: 100%; }
#mission.low #barFuel i { background: linear-gradient(90deg, #dc2626, #f87171); }

#stageWrap { flex: 1; position: relative; min-height: 0; }
canvas#stage { display: block; touch-action: none; }


/* Two steering thumbs and a shine button. The shine is DOUBLE WIDTH because
   it is pressed far more often than either arrow and is the one control a
   child must be able to hit without looking down. */
/* Four controls, and the PLUNGER is the widest because it is the one every
   player reaches for first and the one that has to be held rather than
   tapped. The two flippers sit at the outside edges, under the thumbs. */
#pad { flex: none; display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; padding: 5px 4px max(4px, env(safe-area-inset-bottom)); }
.pbPlunge { background: #fbbf24 !important; border-color: #f59e0b !important; color: #0f172a !important; }
.pbPlunge span { color: #78350f !important; }
.pb { min-height: 48px; border-radius: 14px; background: rgba(0,0,0,0.24); border: 3px solid rgba(255,255,255,0.13); color: #e2e8f0; font-size: 26px; line-height: 1; font-weight: 800; font-family: inherit; cursor: pointer; display: flex; align-items: center; justify-content: center; touch-action: manipulation; }
.pb span { font-size: 11px; font-weight: 800; color: #94a3b8; }
.pb:active { transform: translateY(2px); }
/* A launch button with no ball to launch must not still look like the one
   bright thing on the pad — the amber IS the "press me", so it goes too. */
.pb:disabled { opacity: 0.42; cursor: default; }
.pb:disabled:active { transform: none; }
.pbPlunge:disabled { background: rgba(0,0,0,0.24) !important; border-color: rgba(255,255,255,0.13) !important; color: #64748b !important; }

/* THE PALETTE IS A FUNFAIR AT NIGHT and it is deliberately NOT Firefly Field's
   meadow, even though the two sheets share every rule. Slate blue playfield,
   hot pink for anything that kicks, amber for anything you control. They sit in
   different sections of the shelf and a child must never open one thinking it
   is the other. */

.ovl { position: absolute; inset: 0; display: none; align-items: flex-start; justify-content: center; background: rgba(2,6,23,0.9); border-radius: 12px; padding: 16px; overflow-y: auto; overscroll-behavior: contain;}
.ovl.on { display: flex; }
.ovlCard { text-align: center; width: 100%; max-width: 340px; display: flex; flex-direction: column; gap: 10px; margin: auto;}
#ovlTitle { font-size: 26px; font-weight: 800; color: #f8fafc; }
#ovlSub { color: #c7d2fe; font-weight: 700; min-height: 22px; line-height: 1.45; }
/* A result carries its evidence — the rows are why, not decoration. */
.rows { display: flex; flex-direction: column; gap: 4px; margin: 2px 0 6px; }
.rows .row { display: flex; justify-content: space-between; gap: 12px; font-size: 14px; font-weight: 700; color: #94a3b8; }
.rows .row b { color: #e2e8f0; font-variant-numeric: tabular-nums; }

#scr-how .card { background: rgba(0,0,0,0.22); border: 3px solid rgba(255,255,255,0.12); border-radius: 16px; padding: 14px; margin-bottom: 10px; font-size: 15px; line-height: 1.55; font-weight: 600; }
#scr-how h2 { margin-bottom: 8px; color: #f8fafc; }

.legend { display: flex; flex-direction: column; gap: 6px; }
.lgRow { display: flex; align-items: center; gap: 10px; }
.lgArt { flex: none; width: 66px; display: flex; align-items: center; justify-content: center; font-size: 15px; letter-spacing: -1px; }

.lgTxt { display: flex; flex-direction: column; min-width: 0; }
.lgTxt b { font-size: 14px; font-weight: 800; }
.lgTxt small { font-size: 12.5px; color: #94a3b8; line-height: 1.3; font-weight: 600; }

#toast { position: fixed; left: 50%; bottom: 86px; transform: translateX(-50%); background: #f8fafc; color: #0f172a; font-weight: 800; padding: 10px 16px; border-radius: 14px; opacity: 0; transition: opacity 0.25s; pointer-events: none; z-index: 40; max-width: calc(100vw - 28px); text-align: center; line-height: 1.35; }
#toast.on { opacity: 1; }

/* docs/offline-pwa.md R-C15 — the PAGE must never scroll. */
html, body { overflow: hidden; overscroll-behavior: none; }
.scr { overscroll-behavior: contain; }


/* R40a. THE VERSION CHIP STOPS OWNING A ROW.
   Measured on an 812px phone: header 60, score row 29, mission strip 34,
   pad 66, FOOTER 44. The footer is a full row for a footnote that is read
   maybe twice in the life of an install — 5% of a tall phone and 10% of a
   Galaxy Fold.
   The buttons cannot move INTO it, which was the first idea: 44px minus
   padding leaves about 30px of button, under the 44px tap floor this
   catalogue just spent a whole game (Ant March) enforcing. Putting flippers
   there would be the same defect, deliberately.
   So the chip moves into the PAD instead — floated into the corner, exactly
   what #228 does in landscape, with the pad reserving the width so nothing
   sits under it and no tap is stolen. #footer still exists and check-footer
   still passes; it simply stops costing a row. */
#app { position: relative; }
#footer {
  position: absolute;
  right: 6px;
  bottom: 0;
  z-index: 5;
  padding-bottom: env(safe-area-inset-bottom);
}
/* The floated chip sits over the pad's right end, so the pad must stop before
   it starts. 76px was a MAGIC NUMBER measured off one viewport and never seen
   render — the chip is 108px at v2.3.0 and it landed on the right flipper.
   #282: --chipw is now published by version.js for every product, and this
   game's footer floats in PORTRAIT too, so the reservation is unconditional
   here rather than inside the shared landscape query. */
#pad { padding-right: calc(var(--chipw, 80px) + 22px); }
