/* ============================================================
   CURSOR
   ------------------------------------------------------------
   A reading mark, not a blob. A 5px dot that tracks exactly, and
   a thin ring that lags behind it. The ring is the only thing
   that changes between states, and it never grows large enough
   to obscure what is being read.
   ============================================================ */

.cursor {
  position: fixed;
  top: 0;
  left: 0;
  z-index: var(--z-cursor);
  pointer-events: none;
  mix-blend-mode: difference;
  opacity: 0;
  transition: opacity var(--dur-ui) linear;
}
.cursor.is-on { opacity: 1; }

.cursor__dot {
  position: absolute;
  width: 5px;
  height: 5px;
  margin: -2.5px 0 0 -2.5px;
  border-radius: 50%;
  background: var(--color-paper-leaf);
  transform: translate3d(var(--dx, 0), var(--dy, 0), 0) scale(var(--dot-s, 1));
  transition: transform var(--dur-micro) var(--ease-arrive);
  will-change: transform;
}

.cursor__ring {
  position: absolute;
  width: 34px;
  height: 34px;
  margin: -17px 0 0 -17px;
  border: 1px solid rgb(243 237 225 / 0.55);
  border-radius: 50%;
  transform: translate3d(var(--rx, 0), var(--ry, 0), 0) scale(var(--ring-s, 0.44)) rotate(var(--ring-r, 0deg));
  opacity: var(--ring-o, 0.5);
  transition:
    width var(--dur-micro) var(--ease-arrive),
    height var(--dur-micro) var(--ease-arrive),
    border-radius var(--dur-micro) var(--ease-arrive),
    opacity var(--dur-micro) linear;
  will-change: transform;
}

.cursor__label {
  position: absolute;
  transform: translate3d(var(--rx, 0), var(--ry, 0), 0) translate(26px, -50%);
  font-family: var(--font-meta);
  font-size: var(--t-micro);
  font-weight: 500;
  letter-spacing: var(--track-meta);
  text-transform: uppercase;
  color: var(--color-paper-leaf);
  white-space: nowrap;
  opacity: 0;
  transition: opacity var(--dur-micro) linear;
  will-change: transform;
}

/* ---------- states ---------- */

/* VIEW — over a portrait or an image */
.cursor[data-state='view'] { --ring-s: 1.5; --ring-o: 0.85; --dot-s: 0; }
.cursor[data-state='view'] .cursor__label { opacity: 1; }

/* OPEN — over the book, or a thing that unfolds */
.cursor[data-state='open'] { --ring-s: 1.1; --ring-o: 1; --dot-s: 0.6; }
.cursor[data-state='open'] .cursor__ring { border-radius: var(--radius-2); }
.cursor[data-state='open'] .cursor__label { opacity: 1; }

/* INDEX — over a list entry: the ring flattens into a rule */
.cursor[data-state='index'] .cursor__ring {
  width: 44px;
  height: 1px;
  margin: 0 0 0 -22px;
  border-width: 0;
  border-top: 1px solid rgb(243 237 225 / 0.9);
  border-radius: 0;
}
.cursor[data-state='index'] { --ring-s: 1; --ring-o: 1; --dot-s: 0.8; }
.cursor[data-state='index'] .cursor__label { opacity: 1; }

/* EXPLORE — over the globe */
.cursor[data-state='explore'] { --ring-s: 1.34; --ring-o: 0.9; --dot-s: 0.5; }
.cursor[data-state='explore'] .cursor__label { opacity: 1; }

/* LINK — over navigation and actions */
.cursor[data-state='link'] { --ring-s: 0.78; --ring-o: 1; --dot-s: 0; }

/* pressed */
.cursor.is-down { --ring-s: 0.62; }

/* Hide the native pointer only where we have replaced it. */
.has-cursor,
.has-cursor * { cursor: none !important; }

@media (pointer: coarse), (prefers-reduced-motion: reduce) {
  .cursor { display: none; }
  .has-cursor, .has-cursor * { cursor: auto !important; }
}
