aura / index.html
MultiTrickFox's picture
just change 1 thing: when hovering over something, you notice how to 2 cursors change, make them "catch" each other in the opposite way while hovering (small catches up to big, while in normal its reverse normally) - Initial Deployment
a18f862 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Aura - AI Software for People</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/CustomEase.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/ScrollTrigger.min.js"></script>
<style>
/* FONT IMPORT */
@import url("https://fonts.cdnfonts.com/css/thegoodmonolith");
/* CUSTOM CURSOR */
/* MODIFIED: Added .menu-trigger-container to ensure custom cursor applies */
html, a, button, input, textarea, select, label, [role="button"], .menu-trigger-container {
cursor: none !important;
}
.cursor {
position: fixed;
width: 20px;
height: 20px;
border-radius: 50%;
background: rgba(255,255,255,0.2);
transform: translate(-50%, -50%);
pointer-events: none;
mix-blend-mode: difference;
z-index: 9999;
transition: transform 0.2s ease, background 0.2s ease;
}
.cursor-follower {
position: fixed;
width: 40px;
height: 40px;
border-radius: 50%;
border: 1px solid rgba(255,255,255,0.2);
transform: translate(-50%, -50%);
pointer-events: none;
z-index: 9998;
transition: transform 0.6s cubic-bezier(0.15, 0.85, 0.3, 1.2),
width 0.3s ease,
height 0.3s ease;
}
/* Styles for mouse click effect */
.cursor.mouse-pressed {
transform: translate(-50%, -50%) scale(0.5) !important;
}
.cursor-follower.mouse-pressed {
transform: translate(-50%, -50%) scale(0.8) !important;
}
/* SCROLL INDICATOR */
.scroll-progress {
position: fixed;
top: 0;
left: 0;
width: 0%;
height: 3px;
background: linear-gradient(90deg, #fff, rgba(255,255,255,0.5));
z-index: 1000;
transition: width 0.1s ease-out;
}
/* BASE & TYPOGRAPHY */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
background: #000;
color: #f0f0f0;
font-family: "TheGoodMonolith", monospace;
overflow-x: hidden;
}
.section {
padding: 120px 5%;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
overflow: hidden;
}
h1, h2, h3 {
letter-spacing: 1px;
font-weight: normal;
}
h1 {
font-size: clamp(2.8rem, 6vw, 5rem);
margin-bottom: 10px;
text-shadow: 0 0 20px rgba(255, 255, 255, 0.3);
line-height: 1.1;
}
h2 {
font-size: clamp(2rem, 4vw, 3rem);
margin-bottom: 60px;
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
padding-bottom: 20px;
width: 100%;
max-width: 800px;
}
p {
font-size: clamp(1rem, 1.5vw, 1.1rem);
line-height: 1.7;
max-width: 700px;
color: #b0b0b0;
}
/* HEADER & NAVIGATION */
.header {
position: fixed;
top: 0;
left: 0;
width: 100%;
padding: 20px 5%;
display: flex;
justify-content: space-between;
align-items: center;
z-index: 1001;
background: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.logo {
font-size: 24px;
font-weight: bold;
letter-spacing: 2px;
z-index: 1001;
}
.menu-trigger-container {
position: relative;
width: 60px;
height: 60px;
/* MODIFIED: Removed 'cursor: pointer' */
display: flex;
justify-content: center;
align-items: center;
transform: scale(0.7);
z-index: 1001;
}
.expanding-circles-menu {
position: relative;
width: 60px;
height: 60px;
display: flex;
justify-content: center;
align-items: center;
}
.expanding-circles-menu .circle {
position: absolute;
width: 8px;
height: 8px;
background-color: #fff;
border-radius: 50%;
opacity: 1;
}
.expanding-circles-menu .circle.extra {
opacity: 0;
}
.expanding-circles-menu .circle.micro {
width: 4px;
height: 4px;
opacity: 0;
}
.full-screen-nav {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.95);
backdrop-filter: blur(15px);
-webkit-backdrop-filter: blur(15px);
z-index: 1000;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
visibility: hidden;
opacity: 0;
}
.full-screen-nav a {
color: #f0f0f0;
text-decoration: none;
font-size: clamp(2rem, 5vw, 3rem);
margin: 20px 0;
opacity: 0;
transform: translateY(20px);
transition: color 0.3s, text-shadow 0.3s;
}
.full-screen-nav a:hover {
color: #fff;
text-shadow: 0 0 15px rgba(255, 255, 255, 0.7);
}
.cta-button {
background: transparent;
border: 1px solid #fff;
color: #fff;
padding: 12px 24px;
font-family: inherit;
font-size: 14px;
cursor: pointer;
position: relative;
overflow: hidden;
transition: color 0.4s ease-in-out;
z-index: 1;
}
.cta-button::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: #fff;
transition: left 0.4s ease-in-out;
z-index: -1;
}
.cta-button:hover {
color: #000;
}
.cta-button:hover::before {
left: 0;
}
/* HERO SECTION */
.hero {
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
perspective: 1000px;
position: relative;
overflow: hidden;
}
.particle-bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 0;
}
.hero-content {
z-index: 10;
transition: transform 0.1s ease-out;
width: 100%;
padding: 0 23%;
text-align: left;
}
.hero-content .cta-button {
margin-left: 0;
margin-right: auto;
}
.hero-canvas-container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
}
.hero-canvas {
width: 100%;
height: 100%;
opacity: 0.3;
}
.subheadline {
font-size: clamp(1.2rem, 2vw, 1.5rem);
color: #c0c0c0;
margin-bottom: 40px;
min-height: 1.5rem;
text-align: left;
}
#dynamic-subheadline {
display: inline-block;
}
/* FEATURES SECTION (2x2 GRID) */
.features-grid {
display: grid;
grid-template-columns: 1fr;
gap: 30px;
max-width: 1000px;
width: 100%;
margin: 0 auto;
}
@media (min-width: 640px) {
.features-grid {
grid-template-columns: repeat(2, 1fr);
}
}
.animation-container {
position: relative;
width: 100%;
aspect-ratio: 1 / 1;
border: 1px solid rgba(255, 255, 255, 0.1);
background: rgba(0, 0, 0, 0.5);
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
overflow: visible;
transition: all 0.4s cubic-bezier(0.16, 1, 0.3, 1);
transform-style: preserve-3d;
}
.animation-container:hover {
border-color: rgba(255, 255, 255, 0.4);
background: rgba(255, 255, 255, 0.03);
transform: translateY(-10px) scale(1.02);
box-shadow: 0 20px 40px rgba(0,0,0,0.3);
}
.animation-container:hover {
border-color: rgba(255, 255, 255, 0.4);
background: rgba(255, 255, 255, 0.03);
}
.animation-title {
font-size: 16px;
letter-spacing: 0.5px;
text-transform: uppercase;
text-align: center;
flex-shrink: 0;
}
.animation-description {
font-size: 14px;
color: #999;
flex-shrink: 0;
padding: 15px 0;
line-height: 1.6;
}
.circle-container {
position: relative;
width: 100%;
flex-grow: 1;
display: flex;
justify-content: center;
align-items: center;
min-height: 150px;
}
.circle-container canvas {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* CORNER DECORATIONS */
.corner {
position: absolute;
width: 16px;
height: 16px;
color: white;
opacity: 0;
z-index: 10;
pointer-events: none;
transition: opacity 0.3s ease;
}
.animation-container:hover .corner {
opacity: 1;
}
.corner.top-left { top: -8px; left: -8px; transition-delay: 0s; }
.corner.top-right { top: -8px; right: -8px; transform: rotate(90deg); transition-delay: 0.1s; }
.corner.bottom-left { bottom: -8px; left: -8px; transform: rotate(-90deg); transition-delay: 0.2s; }
.corner.bottom-right { bottom: -8px; right: -8px; transform: rotate(180deg); transition-delay: 0.3s; }
/* HOW IT WORKS SECTION (1x3 GRID) */
.how-it-works-steps {
display: grid;
grid-template-columns: 1fr;
width: 100%;
max-width: 1100px;
gap: 40px;
margin-top: 40px;
}
@media (min-width: 768px) {
.how-it-works-steps {
grid-template-columns: repeat(3, 1fr);
}
}
.step {
padding: 20px;
}
.step-number {
font-size: 3rem;
color: rgba(255,255,255,0.3);
margin-bottom: 20px;
border-bottom: 1px solid rgba(255,255,255,0.1);
padding-bottom: 20px;
}
.step h3 {
font-size: 1.5rem;
margin-bottom: 15px;
color: #fff;
}
/* VISUAL SEPARATOR SECTION */
.visual-separator {
padding: 40px 0;
height: 250px;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}
#orbits-separator-container {
position: relative;
width: 180px;
height: 180px;
}
.orbit-container {
position: absolute;
width: 100%;
height: 100%;
border-radius: 50%;
transform-style: preserve-3d;
animation: rotate 8s infinite linear;
}
.orbit-container .dot {
position: absolute;
border-radius: 50%;
background: #fff;
}
@keyframes rotate {
to {
transform: rotateZ(360deg);
}
}
/* STYLES FOR TESTIMONIALS MARQUEE */
#testimonials {
padding-top: 120px;
padding-bottom: 120px;
width: 100%;
}
.testimonials-marquee {
width: 100%;
overflow: hidden;
-webkit-mask-image: linear-gradient(to right, transparent, black 10%, black 90%, transparent);
mask-image: linear-gradient(to right, transparent, black 10%, black 90%, transparent);
}
.testimonials-track {
display: flex;
width: fit-content;
animation: marquee 60s linear infinite;
}
@keyframes marquee {
from { transform: translateX(0%); }
to { transform: translateX(-50%); }
}
.testimonial-card {
background: rgba(255,255,255,0.03);
border: 1px solid rgba(255, 255, 255, 0.1);
padding: 30px;
text-align: left;
width: 450px;
margin: 0 15px;
flex-shrink: 0;
transition: border-color 0.3s ease;
}
.testimonial-card:hover {
border-color: rgba(255, 255, 255, 0.8);
}
.testimonial-card p {
font-style: italic;
color: #ccc;
margin-bottom: 20px;
}
.testimonial-author {
font-weight: bold;
color: #fff;
}
/* WAITLIST FORM */
.waitlist-form-container {
width: 100%;
max-width: 500px;
}
#waitlist-form {
display: flex;
gap: 10px;
}
#waitlist-form input {
flex-grow: 1;
background: transparent;
border: 1px solid rgba(255,255,255,0.2);
color: #fff;
padding: 12px 15px;
font-family: inherit;
font-size: 14px;
position: relative;
overflow: hidden;
transition: color 0.4s ease-in-out;
}
#waitlist-form input:focus {
outline: none;
border-color: #fff;
}
#waitlist-form input::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: #fff;
transition: left 0.4s ease-in-out;
z-index: -1;
}
/* TOAST MESSAGE */
#toast-message {
position: fixed;
bottom: 30px;
left: 50%;
transform: translateX(-50%);
background: #fff;
color: #000;
padding: 15px 30px;
border-radius: 4px;
z-index: 2000;
visibility: hidden;
opacity: 0;
transition: opacity 0.4s, visibility 0.4s, bottom 0.4s;
}
#toast-message.show {
visibility: visible;
opacity: 1;
bottom: 50px;
}
/* FOOTER */
.footer {
background: #050505;
border-top: 1px solid rgba(255, 255, 255, 0.1);
padding: 60px 5% 27px;
font-size: 14px;
color: #888;
}
.footer-content {
display: flex;
justify-content: space-between;
max-width: 1200px;
width: 100%;
margin: 0 auto;
gap: 40px;
flex-wrap: wrap;
}
.footer-column {
flex: 1;
min-width: 200px;
}
.footer-column h4 {
color: #fff;
margin-bottom: 20px;
font-size: 16px;
}
.footer-column a {
display: block;
color: #888;
text-decoration: none;
margin-bottom: 10px;
transition: color 0.3s;
}
.footer-column a:hover {
color: #fff;
}
.footer-bottom {
display: flex;
justify-content: center;
margin-top: 40px;
padding-top: 20px;
border-top: 1px solid rgba(255, 255, 255, 0.1);
}
/* SCROLL ANIMATIONS */
.fade-in-up {
opacity: 0;
transform: translateY(30px);
}
</style>
</head>
<body>
<header class="header">
<div class="logo">AURA</div>
<div class="menu-trigger-container">
<div class="expanding-circles-menu">
<div class="circle"></div><div class="circle"></div><div class="circle"></div>
<div class="circle"></div><div class="circle"></div><div class="circle"></div>
<div class="circle extra"></div><div class="circle extra"></div><div class="circle extra"></div>
<div class="circle extra"></div><div class="circle extra"></div><div class="circle extra"></div>
<div class="circle micro"></div><div class="circle micro"></div><div class="circle micro"></div>
<div class="circle micro"></div><div class="circle micro"></div><div class="circle micro"></div>
<div class="circle micro"></div><div class="circle micro"></div><div class="circle micro"></div>
<div class="circle micro"></div><div class="circle micro"></div><div class="circle micro"></div>
</div>
</div>
</header>
<nav class="full-screen-nav">
<a href="#features">Features</a>
<a href="#how-it-works">Process</a>
<a href="#testimonials">Testimonials</a>
<a href="#about">About</a>
</nav>
<div class="cursor"></div>
<div class="cursor-follower"></div>
<div class="scroll-progress"></div>
<main>
<section class="hero">
<div class="particle-bg" id="particle-bg"></div>
<div class="hero-canvas-container">
<canvas id="hero-canvas" class="hero-canvas"></canvas>
</div>
<div class="hero-content">
<h1>AURA</h1>
<p class="subheadline"><span id="dynamic-subheadline">AI Software, Reimagined for People.</span></p>
<button class="cta-button">Explore Aura</button>
</div>
</section>
<section id="features" class="section">
<h2 class="fade-in-up">Core Capabilities</h2>
<div class="features-grid">
<div class="animation-container fade-in-up">
<div class="animation-title">Understand</div>
<div id="anim-understand" class="circle-container"></div>
<p class="animation-description">Aura comprehends context and intent, providing nuanced and relevant assistance.</p>
</div>
<div class="animation-container fade-in-up">
<div class="animation-title">Connect</div>
<div id="anim-connect" class="circle-container"></div>
<p class="animation-description">Seamlessly link disparate data points and ideas to uncover novel relationships.</p>
</div>
<div class="animation-container fade-in-up">
<div class="animation-title">Harmonize</div>
<div id="anim-harmonize" class="circle-container"></div>
<p class="animation-description">Balance automated processes with human creativity for a fluid, synergistic workflow.</p>
</div>
<div class="animation-container fade-in-up">
<div class="animation-title">Improve</div>
<div id="anim-improve" class="circle-container"></div>
<p class="animation-description">Continuously learn from your interactions to become a smarter, more personalized partner.</p>
</div>
</div>
</section>
<section id="how-it-works" class="section">
<h2 class="fade-in-up">Simple by Design</h2>
<div class="how-it-works-steps">
<div class="step fade-in-up">
<div class="step-number">01</div>
<h3>Connect</h3>
<p>Integrate Aura with your existing tools and data sources with a single click.</p>
</div>
<div class="step fade-in-up">
<div class="step-number">02</div>
<h3>Create</h3>
<p>Use natural language to command, create, and analyze. Let your ideas flow freely.</p>
</div>
<div class="step fade-in-up">
<div class="step-number">03</div>
<h3>Collaborate</h3>
<p>Aura acts as your creative partner, offering suggestions and automating tasks.</p>
</div>
</div>
</section>
<section id="testimonials" class="section">
<h2 class="fade-in-up">From the Community</h2>
<div class="testimonials-marquee">
<div class="testimonials-track">
<div class="testimonial-card">
<p>"Before Aura, my research was siloed. Now, it's a living web of connections. I asked it to 'find a link between 19th-century architecture and modern UI principles,' and it surfaced three academic papers I'd never have found. It's not an assistant; it's a discovery engine."</p>
<div class="testimonial-author">- Dr. Aris Thorne, Digital Humanist</div>
</div>
<div class="testimonial-card">
<p>"I used to spend 10 hours a week compiling reports. With Flow Weave, I just say, 'Draft the Q2 performance summary, focus on user growth, and use a confident but cautious tone.' It's done in 30 seconds. That's a day of my life back, every single week."</p>
<div class="testimonial-author">- Lena Petrova, COO</div>
</div>
<div class="testimonial-card">
<p>"The magic of Aura is that it disappears. It's so integrated into how I think that I don't feel like I'm 'using' a tool. My ideas just... flow better. It removed the creative friction I didn't even know I had."</p>
<div class="testimonial-author">- Sam Chen, Novelist & Screenwriter</div>
</div>
<div class="testimonial-card">
<p>"Before Aura, my research was siloed. Now, it's a living web of connections. I asked it to 'find a link between 19th-century architecture and modern UI principles,' and it surfaced three academic papers I'd never have found. It's not an assistant; it's a discovery engine."</p>
<div class="testimonial-author">- Dr. Aris Thorne, Digital Humanist</div>
</div>
<div class="testimonial-card">
<p>"I used to spend 10 hours a week compiling reports. With Flow Weave, I just say, 'Draft the Q2 performance summary, focus on user growth, and use a confident but cautious tone.' It's done in 30 seconds. That's a day of my life back, every single week."</p>
<div class="testimonial-author">- Lena Petrova, COO</div>
</div>
<div class="testimonial-card">
<p>"The magic of Aura is that it disappears. It's so integrated into how I think that I don't feel like I'm 'using' a tool. My ideas just... flow better. It removed the creative friction I didn't even know I had."</p>
<div class="testimonial-author">- Sam Chen, Novelist & Screenwriter</div>
</div>
</div>
</div>
</section>
<section class="visual-separator fade-in-up">
<div id="orbits-separator-container"></div>
</section>
<section id="about" class="section" style="padding-top: 60px; padding-bottom: 0;">
<h2 class="fade-in-up">Human-Centric AI</h2>
<p class="fade-in-up">Aura is built on the belief that technology should augment human capability, not replace it. Our mission is to democratize access to powerful AI tools, making them intuitive, accessible, and a seamless extension of your own mind. We focus on privacy, transparency, and ethical design to ensure that you are always in control.</p>
</section>
<section id="waitlist" class="section" style="padding-top: 180px; padding-bottom: 180px;">
<h3 class="fade-in-up" style="font-size: 1.8rem; margin-bottom: 30px; color: #fff;">Be the First to Experience Aura</h3>
<div class="waitlist-form-container fade-in-up">
<form id="waitlist-form">
<input type="email" name="email" placeholder="Enter your email address" required>
<button type="submit" class="cta-button">Submit</button>
</form>
</div>
</section>
</main>
<footer class="footer">
<div class="footer-content">
<div class="footer-column">
<h4>AURA</h4>
<p>AI Software, Reimagined for People.</p>
</div>
<div class="footer-column">
<h4>Product</h4>
<a href="#features">Features</a>
<a href="#">Pricing</a>
<a href="#">Integrations</a>
<a href="#">Changelog</a>
</div>
<div class="footer-column">
<h4>Company</h4>
<a href="#about">About Us</a>
<a href="#">Careers</a>
<a href="#">Contact</a>
<a href="#">Blog</a>
</div>
<div class="footer-column">
<h4>Connect</h4>
<a href="#">X / Twitter</a>
<a href="#">LinkedIn</a>
<a href="#">Discord</a>
</div>
</div>
<div class="footer-bottom">
<p>&copy; 2025 Aura Technologies. All rights reserved.</p>
</div>
</footer>
<div id="toast-message"></div>
<script>
document.addEventListener("DOMContentLoaded", function() {
function setupDynamicSubheadline() {
const subheadlineEl = document.getElementById('dynamic-subheadline');
if (!subheadlineEl) return;
const subheadlines = [
"AI Software, Reimagined for People.",
// "Your Thoughts, Amplified.",
// "Creativity's New Partner.",
// "Flow State, On Demand."
];
let subIndex = 0;
// Set the initial text from the array
if (subheadlines.length > 0) {
subheadlineEl.textContent = subheadlines[0];
}
function changeSubheadline() {
gsap.to(subheadlineEl, {
opacity: 0,
y: -10,
duration: 0.5,
ease: 'power2.in',
onComplete: () => {
subIndex = (subIndex + 1) % subheadlines.length;
subheadlineEl.textContent = subheadlines[subIndex];
gsap.fromTo(subheadlineEl,
{ opacity: 0, y: 10 },
{ opacity: 1, y: 0, duration: 0.5, ease: 'power2.out'}
);
}
});
}
// MODIFICATION: Only start the animation if there's more than one headline
if (subheadlines.length > 1) {
setInterval(changeSubheadline, 6000);
}
}
function setupBreathingSeparator() {
const separator = document.getElementById('orbits-separator-container');
if (!separator) return;
gsap.to(separator, {
scale: 1.15,
duration: 4,
repeat: -1,
yoyo: true,
ease: "sine.inOut"
});
}
setupDynamicSubheadline();
setupBreathingSeparator();
const cursor = document.querySelector('.cursor');
const cursorFollower = document.querySelector('.cursor-follower');
window.addEventListener('mousedown', () => {
cursor.classList.add('mouse-pressed');
cursorFollower.classList.add('mouse-pressed');
});
window.addEventListener('mouseup', () => {
cursor.classList.remove('mouse-pressed');
cursorFollower.classList.remove('mouse-pressed');
});
let mouseX = 0, mouseY = 0;
let followerX = 0, followerY = 0;
let speed = 0.1;
let isMoving = false;
let lastMouseX = 0;
let lastMouseY = 0;
let isHovering = false;
function animateCursor() {
const dx = mouseX - followerX;
const dy = mouseY - followerY;
const distance = Math.sqrt(dx * dx + dy * dy);
const movedX = Math.abs(mouseX - lastMouseX);
const movedY = Math.abs(mouseY - lastMouseY);
isMoving = movedX > 1 || movedY > 1;
lastMouseX = mouseX;
lastMouseY = mouseY;
const dynamicSpeed = Math.min(0.3, speed + distance * 0.005);
followerX += dx * dynamicSpeed;
followerY += dy * dynamicSpeed;
cursor.style.left = mouseX + 'px';
cursor.style.top = mouseY + 'px';
cursorFollower.style.left = followerX + 'px';
cursorFollower.style.top = followerY + 'px';
let followerSize;
if (isHovering) {
followerSize = 20;
if (isMoving) {
followerSize = 15;
}
} else {
followerSize = 40;
if (isMoving) {
followerSize = 30;
if (distance > 50) {
followerSize = 25;
}
}
}
cursorFollower.style.width = followerSize + 'px';
cursorFollower.style.height = followerSize + 'px';
requestAnimationFrame(animateCursor);
}
document.addEventListener('mousemove', (e) => {
mouseX = e.clientX;
mouseY = e.clientY;
});
document.querySelectorAll('a, button, .animation-container').forEach(el => {
el.addEventListener('mouseenter', () => {
isHovering = true;
cursor.style.transform = 'translate(-50%, -50%) scale(2)';
cursor.style.background = 'rgba(255,255,255,0.05)';
cursorFollower.style.borderColor = 'rgba(255,255,255,0.3)';
});
el.addEventListener('mouseleave', () => {
isHovering = false;
cursor.style.transform = 'translate(-50%, -50%) scale(1)';
cursor.style.background = 'rgba(255,255,255,0.3)';
cursorFollower.style.borderColor = 'rgba(255,255,255,0.2)';
});
});
animateCursor();
window.addEventListener('scroll', () => {
const scrollTop = document.documentElement.scrollTop;
const scrollHeight = document.documentElement.scrollHeight;
const clientHeight = document.documentElement.clientHeight;
const scrollPercent = (scrollTop / (scrollHeight - clientHeight)) * 100;
document.querySelector('.scroll-progress').style.width = scrollPercent + '%';
});
gsap.registerPlugin(ScrollTrigger, CustomEase);
if (!CustomEase.get("power1.inOut")) {
CustomEase.create("power1.inOut", "0.42, 0, 0.58, 1");
}
const menuTrigger = document.querySelector('.menu-trigger-container');
const menuIcon = document.querySelector('.expanding-circles-menu');
const nav = document.querySelector('.full-screen-nav');
const navLinks = nav.querySelectorAll('a');
let isMenuActive = false;
const navTimeline = gsap.timeline({ paused: true });
navTimeline.to(nav, { autoAlpha: 1, duration: 0.4, ease: 'power2.inOut' })
.to(navLinks, {
opacity: 1,
y: 0,
duration: 0.4,
stagger: 0.05,
ease: 'power2.out'
}, "-=0.2");
const circles = menuIcon.querySelectorAll(".circle:not(.extra):not(.micro)");
const extraCircles = menuIcon.querySelectorAll(".circle.extra");
const microCircles = menuIcon.querySelectorAll(".circle.micro");
function initMenu() {
const centerX = 30;
const centerY = 30;
const radius = 15;
circles.forEach((circle, i) => {
const angle = (i * 60 * Math.PI) / 180;
gsap.set(circle, {
left: centerX + radius * Math.cos(angle),
top: centerY + radius * Math.sin(angle),
xPercent: -50,
yPercent: -50
});
});
gsap.set(extraCircles, { opacity: 0, scale: 0 });
gsap.set(microCircles, { opacity: 0, scale: 0 });
gsap.set(menuIcon, { rotation: 0 });
}
function activateMenu() {
const centerX = 30, centerY = 30, radius = 15;
const tl = gsap.timeline();
tl.to(menuIcon, { rotation: 360, duration: 1.2, ease: "power1.inOut" });
extraCircles.forEach((circle, index) => {
const angle = ((index * 60 + 30) * Math.PI) / 180;
tl.to(circle, {
left: centerX + radius * Math.cos(angle),
top: centerY + radius * Math.sin(angle),
xPercent: -50, yPercent: -50,
opacity: 1, scale: 1,
duration: 0.1, ease: "power1.out"
}, 0.5);
});
microCircles.forEach((circle, index) => {
const angle = (index * 30 * Math.PI) / 180;
tl.to(circle, {
left: centerX + radius * Math.cos(angle),
top: centerY + radius * Math.sin(angle),
xPercent: -50, yPercent: -50,
opacity: 0.8, scale: 1,
duration: 0.05, ease: "power1.out"
}, 0.55);
});
tl.to([circles, extraCircles], { scale: 0.8, duration: 0.1, ease: "power1.inOut" }, 0.55);
}
function deactivateMenu() {
const tl = gsap.timeline();
tl.to(menuIcon, { rotation: 0, duration: 1.2, ease: "power1.inOut" });
tl.to(microCircles, { opacity: 0, scale: 0, duration: 0.2, ease: "power1.in" }, 0.3);
tl.to([circles, extraCircles], { scale: 1, duration: 0.2, ease: "power1.out" }, 0.4);
tl.to(extraCircles, { opacity: 0, scale: 0, duration: 0.2, ease: "power1.in", onComplete: initMenu }, 0.5);
}
function toggleMenu() {
isMenuActive = !isMenuActive;
if (isMenuActive) {
navTimeline.play();
activateMenu();
} else {
navTimeline.reverse();
deactivateMenu();
}
}
initMenu();
menuTrigger.addEventListener('click', toggleMenu);
navLinks.forEach(link => link.addEventListener('click', toggleMenu));
const heroContent = document.querySelector('.hero-content');
document.querySelector('.hero').addEventListener('mousemove', (e) => {
const { clientX, clientY } = e;
const x = (clientX / window.innerWidth - 0.5) * 40;
const y = (clientY / window.innerHeight - 0.5) * 40;
gsap.to(heroContent, {
transform: `translate(${x}px, ${y}px) rotateY(${-x/2}deg) rotateX(${y/2}deg)`,
duration: 0.5,
ease: 'power1.out'
});
});
const fadeUpElements = document.querySelectorAll('.fade-in-up');
fadeUpElements.forEach(el => {
gsap.fromTo(el, { opacity: 0, y: 30 }, {
opacity: 1,
y: 0,
duration: 0.8,
ease: 'power2.out',
scrollTrigger: {
trigger: el,
start: 'top 85%',
toggleActions: 'play none none none'
}
});
});
const waitlistForm = document.getElementById('waitlist-form');
const toastMessage = document.getElementById('toast-message');
waitlistForm.addEventListener('submit', function(e) {
e.preventDefault();
toastMessage.textContent = 'Thank you! You have been added to the waitlist.';
toastMessage.classList.add('show');
setTimeout(() => {
toastMessage.classList.remove('show');
}, 3000);
waitlistForm.reset();
});
const MONOCHROME_FILL = (opacity) => `rgba(255, 255, 255, ${Math.max(0, Math.min(1, opacity))})`;
function createCanvasInContainer(containerId, width = 180, height = 180) {
const container = document.getElementById(containerId);
if (!container) return null;
container.innerHTML = "";
const canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
container.appendChild(canvas);
return canvas.getContext("2d");
}
function setupParticleBackground() {
const container = document.getElementById('particle-bg');
if (!container) return;
const canvas = document.createElement('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
container.appendChild(canvas);
const ctx = canvas.getContext('2d');
const particles = [];
const particleCount = Math.floor(window.innerWidth / 10);
for (let i = 0; i < particleCount; i++) {
particles.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
size: Math.random() * 3 + 1,
speedX: Math.random() * 1 - 0.5,
speedY: Math.random() * 1 - 0.5,
color: `rgba(255, 255, 255, ${Math.random() * 0.5 + 0.1})`
});
}
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
particles.forEach(p => {
p.x += p.speedX;
p.y += p.speedY;
if (p.x < 0 || p.x > canvas.width) p.speedX *= -1;
if (p.y < 0 || p.y > canvas.height) p.speedY *= -1;
ctx.beginPath();
ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
ctx.fillStyle = p.color;
ctx.fill();
particles.forEach(p2 => {
const dx = p.x - p2.x;
const dy = p.y - p2.y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 100) {
ctx.beginPath();
ctx.strokeStyle = `rgba(255, 255, 255, ${1 - distance/100})`;
ctx.lineWidth = 0.5;
ctx.moveTo(p.x, p.y);
ctx.lineTo(p2.x, p2.y);
ctx.stroke();
}
});
});
requestAnimationFrame(animate);
}
animate();
window.addEventListener('resize', () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
});
}
function setupHeroCanvas() {
const canvas = document.getElementById('hero-canvas');
if (!canvas) return;
const ctx = canvas.getContext('2d');
let particles = [];
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
initParticles();
}
function initParticles() {
particles = [];
const particleCount = window.innerWidth < 768 ? 100 : 250;
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
const maxRadius = Math.sqrt(centerX * centerX + centerY * centerY);
for (let i = 0; i < particleCount; i++) {
const distance = Math.random() * maxRadius;
const angle = Math.random() * Math.PI * 2;
particles.push({
size: 1 + Math.random() * 1.5,
speed: 0.1 + Math.random() * 0.3,
angle: angle,
distance: distance
});
}
}
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
particles.forEach(p => {
p.distance -= p.speed;
if (p.distance <= 0) {
p.distance = Math.sqrt(centerX * centerX + centerY * centerY);
}
const x = centerX + Math.cos(p.angle) * p.distance;
const y = centerY + Math.sin(p.angle) * p.distance;
p.angle += 0.001;
ctx.beginPath();
ctx.arc(x, y, p.size, 0, Math.PI * 2);
ctx.fillStyle = MONOCHROME_FILL(1 - p.distance / (canvas.width / 2));
ctx.fill();
});
requestAnimationFrame(animate);
}
window.addEventListener('resize', resizeCanvas);
resizeCanvas();
animate();
}
function setupPulsatingCirclesAnimation() {
const ctx = createCanvasInContainer("anim-understand");
if (!ctx) return;
const centerX = 90, centerY = 90;
let time = 0; let lastTime = 0;
const rings = [];
for (let r = 0; r < 4; r++) {
const radius = 15 + r * 15;
const count = 6 + r * 3;
for (let i = 0; i < count; i++) {
rings.push({
radius,
count,
index: i,
ringIndex: r,
sz: 3 + r * 0.3,
opacity: (90 - r * 10) / 100,
delay: r * 0.2 + i * 0.1
});
}
}
function animate(timestamp) {
if (!lastTime) lastTime = timestamp;
time += (timestamp - lastTime) * 0.001;
lastTime = timestamp;
ctx.clearRect(0, 0, 180, 180);
const pulseTime = (time % 3) / 3;
let opacity = 0, scale = 0.2;
if(pulseTime < 0.4) {
opacity = pulseTime / 0.4;
scale = 0.2 + (pulseTime/0.4) * 0.8;
} else if (pulseTime < 0.6) {
opacity = 1;
scale = 1;
} else {
opacity = 1 - ((pulseTime-0.6)/0.4);
scale = 1 - ((pulseTime-0.6)/0.4) * 0.8;
}
ctx.beginPath();
ctx.arc(centerX, centerY, 4 * scale, 0, Math.PI * 2);
ctx.fillStyle = MONOCHROME_FILL(opacity);
ctx.fill();
rings.forEach(dot => {
const angle = (dot.index / dot.count) * 2 * Math.PI;
const x = centerX + Math.cos(angle) * dot.radius;
const y = centerY + Math.sin(angle) * dot.radius;
const localTime = ((time + dot.delay) % 3) / 3;
let localOpacity = 0, localScale = 0.2;
if(localTime < 0.4) {
localOpacity = localTime / 0.4;
localScale = 0.2 + (localTime/0.4) * 0.8;
} else if (localTime < 0.6) {
localOpacity = 1;
localScale = 1;
} else {
localOpacity = 1 - ((localTime-0.6)/0.4);
localScale = 1 - ((localTime-0.6)/0.4) * 0.8;
}
ctx.beginPath();
ctx.arc(x, y, dot.sz * localScale, 0, Math.PI * 2);
ctx.fillStyle = MONOCHROME_FILL(localOpacity * dot.opacity);
ctx.fill();
});
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
}
function setupConnectAnimation() {
const ctx = createCanvasInContainer("anim-connect");
if (!ctx) return;
const centerX = 90, centerY = 90;
let time = 0; let lastTime = 0;
const dotCount = 20, rowCount = 5, spacing = 15;
function animate(timestamp) {
if (!lastTime) lastTime = timestamp;
time += (timestamp - lastTime) * 0.001;
lastTime = timestamp;
ctx.clearRect(0, 0, 180, 180);
for (let row = 0; row < rowCount; row++) {
const y = centerY - ((rowCount - 1) / 2) * spacing + row * spacing;
for (let i = 0; i < dotCount; i++) {
const baseX = centerX - ((dotCount - 1) / 2) * 8 + i * 8;
const amplitude = 4 + row * 2;
const frequency = 1 + row * 0.2;
const phaseOffset = row * 0.5;
const offset = Math.sin(time * frequency + i * 0.2 + phaseOffset) * amplitude;
const finalY = y + offset;
ctx.beginPath();
ctx.arc(baseX, finalY, 2, 0, Math.PI * 2);
ctx.fillStyle = MONOCHROME_FILL(0.9);
ctx.fill();
}
}
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
}
function setupHarmonizeAnimation() {
const ctx = createCanvasInContainer("anim-harmonize");
if (!ctx) return;
const centerX = 90, centerY = 90;
let time = 0; let lastTime = 0;
const pendulumCount = 15, baseFrequency = 0.5, pendulumLength = 70, maxAngle = Math.PI / 12;
function animate(timestamp) {
if (!lastTime) lastTime = timestamp;
time += (timestamp - lastTime) * 0.001;
lastTime = timestamp;
ctx.clearRect(0, 0, 180, 180);
const angle = Math.sin(time * baseFrequency * Math.PI) * maxAngle;
for (let i = 0; i < pendulumCount; i++) {
const pendulumX = centerX - pendulumCount * 4 + i * 8;
const pendulumY = centerY - pendulumLength + 20;
const bobX = pendulumX + Math.sin(angle) * pendulumLength;
const bobY = pendulumY + Math.cos(angle) * pendulumLength;
ctx.beginPath(); ctx.moveTo(pendulumX, pendulumY); ctx.lineTo(bobX, bobY); ctx.strokeStyle = MONOCHROME_FILL(0.4); ctx.lineWidth = 1; ctx.stroke();
ctx.beginPath(); ctx.arc(bobX, bobY, 3, 0, Math.PI * 2); ctx.fillStyle = MONOCHROME_FILL(0.9); ctx.fill();
}
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
}
function setupImproveAnimation() {
const ctx = createCanvasInContainer("anim-improve");
if (!ctx) return;
const centerX = 90, centerY = 90;
let time = 0; let lastTime = 0;
const gridSize = 5, spacing = 25;
function animate(timestamp) {
if (!lastTime) lastTime = timestamp;
time += (timestamp - lastTime) * 0.001;
lastTime = timestamp;
ctx.clearRect(0, 0, 180, 180);
const breathingFactor = Math.sin(time * 0.5) * 0.2 + 1.0;
for (let row = 0; row < gridSize; row++) {
for (let col = 0; col < gridSize; col++) {
if (row === Math.floor(gridSize / 2) && col === Math.floor(gridSize / 2)) continue;
const baseX = (col - (gridSize - 1) / 2) * spacing;
const baseY = (row - (gridSize - 1) / 2) * spacing;
const distance = Math.sqrt(baseX * baseX + baseY * baseY);
const maxDistance = (spacing * Math.sqrt(2) * (gridSize - 1)) / 2;
const normalizedDistance = distance / maxDistance;
const breathingX = baseX * breathingFactor;
const breathingY = baseY * breathingFactor;
const waveX = centerX + breathingX;
const waveY = centerY + breathingY;
const baseSize = 1.5 + (1 - normalizedDistance) * 1.5;
const pulseFactor = Math.sin(time * 2 + normalizedDistance * 5) * 0.6 + 1;
const size = baseSize * pulseFactor;
const opacity = 0.5 + Math.sin(time * 1.5 + distance * 0.1) * 0.2 + normalizedDistance * 0.3;
ctx.beginPath();
ctx.arc(waveX, waveY, size, 0, Math.PI * 2);
ctx.fillStyle = MONOCHROME_FILL(opacity);
ctx.fill();
}
}
ctx.beginPath(); ctx.arc(centerX, centerY, 3, 0, Math.PI * 2); ctx.fillStyle = MONOCHROME_FILL(0.9); ctx.fill();
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
}
function setupRotatingOrbitsSeparator() {
const container = document.getElementById('orbits-separator-container');
if(!container) return;
container.innerHTML = "";
const centerDot = document.createElement("div");
centerDot.className = "dot";
centerDot.style.position = "absolute";
centerDot.style.width = "8px";
centerDot.style.height = "8px";
centerDot.style.left = "calc(50% - 4px)";
centerDot.style.top = "calc(50% - 4px)";
centerDot.style.background = "#fff";
centerDot.style.borderRadius = "50%";
container.appendChild(centerDot);
for (let r = 0; r < 3; r++) {
const orbitContainer = document.createElement("div");
orbitContainer.className = "orbit-container";
orbitContainer.style.animationDuration = `${8 + r * 4}s`;
orbitContainer.style.animationDirection = r % 2 ? "reverse" : "normal";
const radius = 20 + r * 20, count = 6 + r * 3;
for (let i = 0; i < count; i++) {
const dot = document.createElement("div");
dot.className = "dot";
const angle = (i / count) * 2 * Math.PI;
const x = Math.cos(angle) * radius, y = Math.sin(angle) * radius;
const sz = 4 - r * 0.5;
dot.style.width = dot.style.height = `${sz}px`;
dot.style.left = `calc(50% + ${x}px - ${sz / 2}px)`;
dot.style.top = `calc(50% + ${y}px - ${sz / 2}px)`;
dot.style.background = `rgba(255,255,255,${(90 - r * 15) / 100})`;
orbitContainer.appendChild(dot);
}
container.appendChild(orbitContainer);
}
}
setupParticleBackground();
setupHeroCanvas();
setupPulsatingCirclesAnimation();
setupConnectAnimation();
setupHarmonizeAnimation();
setupImproveAnimation();
setupRotatingOrbitsSeparator();
});
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=MultiTrickFox/aura" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>