Hiding cursor with JS or CSS

Hi! I have been trying to inject custom code into my Readymag site in order to make a short line of text the “cursor” instead of the default. I have exhausted everything I know to do to achieve this. I was able to effectively hide the default cursor in most scenarios, even as I navigate pages. Still, when the browser is in full-screen mode, something is overriding my JS, and the cursor reappears and stays on screen until I refresh or the mouse leaves the screen. This is the current code I am using:

AFTER :

<div class="cursor-tagline" data-id="698805bcdc1b184afb0e6b3d">Constructing worlds for moving and still image.</div>

html, html * { cursor: none !important; }

BEFORE :

<script>
(function () {

  // ── Config ──────────────────────────────────────────────
  var TAGLINE_ID   = "698805bcdc1b184afb0e6b3d";
  var OFFSET_X     = 8;   // px right of cursor
  var OFFSET_Y     = 10;  // px below cursor
  var IDLE_MS      = 80;  // ms before tagline fades out
  var OBSERVE_MAX  = 15000; // stop watching DOM after 15s
  // ────────────────────────────────────────────────────────

  var selector = '[data-id="' + TAGLINE_ID + '"]';

  function init(el) {

    // Don't run twice on the same element
    if (!el || el.__cursorInit) return;
    el.__cursorInit = true;


    // Keep the tagline out of the normal document flow
    el.style.setProperty("position", "absolute", "important");

    // ── Stage: find the container that fills the viewport ──
    var stage    = pickStage();
    var stageRect = stage.getBoundingClientRect(); // cached

    function pickStage() {
      var vw = window.innerWidth, vh = window.innerHeight;
      var node = el.parentElement;
      while (node && node !== document.body) {
        var r = node.getBoundingClientRect();
        if (r.width >= vw * 0.9 && r.height >= vh * 0.9) return node;
        node = node.parentElement;
      }
      return document.body;
    }

    // Refresh cached rect on resize (not every frame)
    window.addEventListener("resize", function () {
      stage     = pickStage();
      stageRect = stage.getBoundingClientRect();
    }, { passive: true });

    // ── Cursor state ───────────────────────────────────────
    var cursorX   = 0, cursorY = 0;
    var hasMoved  = false;
    var lastMoved = performance.now();
    var rafId     = null;

    // ── Animation loop (only runs when cursor is active) ───
    function frame() {
      var now = performance.now();

      if (hasMoved) {
        // Convert viewport coords → stage-local coords
        var x = (cursorX - stageRect.left) + OFFSET_X;
        var y = (cursorY - stageRect.top)  + OFFSET_Y;

        el.style.setProperty("left", x + "px", "important");
        el.style.setProperty("top",  y + "px", "important");

        el.classList.add("is-on");
        hasMoved = false;
      }

      // Fade out after idle threshold
      if (now - lastMoved > IDLE_MS) {
        el.classList.remove("is-on");
      }

      // Keep looping only while cursor is active;
      // stop after a short idle to save CPU/battery
      if (now - lastMoved < IDLE_MS + 2000) {
        rafId = requestAnimationFrame(frame);
      } else {
        rafId = null; // loop paused — restarts on next mousemove
      }
    }

    // ── Events ─────────────────────────────────────────────
    window.addEventListener("mousemove", function (e) {
      cursorX   = e.clientX;
      cursorY   = e.clientY;
      hasMoved  = true;
      lastMoved = performance.now();

      // Restart the loop if it went idle
      if (!rafId) rafId = requestAnimationFrame(frame);
    }, { passive: true });

    window.addEventListener("mouseleave", function () {
      el.classList.remove("is-on");
    });

  } // end init()

  // ── Wait for the element to appear in the DOM ───────────
  // (ReadyMag injects elements dynamically, so we can't
  //  assume the tagline exists at script-run time.)
  var obs = new MutationObserver(function () {
    var el = document.querySelector(selector);
    if (el) {
      init(el);
      obs.disconnect();
    }
  });

  obs.observe(document.documentElement, { childList: true, subtree: true });

  // Failsafe: stop observing after 15 seconds
  setTimeout(function () { obs.disconnect(); }, OBSERVE_MAX);

  // Also try immediately in case the element already exists
  var existing = document.querySelector(selector);
  if (existing) { init(existing); obs.disconnect(); }

})();
  
  // Force cursor back to hidden after every click
window.addEventListener("click", function () {
  // Hammer cursor hidden every 16ms for 2 seconds after any click
  // This covers the entire duration of Readymag's page transition
  var hammerId = null;
  var hammerCount = 0;
  var MAX = 120; // 120 × 16ms = ~2 seconds

  function hammer() {
    enforce();
    injectStyle();
    hammerCount++;
    if (hammerCount < MAX) {
      hammerId = setTimeout(hammer, 16);
    }
  }

  if (hammerId) clearTimeout(hammerId);
  hammerCount = 0;
  hammer();
}, true);
  
</script>

<script>
(function () {
  var style = document.createElement("style");
  style.textContent = [
    "html, html *, html *:hover,",
    "html *:active, html *:focus,",
    "html *:focus-visible,",
    ".mag, .mag *, .mag-pages-container,",
    ".mag-pages-container *, .page,",
    ".page *, .center-page, .center-page *,",
    ".prev-page, .prev-page *,",
    ".next-page, .next-page * {",
    "  cursor: none !important;",
    "}"
  ].join("\n");

  function injectStyle() {
    if (!document.head.contains(style)) {
      document.head.appendChild(style);
    }
    // Stamp it directly on the html element as a fallback
    document.documentElement.setAttribute("style",
      (document.documentElement.getAttribute("style") || "") +
      "; cursor: none !important;"
    );
  }

  injectStyle();

  // Re-inject if Readymag removes it during a transition
  var obs = new MutationObserver(injectStyle);
  obs.observe(document.head, { childList: true });

  // Also watch the html element's own attributes
  var obsHtml = new MutationObserver(enforce);
  obsHtml.observe(document.documentElement, {
    attributes: true,
    attributeFilter: ["style", "class"]
  });

  // Hammer the body style directly on any interaction
  function enforce() {
    document.documentElement.style.setProperty("cursor", "none", "important");
    document.body.style.setProperty("cursor", "none", "important");
  }

  window.addEventListener("mousemove", enforce, { passive: true });
  window.addEventListener("mousedown", enforce, { passive: true });
  window.addEventListener("click", enforce, true);
  window.addEventListener("mouseup", enforce, true);

})();
</script>

CSS:

/* ── Cursor-follow tagline ─────────────────────────────── */
[data-id="698805bcdc1b184afb0e6b3d"] {
  position: absolute !important;
  left: 0 !important;
  top: 0 !important;
  pointer-events: none !important;
  z-index: 999999 !important;
  opacity: 0 !important;
  mix-blend-mode: difference !important;
  transition: opacity 120ms linear !important;
  transform: none !important;
  will-change: left, top, opacity;
  font-family: "Times New Roman", Times, serif !important;
  font-size: 17pt !important;
  color: #ffffff !important;
}
[data-id="698805bcdc1b184afb0e6b3d"] * {
  color: #ffffff !important;
  font-family: "Times New Roman", Times, serif !important;
  font-size: 17pt !important;
}
[data-id="698805bcdc1b184afb0e6b3d"].is-on {
  opacity: 1 !important;
}

If anyone has suggestions it would be much appreciated. I’m not even sure this can be done haha

Looks like the full-screen mode is overriding your JS. Try continuously forcing cursor: none !important on html and body and using pointer-events: none on the tagline.