/* Custom cursor (CLAUDE.md §6.8) — site-wide, in-house, no library.
   A fast dot + a slow ring; the lag between them is the effect.

   Colour is token-driven rather than mix-blend-mode: `difference` vanished
   against the dock, because backdrop-filter creates its own stacking context
   and the blend can't reach through it. */

.cursor {
  --ink: var(--brand);
  position: fixed;
  top: 0; left: 0;
  z-index: 200;              /* above the dock (60) and everything else */
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.25s ease;
}
.cursor[data-active="true"] { opacity: 1; }
.cursor[data-theme="light"] { --ink: var(--brand); }

/* Over a brand-orange surface the orange cursor disappears into it, so it
   flips to white for as long as the pointer is inside one. Any element marked
   `data-cursor-invert` is such a surface; see initCursor().

   The concrete properties are set here, not just `--ink`. Swapping the custom
   property alone does NOT repaint a property that is both transitioned and
   resolved through `var()` — the dot kept its old orange while
   `getComputedStyle` reported the inherited `--ink` as white. */
.cursor[data-invert="true"] { --ink: var(--secondary); }
.cursor[data-invert="true"] .cursor__dot { background: var(--secondary); }
.cursor[data-invert="true"] .cursor__ring::before { border-color: var(--secondary); }
.cursor[data-invert="true"][data-state="label"] .cursor__ring::before {
  background: var(--secondary);
  border-color: var(--secondary);
}

.cursor__dot,
.cursor__ring {
  position: absolute;
  top: 0; left: 0;
  will-change: transform;
}

/* The ring is a ZERO-SIZE positioner; the visible circle is its ::before.
   This split is load-bearing: CSS's individual `scale` property is applied
   BEFORE `transform`, so putting a scale on the same element that carries the
   position multiplies the translation — the ring drifted further off-pointer
   the further it got from the top-left corner. Position and scale must live on
   separate elements. */
.cursor__ring { width: 0; height: 0; }
.cursor__ring::before {
  content: "";
  position: absolute;
  left: 0; top: 0;
  width: var(--cursor-ring);
  height: var(--cursor-ring);
  margin-left: calc(var(--cursor-ring) / -2);
  margin-top: calc(var(--cursor-ring) / -2);
  border-radius: 999px;
  border: 1.5px solid var(--ink);
  scale: 1;
  transition: scale 0.28s cubic-bezier(0.22, 1, 0.36, 1),
              background-color 0.28s ease,
              border-color 0.28s ease;
}

.cursor__dot {
  width: var(--cursor-size);
  height: var(--cursor-size);
  margin-left: calc(var(--cursor-size) / -2);
  margin-top: calc(var(--cursor-size) / -2);
  border-radius: 999px;
  background: var(--ink);
  transition: opacity 0.2s ease, background-color 0.25s ease;
}

.cursor__label {
  position: absolute;
  top: 0; left: 0;
  font-family: var(--font-body);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--btn-ink);
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.2s ease;
}

/* States */
.cursor[data-state="hover"] .cursor__ring::before { scale: 1.45; }
.cursor[data-state="hover"] .cursor__dot  { opacity: 0; }
.cursor[data-state="label"] .cursor__ring::before { scale: 2; background: var(--ink); border-color: var(--ink); }
.cursor[data-state="label"] .cursor__dot  { opacity: 0; }
.cursor[data-state="label"] .cursor__label { opacity: 1; color: var(--hero-bg); }
.cursor[data-state="cta"]   .cursor__ring::before { scale: 2.1; background: var(--ink); border-color: var(--ink); }
.cursor[data-state="cta"]   .cursor__dot  { opacity: 0; }
.cursor[data-state="cta"]   .cursor__label { opacity: 1; color: var(--btn-ink); }
.cursor[data-pressed="true"] .cursor__ring::before { scale: 0.8; }

/* Hide the native cursor only while ours is live */
.has-custom-cursor,
.has-custom-cursor * { cursor: none !important; }
.has-custom-cursor input,
.has-custom-cursor textarea,
.has-custom-cursor [contenteditable] { cursor: text !important; }

@media (pointer: coarse), (hover: none) {
  .cursor { display: none; }
}
