/* The bonus officer stays in the left scene margin. Reactions play once;
   ordinary free spins leave the complete, grounded idle pose untouched. */
#bonusRival {
  position: absolute;
  left: 42px;   /* nudged 20px right on desktop (2026-09-13) */
  top: 244px;
  width: 228px;
  height: 370px;
  z-index: 3;
  display: none;
  isolation: isolate;
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
}

body.free-spins #bonusRival:not([hidden]) { display: block; }
#bonusRival[hidden] { display: none !important; }
body.chase-active #bonusRival { visibility: hidden; }

/* A small contact shadow anchors both shoes without adding another panel. */
#bonusRival::before {
  content: '';
  position: absolute;
  left: 22%;
  bottom: 0;
  width: 56%;
  height: 4%;
  background: radial-gradient(ellipse, #020714b3 12%, #02071455 48%, transparent 72%);
}

#bonusRival .rival-body {
  position: absolute;
  inset: 0;
  transform-origin: 50% 98%;
}

#bonusRival .rival-pose {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center bottom;
  filter: drop-shadow(0 4px 3px #040a2470);
  -webkit-user-drag: none;
}

#bonusRival .rival-mark {
  position: absolute;
  right: 5px;
  top: 18px;
  width: 68px;
  height: 72px;
  opacity: 0;
  color: #ffea39;
  font: 900 58px/1 var(--font-heavy);
  text-align: center;
  letter-spacing: -3px;
  -webkit-text-stroke: 5px #050b20;
  paint-order: stroke fill;
  text-shadow: 3px 3px 0 #ec21bc;
  transform: rotate(11deg);
  transform-origin: 50% 75%;
}

#bonusRival .rival-impact {
  position: absolute;
  left: 27%;
  bottom: 0;
  width: 46%;
  height: 12px;
  box-sizing: border-box;
  border: 3px solid #6af4ff;
  border-radius: 50%;
  box-shadow: 0 2px 0 #ed25b7;
  opacity: 0;
}

#bonusRival[data-mood='annoyed'] .rival-body {
  animation: rival-admonish .82s ease-in-out both;
}

#bonusRival[data-mood='furious'] .rival-body {
  animation: rival-stamp 1.04s ease-in-out both;
}

#bonusRival[data-mood='retrigger'] .rival-body {
  animation: rival-whistle .94s ease-in-out both;
}

#bonusRival[data-mood='annoyed'] .rival-mark,
#bonusRival[data-mood='furious'] .rival-mark,
#bonusRival[data-mood='retrigger'] .rival-mark {
  opacity: 1;
  animation: rival-punctuation .34s ease-out both;
}

#bonusRival[data-mood='furious'] .rival-mark {
  color: #ff62d4;
  text-shadow: 3px 3px 0 #ffdf36;
}

#bonusRival[data-mood='retrigger'] .rival-mark {
  color: #83f6ff;
  text-shadow: 3px 3px 0 #e926c2;
}

#bonusRival[data-mood='furious'] .rival-impact {
  animation: rival-contact .52s ease-out .24s both;
}

@keyframes rival-admonish {
  0%, 100% { transform: none; }
  22% { transform: rotate(1.2deg); }
  43% { transform: rotate(.3deg); }
  63% { transform: rotate(1.5deg); }
  82% { transform: rotate(.4deg); }
}

@keyframes rival-stamp {
  0%, 100% { transform: none; }
  15% { transform: translateY(-3px) rotate(-.7deg); }
  29% { transform: translateY(2px) rotate(.9deg); }
  44% { transform: translateY(-1px) rotate(.3deg); }
  61% { transform: rotate(1.5deg); }
  81% { transform: rotate(.5deg); }
}

@keyframes rival-whistle {
  0%, 100% { transform: none; }
  22% { transform: translateY(-2px) rotate(-.5deg); }
  47% { transform: rotate(1.4deg); }
  70% { transform: rotate(.4deg); }
}

@keyframes rival-punctuation {
  0% { opacity: 0; transform: translateY(5px) rotate(3deg) scale(.7); }
  60% { opacity: 1; transform: translateY(-2px) rotate(14deg) scale(1.06); }
  100% { opacity: 1; transform: rotate(11deg) scale(1); }
}

@keyframes rival-contact {
  0% { opacity: 0; transform: scaleX(.65); }
  14% { opacity: .9; transform: scaleX(.82); }
  100% { opacity: 0; transform: scaleX(1.2); }
}

/* This response affects only a resting mascot. Flight, spray, landing and
   the existing win celebration keep their own pose and movement unchanged. */
body.free-spins.rival-taunt:not(.mascot-spray):not(.mascot-spray-big):not(.mascot-cheer):not(.chase-active)
#mascot:not(.mascot-on-board):not(.mascot-fly-out):not(.mascot-fly-home):not(.mascot-landed) {
  animation: rival-runner-reply .76s ease-in-out both;
}

@keyframes rival-runner-reply {
  0%, 100% { transform: none; }
  25% { transform: rotate(-1deg); }
  58% { transform: rotate(.45deg); }
  79% { transform: rotate(-.35deg); }
}

/* Enlarge the complete phone sprite by 35% around its original shoe baseline
   (y341.64). The frame starts at y352.82, below the feet and stamp effect. */
#stage.portrait #bonusRival {
  left: 6px;
  top: 75px;      /* clear of the board frame and the screen edge (2026-09-13) */
  width: 176px;
  height: 264px;
  z-index: 1;
  /* compact portrait (js/ui.js layout(), css/reference-ui.css): the whole cage — sprite, mark,
     impact lines and its offsets — follows the header's scale with the logo and runner */
  zoom: var(--char-k, 1);
  /* feet stay 46.76px above the board top (75 + 264 = 339 vs --board-y 385.76 at rest); top is in zoomed px */
  top: calc((var(--board-y, 385.76px) - 46.76px) / var(--char-k, 1) - 264px);
}

#stage.portrait #bonusRival .rival-mark {
  right: 8px;
  top: 9px;
  width: 40px;
  height: 44px;
  font-size: 34px;
  letter-spacing: -2px;
  -webkit-text-stroke-width: 3px;
  text-shadow: 2px 2px 0 #ec21bc;
}

#stage.portrait #bonusRival[data-mood='furious'] .rival-mark {
  text-shadow: 2px 2px 0 #ffdf36;
}

#stage.portrait #bonusRival .rival-impact {
  height: 8px;
  border-width: 2px;
}

body.page-hidden #bonusRival .rival-body,
body.page-hidden #bonusRival .rival-mark,
body.page-hidden #bonusRival .rival-impact,
body.page-hidden.rival-taunt #mascot {
  animation-play-state: paused !important;
}

@media (prefers-reduced-motion: reduce) {
  #bonusRival .rival-body,
  #bonusRival .rival-mark,
  #bonusRival .rival-impact,
  body.free-spins.rival-taunt #mascot {
    animation: none !important;
    transform: none;
  }
  #bonusRival .rival-impact { opacity: 0; }
}

/* ---------- the police dog ----------
   He sits at the officer's feet, in front of his boots, inside the same box
   (so the cell bars cover him too). Between reactions he runs alongside the
   officer in the station and sulks in the cell; during a reaction he barks
   with the cross poses and droops with the sorry ones. */
#bonusRival .rival-dog {
  position: absolute;
  left: -3%;
  bottom: -1.5%;
  width: 74%;
  aspect-ratio: 360 / 280;
  z-index: 2;
  transform-origin: 50% 100%;
}
#bonusRival .rival-dog .dog-run { display: none; position: absolute; inset: 0; }
#bonusRival .rival-dog .dog-pose {
  display: block; width: 100%; height: 100%;
  object-fit: contain; object-position: center bottom;
  filter: drop-shadow(0 3px 2px #040a2470);
  -webkit-user-drag: none;
}
#bonusRival[data-dog='bark'] .rival-dog { animation: dog-bark .46s ease-out 2 both; }
#bonusRival[data-dog='sad'] .rival-dog { animation: dog-sulk 3.2s ease-in-out infinite; }
@keyframes dog-bark {
  0%, 100% { transform: none; }
  30% { transform: translate(6%, -5%) rotate(-6deg); }
  60% { transform: translate(3%, 0) rotate(-2deg); }
}
@keyframes dog-sulk {
  0%, 100% { transform: none; }
  50% { transform: translateY(1.5%) scaleY(.985); }
}

/* ---------- the officer's extra reactions ---------- */
#bonusRival[data-mood='angry'] .rival-body { animation: rival-rage .9s ease-in-out both; }
#bonusRival[data-mood='sad'] .rival-body { animation: rival-sob 1.9s ease-in-out both; }
#bonusRival[data-mood='headdown'] .rival-body { animation: rival-slump 2s ease-out both; }
#bonusRival[data-mood='kneel'] .rival-body { animation: rival-collapse 2.4s cubic-bezier(.2, .9, .3, 1) both; }
#bonusRival[data-mood='angry'] .rival-mark,
#bonusRival[data-mood='sad'] .rival-mark { opacity: 1; animation: rival-punctuation .34s ease-out both; }
#bonusRival[data-mood='angry'] .rival-mark { color: #ff4d4d; text-shadow: 3px 3px 0 #ffdf36; }
#bonusRival[data-mood='sad'] .rival-mark { color: #9fd8ff; text-shadow: 3px 3px 0 #2a3a8a; transform: rotate(0deg); }
#bonusRival[data-mood='angry'] .rival-impact { animation: rival-contact .52s ease-out .18s both; }
@keyframes rival-rage {
  0%, 100% { transform: none; }
  10% { transform: translate(-2px, -2px) rotate(-1.5deg); }
  20% { transform: translate(2px, 1px) rotate(1.5deg); }
  30% { transform: translate(-2px, 0) rotate(-1.2deg); }
  40% { transform: translate(2px, -1px) rotate(1.2deg); }
  50% { transform: translate(-1px, 1px) rotate(-.8deg); }
  60% { transform: translate(1px, 0) rotate(.8deg); }
  75% { transform: rotate(.3deg); }
}
@keyframes rival-sob {
  0%, 100% { transform: none; }
  20% { transform: translateY(2px) rotate(-.8deg); }
  40% { transform: translateY(0) rotate(.6deg); }
  60% { transform: translateY(2px) rotate(-.6deg); }
  80% { transform: translateY(0) rotate(.4deg); }
}
@keyframes rival-slump {
  0% { transform: translateY(-6px); }
  35% { transform: translateY(1px); }
  55% { transform: translateY(0); }
  100% { transform: translateY(0); }
}
@keyframes rival-collapse {
  0% { transform: translateY(-9%) scaleY(1.04); }
  35% { transform: translateY(1%) scaleY(.98); }
  50% { transform: translateY(0) scaleY(1); }
  70% { transform: translateY(0) rotate(-.6deg); }
  100% { transform: none; }
}
#stage.portrait #bonusRival .rival-dog { left: -2%; width: 70%; }
body.page-hidden #bonusRival .rival-dog { animation-play-state: paused !important; }
@media (prefers-reduced-motion: reduce) {
  #bonusRival .rival-dog { animation: none !important; transform: none; }
}
