/* Rail Dash — presentation only. The yard is a canvas: a pseudo-3D projection
   redrawn every frame, so nothing here knows about perspective.

   #279: 44px is the tap floor Apple and Google both publish, and it applies to
   every interactive thing on every screen — including the four-button control
   pad, which is the whole point of offering it. */

:root {
  --bg: #0b1220;
  --panel: #16213a;
  --line: #2c3a55;
  --ink: #e2e8f0;
  --dim: #94a3b8;
  --accent: #38bdf8;
  --go: #22c55e;
  --stop: #ef4444;
  --gold: #fbbf24;
  --card: #16213a;
  --chip: #23324d;

  /* The yard's own palette, named for the ROLE so the legend in the help
     screen resolves the same custom property the canvas draws with and the two
     cannot drift apart. These MUST match data.js's COLOURS — the harness
     compares the two files rather than trusting the comment. */
  --sky: #101d33;
  --ground: #1e3318;
  --bed: #3b3b3e;
  --bedAlt: #47474c;
  --rail: #b9c5d4;
  --sleeper: #4a4033;
  --m-low: #f59e0b;
  --m-high: #c084fc;
  --m-car: #dc2626;
  --m-mover: #f472b6;
  --m-live: #22d3ee;
  --m-ramp: #22c55e;
  --coin: #fbbf24;
  --runner: #38bdf8;
  --dog: #f87171;
  --skyLow: #2b4166;
  --far: #2b4166;
  --city: #16233a;
  --pole: #5b6472;
  --steel: #93a3b8;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
[hidden] { display: none !important; }

html, body {
  margin: 0; padding: 0; height: 100%;
  background: var(--bg); color: var(--ink);
  font: 400 16px/1.45 -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  overflow: hidden; overscroll-behavior: none;
}

#app { height: 100%; display: flex; flex-direction: column; }
.scr { display: none; flex: 1; min-height: 0; flex-direction: column; }
.scr.on { display: flex; }

#scr-menu, #scr-how, #scr-win {
  overflow-y: auto;
  padding: max(16px, env(safe-area-inset-top)) 16px calc(28px + env(safe-area-inset-bottom));
  align-items: stretch;
}

h1 { font-size: 30px; margin: 8px 0 2px; text-align: center; }
h2 { font-size: 17px; margin: 0 0 6px; }
.sub { text-align: center; color: var(--dim); margin-bottom: 16px; }

/* ---- buttons ---- */

.big {
  display: block; width: 100%; margin: 8px 0; padding: 14px 16px;
  font: 600 16px/1 inherit; color: var(--ink);
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
  cursor: pointer; text-align: center; text-decoration: none;
  -webkit-appearance: none; appearance: none; touch-action: manipulation;
  min-height: 44px;
}
.big.primary { background: var(--accent); color: #04233a; border-color: transparent; }
.big:active { transform: translateY(1px); }

.btn {
  padding: 9px 12px; font: 600 14px/1 inherit; color: var(--ink);
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  cursor: pointer; -webkit-appearance: none; appearance: none;
  touch-action: manipulation; min-height: 44px;
}

.pill {
  padding: 8px 10px; min-width: 44px; min-height: 44px;
  font: 600 14px/1 inherit; color: var(--ink);
  background: rgba(255, 255, 255, .06); border: 1px solid var(--line);
  border-radius: 10px; cursor: pointer; white-space: nowrap;
  display: flex; align-items: center; justify-content: center;
  -webkit-appearance: none; appearance: none; touch-action: manipulation;
}
.pill:disabled { opacity: .35; cursor: default; }

/* ---- rungs and modes ---- */

#tierRow { display: flex; gap: 8px; margin-bottom: 4px; }
.tierBtn {
  flex: 1; padding: 12px 6px; border-radius: 12px; cursor: pointer;
  background: var(--panel); border: 1px solid var(--line); color: var(--ink);
  font: 600 13px/1.2 inherit; text-align: center; min-height: 44px;
  -webkit-appearance: none; appearance: none; touch-action: manipulation;
}
.tierBtn .te { display: block; font-size: 18px; line-height: 1.1; }
.tierBtn small { display: block; font-weight: 400; font-size: 11px; color: var(--dim); margin-top: 3px; }
.tierBtn[aria-checked="true"] { border-color: var(--accent); background: #10344a; }

#modeRow { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 10px 0 2px; }
#modeRow .tierBtn small { text-transform: none; letter-spacing: 0; }

/* ---- settings ---- */

details#custom {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 12px; margin: 8px 0; padding: 0 14px;
}
details#custom summary {
  padding: 14px 0; font-weight: 600; cursor: pointer; list-style: none;
  display: flex; align-items: center; gap: 8px; min-height: 44px;
}
details#custom summary::-webkit-details-marker { display: none; }
.badge {
  margin-left: auto; font: 400 12px/1 inherit; color: var(--dim);
  max-width: 60%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fields { padding-bottom: 12px; }
/* WRAPS (R-G26.9). A settings row is [label][control] and the control's width
   is decided at runtime by its own option labels. Wrapping drops the control
   onto its own line ONLY when it has to; at 375px and wider nothing moves. */
.field { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 10px 0; min-height: 44px; }
.field .lbl { flex: 0 0 84px; font-size: 13px; color: var(--dim); }
.seedRow { display: flex; flex: 1; gap: 6px; }
.slideRow { display: flex; flex: 1; align-items: center; gap: 10px; min-width: 0; }
.slideRow input[type=range] { flex: 1 1 auto; min-width: 0; height: 44px;
  accent-color: var(--accent); background: none; border: 0; padding: 0;
  cursor: pointer; }
.slideVal { flex: 0 0 62px; text-align: right; font-size: 13px; color: var(--ink); }
#seedIn {
  flex: 1; min-width: 0; padding: 9px 10px; border-radius: 9px;
  font: 600 13px/1 inherit; color: var(--ink);
  background: rgba(255, 255, 255, .05); border: 1px solid var(--line);
  -webkit-appearance: none; appearance: none;
}
.hint { font-size: 12px; color: var(--dim); margin: 10px 0 0; }
#statsLine { text-align: center; font-size: 12px; color: var(--dim); margin-top: 14px; }

/* A two-way setting inside the panel. The chosen one is marked by BACKGROUND
   AND WEIGHT, never by hue alone (check-settings, and R-C's readability rule). */
.seg { display: flex; gap: 6px; flex: 1; }
.segBtn { flex: 1 1 0; min-height: 44px; border-radius: 10px; cursor: pointer;
          background: rgba(0,0,0,.24); border: 2px solid rgba(255,255,255,.13);
          color: #e2e8f0; font: inherit; font-size: 14px; font-weight: 700; }
.segBtn.on { background: var(--go); border-color: #fff; color: #04233a;
             font-weight: 900; }

/* ---- play ---- */

#hdr {
  flex: 0 0 auto; display: flex; gap: 6px; align-items: center;
  padding: max(6px, env(safe-area-inset-top)) 8px 6px;
  border-bottom: 1px solid var(--line); background: var(--bg);
}
#hdrTitle {
  flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; font-weight: 700; font-size: 15px;
}
#hdr .pill { min-width: 44px; min-height: 44px; font-size: 17px; }

/* The HUD is an overlay ON the yard. Absolutely positioned inside #stage, so
   it takes no layout height and cannot reflow the canvas when a pill appears
   — the scrim behind it is what keeps a white number readable over a bright
   ballast band. `pointer-events` is off on the strip and back on for the pill
   itself, so the whole top of the yard is still swipeable. */
#hud {
  position: absolute; left: 0; right: 0; top: 0; z-index: 2;
  display: flex; gap: 6px; align-items: flex-start;
  padding: 6px 8px; pointer-events: none;
  background: linear-gradient(to bottom, rgba(11, 18, 32, .78) 0, rgba(11, 18, 32, .55) 58%, rgba(11, 18, 32, 0) 100%);
}
#barSpace { flex: 1; min-width: 0; }
#hud .pill { padding: 8px 10px; font-size: 15px; min-height: 44px; pointer-events: auto;
             background: rgba(11, 18, 32, .55); backdrop-filter: blur(2px); }
/* The score keeps its own colour. `#hud .pill` outranks a bare `#hudScore`, so
   the first version of the overlay quietly painted dark ink on a dark plate and
   the one number the player watches became unreadable. */
#hud #hudScore { background: var(--accent); color: #04233a; border-color: transparent; }
/* R-C19: a number the player watches change gets tabular figures, or the pill
   beside it slides sideways on every tick. */
#hudScore, #hudCoins { font-variant-numeric: tabular-nums; }
#hudScore { font-weight: 800; color: #04233a; background: var(--accent);
            border-color: transparent; min-width: 68px; }
#hudLead { letter-spacing: 1px; }
/* R-C19. #bar is a SIBLING of #stage, so a pill that appears and disappears
   would change the bar's height and re-lay the yard mid-run — the road would
   jump the instant a pickup was collected, which is the worst possible moment
   for it. It keeps its box and only its ink goes. */
#hudPicks { min-width: 44px; }
#hudPicks:empty { visibility: hidden; }

/* The canvas is a centred portrait column, sized in resize(). */
#stage { flex: 1; min-height: 0; position: relative; overflow: hidden;
         display: flex; align-items: stretch; justify-content: center;
         background: var(--sky); }
#cv { touch-action: none; display: block; align-self: stretch; }
/* R80: placed over #cv from resize(), the one place the canvas box is decided. */
#glAir { position: absolute; display: block; pointer-events: none; }

/* The hint is on the yard too, and it goes away. It says one thing, once, at
   the start of a run; a permanent caption is chrome that has stopped being
   information. */
#playHint {
  position: absolute; left: 8px; right: 8px; bottom: 10px; z-index: 2;
  font-size: 12.5px; color: var(--ink); text-align: center;
  text-shadow: 0 1px 3px rgba(0, 0, 0, .9);
  pointer-events: none; transition: opacity .5s; opacity: 1;
}
#playHint.gone { opacity: 0; }

/* ---- the control pad (spec R40.3) --------------------------------------
   Four buttons, and every one of them is at least 44px on its shortest side.
   It replaces #playHint's bottom padding rather than adding to it, so turning
   the pad on costs the yard one row of height and not two. */
#pad {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px;
  padding: 4px 10px calc(6px + env(safe-area-inset-bottom));
}
.padBtn {
  min-height: 56px; border-radius: 14px; cursor: pointer;
  background: var(--panel); border: 1px solid var(--line); color: var(--ink);
  font: 700 22px/1 inherit; touch-action: manipulation;
  -webkit-appearance: none; appearance: none;
}
.padBtn:active { background: var(--chip); transform: translateY(1px); }

/* ---- cards ---- */

.card {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 12px; padding: 14px; margin: 8px 0; font-size: 14px;
}
.card.win { text-align: center; }
#winStars { font-size: 34px; letter-spacing: 4px; min-height: 40px; }
#winWhy { font-size: 15px; color: var(--ink); margin-top: 4px; }
#winBody { color: var(--dim); margin-top: 6px; }
#winBest { color: var(--gold); font-weight: 600; margin-top: 8px; min-height: 20px; }
/* A result carries its evidence (#173). */
.evid { text-align: left; font-size: 13px; color: var(--dim); margin-top: 10px; }
.evid .row { display: flex; justify-content: space-between; gap: 12px; padding: 3px 0; }
.evid .row b { color: var(--ink); }

/* ---- the legend (docs/offline-games-pwa.md R-L1) ---- */
.lgSub { font-weight: 600; font-size: 13px; color: var(--dim); margin: 10px 0 6px; }
.legend { display: flex; flex-direction: column; gap: 8px; }
.lgRow { display: flex; align-items: center; gap: 10px; }
.lgArt { flex: none; width: 40px; height: 24px; display: flex; align-items: center;
         justify-content: center; font-style: normal; font-size: 18px; }
.lgArt.lg-slab::after { content: ''; width: 30px; height: 10px; border-radius: 2px; background: var(--m); }
.lgArt.lg-arch::after { content: ''; width: 28px; height: 14px; border-radius: 3px 3px 0 0;
                        border: 3px solid var(--m); border-bottom: 0; }
.lgArt.lg-box::after { content: ''; width: 28px; height: 20px; border-radius: 3px; background: var(--m); }
.lgArt.lg-thin::after { content: ''; width: 32px; height: 3px; background: var(--m); }
.lgArt.lg-wedge::after { content: ''; width: 0; height: 0;
                         border-left: 26px solid var(--m);
                         border-top: 13px solid transparent;
                         border-bottom: 3px solid transparent; }
.lgTxt { display: flex; flex-direction: column; min-width: 0; }
.lgTxt b { font-weight: 700; }
.lgTxt small { font-size: 12.5px; color: var(--dim); line-height: 1.35; }

/* ---- toast ---- */
#toast {
  position: fixed; left: 50%; bottom: calc(64px + env(safe-area-inset-bottom));
  transform: translateX(-50%) translateY(12px);
  background: #0b1220; border: 1px solid var(--line); color: var(--ink);
  padding: 10px 14px; border-radius: 10px; font-size: 14px;
  opacity: 0; pointer-events: none; transition: opacity .18s, transform .18s;
  z-index: 50; max-width: calc(100vw - 32px); text-align: center;
}
#toast.on { opacity: 1; transform: translateX(-50%) translateY(0); }

@media (min-width: 720px) {
  #scr-menu, #scr-how, #scr-win { max-width: 560px; margin: 0 auto; width: 100%; }
}

/* #228: a landscape window under 500px tall must not spend a 44px row on the
   version chip. Nothing here needs a side column — the yard is the whole
   screen and it simply gets taller. */
@media (orientation: landscape) and (max-height: 500px) and (min-width: 600px) {
  #app { position: relative; }
  #footer { position: absolute; right: 0; bottom: 0;
            padding-bottom: env(safe-area-inset-bottom); }
  /* #playHint is inside the stage now and out of flow, so a short landscape
     window costs it nothing — it just gets smaller. */
  #playHint { font-size: 11px; bottom: 4px; }
  .padBtn { min-height: 44px; font-size: 18px; }
}
