Blob effects have become a popular design trend, adding a dynamic and organic feel to modern web interfaces. These fluid shapes can transform a static page into a visually engaging experience.
In this article, we will explore 10 stunning examples of blob effects that can inspire your next design project. From subtle animations to bold, colorful blobs, these examples showcase the versatility and creativity of this design element.
CODE1
Here's the code:
CODETEXT1
CODE2
Here's the code:
CODETEXT2
CODE3
Here's the code:
CODETEXT3
CODE4
Here's the code:
CODETEXT4
CODE5
Here's the code:
CODETEXT5
Subframe's drag-and-drop interface and intuitive, responsive canvas make designing your own Blob Effect a breeze. Loved by designers and developers alike, it ensures pixel-perfect UI every time.
Start for free and elevate your design game today!
CODE6
Here's the code:
CODETEXT6
CODE7
Here's the code:
CODETEXT7
CODE8
Here's the code:
CODETEXT8
CODE9
Here's the code:
CODETEXT9
CODE10
Here's the code:
CODETEXT10
Ready to elevate your design game? With Subframe, you can create stunning UIs, including Blob Effects, with unmatched efficiency. Our drag-and-drop editor ensures pixel-perfect results every time.
Don't wait—start creating beautiful, responsive designs immediately. Start for free and see the difference Subframe can make!
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Morphing Blob Hero</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; } body { width: 100%; height: 100%; overflow: hidden; background-color: #0c0c14; color: #fff; } .hero-container { position: relative; width: 100%; height: 100vh; max-height: 700px; overflow: hidden; display: flex; justify-content: center; align-items: center; } .canvas-container { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 1; } canvas { display: block; width: 100%; height: 100%; } .content { position: relative; z-index: 2; text-align: center; padding: 30px; max-width: 640px; opacity: 0; transform: translateY(30px); animation: fadeIn 1.2s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards 0.5s; } h1 { font-size: 3.2rem; font-weight: 800; margin-bottom: 1.5rem; line-height: 1.1; color: #ffffff; letter-spacing: -0.03em; background: linear-gradient(120deg, #8364e2, #e45a7b); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; } .subtitle { font-size: 1.25rem; line-height: 1.5; color: rgba(255, 255, 255, 0.8); margin-bottom: 2rem; font-weight: 400; } .cta-button { display: inline-flex; align-items: center; padding: 18px 36px; border-radius: 12px; background: rgba(255, 255, 255, 0.08); backdrop-filter: blur(10px); border: 1px solid rgba(255, 255, 255, 0.1); color: #fff; font-size: 1rem; font-weight: 600; cursor: pointer; transition: all 0.3s ease; position: relative; overflow: hidden; margin-right: 16px; } .cta-button:before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(120deg, #8364e2, #e45a7b); z-index: -1; transform: scaleX(0); transform-origin: right; transition: transform 0.6s cubic-bezier(0.165, 0.84, 0.44, 1); } .cta-button:hover:before { transform: scaleX(1); transform-origin: left; } .cta-button:hover { border-color: rgba(255, 255, 255, 0.3); box-shadow: 0 10px 25px rgba(131, 100, 226, 0.2); } .secondary-btn { display: inline-flex; align-items: center; padding: 18px 36px; border-radius: 12px; background: transparent; border: 1px solid rgba(255, 255, 255, 0.1); color: rgba(255, 255, 255, 0.8); font-size: 1rem; font-weight: 500; cursor: pointer; transition: all 0.3s ease; } .secondary-btn:hover { background: rgba(255, 255, 255, 0.05); border-color: rgba(255, 255, 255, 0.2); } .buttons-container { display: flex; justify-content: center; flex-wrap: wrap; gap: 16px; } .visual-indicator { position: absolute; bottom: 50px; left: 50%; transform: translateX(-50%); display: flex; flex-direction: column; align-items: center; gap: 8px; opacity: 0; animation: fadeIn 1s ease forwards 1.8s; } .down-arrow { width: 24px; height: 24px; border-left: 2px solid rgba(255, 255, 255, 0.6); border-bottom: 2px solid rgba(255, 255, 255, 0.6); transform: rotate(-45deg); animation: bounce 2s infinite; } .scroll-text { font-size: 0.8rem; color: rgba(255, 255, 255, 0.6); text-transform: uppercase; letter-spacing: 2px; } @keyframes fadeIn { 0% { opacity: 0; transform: translateY(30px); } 100% { opacity: 1; transform: translateY(0); } } @keyframes bounce { 0%, 20%, 50%, 80%, 100% { transform: translateY(0) rotate(-45deg); } 40% { transform: translateY(10px) rotate(-45deg); } 60% { transform: translateY(5px) rotate(-45deg); } } @media (max-width: 768px) { h1 { font-size: 2.5rem; } .subtitle { font-size: 1.1rem; } .content { padding: 20px; } .buttons-container { flex-direction: column; align-items: center; } .cta-button, .secondary-btn { width: 100%; justify-content: center; margin-right: 0; margin-bottom: 12px; } } @media (max-width: 480px) { h1 { font-size: 2rem; } .subtitle { font-size: 1rem; } .cta-button, .secondary-btn { padding: 15px 30px; } } </style> </head> <body> <div class="hero-container"> <div class="canvas-container"> <canvas id="blobCanvas"></canvas> </div> <div class="content"> <h1>Fluid Design Meets Natural Motion</h1> <p class="subtitle">Experience a digital space where organic shapes continuously morph and evolve, creating a living breathing interface that adapts naturally to your design language.</p> <div class="buttons-container"> <button class="cta-button" id="exploreBtn">Explore Possibilities</button> <button class="secondary-btn" id="learnBtn">Learn More</button> </div> </div> <div class="visual-indicator"> <div class="down-arrow"></div> <span class="scroll-text">Scroll to discover</span> </div> </div> <script> document.addEventListener('DOMContentLoaded', () => { const canvas = document.getElementById('blobCanvas'); const ctx = canvas.getContext('2d'); let width = canvas.width = window.innerWidth; let height = canvas.height = window.innerHeight; // Base colors for gradients const colorPalettes = [ { start: '#8364e2', end: '#e45a7b' }, // Purple to Pink { start: '#3494E6', end: '#EC6EAD' }, // Blue to Pink { start: '#5e72eb', end: '#ff9190' } // Blue to Peach ]; let activePalette = 0; let transitioning = false; let transitionProgress = 0; const transitionSpeed = 0.005; class Blob { constructor(x, y, radius, color) { this.x = x; this.y = y; this.originX = x; this.originY = y; this.radius = radius; this.color = color; this.angle = Math.random() * Math.PI * 2; this.speed = 0.002 + Math.random() * 0.003; this.noiseOffset = Math.random() * 1000; this.points = []; this.numberOfPoints = 7 + Math.floor(Math.random() * 5); this.createPoints(); this.baseNoiseScale = 0.003 + Math.random() * 0.003; this.additionalNoiseScale = 0.003; this.directionX = Math.random() > 0.5 ? 1 : -1; this.directionY = Math.random() > 0.5 ? 1 : -1; this.moveFactor = 0.5 + Math.random() * 0.5; } createPoints() { for (let i = 0; i < this.numberOfPoints; i++) { const angle = (i / this.numberOfPoints) * Math.PI * 2; const radiusVariation = 0.7 + Math.random() * 0.6; this.points.push({ x: this.x + Math.cos(angle) * this.radius * radiusVariation, y: this.y + Math.sin(angle) * this.radius * radiusVariation, angle: angle, speed: this.speed * (0.6 + Math.random() * 0.8), noiseOffset: this.noiseOffset + i * 100, radiusVariation }); } } movePoint(point, time) { const noiseValue = this.noise(point.noiseOffset + time * point.speed, 0, 0); const radius = this.radius * (0.8 + noiseValue * 0.4) * point.radiusVariation; point.x = this.x + Math.cos(point.angle) * radius; point.y = this.y + Math.sin(point.angle) * radius; } move(time) { // Base movement with perlin noise this.x = this.originX + Math.sin(time * 0.0005 * this.directionX) * width * 0.05 * this.moveFactor; this.y = this.originY + Math.sin(time * 0.0007 * this.directionY) * height * 0.05 * this.moveFactor; // Update all points this.points.forEach(point => this.movePoint(point, time)); } draw(ctx) { if (this.points.length < 3) return; const grd = ctx.createLinearGradient( this.x - this.radius, this.y - this.radius, this.x + this.radius, this.y + this.radius ); // If transitioning, blend between current and next palette if (transitioning) { const currentPalette = colorPalettes[activePalette]; const nextPalette = colorPalettes[(activePalette + 1) % colorPalettes.length]; // Interpolate colors const startColor = this.lerpColor(currentPalette.start, nextPalette.start, transitionProgress); const endColor = this.lerpColor(currentPalette.end, nextPalette.end, transitionProgress); grd.addColorStop(0, startColor); grd.addColorStop(1, endColor); } else { grd.addColorStop(0, colorPalettes[activePalette].start); grd.addColorStop(1, colorPalettes[activePalette].end); } ctx.fillStyle = grd; ctx.beginPath(); // Create blob path ctx.moveTo(this.points[0].x, this.points[0].y); for (let i = 0; i < this.points.length; i++) { const currentPoint = this.points[i]; const nextPoint = this.points[(i + 1) % this.points.length]; // Control points for smoother curves const cp1x = currentPoint.x + (nextPoint.x - this.points[(i - 1 + this.points.length) % this.points.length].x) * 0.2; const cp1y = currentPoint.y + (nextPoint.y - this.points[(i - 1 + this.points.length) % this.points.length].y) * 0.2; const cp2x = nextPoint.x - (this.points[(i + 2) % this.points.length].x - currentPoint.x) * 0.2; const cp2y = nextPoint.y - (this.points[(i + 2) % this.points.length].y - currentPoint.y) * 0.2; ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, nextPoint.x, nextPoint.y); } ctx.closePath(); ctx.fill(); } // Simplex noise approximation noise(x, y, z) { const X = Math.floor(x) & 255; const Y = Math.floor(y) & 255; const Z = Math.floor(z) & 255; x -= Math.floor(x); y -= Math.floor(y); z -= Math.floor(z); const u = this.fade(x); const v = this.fade(y); const w = this.fade(z); const A = (this.p[X] + Y) & 255; const B = (this.p[X + 1] + Y) & 255; return this.lerp( this.lerp( this.lerp( this.grad(this.p[A], x, y, z), this.grad(this.p[B], x - 1, y, z), u ), this.lerp( this.grad(this.p[A + 1], x, y - 1, z), this.grad(this.p[B + 1], x - 1, y - 1, z), u ), v ), this.lerp( this.lerp( this.grad(this.p[A + Z], x, y, z - 1), this.grad(this.p[B + Z], x - 1, y, z - 1), u ), this.lerp( this.grad(this.p[A + 1 + Z], x, y - 1, z - 1), this.grad(this.p[B + 1 + Z], x - 1, y - 1, z - 1), u ), v ), w ) * 0.5 + 0.5; } fade(t) { return t * t * t * (t * (t * 6 - 15) + 10); } lerp(a, b, t) { return a + t * (b - a); } grad(hash, x, y, z) { const h = hash & 15; const u = h < 8 ? x : y; const v = h < 4 ? y : h == 12 || h == 14 ? x : z; return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v); } lerpColor(color1, color2, factor) { // Parse hex colors const r1 = parseInt(color1.substring(1, 3), 16); const g1 = parseInt(color1.substring(3, 5), 16); const b1 = parseInt(color1.substring(5, 7), 16); const r2 = parseInt(color2.substring(1, 3), 16); const g2 = parseInt(color2.substring(3, 5), 16); const b2 = parseInt(color2.substring(5, 7), 16); // Interpolate RGB values const r = Math.round(r1 + factor * (r2 - r1)); const g = Math.round(g1 + factor * (g2 - g1)); const b = Math.round(b1 + factor * (b2 - b1)); // Convert back to hex return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`; } // Perlin noise permutation table p = [151,160,137,91,90,15,131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,190,6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,88,237,149,56,87,174,20,125,136,171,168,68,175,74,165,71,134,139,48,27,166,77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,102,143,54,65,25,63,161,1,216,80,73,209,76,132,187,208,89,18,169,200,196,135,130,116,188,159,86,164,100,109,198,173,186,3,64,52,217,226,250,124,123,5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,223,183,170,213,119,248,152,2,44,154,163,70,221,153,101,155,167,43,172,9,129,22,39,253,19,98,108,110,79,113,224,232,178,185,112,104,218,246,97,228,251,34,242,193,238,210,144,12,191,179,162,241,81,51,145,235,249,14,239,107,49,192,214,31,181,199,106,157,184,84,204,176,115,121,50,45,127,4,150,254,138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180]; // Duplicate the permutation table constructor() { this.p = [...this.p, ...this.p]; } } let blobs = []; const createBlobs = () => { blobs = []; // Create 3 different sized blobs blobs.push(new Blob(width * 0.3, height * 0.3, Math.min(width, height) * 0.25, '#8364e2')); blobs.push(new Blob(width * 0.7, height * 0.7, Math.min(width, height) * 0.2, '#e45a7b')); blobs.push(new Blob(width * 0.5, height * 0.5, Math.min(width, height) * 0.3, '#9d63e9')); }; // Handle window resize window.addEventListener('resize', () => { width = canvas.width = window.innerWidth; height = canvas.height = window.innerHeight; createBlobs(); }); createBlobs(); // Change color palette periodically setInterval(() => { transitioning = true; transitionProgress = 0; }, 12000); // Animation loop let lastTime = 0; const animate = (time) => { // Handle color transition if (transitioning) { transitionProgress += transitionSpeed; if (transitionProgress >= 1) { transitioning = false; transitionProgress = 0; activePalette = (activePalette + 1) % colorPalettes.length; } } // Clear canvas with slight overlay for trail effect ctx.fillStyle = 'rgba(12, 12, 20, 0.05)'; ctx.fillRect(0, 0, width, height); // Update and draw blobs blobs.forEach(blob => { blob.move(time); blob.draw(ctx); }); requestAnimationFrame(animate); }; animate(0); // Button interactions const exploreBtn = document.getElementById('exploreBtn'); const learnBtn = document.getElementById('learnBtn'); exploreBtn.addEventListener('click', () => { // Create a subtle ripple effect when clicking transitioning = true; transitionProgress = 0; // Create tiny blobs for click effect const mouseX = width / 2; const mouseY = height / 2; for (let i = 0; i < 3; i++) { const radius = Math.random() * 50 + 20; const newBlob = new Blob( mouseX + (Math.random() - 0.5) * 100, mouseY + (Math.random() - 0.5) * 100, radius, colorPalettes[activePalette].start ); blobs.push(newBlob); // Remove after animation setTimeout(() => { const index = blobs.indexOf(newBlob); if (index > -1) { blobs.splice(index, 1); } }, 2000); } }); learnBtn.addEventListener('mouseenter', () => { // Slight speed increase on hover blobs.forEach(blob => { blob.speed *= 1.5; }); }); learnBtn.addEventListener('mouseleave', () => { // Return to normal speed blobs.forEach(blob => { blob.speed /= 1.5; }); }); // Mouse movement interaction document.addEventListener('mousemove', (e) => { const mouseX = e.clientX; const mouseY = e.clientY; // Subtle influence on blob positions blobs.forEach(blob => { const dx = mouseX - blob.x; const dy = mouseY - blob.y; const distance = Math.sqrt(dx * dx + dy * dy); const maxDistance = Math.min(width, height) * 0.4; if (distance < maxDistance) { const factor = 0.02 * (1 - distance / maxDistance); blob.x += dx * factor; blob.y += dy * factor; } }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Flux Studio - Creative Digital Agency</title> <style> @import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;600;700&display=swap'); * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Space Grotesk', sans-serif; } :root { --primary: #FF6B95; --secondary: #7B68EE; --accent: #61DBFB; --text: #2E2E3A; --bg: #F9F9FD; } body { background-color: var(--bg); color: var(--text); overflow-x: hidden; height: 100%; width: 100%; } .container { max-width: 700px; margin: 0 auto; padding: 0 20px; position: relative; overflow: hidden; height: 100vh; } header { display: flex; justify-content: space-between; align-items: center; padding: 20px 0; position: relative; z-index: 10; } .logo { font-weight: 700; font-size: 24px; color: var(--text); text-decoration: none; position: relative; } .logo::after { content: ""; position: absolute; bottom: 0; left: 0; width: 100%; height: 5px; background-color: var(--primary); transform: scaleX(0.3); transform-origin: left; transition: transform 0.3s ease; } .logo:hover::after { transform: scaleX(1); } nav ul { display: flex; list-style: none; gap: 25px; } nav a { text-decoration: none; color: var(--text); font-weight: 500; font-size: 16px; position: relative; transition: color 0.3s ease; } nav a::after { content: ""; position: absolute; bottom: -5px; left: 0; width: 100%; height: 2px; background-color: var(--primary); transform: scaleX(0); transition: transform 0.3s ease; } nav a:hover { color: var(--primary); } nav a:hover::after { transform: scaleX(1); } .hero { min-height: calc(100vh - 80px); display: flex; flex-direction: column; justify-content: center; position: relative; } .blob-container { position: absolute; top: 0; left: 0; width: 100%; height: 100%; overflow: hidden; z-index: 1; } .blob { position: absolute; border-radius: 50%; filter: blur(30px); transition: all 0.8s ease; opacity: 0.7; } .blob-1 { width: 300px; height: 300px; background-color: var(--primary); top: -100px; right: -100px; } .blob-2 { width: 350px; height: 350px; background-color: var(--secondary); bottom: -150px; left: -150px; } .blob-3 { width: 200px; height: 200px; background-color: var(--accent); top: 50%; left: 50%; transform: translate(-50%, -50%); } .hero-content { position: relative; z-index: 2; } h1 { font-size: 64px; font-weight: 700; line-height: 1.1; margin-bottom: 20px; position: relative; } h1 span { display: block; position: relative; } h1 .highlight { color: var(--primary); display: inline; } .hero-text { font-size: 18px; line-height: 1.5; margin-bottom: 30px; max-width: 600px; } .btn { display: inline-flex; align-items: center; padding: 12px 30px; background-color: var(--primary); color: white; border: none; border-radius: 50px; font-weight: 600; font-size: 16px; cursor: pointer; box-shadow: 0 10px 20px rgba(255, 107, 149, 0.3); transition: all 0.3s ease; text-decoration: none; position: relative; overflow: hidden; } .btn::before { content: ""; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent); transition: all 0.6s ease; } .btn:hover { transform: translateY(-3px); box-shadow: 0 15px 30px rgba(255, 107, 149, 0.4); } .btn:hover::before { left: 100%; } .btn-secondary { background-color: transparent; color: var(--text); border: 2px solid var(--primary); box-shadow: none; margin-left: 15px; } .btn-secondary:hover { background-color: var(--primary); color: white; box-shadow: 0 15px 30px rgba(255, 107, 149, 0.4); } .scroll-indicator { position: absolute; bottom: 30px; left: 50%; transform: translateX(-50%); display: flex; flex-direction: column; align-items: center; z-index: 5; cursor: pointer; } .scroll-text { font-size: 14px; font-weight: 500; margin-bottom: 10px; opacity: 0.7; } .scroll-arrow { width: 30px; height: 30px; border: 2px solid var(--text); border-radius: 50%; display: flex; justify-content: center; align-items: center; animation: pulse 2s infinite; } .scroll-arrow svg { width: 12px; height: 12px; fill: var(--text); } @keyframes pulse { 0% { transform: translateY(0); } 50% { transform: translateY(10px); } 100% { transform: translateY(0); } } .sections { position: relative; z-index: 3; } .section { min-height: 100vh; display: flex; flex-direction: column; justify-content: center; padding: 60px 0; position: relative; opacity: 0; transform: translateY(50px); transition: all 0.8s ease; } .section.active { opacity: 1; transform: translateY(0); } .section-title { font-size: 36px; margin-bottom: 20px; position: relative; display: inline-block; } .section-title::after { content: ""; position: absolute; bottom: -5px; left: 0; width: 60px; height: 5px; background-color: var(--primary); } .services { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 20px; margin-top: 40px; } .service-card { background: rgba(255, 255, 255, 0.9); padding: 25px; border-radius: 15px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.05); transition: all 0.3s ease; position: relative; overflow: hidden; z-index: 1; } .service-card::before { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 5px; background: linear-gradient(90deg, var(--primary), var(--secondary)); transition: height 0.3s ease; z-index: -1; } .service-card:hover { transform: translateY(-10px); box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1); } .service-card:hover::before { height: 100%; opacity: 0.1; } .service-icon { margin-bottom: 15px; font-size: 40px; color: var(--primary); } .service-title { font-size: 18px; font-weight: 600; margin-bottom: 10px; } .service-desc { font-size: 14px; line-height: 1.5; color: rgba(46, 46, 58, 0.8); } @media (max-width: 768px) { h1 { font-size: 40px; } nav ul { gap: 15px; } nav a { font-size: 14px; } .services { grid-template-columns: 1fr; } .blob-1 { width: 200px; height: 200px; } .blob-2 { width: 250px; height: 250px; } .blob-3 { width: 150px; height: 150px; } } @media (max-width: 480px) { h1 { font-size: 32px; } .hero-text { font-size: 16px; } .btn { padding: 10px 20px; font-size: 14px; } .section-title { font-size: 28px; } } /* Cursor effect */ .custom-cursor { position: fixed; width: 40px; height: 40px; border: 2px solid var(--primary); border-radius: 50%; pointer-events: none; transform: translate(-50%, -50%); z-index: 9999; transition: width 0.3s, height 0.3s, background-color 0.3s; mix-blend-mode: difference; } .custom-cursor.hover { width: 80px; height: 80px; background-color: rgba(255, 107, 149, 0.2); } /* Progress bar */ .progress-container { position: fixed; top: 0; left: 0; width: 100%; height: 5px; background: transparent; z-index: 1000; } .progress-bar { height: 100%; background: linear-gradient(90deg, var(--primary), var(--secondary), var(--accent)); width: 0%; } </style> </head> <body> <div class="progress-container"> <div class="progress-bar" id="progressBar"></div> </div> <div class="custom-cursor" id="customCursor"></div> <div class="container"> <header> <a href="#" class="logo">flux</a> <nav> <ul> <li><a href="#" class="nav-link">Work</a></li> <li><a href="#" class="nav-link">Services</a></li> <li><a href="#" class="nav-link">About</a></li> <li><a href="#" class="nav-link">Contact</a></li> </ul> </nav> </header> <div class="blob-container"> <div class="blob blob-1" id="blob1"></div> <div class="blob blob-2" id="blob2"></div> <div class="blob blob-3" id="blob3"></div> </div> <section class="hero" id="hero"> <div class="hero-content"> <h1> <span>We craft</span> <span><span class="highlight">digital experiences</span> that</span> <span>move the needle</span> </h1> <p class="hero-text">We're not just another agency. Flux Studio transforms ideas into immersive digital landscapes where creativity knows no bounds and innovation is the standard.</p> <div class="cta"> <a href="#" class="btn">See our work</a> <a href="#" class="btn btn-secondary">Let's talk</a> </div> </div> <div class="scroll-indicator" id="scrollDown"> <span class="scroll-text">Scroll to explore</span> <div class="scroll-arrow"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M7 10l5 5 5-5z"/> </svg> </div> </div> </section> <div class="sections"> <section class="section" id="services"> <h2 class="section-title">Our Expertise</h2> <p>We blend strategy, design, and technology to create digital solutions that captivate audiences and drive real business outcomes.</p> <div class="services"> <div class="service-card"> <div class="service-icon">🎨</div> <h3 class="service-title">Brand Identity</h3> <p class="service-desc">We craft distinctive visual languages that communicate your brand's unique personality and values.</p> </div> <div class="service-card"> <div class="service-icon">💻</div> <h3 class="service-title">Digital Products</h3> <p class="service-desc">From concept to deployment, we build intuitive, scalable solutions that solve real problems.</p> </div> <div class="service-card"> <div class="service-icon">🚀</div> <h3 class="service-title">Motion Design</h3> <p class="service-desc">We bring static designs to life through mesmerizing animations that enhance user engagement.</p> </div> </div> </section> <section class="section" id="approach"> <h2 class="section-title">Our Approach</h2> <p>We don't follow trends—we set them. Our creative process is a blend of strategic thinking, bold experimentation, and meticulous execution.</p> <div class="services"> <div class="service-card"> <div class="service-icon">🔍</div> <h3 class="service-title">Discovery</h3> <p class="service-desc">We dive deep into your business, audience, and competitive landscape to uncover key insights.</p> </div> <div class="service-card"> <div class="service-icon">💡</div> <h3 class="service-title">Ideation</h3> <p class="service-desc">Through collaborative workshops, we generate innovative concepts that align with your objectives.</p> </div> <div class="service-card"> <div class="service-icon">✨</div> <h3 class="service-title">Execution</h3> <p class="service-desc">We transform ideas into polished solutions with an obsessive attention to detail and craftsmanship.</p> </div> </div> </section> </div> </div> <script> // Custom cursor const cursor = document.getElementById('customCursor'); const links = document.querySelectorAll('a, button, .service-card'); document.addEventListener('mousemove', (e) => { cursor.style.left = e.clientX + 'px'; cursor.style.top = e.clientY + 'px'; }); links.forEach(link => { link.addEventListener('mouseenter', () => { cursor.classList.add('hover'); }); link.addEventListener('mouseleave', () => { cursor.classList.remove('hover'); }); }); // Blob animation on scroll const blob1 = document.getElementById('blob1'); const blob2 = document.getElementById('blob2'); const blob3 = document.getElementById('blob3'); const sections = document.querySelectorAll('.section'); const progressBar = document.getElementById('progressBar'); // Initial positions let blob1X = -100; let blob1Y = -100; let blob2X = -150; let blob2Y = -150; let blob3X = 50; let blob3Y = 50; // Initial appearance gsapLite(blob1, { x: blob1X, y: blob1Y }); gsapLite(blob2, { x: blob2X, y: blob2Y }); gsapLite(blob3, { x: blob3X, y: blob3Y }); // Scroll event window.addEventListener('scroll', () => { // Update progress bar const scrollTop = document.documentElement.scrollTop || document.body.scrollTop; const scrollHeight = document.documentElement.scrollHeight - document.documentElement.clientHeight; const scrollProgress = (scrollTop / scrollHeight) * 100; progressBar.style.width = scrollProgress + '%'; // Animate blobs based on scroll position const scrollY = window.scrollY; // Blob 1 animation gsapLite(blob1, { x: -100 + (scrollY * 0.2), y: -100 + (scrollY * 0.1), scale: 1 + (scrollY * 0.0005) }); // Blob 2 animation gsapLite(blob2, { x: -150 - (scrollY * 0.15), y: -150 + (scrollY * 0.25), scale: 1 + (scrollY * 0.0003) }); // Blob 3 animation gsapLite(blob3, { x: 50 + (scrollY * 0.1), y: 50 - (scrollY * 0.1), scale: 1 - (scrollY * 0.0002), opacity: 0.7 - (scrollY * 0.0005) }); // Check for sections in view sections.forEach(section => { const sectionTop = section.getBoundingClientRect().top; if (sectionTop < window.innerHeight * 0.75) { section.classList.add('active'); } }); }); // GSAP Lite implementation (since we can't import libraries) function gsapLite(element, props) { for (const prop in props) { if (prop === 'x') { element.style.transform = element.style.transform.replace(/translateX\([^)]*\)/, '') + ` translateX(${props[prop]}px)`; } else if (prop === 'y') { element.style.transform = element.style.transform.replace(/translateY\([^)]*\)/, '') + ` translateY(${props[prop]}px)`; } else if (prop === 'scale') { element.style.transform = element.style.transform.replace(/scale\([^)]*\)/, '') + ` scale(${props[prop]})`; } else if (prop === 'opacity') { element.style.opacity = props[prop]; } else { element.style[prop] = props[prop]; } } } // Scroll down button document.getElementById('scrollDown').addEventListener('click', () => { window.scrollTo({ top: window.innerHeight, behavior: 'smooth' }); }); // Simulated loading to trigger animations on page load window.addEventListener('load', () => { // Trigger scroll event to initialize animations window.dispatchEvent(new Event('scroll')); // Animate sections into view setTimeout(() => { const firstSection = document.querySelector('.section'); if (firstSection) { firstSection.classList.add('active'); } }, 500); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Analytics Dashboard with Pulsing Blobs</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; } :root { --bg-primary: #f8fafc; --card-bg: #ffffff; --text-primary: #1e293b; --text-secondary: #64748b; --accent-blue: #3b82f6; --accent-green: #10b981; --accent-purple: #8b5cf6; --accent-pink: #ec4899; --accent-yellow: #f59e0b; --border-color: #e2e8f0; --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05); --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); } @media (prefers-color-scheme: dark) { :root { --bg-primary: #0f172a; --card-bg: #1e293b; --text-primary: #f1f5f9; --text-secondary: #94a3b8; --border-color: #334155; } } body { background-color: var(--bg-primary); color: var(--text-primary); width: 100%; height: 100vh; overflow: hidden; position: relative; } .blob-container { position: absolute; top: 0; left: 0; width: 100%; height: 100%; overflow: hidden; z-index: 0; opacity: 0.4; filter: blur(40px); } .blob { position: absolute; border-radius: 50%; opacity: 0.5; transition: transform 3s ease-in-out; } .blob-1 { width: 300px; height: 300px; background: linear-gradient(135deg, var(--accent-blue), var(--accent-purple)); top: -150px; left: -150px; animation: pulse1 15s infinite alternate, move1 40s infinite linear; } .blob-2 { width: 250px; height: 250px; background: linear-gradient(135deg, var(--accent-green), var(--accent-blue)); bottom: -100px; right: -100px; animation: pulse2 12s infinite alternate, move2 35s infinite linear; } .blob-3 { width: 200px; height: 200px; background: linear-gradient(135deg, var(--accent-pink), var(--accent-purple)); top: 60%; left: 30%; animation: pulse3 18s infinite alternate, move3 45s infinite linear; } .blob-4 { width: 220px; height: 220px; background: linear-gradient(135deg, var(--accent-yellow), var(--accent-pink)); top: 20%; right: 10%; animation: pulse4 14s infinite alternate, move4 50s infinite linear; } @keyframes pulse1 { 0% { transform: scale(1); } 100% { transform: scale(1.3); } } @keyframes pulse2 { 0% { transform: scale(1.1); } 100% { transform: scale(1.4); } } @keyframes pulse3 { 0% { transform: scale(0.9); } 100% { transform: scale(1.2); } } @keyframes pulse4 { 0% { transform: scale(1); } 100% { transform: scale(1.25); } } @keyframes move1 { 0% { transform: translate(0, 0) rotate(0deg); } 33% { transform: translate(100px, 100px) rotate(120deg); } 66% { transform: translate(-50px, 150px) rotate(240deg); } 100% { transform: translate(0, 0) rotate(360deg); } } @keyframes move2 { 0% { transform: translate(0, 0) rotate(0deg); } 33% { transform: translate(-120px, -80px) rotate(120deg); } 66% { transform: translate(70px, -120px) rotate(240deg); } 100% { transform: translate(0, 0) rotate(360deg); } } @keyframes move3 { 0% { transform: translate(0, 0) rotate(0deg); } 33% { transform: translate(80px, -100px) rotate(120deg); } 66% { transform: translate(-120px, -60px) rotate(240deg); } 100% { transform: translate(0, 0) rotate(360deg); } } @keyframes move4 { 0% { transform: translate(0, 0) rotate(0deg); } 33% { transform: translate(-90px, 80px) rotate(120deg); } 66% { transform: translate(100px, 50px) rotate(240deg); } 100% { transform: translate(0, 0) rotate(360deg); } } .dashboard { position: relative; z-index: 10; width: 100%; height: 100%; display: flex; flex-direction: column; padding: 24px; gap: 20px; max-width: 700px; margin: 0 auto; } .header { display: flex; justify-content: space-between; align-items: center; padding-bottom: 16px; border-bottom: 1px solid var(--border-color); } .logo { font-weight: 700; font-size: 22px; color: var(--text-primary); display: flex; align-items: center; gap: 8px; } .logo-icon { background: linear-gradient(135deg, var(--accent-blue), var(--accent-purple)); width: 24px; height: 24px; border-radius: 6px; display: flex; align-items: center; justify-content: center; } .date-selector { display: flex; gap: 8px; align-items: center; font-size: 14px; background-color: var(--card-bg); padding: 8px 12px; border-radius: 8px; border: 1px solid var(--border-color); box-shadow: var(--shadow-sm); cursor: pointer; transition: all 0.2s ease; } .date-selector:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); } .card-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; } .card { background-color: var(--card-bg); border-radius: 12px; padding: 16px; box-shadow: var(--shadow-sm); border: 1px solid var(--border-color); transition: all 0.3s ease; position: relative; overflow: hidden; } .card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); } .card-label { font-size: 14px; color: var(--text-secondary); margin-bottom: 8px; display: flex; align-items: center; gap: 6px; } .card-value { font-size: 28px; font-weight: 700; margin-bottom: 8px; } .card-trend { font-size: 12px; display: flex; align-items: center; gap: 4px; } .positive { color: var(--accent-green); } .negative { color: var(--accent-pink); } .chart-container { grid-column: 1 / -1; height: 240px; position: relative; } .chart { width: 100%; height: 100%; position: relative; } .chart-labels { display: flex; justify-content: space-between; margin-top: 8px; font-size: 12px; color: var(--text-secondary); } .chart-legend { display: flex; gap: 16px; margin-top: 8px; font-size: 12px; } .legend-item { display: flex; align-items: center; gap: 4px; } .legend-dot { width: 8px; height: 8px; border-radius: 50%; } .dot-users { background-color: var(--accent-blue); } .dot-sessions { background-color: var(--accent-purple); } .tab-container { display: flex; gap: 2px; background-color: rgba(0, 0, 0, 0.03); padding: 4px; border-radius: 8px; margin-bottom: 16px; } .tab { padding: 8px 16px; font-size: 14px; border-radius: 6px; cursor: pointer; transition: all 0.2s ease; text-align: center; flex: 1; } .tab.active { background-color: var(--card-bg); box-shadow: var(--shadow-sm); font-weight: 500; } .tab:not(.active):hover { background-color: rgba(0, 0, 0, 0.02); } .metric-row { display: flex; gap: 16px; margin-top: 16px; } .metric { background-color: var(--card-bg); border-radius: 8px; padding: 12px; flex: 1; box-shadow: var(--shadow-sm); border: 1px solid var(--border-color); transition: all 0.3s ease; } .metric:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); } .metric-label { font-size: 13px; color: var(--text-secondary); margin-bottom: 4px; } .metric-value { font-size: 20px; font-weight: 600; } /* Chart lines */ .data-line { fill: none; stroke-width: 2; stroke-linecap: round; } .users-line { stroke: var(--accent-blue); } .sessions-line { stroke: var(--accent-purple); } .area { opacity: 0.1; } .users-area { fill: var(--accent-blue); } .sessions-area { fill: var(--accent-purple); } .tooltip { position: absolute; background-color: var(--card-bg); border-radius: 6px; padding: 8px 12px; box-shadow: var(--shadow-md); font-size: 12px; pointer-events: none; opacity: 0; transition: opacity 0.2s; border: 1px solid var(--border-color); z-index: 100; } .tooltip-date { font-weight: 600; margin-bottom: 4px; } .tooltip-value { display: flex; align-items: center; gap: 4px; } .tooltip-dot { width: 6px; height: 6px; border-radius: 50%; } @media (max-width: 600px) { .card-grid { grid-template-columns: 1fr; } .metric-row { flex-direction: column; gap: 12px; } .card-value { font-size: 24px; } .chart-container { height: 200px; } .dashboard { padding: 16px; } } </style> </head> <body> <div class="blob-container"> <div class="blob blob-1"></div> <div class="blob blob-2"></div> <div class="blob blob-3"></div> <div class="blob blob-4"></div> </div> <div class="dashboard"> <div class="header"> <div class="logo"> <div class="logo-icon"> <svg width="14" height="14" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M10 3H3V10H10V3Z" fill="white"/> <path d="M21 3H14V10H21V3Z" fill="white"/> <path d="M21 14H14V21H21V14Z" fill="white"/> <path d="M10 14H3V21H10V14Z" fill="white"/> </svg> </div> <span>Pulse Analytics</span> </div> <div class="date-selector"> <span>Last 30 days</span> <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M6 9L12 15L18 9" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> </div> </div> <div class="tab-container"> <div class="tab active">Overview</div> <div class="tab">Acquisition</div> <div class="tab">Engagement</div> <div class="tab">Retention</div> </div> <div class="card-grid"> <div class="card"> <div class="card-label"> <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M17 21V19C17 16.7909 15.2091 15 13 15H5C2.79086 15 1 16.7909 1 19V21" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M9 11C11.2091 11 13 9.20914 13 7C13 4.79086 11.2091 3 9 3C6.79086 3 5 4.79086 5 7C5 9.20914 6.79086 11 9 11Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M23 21V19C22.9986 17.1771 21.765 15.5857 20 15.13" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M16 3.13C17.7699 3.58317 19.0078 5.17799 19.0078 7.005C19.0078 8.83201 17.7699 10.4268 16 10.88" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> Total Visitors </div> <div class="card-value">78,291</div> <div class="card-trend positive"> <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M18 15L12 9L6 15" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> 12.8% from last period </div> </div> <div class="card"> <div class="card-label"> <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M22 12H18L15 21L9 3L6 12H2" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> Avg. Session Duration </div> <div class="card-value">4m 12s</div> <div class="card-trend negative"> <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M6 9L12 15L18 9" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> 3.2% from last period </div> </div> <div class="card chart-container"> <div class="card-label">Traffic Overview</div> <div class="chart" id="trafficChart"> <svg width="100%" height="180" id="chartSvg"> <!-- Chart will be rendered here --> </svg> <div class="chart-labels"> <span>Apr 1</span> <span>Apr 8</span> <span>Apr 15</span> <span>Apr 22</span> <span>Apr 30</span> </div> <div class="chart-legend"> <div class="legend-item"> <div class="legend-dot dot-users"></div> <span>Users</span> </div> <div class="legend-item"> <div class="legend-dot dot-sessions"></div> <span>Sessions</span> </div> </div> </div> <div class="tooltip" id="chartTooltip"> <div class="tooltip-date">April 15</div> <div class="tooltip-value"> <div class="tooltip-dot" style="background-color: var(--accent-blue)"></div> <span>Users: 3,245</span> </div> <div class="tooltip-value"> <div class="tooltip-dot" style="background-color: var(--accent-purple)"></div> <span>Sessions: 4,126</span> </div> </div> </div> </div> <div class="metric-row"> <div class="metric"> <div class="metric-label">Bounce Rate</div> <div class="metric-value">42.3%</div> </div> <div class="metric"> <div class="metric-label">Pages/Session</div> <div class="metric-value">3.8</div> </div> <div class="metric"> <div class="metric-label">Conversion Rate</div> <div class="metric-value">5.2%</div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Create simulated data const numDays = 30; const userData = []; const sessionData = []; // Generate random but realistic-looking data let userBase = Math.floor(Math.random() * 1000) + 2000; let sessionBase = userBase * (Math.random() * 0.5 + 1.1); for (let i = 0; i < numDays; i++) { // Add weekly patterns const dayOfWeek = i % 7; const weekendFactor = dayOfWeek >= 5 ? 0.8 : 1; // Add some random variation const userVariation = (Math.random() * 0.3 - 0.1) * userBase; const sessionVariation = (Math.random() * 0.3 - 0.1) * sessionBase; // Add slight upward trend const trendFactor = 1 + (i * 0.005); const userValue = Math.max(0, Math.round((userBase + userVariation) * weekendFactor * trendFactor)); const sessionValue = Math.max(0, Math.round((sessionBase + sessionVariation) * weekendFactor * trendFactor)); userData.push(userValue); sessionData.push(sessionValue); } // Create chart drawChart(userData, sessionData); // Make tabs interactive const tabs = document.querySelectorAll('.tab'); tabs.forEach(tab => { tab.addEventListener('click', function() { tabs.forEach(t => t.classList.remove('active')); this.classList.add('active'); }); }); // Date selector hover effect const dateSelector = document.querySelector('.date-selector'); dateSelector.addEventListener('mouseenter', function() { this.style.borderColor = 'var(--accent-blue)'; }); dateSelector.addEventListener('mouseleave', function() { this.style.borderColor = 'var(--border-color)'; }); // Add chart interactivity const chartSvg = document.getElementById('chartSvg'); const tooltip = document.getElementById('chartTooltip'); chartSvg.addEventListener('mousemove', function(e) { const rect = chartSvg.getBoundingClientRect(); const x = e.clientX - rect.left; const svgWidth = rect.width; // Calculate the day index based on mouse position const dayIndex = Math.floor((x / svgWidth) * (numDays - 1)); if (dayIndex >= 0 && dayIndex < numDays) { // Position tooltip tooltip.style.left = `${x + 10}px`; tooltip.style.top = `${e.clientY - rect.top - 60}px`; tooltip.style.opacity = '1'; // Update tooltip content const date = new Date(); date.setDate(date.getDate() - (numDays - 1) + dayIndex); const formattedDate = date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }); tooltip.querySelector('.tooltip-date').textContent = formattedDate; tooltip.querySelectorAll('.tooltip-value span')[0].textContent = `Users: ${userData[dayIndex].toLocaleString()}`; tooltip.querySelectorAll('.tooltip-value span')[1].textContent = `Sessions: ${sessionData[dayIndex].toLocaleString()}`; } }); chartSvg.addEventListener('mouseleave', function() { tooltip.style.opacity = '0'; }); }); function drawChart(userData, sessionData) { const svg = document.getElementById('chartSvg'); const width = svg.clientWidth || 600; const height = 180; const padding = { top: 20, right: 10, bottom: 30, left: 10 }; // Clear existing content svg.innerHTML = ''; // Calculate scales const xScale = (width - padding.left - padding.right) / (userData.length - 1); const allData = [...userData, ...sessionData]; const yMax = Math.max(...allData) * 1.1; // Add 10% padding at the top const yScale = (height - padding.top - padding.bottom) / yMax; // Create grid lines const gridLines = document.createElementNS('http://www.w3.org/2000/svg', 'g'); for (let i = 1; i <= 4; i++) { const y = height - padding.bottom - (i * (height - padding.top - padding.bottom) / 4); const line = document.createElementNS('http://www.w3.org/2000/svg', 'line'); line.setAttribute('x1', padding.left); line.setAttribute('y1', y); line.setAttribute('x2', width - padding.right); line.setAttribute('y2', y); line.setAttribute('stroke', 'var(--border-color)'); line.setAttribute('stroke-width', '1'); line.setAttribute('stroke-dasharray', '3,3'); gridLines.appendChild(line); } svg.appendChild(gridLines); // Generate path data for users let userPathData = ''; let userAreaData = ''; for (let i = 0; i < userData.length; i++) { const x = padding.left + i * xScale; const y = height - padding.bottom - (userData[i] * yScale); if (i === 0) { userPathData += `M ${x},${y}`; userAreaData += `M ${x},${height - padding.bottom} L ${x},${y}`; } else { userPathData += ` L ${x},${y}`; userAreaData += ` L ${x},${y}`; } } // Close the area path for users userAreaData += ` L ${padding.left + (userData.length - 1) * xScale},${height - padding.bottom} Z`; // Generate path data for sessions let sessionPathData = ''; let sessionAreaData = ''; for (let i = 0; i < sessionData.length; i++) { const x = padding.left + i * xScale; const y = height - padding.bottom - (sessionData[i] * yScale); if (i === 0) { sessionPathData += `M ${x},${y}`; sessionAreaData += `M ${x},${height - padding.bottom} L ${x},${y}`; } else { sessionPathData += ` L ${x},${y}`; sessionAreaData += ` L ${x},${y}`; } } // Close the area path for sessions sessionAreaData += ` L ${padding.left + (sessionData.length - 1) * xScale},${height - padding.bottom} Z`; // Create and add paths to SVG // Area under users line const userArea = document.createElementNS('http://www.w3.org/2000/svg', 'path'); userArea.setAttribute('d', userAreaData); userArea.setAttribute('class', 'users-area area'); svg.appendChild(userArea); // Area under sessions line const sessionArea = document.createElementNS('http://www.w3.org/2000/svg', 'path'); sessionArea.setAttribute('d', sessionAreaData); sessionArea.setAttribute('class', 'sessions-area area'); svg.appendChild(sessionArea); // Users line const userLine = document.createElementNS('http://www.w3.org/2000/svg', 'path'); userLine.setAttribute('d', userPathData); userLine.setAttribute('class', 'users-line data-line'); svg.appendChild(userLine); // Sessions line const sessionLine = document.createElementNS('http://www.w3.org/2000/svg', 'path'); sessionLine.setAttribute('d', sessionPathData); sessionLine.setAttribute('class', 'sessions-line data-line'); svg.appendChild(sessionLine); // Add data points const pointsGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g'); for (let i = 0; i < userData.length; i += 5) { // Add points every 5 days // User data point const userPoint = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); userPoint.setAttribute('cx', padding.left + i * xScale); userPoint.setAttribute('cy', height - padding.bottom - (userData[i] * yScale)); userPoint.setAttribute('r', '3'); userPoint.setAttribute('fill', 'var(--accent-blue)'); userPoint.setAttribute('stroke', 'white'); userPoint.setAttribute('stroke-width', '1.5'); pointsGroup.appendChild(userPoint); // Session data point const sessionPoint = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); sessionPoint.setAttribute('cx', padding.left + i * xScale); sessionPoint.setAttribute('cy', height - padding.bottom - (sessionData[i] * yScale)); sessionPoint.setAttribute('r', '3'); sessionPoint.setAttribute('fill', 'var(--accent-purple)'); sessionPoint.setAttribute('stroke', 'white'); sessionPoint.setAttribute('stroke-width', '1.5'); pointsGroup.appendChild(sessionPoint); } svg.appendChild(pointsGroup); } // Add a fancy hover effect to metrics document.querySelectorAll('.metric').forEach(metric => { metric.addEventListener('mouseenter', function() { this.style.background = `radial-gradient(circle at ${Math.random() * 100}% ${Math.random() * 100}%, var(--card-bg), var(--bg-primary))`; }); metric.addEventListener('mouseleave', function() { this.style.background = 'var(--card-bg)'; }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> /* CSS Reset and Base Styles */ * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; } body { background: #0a0a14; color: #fff; min-height: 700px; display: flex; flex-direction: column; justify-content: center; align-items: center; overflow-x: hidden; padding: 20px; } .container { width: 100%; max-width: 700px; margin: 0 auto; } .header { text-align: center; margin-bottom: 30px; } .header h1 { font-size: 2.5rem; font-weight: 700; margin-bottom: 10px; background: linear-gradient(to right, #ff4dff, #00c8ff); -webkit-background-clip: text; background-clip: text; color: transparent; animation: gradientShift 5s infinite alternate; } .header p { font-size: 1rem; opacity: 0.8; max-width: 500px; margin: 0 auto; line-height: 1.5; } .products { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 25px; margin-bottom: 30px; } .product-card { position: relative; background: rgba(15, 15, 30, 0.6); border-radius: 15px; padding: 20px; transition: transform 0.3s ease; overflow: hidden; cursor: pointer; backdrop-filter: blur(5px); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); z-index: 1; } .product-card::before { content: ''; position: absolute; top: 100%; left: 50%; transform: translate(-50%, -50%) scale(0); width: 150%; height: 250%; background: radial-gradient( circle, rgba(255, 77, 255, 0.2) 0%, rgba(0, 200, 255, 0.2) 50%, rgba(15, 15, 30, 0) 100% ); z-index: -1; opacity: 0; transition: transform 0.6s ease-out, opacity 0.6s ease-out, top 0.6s ease-out; border-radius: 50%; } .product-card:hover { transform: translateY(-5px); } .product-card:hover::before { top: 50%; opacity: 1; transform: translate(-50%, -50%) scale(1); } .product-image { width: 100%; height: 150px; object-fit: cover; border-radius: 10px; margin-bottom: 15px; transition: transform 0.5s ease; filter: saturate(0.9); } .product-card:hover .product-image { transform: scale(1.05); filter: saturate(1.1); } .product-title { font-size: 1rem; font-weight: 600; margin-bottom: 5px; transition: color 0.3s ease; } .product-card:hover .product-title { color: #00c8ff; } .product-price { font-size: 1.2rem; font-weight: 700; margin-bottom: 12px; color: #ff4dff; } .product-desc { font-size: 0.8rem; opacity: 0.7; margin-bottom: 15px; line-height: 1.4; } .add-to-cart { background: linear-gradient(to right, #ff4dff, #00c8ff); color: #fff; border: none; padding: 8px 15px; border-radius: 20px; font-size: 0.8rem; font-weight: 600; cursor: pointer; transition: all 0.3s ease; width: 100%; position: relative; overflow: hidden; z-index: 1; } .add-to-cart::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(to right, #00c8ff, #ff4dff); transition: left 0.3s ease; z-index: -1; } .add-to-cart:hover::before { left: 0; } .featured-block { position: relative; background: rgba(15, 15, 30, 0.6); border-radius: 15px; padding: 25px; margin-top: 20px; overflow: hidden; display: flex; flex-direction: column; justify-content: center; backdrop-filter: blur(5px); box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3); min-height: 120px; } .featured-block::before { content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background: conic-gradient( from 0deg, transparent 0%, rgba(0, 200, 255, 0.1) 25%, rgba(255, 77, 255, 0.1) 50%, transparent 75% ); animation: rotateGradient 10s linear infinite; z-index: -1; } .featured-title { font-size: 1.3rem; margin-bottom: 15px; background: linear-gradient(to right, #ff4dff, #00c8ff); -webkit-background-clip: text; background-clip: text; color: transparent; display: inline-block; } .featured-text { font-size: 0.9rem; line-height: 1.6; opacity: 0.8; } .blob { position: absolute; border-radius: 50%; filter: blur(40px); opacity: 0.15; z-index: -2; animation: float 10s ease-in-out infinite; } .blob-1 { width: 300px; height: 300px; background: #ff4dff; top: -100px; right: -150px; animation-delay: 0s; } .blob-2 { width: 250px; height: 250px; background: #00c8ff; bottom: -80px; left: -100px; animation-delay: -3s; } .blob-3 { width: 200px; height: 200px; background: #864cff; top: 50%; left: 20%; animation-delay: -6s; } .product-tag { position: absolute; top: 15px; right: 15px; background: rgba(255, 77, 255, 0.8); color: white; font-size: 0.7rem; padding: 3px 8px; border-radius: 10px; font-weight: 600; z-index: 2; } .glow-effect { position: absolute; width: 0; height: 0; border-radius: 50%; background: radial-gradient( circle, rgba(255, 77, 255, 0.4) 0%, rgba(0, 200, 255, 0.4) 50%, transparent 70% ); transform: translate(-50%, -50%); pointer-events: none; opacity: 0; z-index: -1; transition: width 0.5s ease, height 0.5s ease, opacity 0.5s ease; } @keyframes float { 0%, 100% { transform: translateY(0) scale(1); } 50% { transform: translateY(-20px) scale(1.05); } } @keyframes rotateGradient { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } @keyframes gradientShift { 0% { background-position: 0% 50%; } 100% { background-position: 100% 50%; } } /* Responsive Adjustments */ @media (max-width: 600px) { .header h1 { font-size: 2rem; } .products { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 15px; } .product-card { padding: 15px; } .product-image { height: 120px; } .featured-block { padding: 20px; } } </style> </head> <body> <div class="container"> <div class="header"> <h1>NEONOVA</h1> <p>Explore our cutting-edge tech collection with interactive hover effects that bring products to life</p> </div> <div class="products"> <div class="product-card"> <span class="product-tag">NEW</span> <img src="https://images.unsplash.com/photo-1511025998370-7d2c1d17c7b8?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=400&q=80" alt="Quantum Earbuds" class="product-image"> <h3 class="product-title">Quantum Earbuds Pro</h3> <p class="product-price">$149.99</p> <p class="product-desc">Spatial audio with adaptive EQ and active noise cancellation technology</p> <button class="add-to-cart">Add to Cart</button> </div> <div class="product-card"> <img src="https://images.unsplash.com/photo-1593121925328-369cc8459c08?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=400&q=80" alt="NeoSync Watch" class="product-image"> <h3 class="product-title">NeoSync Watch</h3> <p class="product-price">$299.99</p> <p class="product-desc">Biometric tracking with holographic display and gesture controls</p> <button class="add-to-cart">Add to Cart</button> </div> <div class="product-card"> <span class="product-tag">SALE</span> <img src="https://images.unsplash.com/photo-1505740420928-5e560c06d30e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=400&q=80" alt="Pulse Headphones" class="product-image"> <h3 class="product-title">Pulse Headphones</h3> <p class="product-price">$179.99</p> <p class="product-desc">Immersive audio with reactive light sync and 36-hour battery</p> <button class="add-to-cart">Add to Cart</button> </div> </div> <div class="featured-block"> <h3 class="featured-title">ECLIPSE COMING SOON</h3> <p class="featured-text">Our most advanced AR glasses with neural interface controls, 8K projection, and all-day comfort design. Join the waitlist for exclusive early access.</p> </div> </div> <div class="blob blob-1"></div> <div class="blob blob-2"></div> <div class="blob blob-3"></div> <div class="glow-effect"></div> <script> // Interactive glow effect that follows the cursor document.addEventListener('DOMContentLoaded', function() { const glowEffect = document.querySelector('.glow-effect'); const container = document.querySelector('.container'); container.addEventListener('mousemove', function(e) { const containerRect = container.getBoundingClientRect(); const mouseX = e.clientX - containerRect.left; const mouseY = e.clientY - containerRect.top; glowEffect.style.width = '300px'; glowEffect.style.height = '300px'; glowEffect.style.opacity = '1'; glowEffect.style.left = `${mouseX}px`; glowEffect.style.top = `${mouseY}px`; }); container.addEventListener('mouseleave', function() { glowEffect.style.width = '0'; glowEffect.style.height = '0'; glowEffect.style.opacity = '0'; }); // Product card hover effect enhancer const productCards = document.querySelectorAll('.product-card'); productCards.forEach(card => { card.addEventListener('mouseenter', function() { this.style.zIndex = '10'; // Create a dynamic blob for each card hover const blob = document.createElement('div'); blob.classList.add('hover-blob'); blob.style.position = 'absolute'; blob.style.width = '120%'; blob.style.height = '120%'; blob.style.top = '-10%'; blob.style.left = '-10%'; blob.style.borderRadius = '30% 70% 70% 30% / 30% 30% 70% 70%'; blob.style.background = 'radial-gradient(circle, rgba(255,77,255,0.15) 0%, rgba(0,200,255,0.1) 100%)'; blob.style.filter = 'blur(15px)'; blob.style.zIndex = '-1'; blob.style.animation = 'morphBlob 3s linear infinite alternate'; // Add keyframes for the blob animation const styleSheet = document.styleSheets[0]; const keyframes = ` @keyframes morphBlob { 0% { border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%; } 25% { border-radius: 50% 50% 30% 70% / 60% 40% 60% 40%; } 50% { border-radius: 70% 30% 50% 50% / 40% 60% 40% 60%; } 75% { border-radius: 40% 60% 70% 30% / 30% 70% 30% 70%; } 100% { border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%; } }`; if (!document.querySelector('style#blob-animation')) { const style = document.createElement('style'); style.id = 'blob-animation'; style.textContent = keyframes; document.head.appendChild(style); } // Clear any existing hover blobs in this card const existingBlobs = this.querySelectorAll('.hover-blob'); existingBlobs.forEach(blob => blob.remove()); this.appendChild(blob); // Add subtle movement to the card content const productTitle = this.querySelector('.product-title'); const productPrice = this.querySelector('.product-price'); const addToCartBtn = this.querySelector('.add-to-cart'); if (productTitle) productTitle.style.transform = 'translateY(-2px)'; if (productPrice) productPrice.style.transform = 'scale(1.05)'; if (addToCartBtn) { addToCartBtn.style.boxShadow = '0 0 15px rgba(255, 77, 255, 0.5)'; addToCartBtn.style.transform = 'translateY(-2px)'; } }); card.addEventListener('mouseleave', function() { this.style.zIndex = '1'; // Remove the hover blob const blob = this.querySelector('.hover-blob'); if (blob) { blob.style.opacity = '0'; setTimeout(() => { blob.remove(); }, 300); } // Reset card content const productTitle = this.querySelector('.product-title'); const productPrice = this.querySelector('.product-price'); const addToCartBtn = this.querySelector('.add-to-cart'); if (productTitle) productTitle.style.transform = 'translateY(0)'; if (productPrice) productPrice.style.transform = 'scale(1)'; if (addToCartBtn) { addToCartBtn.style.boxShadow = 'none'; addToCartBtn.style.transform = 'translateY(0)'; } }); }); // Add to cart interaction const addToCartBtns = document.querySelectorAll('.add-to-cart'); addToCartBtns.forEach(btn => { btn.addEventListener('click', function(e) { e.preventDefault(); // Original text const originalText = this.textContent; // Change button text and add animation this.textContent = 'Added ✓'; this.style.background = 'linear-gradient(to right, #00c8ff, #864cff)'; this.style.boxShadow = '0 0 20px rgba(0, 200, 255, 0.7)'; // Create ripple effect const ripple = document.createElement('span'); ripple.classList.add('ripple'); ripple.style.position = 'absolute'; ripple.style.top = '50%'; ripple.style.left = '50%'; ripple.style.transform = 'translate(-50%, -50%)'; ripple.style.width = '0'; ripple.style.height = '0'; ripple.style.background = 'rgba(255, 255, 255, 0.7)'; ripple.style.borderRadius = '50%'; ripple.style.zIndex = '1'; this.style.position = 'relative'; this.style.overflow = 'hidden'; this.appendChild(ripple); // Animate ripple ripple.animate( [ { width: '0', height: '0', opacity: 1 }, { width: '200px', height: '200px', opacity: 0 } ], { duration: 600, easing: 'ease-out' } ).onfinish = function() { ripple.remove(); }; // Reset button after delay setTimeout(() => { this.textContent = originalText; this.style.background = 'linear-gradient(to right, #ff4dff, #00c8ff)'; this.style.boxShadow = 'none'; }, 1500); }); }); }); </script> </body> </html>
<html> <head> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Cormorant Garamond', serif; color: #333; } body { background-color: #FAF7F2; overflow: hidden; height: 100vh; width: 100%; position: relative; } .canvas-container { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 1; pointer-events: none; } .portfolio-wrapper { position: relative; height: 100%; width: 100%; overflow-y: auto; overflow-x: hidden; z-index: 5; padding: 40px 20px; display: flex; flex-direction: column; align-items: center; } header { margin-bottom: 40px; text-align: center; position: relative; z-index: 10; } .artist-name { font-size: 42px; font-weight: 300; letter-spacing: 3px; margin-bottom: 10px; text-transform: lowercase; position: relative; display: inline-block; } .artist-name::after { content: ''; position: absolute; bottom: -5px; left: 50%; transform: translateX(-50%); width: 80px; height: 1px; background-color: #333; } .artist-title { font-size: 16px; font-weight: 300; letter-spacing: 1px; margin-top: 10px; font-style: italic; } .gallery { display: grid; grid-template-columns: repeat(2, 1fr); gap: 25px; width: 100%; max-width: 650px; margin: 0 auto; } .artwork { position: relative; overflow: hidden; border-radius: 3px; box-shadow: 0 5px 15px rgba(0,0,0,0.05); transition: transform 0.5s ease, box-shadow 0.5s ease; cursor: pointer; aspect-ratio: 1/1; } .artwork:hover { transform: translateY(-8px); box-shadow: 0 12px 25px rgba(0,0,0,0.1); } .artwork img { width: 100%; height: 100%; object-fit: cover; transition: all 0.5s ease; } .artwork:hover img { transform: scale(1.05); } .artwork-info { position: absolute; bottom: 0; left: 0; width: 100%; padding: 15px; background: rgba(255, 255, 255, 0.85); transform: translateY(100%); transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1); display: flex; flex-direction: column; } .artwork:hover .artwork-info { transform: translateY(0); } .artwork-title { font-size: 18px; margin-bottom: 5px; font-weight: 500; } .artwork-medium { font-size: 14px; font-style: italic; color: #666; } .contact-btn { margin-top: 40px; background: transparent; border: 1px solid #333; padding: 12px 30px; font-size: 14px; letter-spacing: 2px; text-transform: uppercase; cursor: pointer; transition: all 0.3s ease; position: relative; overflow: hidden; z-index: 10; } .contact-btn::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: #333; transition: all 0.4s ease; z-index: -1; } .contact-btn:hover { color: #FAF7F2; } .contact-btn:hover::before { left: 0; } footer { margin-top: auto; text-align: center; padding-top: 20px; font-size: 12px; letter-spacing: 1px; color: #888; } .social-links { display: flex; justify-content: center; gap: 15px; margin-bottom: 15px; } .social-links a { color: #888; transition: color 0.3s ease; text-decoration: none; } .social-links a:hover { color: #333; } @media (max-width: 600px) { .gallery { grid-template-columns: 1fr; max-width: 350px; } .artist-name { font-size: 32px; } } .modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.8); display: flex; justify-content: center; align-items: center; z-index: 100; opacity: 0; pointer-events: none; transition: opacity 0.3s ease; } .modal.active { opacity: 1; pointer-events: all; } .modal-content { max-width: 80%; max-height: 80%; position: relative; background-color: white; padding: 20px; border-radius: 5px; box-shadow: 0 5px 30px rgba(0, 0, 0, 0.2); } .modal-close { position: absolute; top: 10px; right: 10px; background: none; border: none; font-size: 24px; cursor: pointer; color: #333; } .modal-img { max-width: 100%; max-height: 65vh; display: block; margin: 0 auto; } .modal-info { margin-top: 15px; text-align: center; } .modal-title { font-size: 22px; margin-bottom: 5px; } .modal-medium { font-style: italic; margin-bottom: 10px; color: #666; } .modal-desc { font-size: 14px; line-height: 1.6; max-width: 500px; margin: 0 auto; } .contact-form { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%) scale(0.9); width: 90%; max-width: 500px; background: #FAF7F2; z-index: 1000; padding: 30px; border-radius: 5px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); opacity: 0; pointer-events: none; transition: all 0.4s ease; } .contact-form.active { opacity: 1; pointer-events: all; transform: translate(-50%, -50%) scale(1); } .form-header { text-align: center; margin-bottom: 25px; } .form-title { font-size: 28px; margin-bottom: 10px; } .form-subtitle { font-size: 14px; color: #666; } .form-group { margin-bottom: 20px; } .form-label { display: block; margin-bottom: 8px; font-size: 14px; } .form-input, .form-textarea { width: 100%; padding: 12px; border: 1px solid #ddd; border-radius: 4px; background: white; font-size: 14px; transition: border-color 0.3s; } .form-input:focus, .form-textarea:focus { border-color: #888; outline: none; } .form-textarea { resize: vertical; min-height: 100px; } .form-submit { background: #333; color: white; border: none; padding: 12px 25px; border-radius: 4px; cursor: pointer; font-size: 14px; letter-spacing: 1px; transition: background 0.3s; width: 100%; } .form-submit:hover { background: #555; } .form-close { position: absolute; top: 15px; right: 15px; background: none; border: none; font-size: 20px; cursor: pointer; color: #333; } .overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); z-index: 999; opacity: 0; pointer-events: none; transition: opacity 0.3s; } .overlay.active { opacity: 1; pointer-events: all; } </style> <link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@300;400;500;600&display=swap" rel="stylesheet"> </head> <body> <div class="canvas-container"> <canvas id="blobCanvas"></canvas> </div> <div class="portfolio-wrapper"> <header> <h1 class="artist-name">Clara Moreau</h1> <p class="artist-title">Watercolor & Mixed Media Artist</p> </header> <div class="gallery"> <div class="artwork" data-title="Ephemeral Bloom" data-medium="Watercolor on Cotton Paper" data-desc="Inspired by the fleeting nature of spring blossoms, this piece explores the delicate balance between permanence and transition."> <img src="https://images.unsplash.com/photo-1579783902614-a3fb3927b6a5?ixlib=rb-4.0.3&auto=format&fit=crop&w=500&q=80" alt="Ephemeral Bloom artwork"> <div class="artwork-info"> <h3 class="artwork-title">Ephemeral Bloom</h3> <p class="artwork-medium">Watercolor on Cotton Paper</p> </div> </div> <div class="artwork" data-title="Coastal Whispers" data-medium="Mixed Media on Canvas" data-desc="A meditation on the dialogue between sea and shore, capturing the rhythmic conversation of waves against the coastline."> <img src="https://images.unsplash.com/photo-1615529162924-f8605388461d?ixlib=rb-4.0.3&auto=format&fit=crop&w=500&q=80" alt="Coastal Whispers artwork"> <div class="artwork-info"> <h3 class="artwork-title">Coastal Whispers</h3> <p class="artwork-medium">Mixed Media on Canvas</p> </div> </div> <div class="artwork" data-title="Morning Mist" data-medium="Ink and Watercolor" data-desc="Capturing the ethereal quality of dawn as it breaks through the valley, merging abstract elements with recognizable landscape forms."> <img src="https://images.unsplash.com/photo-1574922288100-77e11e395d4b?ixlib=rb-4.0.3&auto=format&fit=crop&w=500&q=80" alt="Morning Mist artwork"> <div class="artwork-info"> <h3 class="artwork-title">Morning Mist</h3> <p class="artwork-medium">Ink and Watercolor</p> </div> </div> <div class="artwork" data-title="Remembered Places" data-medium="Gouache and Gold Leaf" data-desc="An exploration of memory as a living, evolving entity, layered with fragments of places both visited and imagined."> <img src="https://images.unsplash.com/photo-1578301978069-46e7abd77aac?ixlib=rb-4.0.3&auto=format&fit=crop&w=500&q=80" alt="Remembered Places artwork"> <div class="artwork-info"> <h3 class="artwork-title">Remembered Places</h3> <p class="artwork-medium">Gouache and Gold Leaf</p> </div> </div> </div> <button class="contact-btn">Commission Artwork</button> <footer> <div class="social-links"> <a href="#" title="Instagram">Instagram</a> <a href="#" title="Pinterest">Pinterest</a> <a href="#" title="Artsy">Artsy</a> </div> <p>© 2023 Clara Moreau | Hand-crafted watercolor narratives</p> </footer> </div> <div class="modal" id="artworkModal"> <div class="modal-content"> <button class="modal-close">×</button> <img class="modal-img" src="" alt="Artwork detail"> <div class="modal-info"> <h3 class="modal-title"></h3> <p class="modal-medium"></p> <p class="modal-desc"></p> </div> </div> </div> <div class="overlay" id="formOverlay"></div> <div class="contact-form" id="contactForm"> <button class="form-close">×</button> <div class="form-header"> <h2 class="form-title">Commission a Piece</h2> <p class="form-subtitle">Share your vision, and we'll create something unique together</p> </div> <div class="form-group"> <label class="form-label" for="name">Name</label> <input type="text" id="name" class="form-input" required> </div> <div class="form-group"> <label class="form-label" for="email">Email</label> <input type="email" id="email" class="form-input" required> </div> <div class="form-group"> <label class="form-label" for="message">Your Vision</label> <textarea id="message" class="form-textarea" placeholder="Tell me about the artwork you envision..." required></textarea> </div> <button class="form-submit" id="submitForm">Send Message</button> </div> <script> // Blob Canvas Background const canvas = document.getElementById('blobCanvas'); const ctx = canvas.getContext('2d'); let width, height; let blobs = []; function resizeCanvas() { width = canvas.width = window.innerWidth; height = canvas.height = window.innerHeight; // Recreate blobs when canvas is resized initBlobs(); } class Blob { constructor(x, y, radius, color) { this.x = x; this.y = y; this.radius = radius; this.color = color; this.angle = Math.random() * Math.PI * 2; this.velocity = 0.001 + Math.random() * 0.002; this.lastX = x; this.lastY = y; this.startSize = radius; this.targetSize = radius; this.sizeVelocity = 0.02; this.active = false; } update() { // Move in a slight circular motion this.angle += this.velocity; this.x = this.lastX + Math.cos(this.angle) * 10; this.y = this.lastY + Math.sin(this.angle) * 10; // Smoothly adjust size if (this.radius < this.targetSize) { this.radius += (this.targetSize - this.radius) * this.sizeVelocity; } else if (this.radius > this.targetSize) { this.radius -= (this.radius - this.targetSize) * this.sizeVelocity; } } draw() { ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2); ctx.fillStyle = this.color; ctx.globalAlpha = 0.5; ctx.fill(); ctx.globalAlpha = 1; } expand() { this.targetSize = this.startSize * 1.5; this.active = true; } contract() { this.targetSize = this.startSize; this.active = false; } } function initBlobs() { blobs = []; // Create 5 different colored blobs const colors = [ 'rgba(220, 180, 200, 0.25)', // Soft pink 'rgba(180, 200, 220, 0.2)', // Soft blue 'rgba(200, 220, 180, 0.2)', // Soft green 'rgba(220, 200, 160, 0.25)', // Soft yellow 'rgba(180, 180, 220, 0.2)' // Soft purple ]; for (let i = 0; i < 5; i++) { const x = Math.random() * width; const y = Math.random() * height; const radius = 50 + Math.random() * 150; blobs.push(new Blob(x, y, radius, colors[i])); } } function animate() { ctx.clearRect(0, 0, width, height); blobs.forEach(blob => { blob.update(); blob.draw(); }); requestAnimationFrame(animate); } // Initialize and start the animation resizeCanvas(); animate(); // Update canvas when window is resized window.addEventListener('resize', resizeCanvas); // Make blobs responsive to mouse movement document.addEventListener('mousemove', e => { blobs.forEach(blob => { const dx = e.clientX - blob.x; const dy = e.clientY - blob.y; const distance = Math.sqrt(dx * dx + dy * dy); if (distance < 150 && !blob.active) { blob.expand(); } else if (distance >= 150 && blob.active) { blob.contract(); } }); }); // Artwork modal functionality const artworks = document.querySelectorAll('.artwork'); const modal = document.getElementById('artworkModal'); const modalImg = modal.querySelector('.modal-img'); const modalTitle = modal.querySelector('.modal-title'); const modalMedium = modal.querySelector('.modal-medium'); const modalDesc = modal.querySelector('.modal-desc'); const modalClose = modal.querySelector('.modal-close'); artworks.forEach(artwork => { artwork.addEventListener('click', () => { modalImg.src = artwork.querySelector('img').src; modalTitle.textContent = artwork.dataset.title; modalMedium.textContent = artwork.dataset.medium; modalDesc.textContent = artwork.dataset.desc; modal.classList.add('active'); }); }); modalClose.addEventListener('click', () => { modal.classList.remove('active'); }); // Close modal when clicking outside the content modal.addEventListener('click', e => { if (e.target === modal) { modal.classList.remove('active'); } }); // Contact form functionality const contactBtn = document.querySelector('.contact-btn'); const contactForm = document.getElementById('contactForm'); const formOverlay = document.getElementById('formOverlay'); const formClose = document.querySelector('.form-close'); const submitForm = document.getElementById('submitForm'); contactBtn.addEventListener('click', () => { contactForm.classList.add('active'); formOverlay.classList.add('active'); }); formClose.addEventListener('click', () => { contactForm.classList.remove('active'); formOverlay.classList.remove('active'); }); formOverlay.addEventListener('click', () => { contactForm.classList.remove('active'); formOverlay.classList.remove('active'); }); submitForm.addEventListener('click', e => { e.preventDefault(); // Show a thank you message instead of submitting const nameInput = document.getElementById('name'); contactForm.innerHTML = ` <div style="text-align: center; padding: 40px 20px;"> <h2 style="margin-bottom: 15px; font-size: 28px;">Thank you, ${nameInput.value}!</h2> <p style="line-height: 1.6;">Your message has been received. I'll be in touch within 48 hours to discuss your commission.</p> <button id="closeThankYou" style="margin-top: 30px; background: #333; color: white; border: none; padding: 10px 20px; cursor: pointer;">Close</button> </div> `; document.getElementById('closeThankYou').addEventListener('click', () => { contactForm.classList.remove('active'); formOverlay.classList.remove('active'); // Reset the form after it's closed setTimeout(() => { contactForm.innerHTML = ` <button class="form-close">×</button> <div class="form-header"> <h2 class="form-title">Commission a Piece</h2> <p class="form-subtitle">Share your vision, and we'll create something unique together</p> </div> <div class="form-group"> <label class="form-label" for="name">Name</label> <input type="text" id="name" class="form-input" required> </div> <div class="form-group"> <label class="form-label" for="email">Email</label> <input type="email" id="email" class="form-input" required> </div> <div class="form-group"> <label class="form-label" for="message">Your Vision</label> <textarea id="message" class="form-textarea" placeholder="Tell me about the artwork you envision..." required></textarea> </div> <button class="form-submit" id="submitForm">Send Message</button> `; // Reattach event listeners document.querySelector('.form-close').addEventListener('click', () => { contactForm.classList.remove('active'); formOverlay.classList.remove('active'); }); document.getElementById('submitForm').addEventListener('click', e => { // The same submit handler submitForm.addEventListener('click', e => { e.preventDefault(); // Show a thank you message instead of submitting const nameInput = document.getElementById('name'); contactForm.innerHTML = ` <div style="text-align: center; padding: 40px 20px;"> <h2 style="margin-bottom: 15px; font-size: 28px;">Thank you, ${nameInput.value}!</h2> <p style="line-height: 1.6;">Your message has been received. I'll be in touch within 48 hours to discuss your commission.</p> <button id="closeThankYou" style="margin-top: 30px; background: #333; color: white; border: none; padding: 10px 20px; cursor: pointer;">Close</button> </div> `; }); }); }, 500); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Fluid Identity | Brand Signature</title> <style> :root { --primary-color: #1a2456; --secondary-color: #ff6b6b; --bg-color: #f8f9fa; --text-color: #1a2456; --transition: all 0.5s cubic-bezier(0.645, 0.045, 0.355, 1); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; } body { background-color: var(--bg-color); color: var(--text-color); overflow-x: hidden; height: 100%; width: 100%; } .container { max-width: 700px; height: 700px; margin: 0 auto; padding: 2rem; position: relative; overflow: hidden; display: flex; flex-direction: column; justify-content: center; } .blob-container { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: -1; overflow: hidden; } .blob { position: absolute; width: 500px; height: 500px; filter: blur(30px); opacity: 0.6; border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%; background: var(--secondary-color); animation: blob-animation 20s ease-in-out infinite alternate; transition: var(--transition); } .blob-1 { top: -20%; left: -20%; animation-delay: 0s; } .blob-2 { bottom: -30%; right: -20%; animation-delay: 5s; background: var(--primary-color); } @keyframes blob-animation { 0% { border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%; transform: scale(1) rotate(0deg); } 33% { border-radius: 70% 30% 50% 50% / 30% 60% 40% 70%; transform: scale(1.1) rotate(60deg); } 66% { border-radius: 40% 60% 70% 30% / 50% 60% 30% 50%; transform: scale(0.9) rotate(120deg); } 100% { border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%; transform: scale(1) rotate(180deg); } } .content { display: flex; flex-direction: column; gap: 2rem; z-index: 1; position: relative; } .header { text-align: center; margin-bottom: 2rem; } .logo { font-size: 2.5rem; font-weight: 800; letter-spacing: -1px; margin-bottom: 0.5rem; background: linear-gradient(45deg, var(--primary-color), var(--secondary-color)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; position: relative; display: inline-block; } .tagline { font-size: 1rem; font-weight: 400; opacity: 0.8; letter-spacing: 1px; text-transform: uppercase; } .section { background: rgba(255, 255, 255, 0.85); backdrop-filter: blur(10px); border-radius: 16px; padding: 2rem; margin-bottom: 2rem; box-shadow: 0 4px 30px rgba(0, 0, 0, 0.04); border: 1px solid rgba(255, 255, 255, 0.6); transform: translateY(20px); opacity: 0; transition: var(--transition); } .section.visible { transform: translateY(0); opacity: 1; } h2 { font-size: 1.5rem; margin-bottom: 1rem; position: relative; display: inline-block; } h2::after { content: ''; position: absolute; bottom: -5px; left: 0; width: 40px; height: 3px; background: var(--secondary-color); transition: var(--transition); } h2:hover::after { width: 100%; } p { line-height: 1.6; margin-bottom: 1rem; font-size: 0.95rem; } .features { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 1rem; margin-top: 1.5rem; } .feature-item { text-align: center; padding: 1rem; border-radius: 12px; background: rgba(255, 255, 255, 0.5); transition: var(--transition); cursor: pointer; } .feature-item:hover { background: var(--primary-color); color: white; transform: translateY(-5px); } .feature-icon { font-size: 1.5rem; margin-bottom: 0.5rem; } .feature-title { font-size: 0.85rem; font-weight: 600; } .cta-container { display: flex; justify-content: center; margin-top: 2rem; } .cta-button { background: var(--primary-color); color: white; border: none; padding: 0.8rem 1.5rem; border-radius: 30px; font-weight: 600; font-size: 0.9rem; cursor: pointer; transition: var(--transition); position: relative; overflow: hidden; z-index: 1; } .cta-button::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: var(--secondary-color); transition: var(--transition); z-index: -1; } .cta-button:hover::before { left: 0; } .cta-button:hover { box-shadow: 0 5px 15px rgba(255, 107, 107, 0.4); } .cursor-follower { position: fixed; width: 20px; height: 20px; background: var(--secondary-color); border-radius: 50%; pointer-events: none; mix-blend-mode: difference; z-index: 9999; opacity: 0.7; transition: transform 0.2s ease; transform: translate(-50%, -50%) scale(1); } .progress-container { position: fixed; top: 0; left: 0; width: 100%; height: 3px; background: transparent; z-index: 100; } .progress-bar { height: 100%; background: linear-gradient(90deg, var(--primary-color), var(--secondary-color)); width: 0%; transition: width 0.2s ease; } @media (max-width: 600px) { .container { padding: 1.5rem; height: auto; } .blob { width: 300px; height: 300px; } .logo { font-size: 2rem; } .features { grid-template-columns: repeat(2, 1fr); } .section { padding: 1.5rem; } } </style> </head> <body> <div class="cursor-follower"></div> <div class="progress-container"> <div class="progress-bar"></div> </div> <div class="container"> <div class="blob-container"> <div class="blob blob-1"></div> <div class="blob blob-2"></div> </div> <div class="content"> <div class="header"> <div class="logo">FluidForms</div> <div class="tagline">Shaping Digital Identities</div> </div> <div class="section" id="section1"> <h2>Morphing Identity</h2> <p>Our brand signature embraces the ever-changing nature of modern identity. Like the continuous morphing blobs that represent us, we adapt, flow, and transform while maintaining our core essence.</p> <p>The dual-tone visual language speaks to the duality of stability and change that defines our approach.</p> </div> <div class="section" id="section2"> <h2>Fluid Experience</h2> <p>The seamless transitions between states mirror our commitment to frictionless experiences. Each transformation is deliberate yet natural—just like our design philosophy.</p> <div class="features"> <div class="feature-item"> <div class="feature-icon">⟳</div> <div class="feature-title">Continuous Flow</div> </div> <div class="feature-item"> <div class="feature-icon">⬗</div> <div class="feature-title">Adaptive Form</div> </div> <div class="feature-item"> <div class="feature-icon">⬡</div> <div class="feature-title">Dual Harmony</div> </div> </div> </div> <div class="section" id="section3"> <h2>Our Approach</h2> <p>The morphing blob isn't just a visual element—it's our design philosophy manifested. We believe in creating spaces that evolve with the user, interfaces that breathe, and experiences that feel organic.</p> <div class="cta-container"> <button class="cta-button">Explore Our Universe</button> </div> </div> </div> </div> <script> // Cursor follower effect const cursorFollower = document.querySelector('.cursor-follower'); const buttons = document.querySelectorAll('button'); const features = document.querySelectorAll('.feature-item'); const headings = document.querySelectorAll('h2'); document.addEventListener('mousemove', (e) => { const { clientX, clientY } = e; cursorFollower.style.transform = `translate(${clientX}px, ${clientY}px) scale(1)`; }); document.addEventListener('mousedown', () => { cursorFollower.style.transform += ' scale(0.7)'; }); document.addEventListener('mouseup', () => { cursorFollower.style.transform = cursorFollower.style.transform.replace(' scale(0.7)', ''); }); buttons.forEach(button => { button.addEventListener('mouseenter', () => { cursorFollower.style.transform += ' scale(2.5)'; cursorFollower.style.opacity = '0.4'; }); button.addEventListener('mouseleave', () => { cursorFollower.style.transform = cursorFollower.style.transform.replace(' scale(2.5)', ''); cursorFollower.style.opacity = '0.7'; }); }); features.forEach(feature => { feature.addEventListener('mouseenter', () => { cursorFollower.style.transform += ' scale(1.8)'; cursorFollower.style.opacity = '0.5'; }); feature.addEventListener('mouseleave', () => { cursorFollower.style.transform = cursorFollower.style.transform.replace(' scale(1.8)', ''); cursorFollower.style.opacity = '0.7'; }); }); headings.forEach(heading => { heading.addEventListener('mouseenter', () => { cursorFollower.style.transform += ' scale(1.5)'; }); heading.addEventListener('mouseleave', () => { cursorFollower.style.transform = cursorFollower.style.transform.replace(' scale(1.5)', ''); }); }); // Scroll progress bar window.addEventListener('scroll', () => { const scrollTop = window.scrollY || document.documentElement.scrollTop; const scrollHeight = document.documentElement.scrollHeight - document.documentElement.clientHeight; const scrollPercentage = (scrollTop / scrollHeight) * 100; document.querySelector('.progress-bar').style.width = `${scrollPercentage}%`; }); // Animation on scroll const sections = document.querySelectorAll('.section'); function checkVisibility() { sections.forEach(section => { const sectionTop = section.getBoundingClientRect().top; const windowHeight = window.innerHeight; if (sectionTop < windowHeight * 0.85) { section.classList.add('visible'); } }); } // Initial check checkVisibility(); // Check on scroll window.addEventListener('scroll', checkVisibility); // Random blob morphing const blobs = document.querySelectorAll('.blob'); function randomizeBlobShape(blob) { const randomRadius = () => `${Math.floor(30 + Math.random() * 50)}% ${Math.floor(30 + Math.random() * 50)}% ${Math.floor(30 + Math.random() * 50)}% ${Math.floor(30 + Math.random() * 50)}% / ${Math.floor(30 + Math.random() * 50)}% ${Math.floor(30 + Math.random() * 50)}% ${Math.floor(30 + Math.random() * 50)}% ${Math.floor(30 + Math.random() * 50)}%`; blob.style.borderRadius = randomRadius(); } // CTA button effect const ctaButton = document.querySelector('.cta-button'); ctaButton.addEventListener('click', function(e) { e.preventDefault(); // Create ripple effect const ripple = document.createElement('span'); ripple.classList.add('ripple'); this.appendChild(ripple); const x = e.clientX - e.target.getBoundingClientRect().left; const y = e.clientY - e.target.getBoundingClientRect().top; ripple.style.left = `${x}px`; ripple.style.top = `${y}px`; setTimeout(() => { ripple.remove(); }, 600); // Change blobs on click blobs.forEach(blob => { randomizeBlobShape(blob); }); }); // Make all sections visible initially for better embed experience setTimeout(() => { sections.forEach(section => { section.classList.add('visible'); }); }, 500); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Nature's Voice - Storytelling Through Wilderness</title> <style> :root { --color-moss: #8B9E70; --color-forest: #556B2F; --color-earth: #74644B; --color-stone: #928779; --color-cream: #F7F3E9; --color-leaf: #91AD70; --font-main: 'Georgia', serif; --font-accent: 'Palatino', serif; } * { margin: 0; padding: 0; box-sizing: border-box; } body { background-color: var(--color-cream); color: #333; font-family: var(--font-main); line-height: 1.6; overflow-x: hidden; position: relative; width: 100%; height: 100vh; } .container { width: 100%; max-width: 700px; height: 100%; max-height: 700px; margin: 0 auto; padding: 20px; position: relative; overflow: hidden; display: flex; flex-direction: column; } header { position: relative; z-index: 10; padding-bottom: 15px; border-bottom: 1px solid rgba(139, 158, 112, 0.3); } .site-title { font-family: var(--font-accent); font-size: 2.1rem; color: var(--color-forest); margin-bottom: 10px; font-weight: normal; } .tagline { font-size: 0.9rem; color: var(--color-earth); font-style: italic; } .ambient-container { position: absolute; top: 0; left: 0; width: 100%; height: 100%; overflow: hidden; pointer-events: none; z-index: 1; opacity: 0.6; } .blob { position: absolute; border-radius: 50%; filter: blur(40px); transform-origin: center; animation: float 20s infinite alternate ease-in-out; opacity: 0.5; } .blob:nth-child(1) { width: 300px; height: 300px; background-color: var(--color-moss); top: 10%; left: 30%; animation-delay: 0s; } .blob:nth-child(2) { width: 200px; height: 200px; background-color: var(--color-leaf); top: 60%; left: 10%; animation-delay: -5s; } .blob:nth-child(3) { width: 250px; height: 250px; background-color: var(--color-stone); top: 40%; left: 50%; animation-delay: -10s; } .blob:nth-child(4) { width: 180px; height: 180px; background-color: var(--color-earth); top: 20%; left: 70%; animation-delay: -15s; } .content { flex: 1; position: relative; z-index: 10; display: flex; flex-direction: column; padding: 20px 0; overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--color-earth) var(--color-cream); } .content::-webkit-scrollbar { width: 6px; } .content::-webkit-scrollbar-track { background: var(--color-cream); } .content::-webkit-scrollbar-thumb { background-color: var(--color-earth); border-radius: 10px; } .featured-story { background-color: rgba(255, 255, 255, 0.7); backdrop-filter: blur(5px); border-radius: 8px; padding: 25px; margin-bottom: 25px; transition: transform 0.3s, box-shadow 0.3s; border-left: 4px solid var(--color-forest); cursor: pointer; } .featured-story:hover { transform: translateY(-5px); box-shadow: 0 8px 15px rgba(0, 0, 0, 0.1); } .story-title { font-family: var(--font-accent); font-size: 1.5rem; color: var(--color-forest); margin-bottom: 10px; position: relative; } .story-title::after { content: ''; position: absolute; bottom: -5px; left: 0; width: 0; height: 2px; background-color: var(--color-leaf); transition: width 0.3s ease; } .featured-story:hover .story-title::after { width: 50%; } .story-excerpt { font-size: 1rem; margin-bottom: 15px; line-height: 1.5; } .story-meta { display: flex; justify-content: space-between; font-size: 0.85rem; color: var(--color-earth); } .read-more { color: var(--color-forest); text-decoration: none; font-weight: bold; position: relative; transition: color 0.3s; } .read-more::after { content: '→'; margin-left: 5px; transition: transform 0.3s; display: inline-block; } .read-more:hover { color: var(--color-moss); } .read-more:hover::after { transform: translateX(5px); } .story-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; margin-top: 20px; } .story-card { background-color: rgba(255, 255, 255, 0.6); backdrop-filter: blur(3px); border-radius: 8px; padding: 15px; transition: all 0.3s ease; border-left: 3px solid var(--color-moss); cursor: pointer; } .story-card:hover { transform: translateY(-3px); box-shadow: 0 6px 12px rgba(0, 0, 0, 0.08); background-color: rgba(255, 255, 255, 0.8); } .story-card .story-title { font-size: 1.1rem; margin-bottom: 8px; } .story-card .story-excerpt { font-size: 0.9rem; margin-bottom: 10px; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; } .footer { margin-top: 20px; padding-top: 15px; border-top: 1px solid rgba(139, 158, 112, 0.3); font-size: 0.85rem; color: var(--color-earth); text-align: center; position: relative; z-index: 10; } .ripple-effect { position: fixed; border-radius: 50%; transform: scale(0); background-color: rgba(139, 158, 112, 0.4); pointer-events: none; animation: ripple 1s linear; } .search-bar { display: flex; margin: 15px 0; position: relative; } .search-input { flex: 1; padding: 10px 15px; border: none; background-color: rgba(255, 255, 255, 0.8); border-radius: 20px; font-family: var(--font-main); font-size: 0.9rem; color: var(--color-earth); box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05); transition: all 0.3s ease; } .search-input:focus { outline: none; background-color: rgba(255, 255, 255, 0.95); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.08); } .search-input::placeholder { color: var(--color-stone); font-style: italic; } .search-btn { background-color: var(--color-forest); border: none; width: 40px; border-radius: 0 20px 20px 0; margin-left: -40px; color: white; cursor: pointer; transition: background-color 0.3s; display: flex; align-items: center; justify-content: center; } .search-btn:hover { background-color: var(--color-moss); } .category-pills { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 20px; } .category-pill { background-color: rgba(255, 255, 255, 0.6); padding: 6px 12px; border-radius: 20px; font-size: 0.85rem; color: var(--color-forest); cursor: pointer; transition: all 0.3s ease; border: 1px solid transparent; } .category-pill:hover, .category-pill.active { background-color: var(--color-moss); color: white; border-color: var(--color-moss); transform: translateY(-2px); } /* Animations */ @keyframes float { 0% { transform: translate(0, 0) scale(1); } 25% { transform: translate(-20px, 10px) scale(1.05); } 50% { transform: translate(10px, -15px) scale(0.95); } 75% { transform: translate(15px, 20px) scale(1.02); } 100% { transform: translate(-10px, -10px) scale(1); } } @keyframes ripple { 0% { transform: scale(0); opacity: 0.5; } 100% { transform: scale(100); opacity: 0; } } /* Responsive adjustments */ @media (max-width: 600px) { .site-title { font-size: 1.8rem; } .story-grid { grid-template-columns: 1fr; } .featured-story { padding: 20px; } .category-pills { gap: 5px; } .category-pill { padding: 5px 10px; font-size: 0.8rem; } } </style> </head> <body> <div class="container"> <header> <h1 class="site-title">Nature's Voice</h1> <p class="tagline">Stories woven from wilderness, whispered by the wind</p> </header> <div class="ambient-container"> <div class="blob"></div> <div class="blob"></div> <div class="blob"></div> <div class="blob"></div> </div> <div class="content"> <div class="search-bar"> <input type="text" class="search-input" placeholder="Search for stories of the wild..."> <button class="search-btn"> <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M21 21L16.65 16.65M19 11C19 15.4183 15.4183 19 11 19C6.58172 19 3 15.4183 3 11C3 6.58172 6.58172 3 11 3C15.4183 3 19 6.58172 19 11Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> </button> </div> <div class="category-pills"> <div class="category-pill active">All Stories</div> <div class="category-pill">Forest Tales</div> <div class="category-pill">Ocean Depths</div> <div class="category-pill">Mountain Whispers</div> <div class="category-pill">Desert Echoes</div> </div> <article class="featured-story" id="featured"> <h2 class="story-title">The Silent Language of Ancient Redwoods</h2> <p class="story-excerpt">When Dr. Eliza Chen first placed her specialized sensors on the ancient redwood's bark, she didn't expect to decode centuries of arboreal communication. But as the data streamed in, patterns emerged—a sophisticated network of chemical signals and root messages that connected these giants across miles of forest floor. What began as research became a profound dialogue with beings that measure time in centuries.</p> <div class="story-meta"> <span>By Dr. Simone Greystone • 12 min read</span> <a href="#" class="read-more">Continue reading</a> </div> </article> <div class="story-grid"> <article class="story-card"> <h3 class="story-title">Patterns in the Tide</h3> <p class="story-excerpt">The intertidal zone's daily rhythm reveals nature's most resilient adaptations—barnacles that withstand crushing waves and anemones that transform from vibrant flowers to stone-like fortresses between breaths of the sea.</p> <div class="story-meta"> <a href="#" class="read-more">Read</a> </div> </article> <article class="story-card"> <h3 class="story-title">Whispering Prairie</h3> <p class="story-excerpt">Beneath the endless sky, tallgrass prairies conduct a symphony of subtle movements. Each blade of bluestem and switchgrass bends uniquely to the wind, creating ripple patterns that indigenous trackers once read like weather forecasts.</p> <div class="story-meta"> <a href="#" class="read-more">Read</a> </div> </article> <article class="story-card"> <h3 class="story-title">The Alpine Time Capsule</h3> <p class="story-excerpt">As climate researchers drill ice cores from ancient glaciers, they uncover pollen grains and atmospheric samples that tell stories of forests that existed thousands of years before human civilization began.</p> <div class="story-meta"> <a href="#" class="read-more">Read</a> </div> </article> <article class="story-card"> <h3 class="story-title">River's Memory</h3> <p class="story-excerpt">The sediment layers of the meandering Mississippi hold artifacts of countless floods and droughts—nature's own historical record that hydrologists are now translating to understand climate patterns spanning millennia.</p> <div class="story-meta"> <a href="#" class="read-more">Read</a> </div> </article> </div> </div> <footer class="footer"> <p>Nature's Voice © 2023 • Sharing wilderness wisdom through storytelling</p> </footer> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Ripple effect on click document.addEventListener('click', function(e) { const ripple = document.createElement('div'); ripple.className = 'ripple-effect'; ripple.style.left = e.clientX + 'px'; ripple.style.top = e.clientY + 'px'; document.body.appendChild(ripple); setTimeout(() => { ripple.remove(); }, 1000); }); // Blob animation enhancement const blobs = document.querySelectorAll('.blob'); blobs.forEach(blob => { // Random starting positions const randomX = Math.random() * 30 - 15; const randomY = Math.random() * 30 - 15; const randomScale = 0.9 + Math.random() * 0.3; blob.style.transform = `translate(${randomX}px, ${randomY}px) scale(${randomScale})`; // More dynamic animations setInterval(() => { const newX = Math.random() * 40 - 20; const newY = Math.random() * 40 - 20; const newScale = 0.85 + Math.random() * 0.3; blob.style.transition = 'transform 10s cubic-bezier(0.21, 0.53, 0.29, 0.8)'; blob.style.transform = `translate(${newX}px, ${newY}px) scale(${newScale})`; }, 10000); }); // Category pills interaction const pills = document.querySelectorAll('.category-pill'); pills.forEach(pill => { pill.addEventListener('click', function() { // Remove active class from all pills pills.forEach(p => p.classList.remove('active')); // Add active class to clicked pill this.classList.add('active'); // Simulate content change with a subtle animation const content = document.querySelector('.content'); content.style.opacity = '0.7'; setTimeout(() => { content.style.opacity = '1'; }, 300); }); }); // Featured story hover effect enhancement const featuredStory = document.getElementById('featured'); featuredStory.addEventListener('mousemove', function(e) { const boundingRect = this.getBoundingClientRect(); const mouseX = e.clientX - boundingRect.left; const mouseY = e.clientY - boundingRect.top; const centerX = boundingRect.width / 2; const centerY = boundingRect.height / 2; const offsetX = (mouseX - centerX) / 30; const offsetY = (mouseY - centerY) / 30; this.style.transform = `translateY(-5px) perspective(1000px) rotateX(${-offsetY}deg) rotateY(${offsetX}deg)`; }); featuredStory.addEventListener('mouseleave', function() { this.style.transform = 'translateY(0) perspective(1000px) rotateX(0) rotateY(0)'; }); // Search input animation const searchInput = document.querySelector('.search-input'); searchInput.addEventListener('focus', function() { this.parentElement.style.transform = 'scale(1.02)'; }); searchInput.addEventListener('blur', function() { this.parentElement.style.transform = 'scale(1)'; }); // Prevent actual form submission document.querySelector('.search-btn').addEventListener('click', function(e) { e.preventDefault(); const query = searchInput.value.trim(); if (query) { // Visual feedback only searchInput.style.backgroundColor = 'rgba(145, 173, 112, 0.2)'; setTimeout(() => { searchInput.style.backgroundColor = 'rgba(255, 255, 255, 0.8)'; }, 300); } }); // Story cards staggered hover effect const storyCards = document.querySelectorAll('.story-card'); storyCards.forEach((card, index) => { card.addEventListener('mouseenter', function() { // Slightly push away adjacent cards storyCards.forEach((otherCard, otherIndex) => { if (otherIndex !== index) { otherCard.style.transform = 'scale(0.98)'; otherCard.style.opacity = '0.8'; } }); }); card.addEventListener('mouseleave', function() { // Restore other cards storyCards.forEach((otherCard) => { otherCard.style.transform = ''; otherCard.style.opacity = ''; }); }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>NeoBlast Gaming</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: #0d0b21; color: #ffffff; overflow: hidden; position: relative; width: 100%; height: 100vh; touch-action: manipulation; max-width: 700px; max-height: 700px; margin: 0 auto; } .container { position: relative; width: 100%; height: 100%; overflow: hidden; display: flex; flex-direction: column; padding: 20px; z-index: 10; } header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; z-index: 2; } .logo { font-weight: 800; font-size: 1.8rem; background: linear-gradient(to right, #ff3e9d, #0bfff9); -webkit-background-clip: text; -webkit-text-fill-color: transparent; animation: pulse 2s infinite; } .nav-btn { background: rgba(255, 255, 255, 0.1); border: none; color: #fff; padding: 8px 16px; border-radius: 25px; cursor: pointer; font-size: 0.9rem; backdrop-filter: blur(5px); border: 1px solid rgba(255, 255, 255, 0.1); transition: all 0.3s ease; } .nav-btn:hover { background: rgba(255, 255, 255, 0.2); transform: translateY(-2px); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); } main { flex: 1; display: flex; flex-direction: column; justify-content: center; z-index: 2; padding: 10px 0; } h1 { font-size: 3rem; margin-bottom: 20px; line-height: 1.1; font-weight: 800; text-shadow: 0 0 10px rgba(255, 62, 157, 0.5); } h1 span { display: block; font-size: 3.5rem; background: linear-gradient(to right, #ff3e9d, #0bfff9); -webkit-background-clip: text; -webkit-text-fill-color: transparent; } p { font-size: 1.1rem; margin-bottom: 30px; line-height: 1.5; color: rgba(255, 255, 255, 0.8); max-width: 500px; } .cta-btn { background: linear-gradient(45deg, #ff3e9d, #0bfff9); color: #0d0b21; font-weight: bold; border: none; padding: 15px 35px; border-radius: 30px; font-size: 1.1rem; cursor: pointer; transition: all 0.3s ease; align-self: flex-start; box-shadow: 0 5px 15px rgba(255, 62, 157, 0.4); position: relative; overflow: hidden; z-index: 1; } .cta-btn::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(45deg, #0bfff9, #ff3e9d); opacity: 0; z-index: -1; transition: opacity 0.3s ease; } .cta-btn:hover { transform: translateY(-5px); box-shadow: 0 10px 20px rgba(255, 62, 157, 0.6); } .cta-btn:hover::before { opacity: 1; } .tilt-instruction { display: flex; align-items: center; margin-top: 20px; font-size: 0.9rem; color: rgba(255, 255, 255, 0.7); animation: fadeInOut 3s infinite; } .tilt-icon { width: 24px; height: 24px; margin-right: 10px; animation: tiltPhone 2s infinite; } footer { padding: 15px 0; text-align: center; font-size: 0.8rem; color: rgba(255, 255, 255, 0.5); z-index: 2; } .blob-container { position: absolute; top: 0; left: 0; width: 100%; height: 100%; overflow: hidden; z-index: 1; } .blob { position: absolute; border-radius: 50%; filter: blur(40px); opacity: 0.7; transition: transform 0.2s ease-out; } .blob1 { width: 300px; height: 300px; background: rgba(255, 62, 157, 0.5); top: -50px; right: -50px; animation: float1 15s infinite alternate; } .blob2 { width: 250px; height: 250px; background: rgba(11, 255, 249, 0.5); bottom: -50px; left: -50px; animation: float2 18s infinite alternate; } .blob3 { width: 200px; height: 200px; background: rgba(191, 64, 255, 0.5); bottom: 30%; right: 20%; animation: float3 12s infinite alternate; } .neon-outline { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 90%; height: 90%; border: 2px solid transparent; border-radius: 30px; background: linear-gradient(45deg, #ff3e9d, #0bfff9, #bf40ff, #0bfff9) border-box; mask: linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0); -webkit-mask: linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0); -webkit-mask-composite: destination-out; mask-composite: exclude; animation: borderPulse 3s infinite; pointer-events: none; z-index: 1; } .game-features { display: flex; justify-content: space-between; margin-top: 20px; margin-bottom: 30px; gap: 15px; } .feature { flex: 1; background: rgba(255, 255, 255, 0.05); border-radius: 15px; padding: 15px; backdrop-filter: blur(5px); border: 1px solid rgba(255, 255, 255, 0.1); transition: all 0.3s ease; text-align: center; } .feature:hover { transform: translateY(-5px); background: rgba(255, 255, 255, 0.1); box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2); } .feature-icon { font-size: 1.5rem; margin-bottom: 10px; display: inline-block; background: linear-gradient(45deg, #ff3e9d, #0bfff9); -webkit-background-clip: text; -webkit-text-fill-color: transparent; } .feature-title { font-size: 0.9rem; font-weight: bold; margin-bottom: 5px; } .feature-desc { font-size: 0.8rem; color: rgba(255, 255, 255, 0.7); margin-bottom: 0; } .touch-points { position: absolute; width: 100%; height: 100%; top: 0; left: 0; pointer-events: none; z-index: 0; } .touch-point { position: absolute; border-radius: 50%; pointer-events: none; opacity: 0; z-index: 0; background: radial-gradient(circle, rgba(255, 62, 157, 0.8) 0%, rgba(11, 255, 249, 0.4) 70%, transparent 100%); } @keyframes ripple { 0% { transform: scale(0); opacity: 1; } 100% { transform: scale(3); opacity: 0; } } @keyframes float1 { 0% { transform: translate(0, 0); } 100% { transform: translate(-30px, 30px); } } @keyframes float2 { 0% { transform: translate(0, 0); } 100% { transform: translate(40px, -40px); } } @keyframes float3 { 0% { transform: translate(0, 0); } 100% { transform: translate(-50px, -20px); } } @keyframes pulse { 0% { opacity: 0.8; } 50% { opacity: 1; } 100% { opacity: 0.8; } } @keyframes borderPulse { 0% { opacity: 0.5; } 50% { opacity: 1; } 100% { opacity: 0.5; } } @keyframes fadeInOut { 0%, 100% { opacity: 0.5; } 50% { opacity: 1; } } @keyframes tiltPhone { 0%, 100% { transform: rotate(0deg); } 25% { transform: rotate(10deg); } 75% { transform: rotate(-10deg); } } @media (max-width: 600px) { h1 { font-size: 2.2rem; } h1 span { font-size: 2.5rem; } p { font-size: 1rem; } .game-features { flex-direction: column; } .cta-btn { padding: 12px 25px; font-size: 1rem; align-self: center; } } </style> </head> <body> <div class="blob-container"> <div class="blob blob1"></div> <div class="blob blob2"></div> <div class="blob blob3"></div> </div> <div class="neon-outline"></div> <div class="container"> <header> <div class="logo">NeoBlast</div> <button class="nav-btn">Sign Up</button> </header> <main> <h1>Immerse in <span>Gaming Reality</span></h1> <p>Tilt, touch, and control your way through an electrifying gaming experience. NeoBlast offers motion-reactive interfaces that adapt to your every move.</p> <div class="game-features"> <div class="feature"> <div class="feature-icon">⚡</div> <div class="feature-title">Motion Control</div> <div class="feature-desc">Responsive tilt mechanics for immersive play</div> </div> <div class="feature"> <div class="feature-icon">🔥</div> <div class="feature-title">Haptic Response</div> <div class="feature-desc">Feel every action with vibration feedback</div> </div> <div class="feature"> <div class="feature-icon">🎮</div> <div class="feature-title">Dynamic UI</div> <div class="feature-desc">Interface adapts to gameplay intensity</div> </div> </div> <button class="cta-btn">Download Now</button> <div class="tilt-instruction"> <svg class="tilt-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <rect x="5" y="2" width="14" height="20" rx="2" ry="2"></rect> <line x1="12" y1="18" x2="12" y2="18"></line> </svg> Tilt your device to see the dynamic blob effect </div> </main> <footer> © 2023 NeoBlast Gaming • Immersive Mobile Experiences </footer> </div> <div class="touch-points"></div> <script> // DOM elements const blobs = document.querySelectorAll('.blob'); const container = document.querySelector('.container'); const touchPointsContainer = document.querySelector('.touch-points'); const ctaBtn = document.querySelector('.cta-btn'); const navBtn = document.querySelector('.nav-btn'); const features = document.querySelectorAll('.feature'); // Device orientation handling window.addEventListener('deviceorientation', handleOrientation); function handleOrientation(event) { if (!event.beta || !event.gamma) return; // Normalize tilt values const tiltX = Math.min(Math.max(event.beta, -45), 45) / 45; // -1 to 1 range const tiltY = Math.min(Math.max(event.gamma, -45), 45) / 45; // -1 to 1 range // Apply transformations to blobs based on device tilt blobs.forEach((blob, index) => { const factor = (index + 1) * 10; blob.style.transform = `translate(${tiltY * factor}px, ${tiltX * factor}px)`; }); // Adjust the neon outline const neonOutline = document.querySelector('.neon-outline'); neonOutline.style.transform = `translate(-50%, -50%) perspective(1000px) rotateX(${tiltX * 5}deg) rotateY(${tiltY * -5}deg)`; } // Fallback for desktop: use mouse movement to simulate tilt effect document.addEventListener('mousemove', (e) => { const { clientX, clientY } = e; const { innerWidth, innerHeight } = window; // Convert mouse position to normalized -1 to 1 range const tiltY = (clientX / innerWidth) * 2 - 1; const tiltX = (clientY / innerHeight) * 2 - 1; // Apply transformations to blobs blobs.forEach((blob, index) => { const factor = (index + 1) * 15; blob.style.transform = `translate(${tiltY * factor}px, ${tiltX * factor}px)`; }); // Adjust the neon outline const neonOutline = document.querySelector('.neon-outline'); neonOutline.style.transform = `translate(-50%, -50%) perspective(1000px) rotateX(${tiltX * 5}deg) rotateY(${tiltY * -5}deg)`; }); // Touch effect handling document.addEventListener('touchstart', createTouchRipple); document.addEventListener('click', createClickRipple); function createTouchRipple(event) { event.preventDefault(); const touches = event.changedTouches; for (let i = 0; i < touches.length; i++) { const touch = touches[i]; createRipple(touch.clientX, touch.clientY); } } function createClickRipple(event) { createRipple(event.clientX, event.clientY); } function createRipple(x, y) { const ripple = document.createElement('div'); ripple.classList.add('touch-point'); // Position the ripple at click/touch point ripple.style.left = `${x}px`; ripple.style.top = `${y}px`; ripple.style.width = '50px'; ripple.style.height = '50px'; // Add to container touchPointsContainer.appendChild(ripple); // Animate and remove ripple.style.animation = 'ripple 1s linear forwards'; // Clean up after animation setTimeout(() => { touchPointsContainer.removeChild(ripple); }, 1000); // Affect nearby blobs blobs.forEach(blob => { const blobRect = blob.getBoundingClientRect(); const blobX = blobRect.left + blobRect.width / 2; const blobY = blobRect.top + blobRect.height / 2; // Calculate distance const dx = x - blobX; const dy = y - blobY; const distance = Math.sqrt(dx * dx + dy * dy); // Move blob slightly toward touch if (distance < 300) { const factor = 1 - (distance / 300); // 0 to 1 based on distance const moveX = dx * factor * 0.2; const moveY = dy * factor * 0.2; // Apply temporary animation blob.animate([ { transform: `translate(${moveX}px, ${moveY}px) scale(1.1)` }, { transform: 'translate(0, 0) scale(1)' } ], { duration: 800, easing: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)' }); } }); } // Button effects ctaBtn.addEventListener('mouseenter', () => { blobs.forEach(blob => { blob.style.filter = 'blur(30px)'; blob.style.opacity = '0.9'; }); }); ctaBtn.addEventListener('mouseleave', () => { blobs.forEach(blob => { blob.style.filter = 'blur(40px)'; blob.style.opacity = '0.7'; }); }); // Feature card hover effects features.forEach(feature => { feature.addEventListener('mouseenter', () => { feature.style.transform = 'translateY(-10px) scale(1.05)'; feature.style.zIndex = '5'; }); feature.addEventListener('mouseleave', () => { feature.style.transform = ''; feature.style.zIndex = '2'; }); }); // Button click handlers (prevent form submission) navBtn.addEventListener('click', (event) => { event.preventDefault(); navBtn.textContent = navBtn.textContent === 'Sign Up' ? 'Signed!' : 'Sign Up'; }); ctaBtn.addEventListener('click', (event) => { event.preventDefault(); // Add a download started message that fades out const downloadMsg = document.createElement('div'); downloadMsg.textContent = 'Download started!'; downloadMsg.style = ` position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: rgba(0, 0, 0, 0.8); color: white; padding: 15px 30px; border-radius: 30px; z-index: 100; font-weight: bold; `; document.body.appendChild(downloadMsg); // Animate blobs on download blobs.forEach(blob => { blob.animate([ { transform: 'scale(1)', opacity: 0.7 }, { transform: 'scale(1.3)', opacity: 0.9 }, { transform: 'scale(1)', opacity: 0.7 } ], { duration: 1000, easing: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)' }); }); // Remove message after animation setTimeout(() => { document.body.removeChild(downloadMsg); ctaBtn.textContent = 'Downloading...'; setTimeout(() => { ctaBtn.textContent = 'Download Now'; }, 2000); }, 2000); }); // Ensure responsive height function setResponsiveHeight() { const container = document.querySelector('.container'); const availableHeight = window.innerHeight; container.style.height = `${Math.min(availableHeight, 700)}px`; } window.addEventListener('resize', setResponsiveHeight); setResponsiveHeight(); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Serene - Mindful Wellness Companion</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Outfit', sans-serif; } :root { --primary: #a6c1ee; --secondary: #f3e7e9; --accent1: #c2e9fb; --accent2: #fbdde8; --accent3: #d4f0f0; --text-dark: #2d3142; --text-light: #4f5d75; } @import url('https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&display=swap'); body { background: linear-gradient(135deg, var(--secondary) 0%, var(--accent3) 100%); color: var(--text-dark); height: 100vh; width: 100%; overflow-x: hidden; position: relative; } .container { max-width: 700px; height: 700px; margin: 0 auto; padding: 2rem; position: relative; overflow: hidden; display: flex; flex-direction: column; } .nav { display: flex; justify-content: space-between; align-items: center; margin-bottom: 2rem; position: relative; z-index: 10; } .logo { font-weight: 700; font-size: 1.8rem; color: var(--text-dark); display: flex; align-items: center; } .logo-dot { display: inline-block; width: 12px; height: 12px; background-color: var(--primary); border-radius: 50%; margin-left: 5px; animation: pulse 3s infinite ease-in-out; } .menu { display: flex; gap: 1.5rem; } .menu-item { cursor: pointer; font-weight: 500; font-size: 1rem; transition: color 0.3s ease; } .menu-item:hover { color: var(--primary); } .content { position: relative; z-index: 10; flex: 1; display: flex; flex-direction: column; justify-content: center; } h1 { font-size: 2.5rem; font-weight: 700; margin-bottom: 1.5rem; line-height: 1.2; } p { font-size: 1.1rem; line-height: 1.6; margin-bottom: 2rem; color: var(--text-light); max-width: 90%; } .feature-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1.2rem; margin-top: 2rem; } .feature-card { background: rgba(255, 255, 255, 0.6); backdrop-filter: blur(8px); border-radius: 12px; padding: 1.2rem; transition: transform 0.3s ease, box-shadow 0.3s ease; cursor: pointer; } .feature-card:hover { transform: translateY(-5px); box-shadow: 0 10px 20px rgba(0, 0, 0, 0.05); } .feature-icon { font-size: 1.5rem; margin-bottom: 0.8rem; color: var(--primary); } .feature-title { font-weight: 600; margin-bottom: 0.5rem; } .feature-desc { font-size: 0.9rem; color: var(--text-light); line-height: 1.4; margin-bottom: 0; } .blobs-container { position: absolute; top: 0; left: 0; width: 100%; height: 100%; overflow: hidden; z-index: 1; } .blob { position: absolute; border-radius: 50%; filter: blur(40px); opacity: 0.7; transition: all 1.5s ease-in-out; } .cta-button { display: inline-block; background: linear-gradient(135deg, var(--primary) 0%, var(--accent1) 100%); color: white; border: none; padding: 0.9rem 2rem; border-radius: 50px; font-weight: 600; font-size: 1rem; cursor: pointer; transition: transform 0.3s ease, box-shadow 0.3s ease; text-decoration: none; margin-top: 1rem; box-shadow: 0 4px 15px rgba(166, 193, 238, 0.3); position: relative; overflow: hidden; z-index: 1; } .cta-button::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); transition: 0.5s; z-index: -1; } .cta-button:hover { transform: translateY(-3px); box-shadow: 0 7px 20px rgba(166, 193, 238, 0.5); } .cta-button:hover::before { left: 100%; } /* Progress tracker */ .progress-tracker { display: flex; align-items: center; gap: 1rem; margin-top: 3rem; } .progress-text { font-size: 0.9rem; font-weight: 500; } .progress-bar { flex: 1; height: 6px; background-color: rgba(255, 255, 255, 0.3); border-radius: 3px; overflow: hidden; position: relative; } .progress-fill { position: absolute; height: 100%; width: 65%; background: linear-gradient(90deg, var(--primary), var(--accent1)); border-radius: 3px; transition: width 1s ease-in-out; } .breathing-circle { width: 50px; height: 50px; border-radius: 50%; background: linear-gradient(135deg, var(--primary) 0%, var(--accent1) 100%); animation: breathe 8s infinite ease-in-out; margin-left: auto; box-shadow: 0 5px 15px rgba(166, 193, 238, 0.3); } @keyframes breathe { 0%, 100% { transform: scale(0.9); box-shadow: 0 5px 15px rgba(166, 193, 238, 0.3); } 50% { transform: scale(1.1); box-shadow: 0 10px 25px rgba(166, 193, 238, 0.5); } } @keyframes pulse { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.2); opacity: 0.7; } } @media (max-width: 640px) { .container { padding: 1.5rem; } h1 { font-size: 2rem; } p { font-size: 1rem; } .feature-grid { grid-template-columns: 1fr; } .nav { margin-bottom: 1.5rem; } .logo { font-size: 1.5rem; } .menu { gap: 1rem; } .menu-item { font-size: 0.9rem; } } </style> </head> <body> <div class="container"> <nav class="nav"> <div class="logo">serene<span class="logo-dot"></span></div> <div class="menu"> <div class="menu-item">Home</div> <div class="menu-item">Journal</div> <div class="menu-item">Meditate</div> </div> </nav> <div class="content"> <h1>Your daily moment of mindful calm</h1> <p>Serene helps you build a consistent wellness practice through guided breathing, personalized meditation sessions, and mood tracking that adapts to your emotional rhythms.</p> <a href="#" class="cta-button">Start your free week</a> <div class="progress-tracker"> <div class="progress-text">Today's mindfulness: 13 min</div> <div class="progress-bar"> <div class="progress-fill"></div> </div> <div class="breathing-circle"></div> </div> <div class="feature-grid"> <div class="feature-card"> <div class="feature-icon">🌬️</div> <div class="feature-title">Adaptive Breathing</div> <div class="feature-desc">Personalized breathing patterns that adjust to your stress levels and sleep quality.</div> </div> <div class="feature-card"> <div class="feature-icon">📊</div> <div class="feature-title">Emotion Tracking</div> <div class="feature-desc">Visual patterns of your emotional landscape with insights for better self-awareness.</div> </div> <div class="feature-card"> <div class="feature-icon">🧠</div> <div class="feature-title">Neural Soundscapes</div> <div class="feature-desc">AI-generated audio environments designed to induce specific brain wave states.</div> </div> <div class="feature-card"> <div class="feature-icon">⏱️</div> <div class="feature-title">Micro-Meditations</div> <div class="feature-desc">30-second mindfulness exercises for busy moments throughout your day.</div> </div> </div> </div> <div class="blobs-container" id="blobs"></div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const blobsContainer = document.getElementById('blobs'); const colors = [ 'rgba(166, 193, 238, 0.5)', // primary 'rgba(243, 231, 233, 0.5)', // secondary 'rgba(194, 233, 251, 0.5)', // accent1 'rgba(251, 221, 232, 0.5)', // accent2 'rgba(212, 240, 240, 0.5)' // accent3 ]; // Create initial blobs createBlobs(5); // Animate progress bar animateProgress(); // Add blob morphing setInterval(morphBlobs, 3000); function createBlobs(count) { for (let i = 0; i < count; i++) { const blob = document.createElement('div'); blob.classList.add('blob'); // Set random properties const size = Math.random() * 300 + 100; blob.style.width = `${size}px`; blob.style.height = `${size}px`; blob.style.left = `${Math.random() * 100}%`; blob.style.top = `${Math.random() * 100}%`; blob.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)]; blobsContainer.appendChild(blob); } } function morphBlobs() { const blobs = document.querySelectorAll('.blob'); blobs.forEach(blob => { // Randomize position blob.style.left = `${Math.random() * 100}%`; blob.style.top = `${Math.random() * 100}%`; // Randomize size const size = Math.random() * 300 + 100; blob.style.width = `${size}px`; blob.style.height = `${size}px`; // Randomize color blob.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)]; }); } function animateProgress() { const progressFill = document.querySelector('.progress-fill'); let width = 0; const maxWidth = 65; // 65% fill const interval = setInterval(() => { if (width >= maxWidth) { clearInterval(interval); } else { width++; progressFill.style.width = width + '%'; } }, 20); } // Feature card hover effect const featureCards = document.querySelectorAll('.feature-card'); featureCards.forEach(card => { card.addEventListener('mouseenter', () => { const randomColor = colors[Math.floor(Math.random() * colors.length)]; card.style.boxShadow = `0 10px 25px ${randomColor}`; }); card.addEventListener('mouseleave', () => { card.style.boxShadow = '0 10px 20px rgba(0, 0, 0, 0.05)'; }); }); // Prevent actual form submissions document.querySelectorAll('a, button').forEach(element => { element.addEventListener('click', function(e) { e.preventDefault(); // Add a subtle animation when clicked this.style.transform = 'scale(0.98)'; setTimeout(() => { this.style.transform = ''; }, 150); }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>CapitalEdge Financial Portal</title> <style> @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap'); :root { --primary: #1a3a5f; --secondary: #3d5a80; --accent: #4b6fa8; --light: #e0e8f0; --white: #ffffff; --shadow: rgba(9, 30, 66, 0.15); --blob-1: #7ca0cf; --blob-2: #5b789b; --blob-3: #2a496b; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', sans-serif; } body { background-color: var(--white); color: var(--primary); height: 700px; width: 100%; max-width: 700px; margin: 0 auto; position: relative; overflow-x: hidden; } .blob-container { position: absolute; top: 0; left: 0; width: 100%; height: 100%; overflow: hidden; z-index: -1; pointer-events: none; opacity: 0.4; } .blob { position: absolute; border-radius: 50%; filter: blur(50px); opacity: 0.8; transform-origin: center; } .blob-1 { width: 300px; height: 300px; background-color: var(--blob-1); top: -150px; right: -100px; animation: blobMove1 20s infinite alternate ease-in-out; } .blob-2 { width: 250px; height: 250px; background-color: var(--blob-2); bottom: -80px; left: -100px; animation: blobMove2 25s infinite alternate ease-in-out; } .blob-3 { width: 200px; height: 200px; background-color: var(--blob-3); top: 250px; right: -50px; animation: blobMove3 18s infinite alternate ease-in-out; } @keyframes blobMove1 { 0% { transform: translate(0, 0); } 100% { transform: translate(-40px, 60px); } } @keyframes blobMove2 { 0% { transform: translate(0, 0); } 100% { transform: translate(80px, -40px); } } @keyframes blobMove3 { 0% { transform: translate(0, 0); } 100% { transform: translate(-60px, -30px); } } .container { width: 100%; height: 100%; padding: 30px; display: flex; flex-direction: column; } header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 30px; } .logo { font-weight: 700; font-size: 24px; color: var(--primary); letter-spacing: -0.5px; display: flex; align-items: center; } .logo-icon { margin-right: 8px; width: 24px; height: 24px; border-radius: 6px; background: linear-gradient(135deg, var(--primary), var(--accent)); display: flex; align-items: center; justify-content: center; color: white; font-size: 16px; } .nav-links { display: flex; gap: 20px; } .nav-link { color: var(--primary); font-weight: 500; font-size: 14px; text-decoration: none; position: relative; padding: 5px 0; } .nav-link::after { content: ''; position: absolute; bottom: 0; left: 0; width: 0; height: 2px; background-color: var(--accent); transition: width 0.3s ease; } .nav-link:hover::after { width: 100%; } main { flex: 1; display: flex; flex-direction: column; justify-content: space-between; } .welcome-section { margin-bottom: 30px; } h1 { font-size: 32px; font-weight: 700; margin-bottom: 10px; line-height: 1.2; color: var(--primary); } p { font-size: 16px; color: var(--secondary); line-height: 1.6; margin-bottom: 24px; } .card-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; margin-bottom: 30px; } .card { background-color: var(--white); border-radius: 12px; padding: 20px; box-shadow: 0 4px 16px var(--shadow); transition: transform 0.3s ease, box-shadow 0.3s ease; cursor: pointer; position: relative; overflow: hidden; height: 140px; display: flex; flex-direction: column; justify-content: space-between; } .card:hover { transform: translateY(-5px); box-shadow: 0 8px 24px var(--shadow); } .card::before { content: ''; position: absolute; top: 0; left: 0; width: 4px; height: 0; background-color: var(--accent); transition: height 0.3s ease; } .card:hover::before { height: 100%; } .card-icon { font-size: 24px; margin-bottom: 10px; color: var(--accent); } .card h3 { font-size: 16px; font-weight: 600; margin-bottom: 5px; } .card p { font-size: 13px; color: var(--secondary); margin-bottom: 0; } .login-section { background-color: var(--light); border-radius: 12px; padding: 24px; margin-bottom: 30px; } .login-section h2 { font-size: 20px; font-weight: 600; margin-bottom: 20px; } .form-group { margin-bottom: 16px; } label { display: block; font-size: 14px; font-weight: 500; margin-bottom: 6px; color: var(--primary); } input { width: 100%; padding: 12px 16px; border: 1px solid #c9d6e5; border-radius: 6px; font-size: 14px; transition: border-color 0.3s ease, box-shadow 0.3s ease; } input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(75, 111, 168, 0.2); outline: none; } .input-group { position: relative; } .password-toggle { position: absolute; right: 16px; top: 50%; transform: translateY(-50%); background: none; border: none; cursor: pointer; color: var(--secondary); } .login-options { display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px; font-size: 14px; } .remember { display: flex; align-items: center; } .remember input { width: auto; margin-right: 8px; } .forgot-password { color: var(--accent); text-decoration: none; } .forgot-password:hover { text-decoration: underline; } .btn { background-color: var(--primary); color: var(--white); border: none; border-radius: 6px; padding: 12px 24px; font-weight: 500; cursor: pointer; transition: background-color 0.3s ease, transform 0.2s ease; width: 100%; font-size: 16px; } .btn:hover { background-color: var(--accent); transform: translateY(-2px); } .btn:active { transform: translateY(1px); } footer { display: flex; justify-content: space-between; align-items: center; margin-top: auto; font-size: 12px; color: var(--secondary); padding-top: 20px; border-top: 1px solid var(--light); } .footer-links { display: flex; gap: 15px; } .footer-link { color: var(--secondary); text-decoration: none; } .footer-link:hover { color: var(--accent); } /* Responsive */ @media (max-width: 600px) { .container { padding: 20px; } header { flex-direction: column; align-items: flex-start; } .nav-links { margin-top: 15px; width: 100%; justify-content: space-between; } h1 { font-size: 28px; } .card-grid { grid-template-columns: 1fr; } footer { flex-direction: column; gap: 10px; align-items: flex-start; } } /* Animation for cards */ .card-grid { opacity: 0; transform: translateY(20px); animation: fadeInUp 0.8s forwards 0.3s; } @keyframes fadeInUp { to { opacity: 1; transform: translateY(0); } } /* Login form animation */ .login-section { opacity: 0; transform: translateY(20px); animation: fadeInUp 0.8s forwards 0.6s; } /* Logo animation */ .logo { position: relative; overflow: hidden; } .logo::after { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); animation: shimmer 3s infinite; } @keyframes shimmer { 0% { left: -100%; } 100% { left: 100%; } } /* Pulse animation for login button */ .btn { position: relative; } .btn::after { content: ''; position: absolute; width: 100%; height: 100%; top: 0; left: 0; border-radius: 6px; opacity: 0; background: rgba(255, 255, 255, 0.2); animation: pulse 2s infinite; } @keyframes pulse { 0% { transform: scale(1); opacity: 0; } 50% { opacity: 0.3; } 100% { transform: scale(1.2); opacity: 0; } } </style> </head> <body> <div class="blob-container"> <div class="blob blob-1"></div> <div class="blob blob-2"></div> <div class="blob blob-3"></div> </div> <div class="container"> <header> <div class="logo"> <div class="logo-icon">C</div> CapitalEdge </div> <nav class="nav-links"> <a href="#" class="nav-link">Dashboard</a> <a href="#" class="nav-link">Investments</a> <a href="#" class="nav-link">Support</a> </nav> </header> <main> <section class="welcome-section"> <h1>Intelligent finance, simplified access</h1> <p>Welcome to your secure financial hub where you can monitor investments, manage transactions, and access personalized insights—all with enterprise-grade security.</p> </section> <section class="card-grid"> <div class="card"> <div> <div class="card-icon">💼</div> <h3>Portfolio Analytics</h3> </div> <p>Real-time performance insights and risk assessment tools</p> </div> <div class="card"> <div> <div class="card-icon">📊</div> <h3>Wealth Planning</h3> </div> <p>Customized strategies for your long-term financial objectives</p> </div> <div class="card"> <div> <div class="card-icon">🔒</div> <h3>Secure Transfers</h3> </div> <p>Multi-factor authenticated transactions with fraud detection</p> </div> </section> <section class="login-section"> <h2>Secure Account Access</h2> <form id="loginForm"> <div class="form-group"> <label for="username">Username</label> <input type="text" id="username" name="username" placeholder="Enter your username"> </div> <div class="form-group"> <label for="password">Password</label> <div class="input-group"> <input type="password" id="password" name="password" placeholder="Enter your password"> <button type="button" class="password-toggle" id="togglePassword">👁️</button> </div> </div> <div class="login-options"> <div class="remember"> <input type="checkbox" id="remember" name="remember"> <label for="remember">Remember device</label> </div> <a href="#" class="forgot-password">Forgot password?</a> </div> <button type="button" id="loginButton" class="btn">Sign In Securely</button> </form> </section> </main> <footer> <div class="copyright">© 2023 CapitalEdge Financial Services, Inc.</div> <div class="footer-links"> <a href="#" class="footer-link">Privacy</a> <a href="#" class="footer-link">Terms</a> <a href="#" class="footer-link">Security</a> </div> </footer> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Password toggle functionality const togglePassword = document.getElementById('togglePassword'); const password = document.getElementById('password'); togglePassword.addEventListener('click', function() { const type = password.getAttribute('type') === 'password' ? 'text' : 'password'; password.setAttribute('type', type); togglePassword.textContent = type === 'password' ? '👁️' : '👁️🗨️'; }); // Login button animation const loginButton = document.getElementById('loginButton'); loginButton.addEventListener('click', function() { this.textContent = 'Authenticating...'; this.style.backgroundColor = '#3d5a80'; setTimeout(() => { this.textContent = 'Authentication Complete'; this.style.backgroundColor = '#2d6a4f'; document.getElementById('username').value = ''; document.getElementById('password').value = ''; setTimeout(() => { this.textContent = 'Sign In Securely'; this.style.backgroundColor = ''; }, 2000); }, 1500); }); // Cards hover effect refinement const cards = document.querySelectorAll('.card'); cards.forEach(card => { card.addEventListener('mouseenter', function() { cards.forEach(c => { if (c !== this) { c.style.opacity = '0.7'; } }); }); card.addEventListener('mouseleave', function() { cards.forEach(c => { c.style.opacity = '1'; }); }); }); // Prevent form submission (as per instructions) const form = document.getElementById('loginForm'); form.addEventListener('submit', function(e) { e.preventDefault(); }); // Enhanced blob animation based on mouse movement const blobContainer = document.querySelector('.blob-container'); const blobs = document.querySelectorAll('.blob'); document.addEventListener('mousemove', function(e) { const x = e.clientX / window.innerWidth; const y = e.clientY / window.innerHeight; blobs.forEach((blob, index) => { const factor = 0.02 * (index + 1); const offsetX = 30 * (x - 0.5) * factor; const offsetY = 30 * (y - 0.5) * factor; blob.style.transform = `translate(${offsetX}px, ${offsetY}px)`; }); }); }); </script> </body> </html>