/* Touch controls overlay for the Sonic level player (index + /play routes).
 *
 * Sprite facts for /images/controls.png (512x512, 2x2 cells of 256px,
 * measured with PIL, alpha>50 strict bbox):
 *   TL dpad base   bbox (2,2)-(251,252)   250x251, ring ~15px, smoky interior
 *   TR button ring bbox (258,2)-(509,253) 252x252
 *   BL knob        bbox (44,300)-(211,467) 168x168, center (127.5,383.5)
 *   BR feedback    bbox (260,259)-(509,509) 250x251, gold ring ~15px, hollow
 *
 * Positioning rule: the sheet is divided into 4 equal 256px quadrants and
 * every sprite is centered on its quadrant center, exactly as laid out in
 * the sheet:
 *   TL (128,128)  TR (384,128)  BL (128,384)  BR (384,384)
 * For an element of size E showing a quadrant through a sheet scaled to
 * S x S px, the centered background-position is:
 *   (E/2 - cx*S/512)  (E/2 - cy*S/512)
 * Full-cell layers (E = S/2) reduce to the plain cell offsets; smaller
 * windows (knobs) use the same formula so the art stays centered. The one
 * exception is the BR feedback layer, which carries a measured (-2,-1)
 * source-px nudge so its ring lands exactly on the TL ring (the two arts
 * are cut ~1px apart in the sheet).
 * Sizing: the cluster scales with the viewport (--pad/--btn in vmin)
 * so the controls keep a constant proportion of the screen instead of
 * shrinking on bigger screens. --du/--bu are unit lengths (pad/132,
 * btn/88); every sprite number below is the original validated 132/88-px
 * measurement multiplied by its unit, preserving the geometry exactly.
 *
 * Feedback rule: pushing a direction shows that HALF of BR (gold) over the
 * opposite half of TL (silver), e.g. left = left half of BR + right half
 * of TL. Implemented with two stacked layers + clip-path halves.
 */

#gamecontainer {
  position: relative;
}

#touch-controls {
  position: absolute;
  inset: 0;
  z-index: 50;
  pointer-events: none;
  display: none; /* shown only when all three hold: touch device (JS adds
                    .tc-on), Sonic player page (markup present), and the
                    stage is fullscreened (selectors below) */
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

/* Touch controls appear ONLY on the fullscreen stage. The primary gate
   is the JS-mirrored .tc-stage-fullscreen class (set from
   fullscreenchange events); the :fullscreen selectors
   are a belt-and-suspenders fallback. NOTE: the webkit-prefixed selector
   lives in its own rule — one invalid selector in a comma group drops the
   WHOLE rule, and non-webkit engines (Firefox) reject :-webkit-full-screen. */
#gamecontainer.tc-stage-fullscreen #touch-controls.tc-on.tc-playing,
#gamecontainer:fullscreen #touch-controls.tc-on.tc-playing {
  display: block;
}

#gamecontainer:-webkit-full-screen #touch-controls.tc-on.tc-playing {
  display: block;
}

/* Left dpad cluster */
.tc-dpad {
  --pad: 34vmin;
  --du: calc(var(--pad) / 132);
  position: absolute;
  left: calc(var(--pad) * 12 / 132);
  bottom: calc(var(--pad) * 12 / 132);
  width: var(--pad);
  height: var(--pad);
  pointer-events: auto;
  touch-action: none;
}

.tc-base,
.tc-feedback {
  position: absolute;
  inset: 0;
  background-image: url("/images/controls.png");
  /* Whole sheet scaled so one 256px cell == control size (S = 2E). */
  background-size: calc(var(--pad) * 2) calc(var(--pad) * 2);
  background-repeat: no-repeat;
}

.tc-base {
  /* TL cell centered: (66 - 128*264/512) = 0, 0. */
  background-position: 0 0;
  opacity: 0.92;
}

.tc-feedback {
  /* BR cell: same centering as the base, plus a measured (-2,-1) source-px
     compensation — the gold art sits ~1px right of the silver art in the
     sheet (TL center 126.5 vs BR center 384.5), so without this the rings
     misalign by 1px to the right. (-133.03, -132.52) at 132px. */
  background-position: calc(-133.03 * var(--du)) calc(-132.52 * var(--du));
  opacity: 0;
}

/* Directional halves: active half of the gold ring over the silver base.
   Left push => left half gold + right half silver, etc. The cut edge of
   each half is pulled back 5px-at-132 (e.g. left half shows x < center -
   pullback) so the gap triangles straddling the center line never show
   half-highlighted; the facing arrow itself is untouched. */
#touch-controls[data-dir="left"] .tc-feedback {
  opacity: 1;
  clip-path: inset(0 calc(50% + var(--pad) * 5 / 132) 0 0);
}

#touch-controls[data-dir="right"] .tc-feedback {
  opacity: 1;
  clip-path: inset(0 0 0 calc(50% + var(--pad) * 5 / 132));
}

#touch-controls[data-dir="up"] .tc-feedback {
  opacity: 1;
  clip-path: inset(0 0 calc(50% + var(--pad) * 5 / 132) 0);
}

#touch-controls[data-dir="down"] .tc-feedback {
  opacity: 1;
  clip-path: inset(calc(50% + var(--pad) * 5 / 132) 0 0 0);
}

/* Draggable knob (BL cell): 168px art fitted to 78px-at-132, centered on
   the quadrant center: (-20.5, -139.5) at 132px. */
.tc-knob {
  position: absolute;
  left: 50%;
  top: 50%;
  width: calc(78 * var(--du));
  height: calc(78 * var(--du));
  margin: calc(-39 * var(--du)) 0 0 calc(-39 * var(--du));
  background-image: url("/images/controls.png");
  background-size: calc(238 * var(--du)) calc(238 * var(--du));
  background-position: calc(-20.5 * var(--du)) calc(-139.5 * var(--du));
  background-repeat: no-repeat;
  pointer-events: none;
  will-change: transform;
  /* Tween between the 4-way detents (and back to center) instead of
     snapping: JS only ever sets one of 5 quantized positions, so a short
     ease-out glides the knob there. */
  transition: transform 0.12s ease-out;
}

/* Right action button: TR outline + BL knob cap. */
.tc-btn {
  --btn: 23vmin;
  --bu: calc(var(--btn) / 88);
  position: absolute;
  right: calc(var(--btn) * 14 / 88);
  bottom: calc(var(--btn) * 26 / 88);
  width: var(--btn);
  height: var(--btn);
  pointer-events: auto;
  touch-action: none;
}

.tc-btn-ring {
  position: absolute;
  inset: 0;
  background-image: url("/images/controls.png");
  background-size: calc(var(--btn) * 2) calc(var(--btn) * 2);
  background-repeat: no-repeat;
  /* TR cell centered: (44 - 384*176/512, 44 - 128*176/512) = (-88, 0). */
  background-position: calc(-88 * var(--bu)) 0;
  opacity: 0.92;
}

/* 168px knob art fitted to 64px-at-88, centered on BL center:
   (-16.75, -114.25) at 88px. */
.tc-btn-knob {
  position: absolute;
  left: 50%;
  top: 50%;
  width: calc(64 * var(--bu));
  height: calc(64 * var(--bu));
  margin: calc(-32 * var(--bu)) 0 0 calc(-32 * var(--bu));
  background-image: url("/images/controls.png");
  background-size: calc(195 * var(--bu)) calc(195 * var(--bu));
  background-position: calc(-16.75 * var(--bu)) calc(-114.25 * var(--bu));
  background-repeat: no-repeat;
  pointer-events: none;
  transition: transform 0.1s ease-out, filter 0.1s ease-out;
}

#touch-controls[data-jump="1"] .tc-btn-knob {
  transform: scale(0.88);
  filter: brightness(1.25);
}
