diff --git a/attached_assets/image_1762647890379.png b/attached_assets/image_1762647890379.png new file mode 100644 index 0000000..1f74dbf Binary files /dev/null and b/attached_assets/image_1762647890379.png differ diff --git a/static/css/styles.css b/static/css/styles.css index 38b90d1..7114ff7 100644 --- a/static/css/styles.css +++ b/static/css/styles.css @@ -32,6 +32,34 @@ body { line-height: 1.6; overflow-x: hidden; position: relative; + cursor: none; +} + +.dot-cursor { + position: fixed; + width: 8px; + height: 8px; + background: #3b82f6; + border-radius: 50%; + pointer-events: none; + z-index: 999999; + transition: transform 0.15s ease, background 0.2s ease; + will-change: transform; +} + +.dot-cursor.hover { + transform: scale(1.5); + background: #60a5fa; +} + +@media (max-width: 768px) { + body { + cursor: auto; + } + + .dot-cursor { + display: none; + } } body::after { @@ -87,7 +115,7 @@ body::after { .navbar-links { display: flex; - gap: 40px; + gap: 56px; align-items: center; justify-content: center; flex: 1; @@ -856,7 +884,7 @@ hr { .card, .card-sponsors { - background: var(--gray-900); + background: #0a0a0a; border-radius: 20px; overflow: hidden; border: 1px solid var(--gray-700); diff --git a/static/js/scripts.js b/static/js/scripts.js index 5a5893a..3183cdc 100644 --- a/static/js/scripts.js +++ b/static/js/scripts.js @@ -45,6 +45,8 @@ document.addEventListener('DOMContentLoaded', function() { ScrollTrigger.addEventListener('refresh', () => lenis.resize()); ScrollTrigger.refresh(); + initSmoothCursor(); + let lastScrollTop = 0; const nav = document.querySelector('nav'); @@ -411,3 +413,60 @@ function initStars() { section.appendChild(starContainer); }); } + +function initSmoothCursor() { + if (window.innerWidth <= 768) return; + + const cursor = document.createElement('div'); + cursor.className = 'dot-cursor'; + document.body.appendChild(cursor); + + let mouseX = 0; + let mouseY = 0; + let cursorX = 0; + let cursorY = 0; + let velocityX = 0; + let velocityY = 0; + + const ease = 0.15; + const friction = 0.85; + + document.addEventListener('mousemove', (e) => { + mouseX = e.clientX; + mouseY = e.clientY; + }); + + const interactiveElements = 'a, button, [role="button"], input, textarea, select, .card, .card-sponsors'; + + document.addEventListener('mouseover', (e) => { + if (e.target.closest(interactiveElements)) { + cursor.classList.add('hover'); + } + }); + + document.addEventListener('mouseout', (e) => { + if (e.target.closest(interactiveElements)) { + cursor.classList.remove('hover'); + } + }); + + function updateCursor() { + const dx = mouseX - cursorX; + const dy = mouseY - cursorY; + + velocityX += dx * ease; + velocityY += dy * ease; + + velocityX *= friction; + velocityY *= friction; + + cursorX += velocityX; + cursorY += velocityY; + + cursor.style.transform = `translate(${cursorX - 4}px, ${cursorY - 4}px)`; + + requestAnimationFrame(updateCursor); + } + + updateCursor(); +}