@layer base {
  /* ── Custom cursor ────────────────────────────────────────────────
     Native cursor is hidden site-wide once JS confirms the custom one
     is mounted (via `html.cursor-enabled`). Before that boot, the OS
     pointer stays — so a brand-new tab doesn't show "no cursor" if
     something prevents JS from running.

     The cursor itself is a fixed-position 14px circle that uses
     mix-blend-mode: difference against white, so it always reads as
     the inverse of whatever sits underneath. On hover of an
     interactive element, the blend mode flips off and the circle
     turns pink. On mousedown, the circle is briefly swapped for an X
     glyph of the same size.
  ──────────────────────────────────────────────────────────────── */
  html.cursor-enabled,
  html.cursor-enabled body,
  html.cursor-enabled * {
    cursor: none !important;
  }

  .cursor {
    position: fixed;
    top: 0;
    left: 0;
    width: 18px;
    height: 18px;
    pointer-events: none;
    z-index: 2147483647;
    will-change: transform;
    /* The blend lives on the cursor wrapper itself, not the child dot.
       The translate keeps the element in its own stacking context, so a
       blend mode on an inner element only sees the wrapper's (empty)
       backdrop and the dot ends up looking solid white on light pages.
       Blending the wrapper instead lets it inverse against the page. */
    mix-blend-mode: difference;
    transition: opacity 120ms ease;
  }
  .cursor--hidden { opacity: 0; }

  /* Pink hover state — solid pink, no blend. */
  .cursor--hot { mix-blend-mode: normal; }

  /* Default state — hollow ring with the same stroke weight as the X.
     Hover fills it in (pink, blend off — handled by .cursor--hot above). */
  .cursor-dot {
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: transparent;
    border: 3.2px solid #fff;
    box-sizing: border-box;
    transition:
      background 120ms ease,
      border-color 120ms ease,
      transform 140ms cubic-bezier(.18, .85, .25, 1),
      opacity 80ms ease;
  }
  .cursor--hot .cursor-dot {
    background: var(--pink);
    border-color: var(--pink);
    box-shadow: 0 0 0 1.5px #fff;
    transform: scale(1.15);
  }

  /* Click flash — circle gives way to a bigger X. Centered on the
     cursor point with squared stroke ends so it reads as a sharp
     "click landed" mark, not a soft cross. */
  .cursor-x {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 22px;
    height: 22px;
    transform: translate(-50%, -50%);
    stroke: #fff;
    stroke-width: 2.6;
    stroke-linecap: square;
    fill: none;
    opacity: 0;
    transition: opacity 80ms ease, stroke 80ms ease;
  }
  .cursor--click .cursor-dot { opacity: 0; }
  .cursor--click .cursor-x   { opacity: 1; }
  .cursor--click.cursor--hot .cursor-x { stroke: var(--pink); }

  /* Coarse-pointer devices — let the OS handle it. */
  @media (pointer: coarse) {
    html.cursor-enabled,
    html.cursor-enabled body,
    html.cursor-enabled * { cursor: auto !important; }
    .cursor { display: none !important; }
  }

  /* Respect users who want reduced motion — drop the scale/transition. */
  @media (prefers-reduced-motion: reduce) {
    .cursor-dot,
    .cursor-x { transition: none; }
    .cursor--hot .cursor-dot { transform: none; }
  }
}
