(() => { const textSelectors = 'p, h1, h2, h3, h4, h5, h6, span, li, label, td, th, pre, .code'; const linkSelectors = 'a, button, [role="button"], input[type="submit"], input[type="button"]'; const padding = 6; let mouseX = 0, mouseY = 0; let currentLinkEl = null; let rafId = null; let cursor = null; let cursorVisible = false; let lastTouchTime = 0; let isMouseDown = false; const TOUCH_MOUSE_GUARD_MS = 800; function showCursor() { if (!cursorVisible && cursor) { cursorVisible = true; cursor.classList.add('visible'); } } function hideCursor() { if (cursor) { cursorVisible = false; cursor.classList.remove('visible'); currentLinkEl = null; if (rafId) { cancelAnimationFrame(rafId); rafId = null; } cursor.classList.remove('on-link', 'on-text'); } } function isSyntheticMouse() { return Date.now() - lastTouchTime < TOUCH_MOUSE_GUARD_MS; } function updateCursorForLink(el) { const rect = el.getBoundingClientRect(); cursor.classList.remove('on-text'); cursor.classList.add('on-link'); cursor.style.transform = 'none'; cursor.style.left = (rect.left - padding) + 'px'; cursor.style.top = (rect.top - padding) + 'px'; cursor.style.width = (rect.width + padding * 2) + 'px'; cursor.style.height = (rect.height + padding * 2) + 'px'; } function trackLink() { if (currentLinkEl) { updateCursorForLink(currentLinkEl); rafId = requestAnimationFrame(trackLink); } } document.addEventListener('DOMContentLoaded', () => { cursor = document.getElementById('cursor'); if (!cursor) return; document.addEventListener('touchstart', () => { lastTouchTime = Date.now(); hideCursor(); }, { passive: true }); document.addEventListener('touchmove', () => { lastTouchTime = Date.now(); hideCursor(); }, { passive: true }); document.addEventListener('touchend', () => { lastTouchTime = Date.now(); }, { passive: true }); document.addEventListener('mousemove', (e) => { if (isSyntheticMouse()) return; if (e.sourceCapabilities && e.sourceCapabilities.firesTouchEvents) return; mouseX = e.clientX; mouseY = e.clientY; showCursor(); const el = document.elementFromPoint(mouseX, mouseY); const linkEl = el ? el.closest(linkSelectors) : null; if (linkEl) { if (currentLinkEl !== linkEl) { currentLinkEl = linkEl; if (rafId) cancelAnimationFrame(rafId); rafId = requestAnimationFrame(trackLink); } } else { if (currentLinkEl) { currentLinkEl = null; if (rafId) { cancelAnimationFrame(rafId); rafId = null; } } cursor.classList.remove('on-link'); cursor.style.transform = isMouseDown ? 'translate(-50%, -50%) scale(0.9)' : 'translate(-50%, -50%)'; cursor.style.left = mouseX + 'px'; cursor.style.top = mouseY + 'px'; cursor.style.width = ''; cursor.style.height = ''; if (el && el.closest(textSelectors)) { cursor.classList.add('on-text'); } else { cursor.classList.remove('on-text'); } } }); document.addEventListener('mousedown', () => { isMouseDown = true; cursor.style.transform = currentLinkEl ? 'none' : 'translate(-50%, -50%) scale(0.9)'; }); document.addEventListener('mouseup', () => { isMouseDown = false; cursor.style.transform = currentLinkEl ? 'none' : 'translate(-50%, -50%) scale(1)'; }); window.addEventListener('scroll', () => { if (currentLinkEl) updateCursorForLink(currentLinkEl); }, { passive: true }); }); if (document.startViewTransition) { document.addEventListener("click", (event) => { const link = event.target.closest("a"); if (!link || link.hasAttribute('download')) return; const url = new URL(link.href, location.href); if (url.origin !== location.origin) return; if (link.target || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return; if (url.hash && url.pathname === location.pathname) { event.preventDefault(); const target = document.querySelector(url.hash); if (target) { target.scrollIntoView({ behavior: 'smooth', block: 'start' }); history.pushState(null, '', url.hash); } return; } event.preventDefault(); document.startViewTransition(async () => { const response = await fetch(url.href, { headers: { "X-Requested-With": "view-transition" } }); const html = await response.text(); const doc = new DOMParser().parseFromString(html, "text/html"); for (const tag of ['head', 'header', 'main', 'footer']) { const newEl = doc.querySelector(tag); const curEl = document.querySelector(tag); if (!newEl || !curEl) { location.href = url.href; return; } curEl.innerHTML = newEl.innerHTML; curEl.querySelectorAll('script').forEach(old => { const s = document.createElement('script'); [...old.attributes].forEach(a => s.setAttribute(a.name, a.value)); s.textContent = old.textContent; old.replaceWith(s); }); } history.pushState(null, "", url.href); currentLinkEl = null; if (rafId) { cancelAnimationFrame(rafId); rafId = null; } cursor.classList.remove('on-link', 'on-text'); cursor.style.transform = 'translate(-50%, -50%)'; cursor.style.left = mouseX + 'px'; cursor.style.top = mouseY + 'px'; cursor.style.width = ''; cursor.style.height = ''; const el = document.elementFromPoint(mouseX, mouseY); const newLinkEl = el ? el.closest(linkSelectors) : null; if (newLinkEl) { currentLinkEl = newLinkEl; rafId = requestAnimationFrame(trackLink); } else if (el && el.closest(textSelectors)) { cursor.classList.add('on-text'); } }); }); window.addEventListener("popstate", () => location.reload()); } })();