/* ============================================================
   Cursor buddy — a tiny sprite of the player that trails the
   mouse, idling in place and breaking into a run once it has
   to catch up. Real cursor stays untouched; this just rides
   alongside it. Desktop/hover-capable pointers only.
   ============================================================ */

.ctrlv-cursor-buddy {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 999;
  pointer-events: none;
  image-rendering: pixelated;
  background-repeat: no-repeat;
  opacity: 0;
  transition: opacity 0.25s ease;
  will-change: transform;
  /* The scanner beam child (.ctrlv-cursor-buddy-scanner) is wider than
     this box and positioned with `left: 75%`, so it overflows this
     element (visible by default). Since this element is `position:
     fixed` with a `transform` applied every animation frame, browsers
     can disagree on whether that overflowing child should ever count
     toward the page's own scrollable-content bookkeeping. `contain:
     layout` is the spec-guaranteed way to say it never should. */
  contain: layout;
}

.ctrlv-cursor-buddy.is-visible {
  opacity: 1;
}

.ctrlv-cursor-buddy::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -2px;
  width: 60%;
  height: 6px;
  background: radial-gradient(closest-side, rgba(0, 0, 0, 0.35), transparent);
  transform: translateX(-50%);
}

.ctrlv-cursor-buddy.is-idle {
  width: 46px;
  height: 94px;
  background-image: url("/assets/images/projects/CTRL-V/sprites/player-buddy-idle.png");
  background-size: 368px 94px; /* 8 frames * 46px */
  animation: ctrlv-buddy-idle-frames 1.1s steps(8) infinite;
}

.ctrlv-cursor-buddy.is-walk {
  width: 64px;
  height: 96px;
  background-image: url("/assets/images/projects/CTRL-V/sprites/player-buddy-run.png");
  background-size: 512px 96px; /* 8 frames * 64px */
  animation: ctrlv-buddy-walk-frames 0.55s steps(8) infinite;
}

@keyframes ctrlv-buddy-idle-frames {
  from { background-position-x: 0; }
  to { background-position-x: -368px; }
}

@keyframes ctrlv-buddy-walk-frames {
  from { background-position-x: 0; }
  to { background-position-x: -512px; }
}

/* Scanning — like the game, the CTRL arm holds a single raised "up"
   pose for as long as Ctrl/Cmd is held (no flipbook animation for the
   arm itself — PlayerAnimator.cs swaps to a static aim-direction
   sprite instead). The legs keep animating underneath: idle breathing
   if the buddy is standing still, the walk cycle if it's catching up. */
.ctrlv-cursor-buddy.is-scanning.is-idle {
  width: 64px;
  height: 96px;
  background-image: url("/assets/images/projects/CTRL-V/sprites/player-buddy-scan-idle.png");
  background-size: 512px 96px; /* 8 frames * 64px */
  animation: ctrlv-buddy-walk-frames 1.1s steps(8) infinite;
}

.ctrlv-cursor-buddy.is-scanning.is-walk {
  width: 64px;
  height: 96px;
  background-image: url("/assets/images/projects/CTRL-V/sprites/player-buddy-scan-walk.png");
  background-size: 512px 96px; /* 8 frames * 64px */
  animation: ctrlv-buddy-walk-frames 0.55s steps(8) infinite;
}

/* Scanner beam — the game's own scan effect, anchored the same way it
   is in Unity: pivot (0, 0.5), i.e. its left edge sits at the hand and
   the beam fans out from there, not from the sprite's own center.
   Position matches the raised device in player-buddy-scan.png. */
.ctrlv-cursor-buddy-scanner {
  position: absolute;
  left: 75%;
  top: 31%;
  width: 76px;
  height: 106px;
  transform: translateY(-50%);
  background-image: url("/assets/images/projects/CTRL-V/sprites/player-buddy-scanner.png");
  background-repeat: no-repeat;
  background-size: 304px 212px; /* 4 cols * 76px, 2 rows * 106px */
  background-position: 0 0;
  mix-blend-mode: screen;
  opacity: 0;
  transition: opacity 0.15s ease;
  pointer-events: none;
}

.ctrlv-cursor-buddy.is-scanning .ctrlv-cursor-buddy-scanner {
  opacity: 0.9;
}

/* Not `@media (hover: none)`: iPadOS Safari always matches that, even
   with a trackpad connected, which would permanently hide this on any
   iPad. Gated on ctrl-v_cursor-buddy.js's own live pointerType
   detection (ctrlv-pointer-ready) instead. */
body:not(.ctrlv-pointer-ready) .ctrlv-cursor-buddy {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .ctrlv-cursor-buddy {
    display: none;
  }
}
