// Agent Cursor Animation Module APP.ui.cursor = {}; APP.ui.cursor.ensureAgentCursorOverlay = function () { const { $ } = APP.core.utils; if ($("#agentCursor")) return; const el = document.createElement("div"); el.id = "agentCursor"; el.style.cssText = ` position: fixed; width: 12px; height: 12px; border-radius: 50%; background: linear-gradient(135deg, rgba(34, 211, 238, 0.9), rgba(124, 58, 237, 0.9)); box-shadow: 0 0 20px rgba(34, 211, 238, 0.6), 0 0 40px rgba(124, 58, 237, 0.4); pointer-events: none; z-index: 10000; opacity: 0; display: none; transition: opacity 0.3s ease; `; document.body.appendChild(el); }; APP.ui.cursor.setCursorVisible = function (visible) { const { $ } = APP.core.utils; const { state } = APP.core; APP.ui.cursor.ensureAgentCursorOverlay(); const el = $("#agentCursor"); if (!el) return; state.ui.agentCursor.visible = visible; el.style.opacity = visible ? "1" : "0"; el.style.display = visible ? "block" : "none"; }; APP.ui.cursor.moveCursorToRect = function (rect) { const { state } = APP.core; const { $, now } = APP.core.utils; if (state.ui.cursorMode === "off") return; APP.ui.cursor.ensureAgentCursorOverlay(); const el = $("#agentCursor"); if (!el) return; const c = state.ui.agentCursor; c.visible = true; c.target = rect; c.t0 = now(); el.style.opacity = "1"; el.style.display = "block"; }; APP.ui.cursor.tickAgentCursor = function () { const { state } = APP.core; const { $, clamp, now } = APP.core.utils; const el = $("#agentCursor"); if (!el || state.ui.cursorMode !== "on" || !state.ui.agentCursor.visible) return; const c = state.ui.agentCursor; if (!c.target) return; const tx = c.target.left + c.target.width * 0.72; const ty = c.target.top + c.target.height * 0.50; // Smooth spring physics const dx = tx - (c.x * window.innerWidth); const dy = ty - (c.y * window.innerHeight); c.vx = (c.vx + dx * 0.0018) * 0.85; c.vy = (c.vy + dy * 0.0018) * 0.85; const px = (c.x * window.innerWidth) + c.vx * 18; const py = (c.y * window.innerHeight) + c.vy * 18; c.x = clamp(px / window.innerWidth, 0.02, 0.98); c.y = clamp(py / window.innerHeight, 0.02, 0.98); el.style.transform = `translate(${c.x * window.innerWidth}px, ${c.y * window.innerHeight}px)`; // Hide after settling const settle = Math.hypot(dx, dy); if (settle < 6 && (now() - c.t0) > 650) { el.style.opacity = "0.75"; } };