/* The page around the game: the playfield, and the few controls laid over it.
   Colours and faces are the game's own, set from its theme's `chrome` palette
   by web/host.js; the values here are only a fallback. */
:root {
  /* The page claims dark support, and its dark look is its light look (the
     block at the end). "only light" did not stop Samsung Internet darkening the
     controls on a real phone; its dark mode is documented as standing down for
     pages that declare dark. The control discs are painted into a canvas anyway
     (web/host.js paintFaces), which no dark-mode algorithm repaints. The meta tag
     in each game's head says the same for the first paint. */
  color-scheme: light dark;
  --page: #f8f5ec;
  --plate: #fffdf6; /* the controls' disc */
  --glyph: #3f3f48; /* the controls' ink */
  --line: 2.9px;
  --edge: #3f3f48; /* the controls' rim */
  --focus: #22408f; /* keyboard focus over the playfield */
  --accent: #22408f; /* the Resume button */
  --accentGlyph: #fffdf6;
  --sheet: #fffdf6; /* the settings sheet */
  --ink: #3f3f48;
  --dim: #5e5e68;
  --on: #22408f; /* a switch that is on */
  --sheetFocus: #22408f;
  --scrim: rgba(20, 20, 24, 0.55);
  --ui: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --title: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --field-left: 0px;
  --field-right: 0px;
}
* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: var(--page);
  color: var(--ink);
  font: 16px/1.3 var(--ui);
  overscroll-behavior: none;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
body {
  /* Pinned to the viewport: no scrolling either way, no rubber-band bounce and
     no pull-to-refresh mid-run. touch-action: none also stops pinch and
     double-tap zoom everywhere, including on the controls. */
  position: fixed;
  inset: 0;
  touch-action: none;
}

.stage {
  position: absolute;
  inset: 0;
  display: flex;
  justify-content: center;
  overflow: hidden;
  background: var(--page);
  outline: none; /* focused only to hand Space back to the game; the canvas is the focus */
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
  cursor: pointer;
}
.stage::before {
  /* dims the page colour either side of the playfield on wide screens */
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.18);
  pointer-events: none;
}
canvas {
  position: relative;
  display: block;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.25), 0 0 30px rgba(0, 0, 0, 0.25);
}

/* ---- icon controls: The Runner's Line glyphs (web/host.js glyph) on a 48 px
   filled disc in the game's colours, opaque so the glyph reads over any art.
   The disc, rim and glyph are pixels in the button's own canvas (.face, drawn
   by web/host.js paintFaces from --plate, --edge, --glyph and --line), not CSS
   colours, so a browser's dark mode has nothing to rewrite. */
.icon-btn {
  --rim: 2.5px;
  --mark: 30px; /* the glyph's box, read by paintFaces */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  padding: 0;
  /* Transparent, but it keeps the box and tells paintFaces the rim width as the
     browser snaps it (Chrome draws 2.5px as 2px). */
  border: var(--rim) solid transparent;
  border-radius: 50%;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
  -webkit-user-select: none;
}
/* Over the whole button, border included; paintFaces sets its size and margin. */
.icon-btn .face { flex: none; display: block; box-shadow: none; }
.icon-btn:focus { outline: none; }
.icon-btn:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
.icon-btn:active { transform: scale(0.92); }

/* Limbs are strokes, heads are filled. Units are the 24-unit box. */
.glyph { overflow: visible; }
.glyph path,
.glyph circle { stroke: currentColor; stroke-width: var(--line, 2.9px); stroke-linecap: round; stroke-linejoin: round; }
.glyph path { fill: none; }
/* A gear: flat-ended teeth, and a head without the stroke so it stays clear of the ring. */
.glyph .teeth { stroke-linecap: butt; stroke-width: calc(var(--line, 2.9px) * 1.12); }
.glyph .teeth ~ circle { stroke: none; }
.glyph circle { fill: currentColor; }

/* The secondary controls, on the bottom edge clear of the home indicator and
   gesture bar, as in Hands Off: Settings, then Pause while a run is live, in
   the bottom-left corner; How to play, on the start screen, alone in the
   bottom-right corner, mirroring it. The gaps between them are still play
   surface. */
.controls {
  position: fixed;
  left: max(calc(var(--field-left) + 16px), calc(env(safe-area-inset-left) + 16px));
  bottom: calc(env(safe-area-inset-bottom) + 12px);
  display: flex;
  gap: 12px;
  pointer-events: none;
}
.controls-end {
  left: auto;
  right: max(calc(var(--field-right) + 16px), calc(env(safe-area-inset-right) + 16px));
}
.controls > * { pointer-events: auto; }

/* Resume, on the theme's pause card: a larger disc in the accent holding the
   runner. web/host.js sets left and top. */
.resume {
  --rim: 3px;
  --mark: 46px;
  position: fixed;
  width: 72px;
  height: 72px;
  margin: -36px 0 0 -36px;
}
.resume:active { transform: scale(0.92); }

/* On the settings sheet, a lighter line. */
.row-icon { --line: 2.4px; }

/* Over the how-to-play demo: what it is and how to leave, in the settings
   sheet's colours. Taps go through it to the playfield, which closes the demo. */
.howto-note {
  position: fixed;
  top: calc(env(safe-area-inset-top) + 20px);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 10px 22px 12px;
  border: 2.5px solid var(--sheetEdge, var(--edge));
  border-radius: 18px;
  background: var(--sheet);
  color: var(--ink);
  font: var(--labelWeight, 700) 18px/1.2 var(--ui);
  white-space: nowrap;
  pointer-events: none;
}
.howto-title { font: 400 26px/1.1 var(--title); }

/* ---- the settings sheet ------------------------------------------------ */
.scrim {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px max(16px, env(safe-area-inset-right)) 24px max(16px, env(safe-area-inset-left));
  background: var(--scrim);
}
.sheet {
  width: 100%;
  max-width: 420px;
  padding: 16px 20px 20px;
  border: 3px solid var(--sheetEdge, var(--edge));
  border-radius: 20px;
  background: var(--sheet);
  color: var(--ink);
  box-shadow: 0 16px 48px rgba(0, 0, 0, 0.35);
}
.sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 8px;
}
.sheet h2 {
  margin: 0;
  font: 400 28px/1.1 var(--title);
}
.sheet .icon-btn:focus-visible { outline-color: var(--sheetFocus); }
.row {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  min-height: 68px;
  margin: 0;
  padding: 10px 6px;
  border: 0;
  border-top: 2px solid color-mix(in srgb, var(--ink) 16%, transparent);
  border-radius: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  text-decoration: none; /* the Privacy row is a link */
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.row:focus { outline: none; }
.row:focus-visible { outline: 3px solid var(--sheetFocus); outline-offset: -3px; border-radius: 10px; }
.row-icon svg { display: block; width: 28px; height: 28px; }
.row-end { flex: 0 0 auto; color: var(--dim); }
.row-text { flex: 1 1 auto; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.row-label { font-size: 19px; font-weight: var(--labelWeight, 700); }
.row-hint { font-size: 14.5px; color: var(--dim); }
/* On and off read from the thumb's side as well as its colour. */
.switch {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  width: 56px;
  height: 32px;
  padding: 0 4px;
  border: 2.5px solid var(--dim);
  border-radius: 16px;
}
.thumb { width: 20px; height: 20px; border-radius: 50%; background: var(--dim); }
.row[aria-checked='true'] .switch { justify-content: flex-end; background: var(--on); border-color: var(--on); }
.row[aria-checked='true'] .thumb { background: var(--sheet); }

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
.noscript {
  position: absolute;
  inset: 0;
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  text-align: center;
  background: var(--page);
  color: var(--ink);
  font-size: 16px;
}

/* ---- dark mode ---------------------------------------------------------
   These games are printed artwork with no dark palette: in a dark-mode
   browser they look exactly as they do in light. The page declares
   color-scheme: light dark (above, and in each game's meta tag) and restates
   its own colours here, so a browser that looks for a page's dark styles
   finds them and leaves the page alone. No second palette: every value is
   still the theme's chrome token. */
@media (prefers-color-scheme: dark) {
  html, body, .stage, .noscript { background: var(--page); color: var(--ink); }
  .sheet, .howto-note { background: var(--sheet); color: var(--ink); }
}
