/* ------------------------------------------------------------
   Site cursor — DOM element that follows the mouse.
   Activated by /components/cursor.js when the device supports
   fine pointers + hover + non-reduced motion. Ported from the
   crashparty-brain selector demo; `button` added to the hover
   cross-fade for the lobby HUD's plain <button> controls.
   ------------------------------------------------------------ */
.site-cursor {
  position: fixed;
  inset-block-start: 0;
  inset-inline-start: 0;
  inline-size: 64px;
  block-size: 64px;
  pointer-events: none;
  /* Sits above everything — including dev panels (z 20000). */
  z-index: 2147483646;
  /* Shift the element so the image's hotspot (8, 6) lines up
     with the actual pointer coordinate delivered by pointermove. */
  margin-inline-start: -8px;
  margin-block-start: -6px;
  opacity: 0;
  transition: opacity 180ms ease;
  will-change: transform;
}

/* Tunable cursor settings — read each frame by cursor.js via
   getComputedStyle. */
:root {
  --cursor-lift:       17px;  /* upward offset over buttons / card anchors */
  --cursor-press:      10px;  /* downward offset while pressed */
  --cursor-scale:      1.00;  /* scale factor over buttons / card anchors */
  --cursor-stiffness:   270;  /* spring k — higher = tighter, faster */
  --cursor-damping:      19;  /* spring c — higher = settles faster, less bounce */
  --cursor-fade:       20ms;  /* color cross-fade duration (CSS) */

  /* Subtler hover response over plain text links (inline <a>,
     back links, bio mentions, etc.) where the full button-scale
     treatment feels too dramatic. */
  --cursor-link-lift:   4px;
  --cursor-link-scale: 1.02;
}

.site-cursor__inner {
  position: relative;
  inline-size: 100%;
  block-size: 100%;
  /* Motion (translate, scale, and any future rotation) is driven
     entirely by cursor.js's rAF loop via spring physics. No CSS
     animation, transition, or base rest values — the JS integrator
     owns these properties end-to-end. */
}

/* Two layered cursor images — default gray on ::before, hover
   variant on ::after. Opacity cross-fade gives a smooth color
   transition; this stays in CSS because opacity doesn't compose
   with the JS-owned transforms. */
.site-cursor__inner::before,
.site-cursor__inner::after {
  content: "";
  position: absolute;
  inset: 0;
  background-position: center;
  background-size: contain;
  background-repeat: no-repeat;
  transition: opacity var(--cursor-fade) ease;
}
.site-cursor__inner::before {
  background-image: url("cursor.png");
  opacity: 1;
}
.site-cursor__inner::after {
  background-image: url("cursor-btn.png");
  opacity: 0;
}

/* Over a button or link: cross-fade to the hover variant. */
body:has(.cp-btn:hover, a:hover, button:hover) .site-cursor__inner::before {
  opacity: 0;
}
body:has(.cp-btn:hover, a:hover, button:hover) .site-cursor__inner::after {
  opacity: 1;
}

/* When the DOM cursor is active, hide every native cursor.
   !important is necessary to override per-element cursor rules. */
html.has-site-cursor,
html.has-site-cursor * {
  cursor: none !important;
}
