Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Neon Abyss | Digital Aquarium</title> | |
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
| <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&family=Rajdhani:wght@300;500;700&display=swap" rel="stylesheet"> | |
| <style> | |
| :root { | |
| --primary-color: #00f2ff; /* Cyan Neon */ | |
| --secondary-color: #bc13fe; /* Deep Purple Neon */ | |
| --accent-color: #0aff0a; /* Matrix Green */ | |
| --deep-blue: #000022; | |
| --midnight-blue: #00000a; | |
| --glass-bg: rgba(255, 255, 255, 0.05); | |
| --glass-border: rgba(255, 255, 255, 0.1); | |
| --text-main: #e0f7ff; | |
| } | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| background: linear-gradient(180deg, var(--midnight-blue) 0%, var(--deep-blue) 50%, #001a33 100%); | |
| color: var(--text-main); | |
| font-family: 'Rajdhani', sans-serif; | |
| overflow-x: hidden; | |
| min-height: 300vh; /* Long scroll for parallax effect */ | |
| cursor: default; | |
| } | |
| /* --- Background Particles (Bubbles) --- */ | |
| .bubbles-container { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| pointer-events: none; | |
| z-index: 0; | |
| overflow: hidden; | |
| } | |
| .bubble { | |
| position: absolute; | |
| bottom: -50px; | |
| background: radial-gradient(circle at 30% 30%, rgba(255,255,255,0.4), rgba(255,255,255,0.1) 60%, transparent 70%); | |
| border-radius: 50%; | |
| animation: rise linear infinite; | |
| opacity: 0.6; | |
| } | |
| @keyframes rise { | |
| 0% { transform: translateY(0) translateX(0); opacity: 0; bottom: -10%; } | |
| 20% { opacity: 0.8; } | |
| 100% { transform: translateY(-120vh) translateX(20px); opacity: 0; bottom: 110%; } | |
| } | |
| /* --- Navigation / Glassmorphism Header --- */ | |
| header { | |
| position: fixed; | |
| top: 0; | |
| width: 100%; | |
| padding: 2rem 5%; | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| z-index: 100; | |
| background: linear-gradient(to bottom, rgba(0,0,0,0.8), transparent); | |
| backdrop-filter: blur(10px); | |
| -webkit-backdrop-filter: blur(10px); | |
| border-bottom: 1px solid var(--glass-border); | |
| } | |
| .logo { | |
| font-family: 'Orbitron', sans-serif; | |
| font-weight: 900; | |
| font-size: 2rem; | |
| color: var(--primary-color); | |
| text-shadow: 0 0 10px var(--primary-color), 0 0 20px var(--primary-color); | |
| letter-spacing: 2px; | |
| text-transform: uppercase; | |
| } | |
| .nav-links { | |
| display: flex; | |
| gap: 2rem; | |
| } | |
| .nav-link { | |
| color: var(--text-main); | |
| text-decoration: none; | |
| font-size: 1.2rem; | |
| font-weight: 500; | |
| position: relative; | |
| transition: color 0.3s; | |
| } | |
| .nav-link::after { | |
| content: ''; | |
| position: absolute; | |
| width: 0; | |
| height: 2px; | |
| bottom: -5px; | |
| left: 0; | |
| background: var(--primary-color); | |
| box-shadow: 0 0 8px var(--primary-color); | |
| transition: width 0.4s ease; | |
| } | |
| .nav-link:hover { | |
| color: var(--primary-color); | |
| text-shadow: 0 0 5px var(--primary-color); | |
| } | |
| .nav-link:hover::after { | |
| width: 100%; | |
| } | |
| /* --- Hero Section --- */ | |
| .hero { | |
| height: 100vh; | |
| display: flex; | |
| flex-direction: column; | |
| justify-content: center; | |
| align-items: center; | |
| text-align: center; | |
| position: relative; | |
| z-index: 10; | |
| padding: 0 1rem; | |
| } | |
| h1 { | |
| font-family: 'Orbitron', sans-serif; | |
| font-size: clamp(3rem, 8vw, 6rem); | |
| line-height: 1; | |
| font-weight: 900; | |
| text-transform: uppercase; | |
| margin-bottom: 1rem; | |
| background: linear-gradient(to right, #fff, var(--primary-color), var(--secondary-color)); | |
| -webkit-background-clip: text; | |
| background-clip: text; | |
| color: transparent; | |
| animation: flicker 4s infinite alternate; | |
| } | |
| @keyframes flicker { | |
| 0%, 19%, 21%, 23%, 25%, 54%, 56%, 100% { opacity: 1; text-shadow: 0 0 20px rgba(0, 242, 255, 0.5); } | |
| 20%, 24%, 55% { opacity: 0.8; text-shadow: none; } | |
| } | |
| .subtitle { | |
| font-size: clamp(1.2rem, 3vw, 2rem); | |
| max-width: 600px; | |
| color: #aaddff; | |
| margin-bottom: 3rem; | |
| line-height: 1.6; | |
| text-shadow: 0 0 5px rgba(0,0,0,0.8); | |
| } | |
| .cta-button { | |
| padding: 1rem 3rem; | |
| font-family: 'Orbitron', sans-serif; | |
| font-size: 1.2rem; | |
| font-weight: 700; | |
| color: var(--midnight-blue); | |
| background: var(--primary-color); | |
| border: none; | |
| border-radius: 50px; | |
| cursor: pointer; | |
| position: relative; | |
| overflow: hidden; | |
| transition: all 0.3s ease; | |
| box-shadow: 0 0 20px var(--primary-color); | |
| clip-path: polygon(10% 0, 100% 0, 100% 70%, 90% 100%, 0 100%, 0 30%); | |
| } | |
| .cta-button::before { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: -100%; | |
| width: 100%; | |
| height: 100%; | |
| background: linear-gradient(90deg, transparent, rgba(255,255,255,0.8), transparent); | |
| transition: 0.5s; | |
| } | |
| .cta-button:hover { | |
| transform: translateY(-5px); | |
| box-shadow: 0 0 40px var(--primary-color), 0 0 60px var(--primary-color); | |
| color: var(--midnight-blue); | |
| } | |
| .cta-button:hover::before { | |
| left: 100%; | |
| } | |
| /* --- Content Sections --- */ | |
| section { | |
| padding: 8rem 10%; | |
| position: relative; | |
| z-index: 10; | |
| } | |
| .section-title { | |
| font-family: 'Orbitron', sans-serif; | |
| font-size: 3rem; | |
| margin-bottom: 3rem; | |
| color: var(--primary-color); | |
| text-transform: uppercase; | |
| border-left: 5px solid var(--secondary-color); | |
| padding-left: 1.5rem; | |
| text-shadow: 0 0 10px rgba(188, 19, 254, 0.5); | |
| } | |
| .grid-container { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); | |
| gap: 2rem; | |
| } | |
| .card { | |
| background: var(--glass-bg); | |
| border: 1px solid var(--glass-border); | |
| border-radius: 20px; | |
| padding: 2.5rem; | |
| backdrop-filter: blur(15px); | |
| transition: transform 0.4s ease, box-shadow 0.4s ease; | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .card:hover { | |
| transform: translateY(-10px) scale(1.02); | |
| box-shadow: 0 10px 30px rgba(0, 242, 255, 0.15); | |
| border-color: var(--primary-color); | |
| } | |
| .card h3 { | |
| font-family: 'Orbitron', sans-serif; | |
| font-size: 1.5rem; | |
| margin-bottom: 1rem; | |
| color: var(--text-main); | |
| } | |
| .card p { | |
| line-height: 1.8; | |
| color: #bbccdd; | |
| font-size: 1.1rem; | |
| } | |
| .card::before { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 3px; | |
| background: linear-gradient(90deg, var(--secondary-color), var(--primary-color)); | |
| transform: scaleX(0); | |
| transition: transform 0.5s ease; | |
| transform-origin: left; | |
| } | |
| .card:hover::before { | |
| transform: scaleX(1); | |
| } | |
| /* --- Fish CSS Art Styles --- */ | |
| .fish-container { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| pointer-events: none; | |
| z-index: 1; | |
| overflow: hidden; | |
| } | |
| .fish { | |
| position: absolute; | |
| will-change: transform; | |
| } | |
| /* Fish Body Styles */ | |
| .fish-body { | |
| position: relative; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| } | |
| /* Common Fish Properties */ | |
| .fish.f1 { width: 60px; height: 40px; top: 20%; left: -10%; animation-duration: 15s; z-index: 50; } | |
| .fish.f2 { width: 40px; height: 25px; top: 50%; left: -15%; animation-duration: 12s; z-index: 40; } | |
| .fish.f3 { width: 80px; height: 50px; top: 35%; left: -20%; animation-duration: 20s; z-index: 60; } | |
| .fish.f4 { width: 30px; height: 20px; top: 70%; left: -10%; animation-duration: 10s; z-index: 35; } | |
| .fish.f5 { width: 50px; height: 35px; top: 15%; left: -25%; animation-duration: 18s; z-index: 55; } | |
| /* Fish 1: The Cyber Tang (Flat, Bold Colors) */ | |
| .cyber-tang { | |
| width: 100%; | |
| height: 100%; | |
| background: radial-gradient(circle at 30% 30%, #ff0055, #8b0000); | |
| border-radius: 50% 50% 40% 40%; | |
| box-shadow: 0 0 15px #ff0055; | |
| } | |
| .cyber-tang::before { /* Tail */ | |
| content: ''; | |
| position: absolute; | |
| left: -25px; | |
| top: 10%; | |
| width: 30px; | |
| height: 80%; | |
| background: #ff0055; | |
| clip-path: polygon(0% 0%, 100% 50%, 0% 100%); | |
| animation: tail-wag 0.5s infinite alternate ease-in-out; | |
| } | |
| .cyber-tang::after { /* Fin */ | |
| content: ''; | |
| position: absolute; | |
| top: -10px; | |
| left: 20px; | |
| width: 20px; | |
| height: 15px; | |
| background: #ff0055; | |
| clip-path: polygon(50% 0%, 0% 100%, 100% 100%); | |
| animation: fin-flutter 0.3s infinite alternate; | |
| } | |
| /* Fish 2: The Glass Eel (Glassmorphism) */ | |
| .glass-eel { | |
| width: 100%; | |
| height: 100%; | |
| background: linear-gradient(135deg, rgba(255,255,255,0.1), rgba(255,255,255,0.05)); | |
| border: 1px solid rgba(255,255,255,0.3); | |
| border-radius: 50px 50px 0 0; /* Eel shape */ | |
| box-shadow: 0 0 20px rgba(0, 242, 255, 0.3) inset, 0 0 10px var(--primary-color); | |
| transform: rotate(90deg); | |
| } | |
| .glass-eel::before { /* Tail Fin */ | |
| content: ''; | |
| position: absolute; | |
| right: -15px; | |
| top: -10px; | |
| width: 20px; | |
| height: 20px; | |
| background: rgba(0, 242, 255, 0.5); | |
| clip-path: polygon(0% 0%, 100% 50%, 0% 100%); | |
| animation: tail-wag 0.8s infinite alternate ease-in-out; | |
| } | |
| .glass-eel::after { /* Eye */ | |
| content: ''; | |
| position: absolute; | |
| left: 5px; | |
| top: 5px; | |
| width: 4px; | |
| height: 4px; | |
| background: #fff; | |
| border-radius: 50%; | |
| box-shadow: 0 0 5px #fff; | |
| } | |
| /* Fish 3: The Neon Shark (3D-ish Style) */ | |
| .neon-shark { | |
| width: 100%; | |
| height: 100%; | |
| position: relative; | |
| } | |
| .neon-shark-body { | |
| width: 100%; | |
| height: 100%; | |
| background: linear-gradient(to bottom, #0033cc, #000055); | |
| border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%; | |
| position: absolute; | |
| box-shadow: 5px 5px 10px rgba(0,0,0,0.5); | |
| } | |
| .neon-shark::before { /* Dorsal Fin */ | |
| content: ''; | |
| position: absolute; | |
| top: -15px; | |
| left: 25px; | |
| width: 0; | |
| height: 0; | |
| border-left: 10px solid transparent; | |
| border-right: 10px solid transparent; | |
| border-bottom: 25px solid var(--secondary-color); | |
| box-shadow: 0 0 10px var(--secondary-color); | |
| animation: fin-flutter 0.4s infinite alternate; | |
| } | |
| .neon-shark::after { /* Tail */ | |
| content: ''; | |
| position: absolute; | |
| right: -30px; | |
| top: 0; | |
| width: 30px; | |
| height: 100%; | |
| background: #000055; | |
| clip-path: polygon(100% 0%, 0% 40%, 0% 60%, 100% 100%); | |
| animation: tail-wag 0.6s infinite alternate ease-in-out; | |
| } | |
| .neon-eye { | |
| position: absolute; | |
| left: 5px; | |
| top: 15px; | |
| width: 8px; | |
| height: 8px; | |
| background: var(--accent-color); | |
| border-radius: 50%; | |
| box-shadow: 0 0 10px var(--accent-color); | |
| animation: blink 3s infinite; | |
| } | |
| /* Fish 4 & 5: Abstract Shapes */ | |
| .abstract-fish { | |
| width: 100%; | |
| height: 100%; | |
| background: radial-gradient(circle at 30% 30%, #ffcc00, #cc6600); | |
| clip-path: polygon(100% 50%, 0 0, 0 100%); /* Triangle */ | |
| box-shadow: 0 0 15px #ffcc00; | |
| } | |
| .abstract-fish::before { | |
| content: ''; | |
| position: absolute; | |
| left: -20px; | |
| top: 20%; | |
| width: 20px; | |
| height: 60%; | |
| background: #ffcc00; | |
| clip-path: polygon(0 0, 100% 50%, 0 100%); | |
| animation: tail-wag 0.4s infinite alternate; | |
| } | |
| /* Animations */ | |
| @keyframes tail-wag { | |
| 0% { transform: rotate(-15deg); } | |
| 100% { transform: rotate(15deg); } | |
| } | |
| @keyframes fin-flutter { | |
| 0% { transform: rotate(-10deg); opacity: 0.8; } | |
| 100% { transform: rotate(10deg); opacity: 1; } | |
| } | |
| @keyframes blink { | |
| 0%, 90%, 100% { transform: scaleY(1); } | |
| 95% { transform: scaleY(0.1); } | |
| } | |
| @keyframes swim { | |
| 0% { left: -20%; transform: translateY(0) rotate(0deg); } | |
| 25% { transform: translateY(-20px) rotate(5deg); } | |
| 50% { transform: translateY(20px) rotate(-5deg); } | |
| 75% { transform: translateY(-10px) rotate(3deg); } | |
| 100% { left: 110%; transform: translateY(10px) rotate(-3deg); } | |
| } | |
| /* Parallax Scroll Text */ | |
| .parallax-text { | |
| position: absolute; | |
| width: 100%; | |
| text-align: center; | |
| font-size: 15rem; | |
| font-family: 'Orbitron', sans-serif; | |
| color: rgba(255,255,255,0.03); | |
| white-space: nowrap; | |
| z-index: 0; | |
| pointer-events: none; | |
| } | |
| .p-top { top: 20%; animation: floatText 60s linear infinite; } | |
| .p-bottom { bottom: 20%; animation: floatText 50s linear infinite reverse; } | |
| @keyframes floatText { | |
| 0% { transform: translateX(-20%); } | |
| 100% { transform: translateX(20%); } | |
| } | |
| footer { | |
| text-align: center; | |
| padding: 4rem; | |
| border-top: 1px solid var(--glass-border); | |
| background: rgba(0,0,0,0.8); | |
| color: #8899aa; | |
| font-size: 1.2rem; | |
| position: relative; | |
| z-index: 10; | |
| } | |
| .footer-link { | |
| color: var(--primary-color); | |
| text-decoration: none; | |
| font-weight: 700; | |
| transition: color 0.3s; | |
| } | |
| .footer-link:hover { | |
| color: var(--secondary-color); | |
| text-shadow: 0 0 10px var(--secondary-color); | |
| } | |
| /* Responsive Adjustments */ | |
| @media (max-width: 768px) { | |
| header { flex-direction: column; gap: 1rem; padding: 1.5rem; } | |
| .nav-links { gap: 1rem; font-size: 0.9rem; } | |
| .hero h1 { font-size: 3rem; } | |
| section { padding: 5rem 5%; } | |
| .parallax-text { font-size: 8rem; } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- Background Bubbles --> | |
| <div class="bubbles-container" id="bubbles"></div> | |
| <!-- Parallax Text Layers --> | |
| <div class="parallax-text p-top">ABYSS</div> | |
| <div class="parallax-text p-bottom">FUTURE</div> | |
| <!-- Fish Animation Container --> | |
| <div class="fish-container" id="fishContainer"> | |
| <!-- Fish 1: Cyber Tang --> | |
| <div class="fish f1" style="animation-name: swimCyber;"> | |
| <div class="fish-body cyber-tang"> | |
| <div class="neon-eye"></div> | |
| </div> | |
| </div> | |
| <!-- Fish 2: Glass Eel --> | |
| <div class="fish f2" style="animation-name: swimGlass;"> | |
| <div class="fish-body glass-eel"></div> | |
| </div> | |
| <!-- Fish 3: Neon Shark --> | |
| <div class="fish f3" style="animation-name: swimShark;"> | |
| <div class="neon-shark"> | |
| <div class="neon-shark-body"></div> | |
| <div class="neon-eye"></div> | |
| </div> | |
| </div> | |
| <!-- Fish 4: Abstract Gold --> | |
| <div class="fish f4" style="animation-name: swimGold;"> | |
| <div class="fish-body abstract-fish"></div> | |
| </div> | |
| <!-- Fish 5: Abstract Cyan --> | |
| <div class="fish f5" style="animation-name: swimCyan;"> | |
| <div class="fish-body" style="background: radial-gradient(circle at 30% 30%, #00ffff, #006666); clip-path: polygon(100% 50%, 0 0, 0 100%); width: 50px; height: 40px; box-shadow: 0 0 15px #00ffff;"> | |
| <div style="position: absolute; left: 20px; top: 10px; width: 20px; height: 60%; background: #00ffff; clip-path: polygon(0 0, 100% 50%, 0 100%); animation: tail-wag 0.5s infinite alternate;"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <header> | |
| <div class="logo">Nemo<span style="color:var(--secondary-color)">Tech</span></div> | |
| <nav class="nav-links"> | |
| <a href="#home" class="nav-link">Home</a> | |
| <a href="#explore" class="nav-link">Explore</a> | |
| <a href="#data" class="nav-link">Data</a> | |
| <a href="#contact" class="nav-link">Contact</a> | |
| </nav> | |
| </header> | |
| <section id="home" class="hero"> | |
| <h1>Deep Dive<br>Future</h1> | |
| <p class="subtitle"> | |
| Enter the digital ocean. A seamless blend of organic fluidity and cutting-edge technology. | |
| Experience the calm of the deep sea with the clarity of a high-tech interface. | |
| </p> | |
| <button class="cta-button" onclick="document.getElementById('explore').scrollIntoView({behavior: 'smooth'})"> | |
| INITIALIZE DIVE | |
| </button> | |
| </section> | |
| <section id="explore"> | |
| <h2 class="section-title">Oceanic Layers</h2> | |
| <div class="grid-container"> | |
| <div class="card"> | |
| <h3>Neon Trenches</h3> | |
| <p>Explore the deepest reaches of the digital spectrum where light meets darkness. Our glassmorphism designs mimic the pressure and beauty of the abyss.</p> | |
| </div> | |
| <div class="card"> | |
| <h3>Current Data Streams</h3> | |
| <p>Experience fluid navigation. Our parallax scrolling engine ensures your journey through our content is as smooth as water.</p> | |
| </div> | |
| <div class="card"> | |
| <h3>Coral Infrastructure</h3> | |
| <p>Built on a robust, yet organic architecture. Bold colors and soft edges create a harmonious balance between form and function.</p> | |
| </div> | |
| </div> | |
| </section> | |
| <section id="data" style="background: linear-gradient(to bottom, transparent, rgba(0,20,40,0.5));"> | |
| <h2 class="section-title">System Status</h2> | |
| <div class="card" style="border-left: 4px solid var(--accent-color); box-shadow: 0 0 20px rgba(10, 255, 10, 0.1);"> | |
| <h3>Deep Sea Systems: Online</h3> | |
| <p style="color: var(--accent-color); font-family: 'Orbitron', sans-serif; letter-spacing: 1px;"> | |
| > All Tanks Stable<br> | |
| > Light Arrays: 100%<br> | |
| > Oxygen Levels: Optimal<br> | |
| > Swimming Cycles: Active | |
| </p> | |
| </div> | |
| </section> | |
| <footer id="contact"> | |
| <p> | |
| © 2023 NemoTech Aquatic Systems. <br> | |
| Designed for the future, built for the deep. <br> | |
| <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="footer-link">Built with anycoder</a> | |
| </p> | |
| </footer> | |
| <script> | |
| // --- 1. Bubble Generator --- | |
| const bubbleContainer = document.getElementById('bubbles'); | |
| const bubbleCount = 30; | |
| function createBubbles() { | |
| for (let i = 0; i < bubbleCount; i++) { | |
| const bubble = document.createElement('div'); | |
| bubble.classList.add('bubble'); | |
| // Randomize size | |
| const size = Math.random() * 30 + 5 + 'px'; | |
| bubble.style.width = size; | |
| bubble.style.height = size; | |
| // Randomize position | |
| bubble.style.left = Math.random() * 100 + '%'; | |
| // Randomize animation duration and delay | |
| const duration = Math.random() * 10 + 10 + 's'; // 10-20s | |
| const delay = Math.random() * 5 + 's'; | |
| bubble.style.animationDuration = duration; | |
| bubble.style.animationDelay = delay; | |
| // Randomize opacity | |
| bubble.style.opacity = Math.random() * 0.5 + 0.1; | |
| bubbleContainer.appendChild(bubble); | |
| } | |
| } | |
| createBubbles(); | |
| // --- 2. Fish Animation Logic (Parallax & Randomness) --- | |
| const fishContainer = document.getElementById('fishContainer'); | |
| const fishes = document.querySelectorAll('.fish'); | |
| // Define custom keyframes for each fish to vary their movement patterns | |
| function addFishAnimations() { | |
| const styleSheet = document.createElement("style"); | |
| // Helper to generate random path keyframes | |
| const generateKeyframes = (name, delay, duration, yOffset, rotateRange) => { | |
| return ` | |
| @keyframes ${name} { | |
| 0% { left: -20%; transform: translateY(${yOffset}px) rotate(0deg); } | |
| 25% { transform: translateY(${yOffset - 50}px) rotate(${rotateRange}deg); } | |
| 50% { transform: translateY(${yOffset + 50}px) rotate(${-rotateRange}deg); } | |
| 75% { transform: translateY(${yOffset - 20}px) rotate(${rotateRange/2}deg); } | |
| 100% { left: 110%; transform: translateY(${yOffset + 30}px) rotate(${-rotateRange/2}deg); } | |
| }`; | |
| }; | |
| styleSheet.innerText = ` | |
| ${generateKeyframes('swimCyber', '0s', '15s', 0, 10)} | |
| ${generateKeyframes('swimGlass', '2s', '12s', 30, 5)} | |
| ${generateKeyframes('swimShark', '1s', '20s', -20, 15)} | |
| ${generateKeyframes('swimGold', '3s', '10s', 50, 8)} | |
| ${generateKeyframes('swimCyan', '0.5s', '18s', -40, 12)} | |
| `; | |
| document.head.appendChild(styleSheet); | |
| } | |
| addFishAnimations(); | |
| // Add random delays to start so they don't all swim in sync | |
| fishes.forEach((fish, index) => { | |
| const delay = Math.random() * 5; | |
| fish.style.animationDelay = `${delay}s`; | |
| // Randomize speed slightly via JS for organic feel | |
| const speedVar = 0.8 + Math.random() * 0.4; | |
| fish.style.animationDuration = `${parseFloat(fish.style.animationDuration) * speedVar}s`; | |
| }); | |
| // --- 3. Scroll Parallax Effect on Text --- | |
| window.addEventListener('scroll', () => { | |
| const scrolled = window.pageYOffset; | |
| const pTop = document.querySelector('.p-top'); | |
| const pBottom = document.querySelector('.p-bottom'); | |
| pTop.style.transform = `translateX(${scrolled * 0.05}%)`; | |
| pBottom.style.transform = `translateX(${-scrolled * 0.05}%)`; | |
| }); | |
| // --- 4. Mouse Interaction: Fish Evasion (Subtle) --- | |
| document.addEventListener('mousemove', (e) => { | |
| const mouseX = e.clientX / window.innerWidth; | |
| const mouseY = e.clientY / window.innerHeight; | |
| fishes.forEach((fish, index) => { | |
| // Only move fish if mouse is somewhat close to them (randomly distributed) | |
| // This adds a subtle "sensing" effect without being distracting | |
| const moveX = (mouseX - 0.5) * -20; | |
| const moveY = (mouseY - 0.5) * -20; | |
| // Apply a very subtle rotation/translation based on mouse | |
| fish.style.transform = `translate(${moveX}px, ${moveY}px) rotate(${moveX * 0.5}deg)`; | |
| }); | |
| }); | |
| // Reset transform on mouse leave | |
| document.addEventListener('mouseleave', () => { | |
| fishes.forEach(fish => { | |
| fish.style.transform = 'none'; | |
| }); | |
| }); | |
| // --- 5. Typewriter Effect for Hero Subtitle (Optional Polish) --- | |
| const subtitle = document.querySelector('.subtitle'); | |
| const text = subtitle.textContent; | |
| subtitle.textContent = ''; | |
| let i = 0; | |
| const speed = 50; // ms | |
| function typeWriter() { | |
| if (i < text.length) { | |
| subtitle.textContent += text.charAt(i); | |
| i++; | |
| setTimeout(typeWriter, speed); | |
| } | |
| } | |
| // Start typing after a short delay | |
| setTimeout(typeWriter, 1000); | |
| </script> | |
| </body> | |
| </html> |