// StrikeSimple — Cursor. Replaces the native pointer with the brand mark on devices that have
// a hovering, precise pointer (mouse / trackpad). The mark spins slowly, 16px at rest; over
// anything clickable it grows to 33px, twists and gains a ring; while the button is held it
// compresses.
// Exposes window.Cursor. Ported from the v3 landing page; its styles ship with the component
// (CURSOR_CSS below), as this page keeps styling inside its components.
//
//   <Cursor />   mount once, anywhere in the tree (it is position: fixed)
//
// Behaviour
//   • Only active when `(hover: hover) and (pointer: fine)` matches — touch devices keep their
//     native behaviour. While active, <html class="lp-has-cursor"> hides the native cursor.
//   • Position is written straight to the DOM on mousemove (no React re-render per move);
//     only the hover / pressed states go through React.
//   • Anything matching INTERACTIVE (links, buttons, form controls, role="button" / "link",
//     `[data-cursor="link"]`) puts it in the link state — unless it is disabled (`:disabled` /
//     aria-disabled), e.g. a carousel arrow at its last slide. Hidden when the pointer leaves the
//     window.
(function () {
  const { Mark } = window.StrikeXDesignSystem_787c16;
  const INTERACTIVE = 'a[href], button, [role="button"], [role="link"], input, select, textarea, label, summary, [data-cursor="link"]';

  // Above everything on the page, the intro splash (z-index 9999) included.
  const CURSOR_CSS = `
    html.lp-has-cursor, html.lp-has-cursor * { cursor: none !important; }
    .lp-cursor {
      position: fixed; left: 0; top: 0; z-index: 10001;
      width: 0; height: 0;
      pointer-events: none;
      opacity: 0;
      transition: opacity 0.25s var(--ease-out);
      will-change: transform;
    }
    .lp-cursor.is-visible { opacity: 1; }
    /* Drawn at its hover size (33px) and scaled down to 16px at rest, so the hover state is the
       mark at full size and its strokes keep their weight. */
    .lp-cursor-mark {
      position: absolute; left: 0; top: 0;
      display: block; width: 33px; height: 33px;
      color: var(--blue-400);
      transform: translate(-50%, -50%) scale(0.485);
      transition: transform 0.3s var(--ease-out), color 0.3s var(--ease-out);
    }
    .lp-cursor-mark svg { display: block; animation: lp-cursor-spin 9s linear infinite; }
    .lp-cursor-ring {
      position: absolute; left: 0; top: 0;
      width: 44px; height: 44px;
      border: 1px solid var(--blue-400); border-radius: 50%;
      transform: translate(-50%, -50%) scale(0.4);
      opacity: 0;
      transition: transform 0.35s var(--ease-out), opacity 0.3s var(--ease-out), border-color 0.3s var(--ease-out);
    }
    /* Over something clickable the mark grows, twists and inverts against whatever is beneath it
       (difference blend on the fixed cursor element itself — a blend on a child would only see
       the cursor's own transparent backdrop), so it stays visible on the cobalt buttons, the
       light sections and the dark ones alike; a ring fades in around it. */
    .lp-cursor.is-link { mix-blend-mode: difference; }
    .lp-cursor.is-link .lp-cursor-mark {
      color: #fff;
      transform: translate(-50%, -50%) rotate(45deg);
    }
    .lp-cursor.is-link .lp-cursor-ring { opacity: 0.7; transform: translate(-50%, -50%) scale(1); border-color: #fff; }
    /* pressed: the mark shrinks to 0.8 of its 16px rest size (12.8px) and the ring, hidden at
       rest, shows at 0.7 of its 44px box scaled by 16/22 (22.4px); over something clickable both
       keep the pressed sizes they had with the old 22px rest: mark 0.8 × 22 = 17.6px, ring
       0.7 × 44 = 30.8px. */
    .lp-cursor.is-down .lp-cursor-mark { transform: translate(-50%, -50%) scale(0.39) rotate(90deg); }
    .lp-cursor.is-down .lp-cursor-ring { opacity: 0.9; transform: translate(-50%, -50%) scale(0.51); }
    .lp-cursor.is-link.is-down .lp-cursor-mark { transform: translate(-50%, -50%) scale(0.533) rotate(90deg); }
    .lp-cursor.is-link.is-down .lp-cursor-ring { transform: translate(-50%, -50%) scale(0.7); }
    @keyframes lp-cursor-spin { to { transform: rotate(360deg); } }
    @media (prefers-reduced-motion: reduce) {
      .lp-cursor-mark svg { animation: none; }
      .lp-cursor-mark, .lp-cursor-ring { transition: none; }
    }
    @media print { .lp-cursor { display: none !important; } }
  `;

  function useMedia(query) {
    const get = () => typeof window !== "undefined" && !!window.matchMedia && window.matchMedia(query).matches;
    const [m, setM] = React.useState(get);
    React.useEffect(() => {
      if (!window.matchMedia) return;
      const mq = window.matchMedia(query);
      const on = () => setM(mq.matches);
      mq.addEventListener ? mq.addEventListener("change", on) : mq.addListener(on);
      return () => { mq.removeEventListener ? mq.removeEventListener("change", on) : mq.removeListener(on); };
    }, [query]);
    return m;
  }

  function Cursor() {
    const enabled = useMedia("(hover: hover) and (pointer: fine)");
    const ref = React.useRef(null);
    const [visible, setVisible] = React.useState(false);
    const [link, setLink] = React.useState(false);
    const [down, setDown] = React.useState(false);

    React.useEffect(() => {
      if (!enabled) return;
      document.documentElement.classList.add("lp-has-cursor");
      let x = -100, y = -100, raf = 0, shown = false;
      const paint = () => {
        raf = 0;
        if (ref.current) ref.current.style.transform = `translate3d(${x}px, ${y}px, 0)`;
      };
      const onMove = (e) => {
        x = e.clientX; y = e.clientY;
        if (!raf) raf = requestAnimationFrame(paint);
        if (!shown) { shown = true; setVisible(true); }
      };
      const check = (t) => {
        const hit = t && t.closest && t.closest(INTERACTIVE);
        setLink(!!hit && !hit.matches(':disabled, [aria-disabled="true"]'));
      };
      const onOver = (e) => check(e.target);
      // A click can disable the control under a still pointer (Next → last slide), which fires no
      // mouseover, so look again once the click has been handled.
      const onClick = () => requestAnimationFrame(() => check(document.elementFromPoint(x, y)));
      const onDown = () => setDown(true);
      const onUp = () => setDown(false);
      const onOut = (e) => { if (!e.relatedTarget) { shown = false; setVisible(false); setDown(false); setLink(false); } };
      // Losing window focus (new tab, app switch) hides the mark; getting focus back re-shows it
      // at the last known position so the visitor is never left with no pointer at all.
      const onBlur = () => { shown = false; setVisible(false); setDown(false); };
      const onFocus = () => { if (x > -100 && !shown) { shown = true; setVisible(true); } };
      window.addEventListener("mousemove", onMove, { passive: true });
      window.addEventListener("mouseover", onOver, { passive: true });
      window.addEventListener("mousedown", onDown, { passive: true });
      window.addEventListener("mouseup", onUp, { passive: true });
      window.addEventListener("click", onClick, { passive: true });
      document.addEventListener("mouseout", onOut);
      window.addEventListener("blur", onBlur);
      window.addEventListener("focus", onFocus);
      return () => {
        document.documentElement.classList.remove("lp-has-cursor");
        if (raf) cancelAnimationFrame(raf);
        window.removeEventListener("mousemove", onMove);
        window.removeEventListener("mouseover", onOver);
        window.removeEventListener("mousedown", onDown);
        window.removeEventListener("mouseup", onUp);
        window.removeEventListener("click", onClick);
        document.removeEventListener("mouseout", onOut);
        window.removeEventListener("blur", onBlur);
        window.removeEventListener("focus", onFocus);
      };
    }, [enabled]);

    if (!enabled) return null;
    return (
      <React.Fragment>
        <style>{CURSOR_CSS}</style>
        <div ref={ref} className={`lp-cursor ${visible ? "is-visible" : ""} ${link ? "is-link" : ""} ${down ? "is-down" : ""}`.trim()} aria-hidden="true">
          <span className="lp-cursor-ring" />
          <span className="lp-cursor-mark">
            <Mark size={33} color="currentColor" strokeWidth={9} title="" />
          </span>
        </div>
      </React.Fragment>
    );
  }

  window.Cursor = Cursor;
})();
