/* shared/joystick.css — arcade-cabinet controls.

   Use:
     <div class="controls-bar">
       <div class="joystick" id="joystick">
         <div class="joystick-base">
           <span class="joystick-arrow joystick-arrow-up">▲</span>
           <span class="joystick-arrow joystick-arrow-down">▼</span>
           <span class="joystick-arrow joystick-arrow-left">◀</span>
           <span class="joystick-arrow joystick-arrow-right">▶</span>
         </div>
         <div class="joystick-ball" id="joystick-ball"></div>
       </div>
       <div class="arcade-buttons">
         <button class="arcade-btn arcade-btn-red">🔥</button>
       </div>
     </div>

   Joystick uses Pointer Events — wire via SiteJoystick.bind() in
   shared/joystick.js. Action buttons are plain <button>s; attach your
   own click/pointer handlers. The shared CSS only provides the look.
*/

.controls-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin: 18px auto;
  /* Minimal horizontal padding so joystick / buttons sit flush
     against the chassis edges, like a real fight stick. */
  padding: 18px 6px;
  /* Real arcade-fight-stick chassis — molded dark-charcoal plastic with
     a slightly lighter top edge from above-lighting. No neon trim. */
  background: linear-gradient(180deg, #353947 0%, #1d2029 60%, #14161d 100%);
  border: 1px solid rgba(0, 0, 0, 0.55);
  border-radius: 18px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.07),
    inset 0 -2px 6px rgba(0, 0, 0, 0.5),
    0 12px 26px rgba(0, 0, 0, 0.55);
  width: clamp(320px, 95vw, 380px);
  max-width: calc(100% - 8px);
}

/* ---- Joystick ---------------------------------------------------- */
.joystick {
  position: relative;
  width: 130px;
  height: 130px;
  touch-action: none;
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none;
  user-select: none;
  flex: 0 0 auto;
}
/* Dust skirt fills the whole joystick element — no inset buffer so
   the visible base ring touches the chassis edge. */
.joystick-base {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 50%, #14161d 0%, #08090c 100%);
  box-shadow:
    inset 0 3px 6px rgba(0, 0, 0, 0.7),
    inset 0 -2px 3px rgba(255, 255, 255, 0.04);
}
.joystick-arrow {
  position: absolute;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(255, 255, 255, 0.55);
  font-size: 0;
  font-weight: 900;
  pointer-events: none;
  line-height: 1;
  /* Default: a small dark LED, off */
  background: radial-gradient(circle at 50% 40%, #2a2c36 0%, #0a0b10 90%);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.7);
  transition: background 0.06s ease, box-shadow 0.06s ease,
              transform 0.06s ease;
}
.joystick-arrow-up    { top: 4px;    left: 50%; transform: translateX(-50%); }
.joystick-arrow-down  { bottom: 4px; left: 50%; transform: translateX(-50%); }
.joystick-arrow-left  { left: 4px;   top: 50%;  transform: translateY(-50%); }
.joystick-arrow-right { right: 4px;  top: 50%;  transform: translateY(-50%); }

.joystick-ball {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 72px;
  height: 72px;
  margin: -36px 0 0 -36px;
  border-radius: 50%;
  /* Classic red arcade ball top — glossy plastic dome. */
  background:
    radial-gradient(circle at 36% 26%, #ffdede 0%, #ff8a8a 10%, #e6202c 35%, #960812 75%, #3a0306 100%);
  border: 1.5px solid rgba(255, 255, 255, 0.15);
  box-shadow:
    inset 0 -10px 18px rgba(0, 0, 0, 0.55),
    inset 0 8px 14px rgba(255, 255, 255, 0.28),
    0 6px 16px rgba(0, 0, 0, 0.55),
    0 0 22px rgba(255, 90, 90, 0.30);
  /* Quick snap to cardinal positions — feels like the stick clicking
     into a microswitch. Spring overshoot on the recoil to centre. */
  transition: transform 0.07s cubic-bezier(0.32, 1.42, 0.42, 1);
  pointer-events: none;
}
.joystick.dragging .joystick-ball {
  box-shadow:
    inset 0 -10px 18px rgba(0, 0, 0, 0.55),
    inset 0 8px 14px rgba(255, 255, 255, 0.30),
    0 8px 20px rgba(0, 0, 0, 0.65);
}

/* Direction-committed: the LED for that axis lights up bright cyan-blue
   (less harsh than red). Diagonals light TWO LEDs simultaneously,
   mirroring how a real 8-way arcade switch closes both contacts. */
.joystick.dir-up    .joystick-arrow-up,
.joystick.dir-down  .joystick-arrow-down,
.joystick.dir-left  .joystick-arrow-left,
.joystick.dir-right .joystick-arrow-right {
  background: radial-gradient(circle at 50% 35%,
    #d8f4ff 0%, #5dd1ff 18%, #1c7fe5 55%, #06346e 100%);
  box-shadow:
    inset 0 1px 1px rgba(255, 255, 255, 0.65),
    0 0 6px rgba(58, 184, 255, 0.95),
    0 0 14px rgba(58, 184, 255, 0.6);
  transform: translateX(-50%) scale(1.08);
}
.joystick.dir-left .joystick-arrow-left,
.joystick.dir-right .joystick-arrow-right {
  transform: translateY(-50%) scale(1.08);
}

/* ---- Action buttons --------------------------------------------- */
.arcade-buttons {
  /* Real fight stick: action buttons cluster horizontally in a row.
     Single-button games (most) have one big plunger; multi-button
     games (tetris) get a row of small ones, like a row of Sanwa
     punch buttons. */
  display: flex;
  flex-direction: row;
  gap: 6px;
  align-items: center;
  justify-content: center;
}

/* Arcade-button group — TWO concentric circles like a real fight stick:
   - the outer bezel disc (drawn by ::before on this group) is the
     black plastic collar fixed in the cabinet panel
   - the inner red plunger (.arcade-btn) sits on top of the bezel and
     translates down on press, sinking INTO the collar
   The bezel lives on the group, not the button, so transforming the
   button on :active doesn't shrink the bezel with it.
   No printed labels — like a real Sanwa button bank, identification
   is by position alone. */
.arcade-btn-group {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  /* Reserve a 92 px-tall slot so the bezel and the inner plunger
     share the same vertical centre. Plunger lives in flex flow inside
     this slot via justify-content: center. */
  width: 92px;
  height: 92px;
}
.arcade-btn-group::before {
  content: '';
  position: absolute;
  inset: 0;             /* fills the slot — perfectly centred with group */
  border-radius: 50%;
  background: radial-gradient(circle at 50% 40%, #2a2c36 0%, #0a0c14 60%, #03040a 100%);
  box-shadow:
    inset 0 3px 5px rgba(0, 0, 0, 0.8),
    inset 0 -2px 3px rgba(255, 255, 255, 0.05),
    0 2px 4px rgba(0, 0, 0, 0.5);
  z-index: 0;
}
/* Smaller slot + bezel for the .sm plunger variant — tetris's three */
.arcade-btn-group:has(.arcade-btn.sm) {
  width: 58px;
  height: 58px;
}
.arcade-btn-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 1.5px;
  color: rgba(255, 255, 255, 0.78);
  text-transform: uppercase;
  user-select: none;
}

.arcade-btn {
  position: relative;
  width: 74px;        /* plunger — fits inside the 92 px bezel */
  height: 74px;
  border-radius: 50%;
  border: none;
  /* No surface text — like a real arcade button. */
  font-size: 0;
  color: transparent;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  padding: 0;
  line-height: 0;
  transition: transform 0.07s ease, box-shadow 0.10s ease, filter 0.10s ease,
              background 0.07s ease;
  z-index: 1;
  /* True top-down view of the plunger surface — soft radial highlight
     in the upper-centre (light directly overhead) fading to a
     uniform red body. No bottom-rim shadow, no drop shadow — the
     button reads as a flat disc, not a hemisphere. */
  background: radial-gradient(circle at 50% 38%,
    #ff6a72 0%,
    #e6202a 38%,
    #c41018 80%,
    #a40c14 100%);
  box-shadow:
    /* Thin dark ring at the plunger / bezel boundary */
    inset 0 0 0 1px rgba(0, 0, 0, 0.35);
}
/* Dark bezel collar — the black plastic ring real buttons sit in. */
.arcade-btn:active,
.arcade-btn.arcade-pressed {
  /* Pushed-in plunger from a top-down view: darker red overall,
     strong central depression shadow, slight inward shrink.
     .arcade-pressed mirrors :active for JS-controlled press state
     (needed on iOS Safari where preventDefault on touchstart kills
     the :active pseudo-class). */
  transform: scale(0.93);
  background: radial-gradient(circle at 50% 50%,
    #5e0610 0%,
    #8a0e16 35%,
    #b41820 80%,
    #c01b22 100%);
  box-shadow:
    inset 0 0 16px rgba(0, 0, 0, 0.55),
    inset 0 0 0 1px rgba(0, 0, 0, 0.40);
}
/* The press depression now comes from the inset shadow swap on
   :active itself, not a separate dark-indent pseudo-element. */

/* Legacy colour-variant classes are aliased to the default red look so
   any existing HTML keeps working without an immediate edit. The body
   gradient ignores them — every arcade button is now red. */
.arcade-btn-red, .arcade-btn-blue, .arcade-btn-yellow, .arcade-btn-green {
  /* intentionally empty — default styles apply */
}

/* Compact size — tetris's row of three plungers. Same flat top-down
   look as the default plunger, just smaller. */
.arcade-btn.sm {
  width: 46px;
  height: 46px;
  box-shadow:
    inset 0 0 0 1px rgba(0, 0, 0, 0.35);
}
.arcade-btn.sm:active,
.arcade-btn.sm.arcade-pressed {
  transform: scale(0.92);
  background: radial-gradient(circle at 50% 50%,
    #5e0610 0%, #8a0e16 35%, #b41820 80%, #c01b22 100%);
  box-shadow:
    inset 0 0 12px rgba(0, 0, 0, 0.55),
    inset 0 0 0 1px rgba(0, 0, 0, 0.40);
}

/* Hide on desktop with a real pointer */
@media (pointer: fine) {
  .controls-bar { display: none; }
}

/* Narrow phones (iPhone SE 1st gen 320 px, older Android < 360 px).
   Shrink joystick + buttons uniformly so the whole control bar still
   fits inside the 95vw chassis width. */
@media (max-width: 360px) {
  .joystick           { width: 112px; height: 112px; }
  .joystick-ball      { width: 62px;  height: 62px; margin: -31px 0 0 -31px; }
  .joystick-arrow     { width: 14px;  height: 14px; }
  .arcade-btn-group   { width: 78px;  height: 78px; }
  .arcade-btn-group:has(.arcade-btn.sm) { width: 50px; height: 50px; }
  .arcade-btn         { width: 62px;  height: 62px; }
  .arcade-btn.sm      { width: 40px;  height: 40px; }
  .controls-bar       { padding: 14px 4px; }
}

/* ============================================================
   Arcade-cabinet panel buttons — used when <body class="arcade-game">
   is set. Restyles every .btn / .select inside the game so the
   New-Game / Pause / Sound row matches the arcade joystick. Looks
   like an illuminated cabinet panel button (dark gradient, cyan
   neon glow, pressed-in active state).
   ============================================================ */
body.arcade-game .app .btn,
body.arcade-game .app .select {
  background: linear-gradient(180deg, #1c2a4f 0%, #0c1530 100%);
  color: #cfeaff;
  border: 1.5px solid rgba(91, 224, 255, 0.42);
  border-radius: 12px;
  font-weight: 800;
  letter-spacing: 0.4px;
  text-shadow: 0 0 10px rgba(91, 224, 255, 0.55);
  box-shadow:
    inset 0 1px 0 rgba(91, 224, 255, 0.22),
    inset 0 -2px 4px rgba(0, 0, 0, 0.40),
    0 2px 6px rgba(0, 0, 0, 0.35),
    0 0 14px rgba(91, 224, 255, 0.18);
  transition: filter 0.15s, transform 0.08s, box-shadow 0.15s;
}
body.arcade-game .app .btn:hover,
body.arcade-game .app .select:hover {
  filter: brightness(1.18);
}
body.arcade-game .app .btn:active {
  transform: translateY(1px);
  box-shadow:
    inset 0 2px 7px rgba(0, 0, 0, 0.55),
    0 0 18px rgba(91, 224, 255, 0.45);
}
/* Pressed-on toggle (sound/pause indicator) */
body.arcade-game .app .btn-toggle[aria-pressed="false"] {
  filter: brightness(0.7) saturate(0.5);
}
/* Score boxes — match the panel look */
body.arcade-game .app .score-box {
  background: linear-gradient(180deg, #14224a 0%, #08102a 100%);
  border: 1.5px solid rgba(91, 224, 255, 0.30);
  color: #cfeaff;
  box-shadow:
    inset 0 1px 0 rgba(91, 224, 255, 0.18),
    0 2px 6px rgba(0, 0, 0, 0.30);
}
body.arcade-game .app .score-label {
  color: rgba(91, 224, 255, 0.75);
  text-shadow: 0 0 6px rgba(91, 224, 255, 0.5);
}
body.arcade-game .app .score-value {
  color: #fff;
  text-shadow: 0 0 8px rgba(91, 224, 255, 0.55);
}
/* Title in arcade neon */
body.arcade-game .app .title {
  color: #5be0ff;
  text-shadow:
    0 0 8px rgba(91, 224, 255, 0.65),
    0 0 18px rgba(91, 224, 255, 0.35);
  letter-spacing: 1px;
}
/* Overlay text/btn in arcade games */
body.arcade-game .overlay {
  background: rgba(2, 6, 22, 0.78);
}
body.arcade-game .overlay-text {
  color: #ffe23d;
  text-shadow:
    0 0 10px rgba(255, 226, 90, 0.7),
    0 0 22px rgba(255, 226, 90, 0.35);
}
