Glow effects can add a touch of magic to any design, making elements stand out and capture attention. Whether you're designing a website, an app, or a digital advertisement, mastering glow effects can elevate your visual storytelling.
In this article, we'll explore ten stunning glow effect examples that showcase the versatility and impact of this design technique. From subtle highlights to bold, radiant glows, these examples will inspire your next creative project.
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 it effortless to design pixel-perfect UI, including stunning glow effects. Loved by designers and developers alike, Subframe ensures your creative vision comes to life seamlessly.
Start for free and elevate your designs 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 UI designs? With Subframe, you can create pixel-perfect interfaces and stunning glow effects effortlessly. Our drag-and-drop editor ensures efficiency and precision.
Start for free and begin designing immediately. Unleash your creativity with Subframe today!
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Luminara - Artisan Lighting Collection</title> <style> @import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@300;400;600&family=Montserrat:wght@300;400;500;600&display=swap'); :root { --primary-color: #f8b87f; --secondary-color: #ffeee2; --dark-color: #2d2b38; --light-color: #ffffff; --accent-color: #e06b4e; --shadow-color: rgba(252, 191, 143, 0.3); } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Montserrat', sans-serif; background-color: #fcfaf8; color: var(--dark-color); max-width: 700px; height: 700px; margin: 0 auto; padding: 20px; overflow-x: hidden; } header { text-align: center; margin-bottom: 30px; } h1 { font-family: 'Cormorant Garamond', serif; font-weight: 600; font-size: 2.5rem; margin-bottom: 10px; color: var(--dark-color); } p.tagline { font-size: 1rem; color: #666; margin-bottom: 15px; } .controls { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; } .filter { font-size: 0.9rem; display: flex; gap: 10px; } .filter-btn { background: transparent; border: 1px solid #e0e0e0; padding: 6px 12px; border-radius: 20px; cursor: pointer; transition: all 0.3s ease; } .filter-btn:hover, .filter-btn.active { background-color: var(--primary-color); color: white; border-color: var(--primary-color); } .sort { font-size: 0.9rem; } .sort select { padding: 6px 12px; border: 1px solid #e0e0e0; border-radius: 20px; background-color: white; } .products { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 25px; margin-top: 10px; } .product-card { position: relative; background-color: white; border-radius: 10px; overflow: hidden; transition: transform 0.3s ease, box-shadow 0.3s ease; height: 100%; } .product-card:hover { transform: translateY(-5px); box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1); } .product-image { position: relative; width: 100%; height: 180px; overflow: hidden; } .product-image img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.5s ease; } .product-card:hover .product-image img { transform: scale(1.05); } .product-details { padding: 15px; } .product-title { font-family: 'Cormorant Garamond', serif; font-weight: 600; font-size: 1.1rem; margin-bottom: 5px; } .product-price { color: var(--accent-color); font-weight: 500; margin-bottom: 10px; } .product-rating { display: flex; align-items: center; margin-bottom: 10px; } .stars { color: #ffd700; margin-right: 5px; } .review-count { font-size: 0.8rem; color: #777; } .add-to-cart { background-color: var(--dark-color); color: white; border: none; padding: 8px 15px; border-radius: 5px; font-size: 0.9rem; cursor: pointer; transition: background-color 0.3s ease; width: 100%; display: flex; justify-content: center; align-items: center; gap: 5px; } .add-to-cart:hover { background-color: var(--accent-color); } .cart-icon { font-size: 1rem; } /* Featured Product Glow Effect */ .featured::before { content: ''; position: absolute; inset: -3px; border-radius: 12px; padding: 3px; background: radial-gradient(circle at top left, var(--primary-color), transparent 70%), radial-gradient(circle at bottom right, var(--accent-color), transparent 70%); -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); -webkit-mask-composite: xor; mask-composite: exclude; z-index: -1; opacity: 0.8; filter: blur(5px); transition: opacity 0.3s ease, filter 0.3s ease; } .featured:hover::before { opacity: 1; filter: blur(8px); } .featured .product-image::after { content: 'Featured'; position: absolute; top: 10px; right: 10px; background-color: var(--accent-color); color: white; padding: 5px 10px; font-size: 0.7rem; border-radius: 20px; font-weight: 600; letter-spacing: 0.5px; box-shadow: 0 3px 10px rgba(224, 107, 78, 0.3); } .featured::after { content: ''; position: absolute; width: 100%; height: 100%; top: 0; left: 0; background: linear-gradient(45deg, rgba(248, 184, 127, 0.05) 0%, rgba(248, 184, 127, 0) 40%); border-radius: 10px; z-index: 1; pointer-events: none; } /* Pulse animation for the featured product */ @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(248, 184, 127, 0.4); } 70% { box-shadow: 0 0 0 10px rgba(248, 184, 127, 0); } 100% { box-shadow: 0 0 0 0 rgba(248, 184, 127, 0); } } .featured { position: relative; animation: pulse 2s infinite; box-shadow: 0 5px 15px var(--shadow-color); } /* Custom Scrollbar */ ::-webkit-scrollbar { width: 8px; } ::-webkit-scrollbar-track { background: #f1f1f1; } ::-webkit-scrollbar-thumb { background: var(--primary-color); border-radius: 10px; } ::-webkit-scrollbar-thumb:hover { background: var(--accent-color); } /* Responsive Adjustments */ @media (max-width: 600px) { .products { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 15px; } .product-image { height: 150px; } h1 { font-size: 2rem; } .controls { flex-direction: column; gap: 15px; align-items: flex-start; } .filter { overflow-x: auto; width: 100%; padding-bottom: 10px; } .filter-btn { white-space: nowrap; } } /* Product Spotlight Animation */ @keyframes spotlight { 0%, 100% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } } .featured .product-image::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient( 135deg, rgba(248, 184, 127, 0) 0%, rgba(248, 184, 127, 0.1) 25%, rgba(248, 184, 127, 0.2) 50%, rgba(248, 184, 127, 0.1) 75%, rgba(248, 184, 127, 0) 100% ); background-size: 200% 200%; animation: spotlight 3s ease-in-out infinite; pointer-events: none; z-index: 2; } /* Add to cart hover effect */ .add-to-cart .add-text { position: relative; transition: all 0.3s ease; } .add-to-cart:hover .add-text { transform: translateX(-3px); } .add-to-cart .cart-icon { opacity: 0; transform: translateX(20px); transition: all 0.3s ease; } .add-to-cart:hover .cart-icon { opacity: 1; transform: translateX(0); } </style> </head> <body> <header> <h1>Luminara</h1> <p class="tagline">Artisan lighting for the modern home</p> </header> <div class="controls"> <div class="filter"> <button class="filter-btn active">All</button> <button class="filter-btn">Pendant</button> <button class="filter-btn">Table</button> <button class="filter-btn">Floor</button> <button class="filter-btn">Wall</button> </div> <div class="sort"> <select> <option>Featured</option> <option>Price: Low to High</option> <option>Price: High to Low</option> <option>Best Selling</option> </select> </div> </div> <div class="products"> <div class="product-card featured"> <div class="product-image"> <img src="https://images.unsplash.com/photo-1513506003901-1e6a229e2d15?w=500&auto=format&fit=crop&q=80" alt="Orion Pendant Light"> </div> <div class="product-details"> <h3 class="product-title">Orion Pendant Light</h3> <p class="product-price">$189.99</p> <div class="product-rating"> <div class="stars">★★★★★</div> <span class="review-count">(42)</span> </div> <button class="add-to-cart"> <span class="add-text">Add to Cart</span> <span class="cart-icon">→</span> </button> </div> </div> <div class="product-card"> <div class="product-image"> <img src="https://images.unsplash.com/photo-1507473885765-e6ed057f782c?w=500&auto=format&fit=crop&q=80" alt="Luna Table Lamp"> </div> <div class="product-details"> <h3 class="product-title">Luna Table Lamp</h3> <p class="product-price">$129.99</p> <div class="product-rating"> <div class="stars">★★★★☆</div> <span class="review-count">(28)</span> </div> <button class="add-to-cart"> <span class="add-text">Add to Cart</span> <span class="cart-icon">→</span> </button> </div> </div> <div class="product-card featured"> <div class="product-image"> <img src="https://images.unsplash.com/photo-1602143407151-7111542de6e8?w=500&auto=format&fit=crop&q=80" alt="Soleil Floor Lamp"> </div> <div class="product-details"> <h3 class="product-title">Soleil Floor Lamp</h3> <p class="product-price">$249.99</p> <div class="product-rating"> <div class="stars">★★★★★</div> <span class="review-count">(37)</span> </div> <button class="add-to-cart"> <span class="add-text">Add to Cart</span> <span class="cart-icon">→</span> </button> </div> </div> <div class="product-card"> <div class="product-image"> <img src="https://images.unsplash.com/photo-1517991104123-1d56a6e81ed9?w=500&auto=format&fit=crop&q=80" alt="Vega Wall Sconce"> </div> <div class="product-details"> <h3 class="product-title">Vega Wall Sconce</h3> <p class="product-price">$89.99</p> <div class="product-rating"> <div class="stars">★★★★☆</div> <span class="review-count">(19)</span> </div> <button class="add-to-cart"> <span class="add-text">Add to Cart</span> <span class="cart-icon">→</span> </button> </div> </div> <div class="product-card"> <div class="product-image"> <img src="https://images.unsplash.com/photo-1567459169678-26116efed0a1?w=500&auto=format&fit=crop&q=80" alt="Nova Pendant Light"> </div> <div class="product-details"> <h3 class="product-title">Nova Pendant Light</h3> <p class="product-price">$159.99</p> <div class="product-rating"> <div class="stars">★★★★☆</div> <span class="review-count">(23)</span> </div> <button class="add-to-cart"> <span class="add-text">Add to Cart</span> <span class="cart-icon">→</span> </button> </div> </div> <div class="product-card featured"> <div class="product-image"> <img src="https://images.unsplash.com/photo-1530603907829-659ab5ec057b?w=500&auto=format&fit=crop&q=80" alt="Aurora Table Lamp"> </div> <div class="product-details"> <h3 class="product-title">Aurora Table Lamp</h3> <p class="product-price">$139.99</p> <div class="product-rating"> <div class="stars">★★★★★</div> <span class="review-count">(31)</span> </div> <button class="add-to-cart"> <span class="add-text">Add to Cart</span> <span class="cart-icon">→</span> </button> </div> </div> </div> <script> // Filter buttons functionality const filterButtons = document.querySelectorAll('.filter-btn'); filterButtons.forEach(button => { button.addEventListener('click', () => { // Remove active class from all buttons filterButtons.forEach(btn => btn.classList.remove('active')); // Add active class to clicked button button.classList.add('active'); }); }); // Add hover effect enhancement for featured products const featuredProducts = document.querySelectorAll('.featured'); featuredProducts.forEach(product => { product.addEventListener('mouseenter', () => { // Create a more intense glow on hover product.style.boxShadow = `0 8px 25px ${getComputedStyle(document.documentElement).getPropertyValue('--shadow-color')}`; }); product.addEventListener('mouseleave', () => { // Reset to original animation product.style.boxShadow = ''; }); }); // Add to cart button functionality (simulation) const addToCartButtons = document.querySelectorAll('.add-to-cart'); addToCartButtons.forEach(button => { button.addEventListener('click', (e) => { e.preventDefault(); // Get the product title const productTitle = button.closest('.product-details').querySelector('.product-title').textContent; // Visual feedback const originalText = button.querySelector('.add-text').textContent; button.querySelector('.add-text').textContent = 'Added!'; button.style.backgroundColor = '#4CAF50'; // Reset after 1.5 seconds setTimeout(() => { button.querySelector('.add-text').textContent = originalText; button.style.backgroundColor = ''; }, 1500); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>NeoGlow Gaming Portal</title> <style> :root { --neon-purple: #b829f8; --neon-blue: #2962ff; --neon-pink: #ff00c8; --neon-teal: #00ffe1; --neon-green: #39ff14; --bg-color: #0a0a15; --card-bg: rgba(18, 18, 30, 0.7); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Rajdhani', 'Orbitron', sans-serif; } body { background-color: var(--bg-color); background-image: radial-gradient(circle at 10% 20%, rgba(41, 98, 255, 0.1) 0%, transparent 20%), radial-gradient(circle at 90% 80%, rgba(184, 41, 248, 0.1) 0%, transparent 20%), radial-gradient(circle at 50% 50%, rgba(0, 255, 225, 0.05) 0%, transparent 50%); color: white; overflow-x: hidden; height: 100vh; width: 100%; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; padding: 20px; } header { width: 100%; text-align: center; margin-bottom: 20px; } .logo { font-size: 32px; font-weight: 700; letter-spacing: 1px; background: linear-gradient(to right, var(--neon-purple), var(--neon-blue), var(--neon-teal)); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; position: relative; display: inline-block; margin-bottom: 5px; } .logo::after { content: ''; position: absolute; height: 3px; width: 50%; background: linear-gradient(to right, var(--neon-purple), var(--neon-blue), var(--neon-teal)); bottom: -5px; left: 25%; border-radius: 10px; } .subtitle { font-size: 14px; opacity: 0.7; margin-top: 10px; } .game-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 20px; width: 100%; max-width: 660px; margin: 10px auto; padding: 10px; } .game-card { position: relative; background: var(--card-bg); border-radius: 10px; overflow: hidden; cursor: pointer; transition: transform 0.3s ease; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); aspect-ratio: 1/1; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 10px; } .game-card:hover { transform: translateY(-5px); } .game-card::before { content: ''; position: absolute; top: -2px; left: -2px; right: -2px; bottom: -2px; background: var(--card-bg); z-index: -1; border-radius: 12px; } .game-icon { width: 60px; height: 60px; margin-bottom: 10px; position: relative; z-index: 1; } .game-title { font-size: 14px; font-weight: 600; margin-top: 5px; z-index: 1; } .game-type { font-size: 12px; opacity: 0.7; z-index: 1; } .glow-effect { position: absolute; width: 150%; height: 150%; background: radial-gradient(circle, rgba(57, 255, 20, 0.5) 0%, rgba(41, 98, 255, 0.3) 40%, transparent 70%); filter: blur(20px); opacity: 0; transition: opacity 0.5s ease; mix-blend-mode: screen; transform: translate(-50%, -50%); left: 50%; top: 50%; z-index: 0; border-radius: 50%; } .featured-section { width: 100%; max-width: 660px; margin-top: 20px; background: var(--card-bg); border-radius: 15px; padding: 15px; position: relative; overflow: hidden; box-shadow: 0 5px 20px rgba(0, 0, 0, 0.3); } .featured-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; } .featured-title { font-size: 18px; font-weight: 700; background: linear-gradient(to right, var(--neon-pink), var(--neon-purple)); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; } .featured-game { display: flex; align-items: center; gap: 15px; margin-top: 10px; position: relative; } .featured-img { width: 80px; height: 80px; border-radius: 10px; object-fit: cover; } .featured-content { flex: 1; } .featured-game-title { font-size: 16px; font-weight: 600; margin-bottom: 5px; } .featured-game-desc { font-size: 13px; opacity: 0.8; line-height: 1.4; } .play-btn { background: linear-gradient(45deg, var(--neon-blue), var(--neon-purple)); border: none; border-radius: 20px; color: white; padding: 8px 15px; font-size: 14px; font-weight: 600; cursor: pointer; transition: all 0.3s ease; position: relative; overflow: hidden; margin-top: 10px; } .play-btn::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; } .play-btn:hover::before { left: 100%; } .play-btn:hover { box-shadow: 0 0 10px rgba(184, 41, 248, 0.5), 0 0 20px rgba(41, 98, 255, 0.3); } .pulse { animation: pulse 2s infinite; } @keyframes pulse { 0% { transform: scale(1); opacity: 0.6; } 50% { transform: scale(1.1); opacity: 0.8; } 100% { transform: scale(1); opacity: 0.6; } } .pulse-fast { animation: pulse-fast 1s infinite; } @keyframes pulse-fast { 0% { transform: scale(1); opacity: 0.8; } 50% { transform: scale(1.1); opacity: 1; } 100% { transform: scale(1); opacity: 0.8; } } .category-tabs { display: flex; gap: 10px; margin-bottom: 15px; overflow-x: auto; padding: 5px; width: 100%; max-width: 660px; scrollbar-width: none; } .category-tabs::-webkit-scrollbar { display: none; } .category-tab { background: rgba(41, 98, 255, 0.1); border: 1px solid rgba(41, 98, 255, 0.3); color: white; border-radius: 20px; padding: 8px 15px; font-size: 13px; cursor: pointer; transition: all 0.3s ease; white-space: nowrap; } .category-tab:hover, .category-tab.active { background: rgba(41, 98, 255, 0.3); border-color: var(--neon-blue); box-shadow: 0 0 10px rgba(41, 98, 255, 0.5); } .energy-meter { position: absolute; bottom: 15px; right: 15px; width: 60px; height: 15px; background: rgba(0, 0, 0, 0.3); border-radius: 10px; overflow: hidden; } .energy-level { height: 100%; width: 70%; background: linear-gradient(to right, var(--neon-green), var(--neon-teal)); border-radius: 10px; } @media (max-width: 600px) { .game-grid { grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 15px; } .game-icon { width: 50px; height: 50px; } .featured-game { flex-direction: column; text-align: center; } .featured-img { width: 100%; height: auto; max-height: 120px; } .play-btn { margin: 10px auto 0; display: block; } } /* Animation for color shifting glow */ @keyframes colorShift { 0% { background-color: var(--neon-purple); } 33% { background-color: var(--neon-blue); } 66% { background-color: var(--neon-teal); } 100% { background-color: var(--neon-purple); } } .color-shift { animation: colorShift 10s infinite; } </style> </head> <body> <header> <h1 class="logo">NeoGlow</h1> <p class="subtitle">Where legends find their glow</p> </header> <div class="category-tabs"> <div class="category-tab active">All Games</div> <div class="category-tab">Action</div> <div class="category-tab">RPG</div> <div class="category-tab">Strategy</div> <div class="category-tab">Simulation</div> <div class="category-tab">Racing</div> </div> <div class="featured-section"> <div class="featured-header"> <h2 class="featured-title">FEATURED GAME</h2> <div class="energy-meter"> <div class="energy-level pulse"></div> </div> </div> <div class="featured-game"> <img src="https://i.imgur.com/sWZvZDv.jpg" alt="Neon Abyss" class="featured-img"> <div class="featured-content"> <h3 class="featured-game-title">Neon Abyss</h3> <p class="featured-game-desc">Dive into procedurally generated dungeons where your growing horde of pets grant dynamic abilities and synergies.</p> <button class="play-btn">PLAY NOW</button> </div> </div> </div> <div class="game-grid"> <div class="game-card" data-color="purple" data-energy="82"> <div class="glow-effect"></div> <img src="https://i.imgur.com/bM2RA8d.png" alt="Cyberpunk Rebels" class="game-icon"> <h3 class="game-title">Cyberpunk Rebels</h3> <span class="game-type">Action RPG</span> </div> <div class="game-card" data-color="blue" data-energy="95"> <div class="glow-effect"></div> <img src="https://i.imgur.com/rvmDcZx.png" alt="Astral Nexus" class="game-icon"> <h3 class="game-title">Astral Nexus</h3> <span class="game-type">Space Sim</span> </div> <div class="game-card" data-color="teal" data-energy="60"> <div class="glow-effect"></div> <img src="https://i.imgur.com/lGqIyoy.png" alt="Quantum Break" class="game-icon"> <h3 class="game-title">Quantum Break</h3> <span class="game-type">Puzzle</span> </div> <div class="game-card" data-color="pink" data-energy="78"> <div class="glow-effect"></div> <img src="https://i.imgur.com/GfRGsLH.png" alt="Neon Drift" class="game-icon"> <h3 class="game-title">Neon Drift</h3> <span class="game-type">Racing</span> </div> <div class="game-card" data-color="green" data-energy="87"> <div class="glow-effect"></div> <img src="https://i.imgur.com/4Xrjywm.png" alt="Synthwave Samurai" class="game-icon"> <h3 class="game-title">Synthwave Samurai</h3> <span class="game-type">Action</span> </div> <div class="game-card" data-color="purple" data-energy="72"> <div class="glow-effect"></div> <img src="https://i.imgur.com/nV6msvw.png" alt="Digital Dreamscape" class="game-icon"> <h3 class="game-title">Digital Dreamscape</h3> <span class="game-type">Adventure</span> </div> <div class="game-card" data-color="blue" data-energy="65"> <div class="glow-effect"></div> <img src="https://i.imgur.com/FZBbHqB.png" alt="Electron Tactics" class="game-icon"> <h3 class="game-title">Electron Tactics</h3> <span class="game-type">Strategy</span> </div> <div class="game-card" data-color="teal" data-energy="91"> <div class="glow-effect"></div> <img src="https://i.imgur.com/0Dx57AM.png" alt="Hologram Heroes" class="game-icon"> <h3 class="game-title">Hologram Heroes</h3> <span class="game-type">Co-op RPG</span> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const gameCards = document.querySelectorAll('.game-card'); const categoryTabs = document.querySelectorAll('.category-tab'); // Set up game cards glow effects gameCards.forEach(card => { const glowElement = card.querySelector('.glow-effect'); const energyLevel = parseInt(card.getAttribute('data-energy')); const colorType = card.getAttribute('data-color'); // Set color based on game type let glowColor; switch(colorType) { case 'purple': glowColor = 'rgba(184, 41, 248, 0.7)'; break; case 'blue': glowColor = 'rgba(41, 98, 255, 0.7)'; break; case 'teal': glowColor = 'rgba(0, 255, 225, 0.7)'; break; case 'pink': glowColor = 'rgba(255, 0, 200, 0.7)'; break; case 'green': glowColor = 'rgba(57, 255, 20, 0.7)'; break; default: glowColor = 'rgba(184, 41, 248, 0.7)'; } // Set initial glow opacity based on energy level const baseOpacity = energyLevel / 200; // Divided by 200 to get a lower opacity glowElement.style.opacity = baseOpacity; glowElement.style.background = `radial-gradient(circle, ${glowColor} 0%, transparent 70%)`; // Pulsating effect based on energy level if (energyLevel > 85) { glowElement.classList.add('pulse-fast'); } else if (energyLevel > 70) { glowElement.classList.add('pulse'); } // Mouse enter event card.addEventListener('mouseenter', () => { glowElement.style.opacity = Math.min(baseOpacity * 3, 0.9); card.style.transform = 'translateY(-5px) scale(1.05)'; card.style.zIndex = '10'; }); // Mouse leave event card.addEventListener('mouseleave', () => { glowElement.style.opacity = baseOpacity; card.style.transform = 'translateY(0) scale(1)'; card.style.zIndex = '1'; }); // Click event card.addEventListener('click', () => { // Animate glow to full intensity glowElement.style.opacity = '1'; // Then fade back to base setTimeout(() => { glowElement.style.opacity = baseOpacity; }, 800); // Ripple animation effect const ripple = document.createElement('div'); ripple.style.position = 'absolute'; ripple.style.width = '10px'; ripple.style.height = '10px'; ripple.style.background = glowColor; ripple.style.borderRadius = '50%'; ripple.style.transform = 'translate(-50%, -50%)'; ripple.style.pointerEvents = 'none'; ripple.style.opacity = '1'; card.appendChild(ripple); // Animate ripple growth and fade const animation = ripple.animate([ { top: '50%', left: '50%', width: '10px', height: '10px', opacity: 1 }, { top: '50%', left: '50%', width: '200px', height: '200px', opacity: 0 } ], { duration: 800, easing: 'ease-out' }); animation.onfinish = () => { ripple.remove(); }; }); }); // Category tabs categoryTabs.forEach(tab => { tab.addEventListener('click', () => { // Remove active class from all tabs categoryTabs.forEach(t => t.classList.remove('active')); // Add active class to clicked tab tab.classList.add('active'); // Add ripple effect to clicked tab const ripple = document.createElement('div'); ripple.style.position = 'absolute'; ripple.style.width = '5px'; ripple.style.height = '5px'; ripple.style.background = 'rgba(255, 255, 255, 0.8)'; ripple.style.borderRadius = '50%'; ripple.style.transform = 'translate(-50%, -50%)'; ripple.style.pointerEvents = 'none'; const rect = tab.getBoundingClientRect(); ripple.style.top = '50%'; ripple.style.left = '50%'; tab.style.position = 'relative'; tab.appendChild(ripple); // Animate ripple const animation = ripple.animate([ { top: '50%', left: '50%', width: '5px', height: '5px', opacity: 1 }, { top: '50%', left: '50%', width: '100px', height: '100px', opacity: 0 } ], { duration: 600, easing: 'ease-out' }); animation.onfinish = () => { ripple.remove(); }; }); }); // Play button effect const playBtn = document.querySelector('.play-btn'); playBtn.addEventListener('click', (e) => { e.preventDefault(); // Add energy pulse to featured game const energyLevel = document.querySelector('.energy-level'); energyLevel.style.width = '100%'; energyLevel.style.background = 'linear-gradient(to right, var(--neon-green), var(--neon-purple))'; energyLevel.classList.add('pulse-fast'); setTimeout(() => { energyLevel.style.width = '70%'; energyLevel.style.background = 'linear-gradient(to right, var(--neon-green), var(--neon-teal))'; energyLevel.classList.remove('pulse-fast'); energyLevel.classList.add('pulse'); }, 2000); }); // Add random glow pulses to game cards periodically setInterval(() => { const randomCard = gameCards[Math.floor(Math.random() * gameCards.length)]; const glowElement = randomCard.querySelector('.glow-effect'); const currentOpacity = parseFloat(glowElement.style.opacity); glowElement.style.opacity = currentOpacity * 2; setTimeout(() => { glowElement.style.opacity = currentOpacity; }, 500); }, 3000); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Glow - Educational App Interactive Elements</title> <style> :root { --mint: #c5ead9; --lavender: #d9c5ea; --peach: #f8c9b8; --skyblue: #b8e2f8; --buttercream: #f8f3b8; --light-shadow: rgba(255, 255, 255, 0.7); --dark-shadow: rgba(0, 0, 0, 0.1); --font-main: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: var(--font-main); background-color: #f9f7ff; width: 100%; height: 100vh; display: flex; flex-direction: column; justify-content: center; align-items: center; padding: 1.5rem; overflow-x: hidden; background-image: radial-gradient(circle at 10% 20%, rgba(197, 234, 217, 0.2) 0%, transparent 40%), radial-gradient(circle at 80% 80%, rgba(217, 197, 234, 0.2) 0%, transparent 40%); } .app-container { width: 100%; max-width: 680px; height: 680px; background-color: white; border-radius: 24px; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08); padding: 2rem; display: flex; flex-direction: column; position: relative; overflow: hidden; } h1 { font-size: 1.8rem; color: #333; margin-bottom: 0.5rem; font-weight: 600; } h2 { font-size: 1.3rem; color: #555; margin-bottom: 1.5rem; font-weight: 400; } .intro-text { font-size: 0.95rem; color: #666; line-height: 1.5; margin-bottom: 2rem; } .modules-container { flex: 1; display: grid; grid-template-columns: repeat(2, 1fr); grid-template-rows: repeat(2, 1fr); gap: 1.2rem; margin-bottom: 1.5rem; } .module { position: relative; background-color: white; border-radius: 16px; display: flex; flex-direction: column; justify-content: center; align-items: center; padding: 1.2rem; cursor: pointer; overflow: hidden; transition: transform 0.3s ease-out; border: 1px solid rgba(0, 0, 0, 0.05); } .module:hover { transform: translateY(-4px); } .module::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; border-radius: 16px; background: radial-gradient( circle at center, var(--light-shadow) 0%, transparent 70% ); opacity: 0; z-index: 1; transition: opacity 0.5s ease; } .module:hover::before { opacity: 0.6; } .module.active::before { opacity: 0.8; animation: pulse 2s infinite; } .module-icon { width: 60px; height: 60px; border-radius: 50%; display: flex; justify-content: center; align-items: center; margin-bottom: 1rem; transition: all 0.3s ease; position: relative; z-index: 2; } .module-icon i { color: white; font-size: 1.5rem; } .module-title { font-weight: 500; font-size: 1rem; color: #444; margin-bottom: 0.5rem; text-align: center; position: relative; z-index: 2; } .module-desc { font-size: 0.8rem; color: #777; text-align: center; position: relative; z-index: 2; } .module-1 { background-color: rgba(197, 234, 217, 0.1); } .module-1 .module-icon { background-color: var(--mint); box-shadow: 0 0 0 6px rgba(197, 234, 217, 0.2); } .module-2 { background-color: rgba(217, 197, 234, 0.1); } .module-2 .module-icon { background-color: var(--lavender); box-shadow: 0 0 0 6px rgba(217, 197, 234, 0.2); } .module-3 { background-color: rgba(248, 201, 184, 0.1); } .module-3 .module-icon { background-color: var(--peach); box-shadow: 0 0 0 6px rgba(248, 201, 184, 0.2); } .module-4 { background-color: rgba(184, 226, 248, 0.1); } .module-4 .module-icon { background-color: var(--skyblue); box-shadow: 0 0 0 6px rgba(184, 226, 248, 0.2); } .module:hover .module-icon, .module.active .module-icon { transform: scale(1.1); } .module-1:hover .module-icon, .module-1.active .module-icon { box-shadow: 0 0 0 8px rgba(197, 234, 217, 0.3), 0 0 25px rgba(197, 234, 217, 0.7); } .module-2:hover .module-icon, .module-2.active .module-icon { box-shadow: 0 0 0 8px rgba(217, 197, 234, 0.3), 0 0 25px rgba(217, 197, 234, 0.7); } .module-3:hover .module-icon, .module-3.active .module-icon { box-shadow: 0 0 0 8px rgba(248, 201, 184, 0.3), 0 0 25px rgba(248, 201, 184, 0.7); } .module-4:hover .module-icon, .module-4.active .module-icon { box-shadow: 0 0 0 8px rgba(184, 226, 248, 0.3), 0 0 25px rgba(184, 226, 248, 0.7); } .continue-btn { background-color: #6a5acd; color: white; border: none; padding: 1rem 2rem; font-size: 1rem; border-radius: 50px; font-weight: 500; cursor: pointer; transition: all 0.3s ease; position: relative; overflow: hidden; width: 80%; margin: 0 auto; display: block; box-shadow: 0 4px 15px rgba(106, 90, 205, 0.3); } .continue-btn::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient( 45deg, transparent 25%, rgba(255, 255, 255, 0.2) 50%, transparent 75% ); background-size: 200% 200%; animation: shimmer 3s infinite linear; transition: all 0.3s ease; opacity: 0.5; } .continue-btn:hover { transform: translateY(-3px); box-shadow: 0 8px 20px rgba(106, 90, 205, 0.4); } .continue-btn:active { transform: translateY(1px); box-shadow: 0 2px 10px rgba(106, 90, 205, 0.3); } .progress-bar { width: 100%; height: 6px; background-color: #eee; border-radius: 10px; margin-bottom: 1.5rem; position: relative; overflow: hidden; } .progress-fill { position: absolute; top: 0; left: 0; height: 100%; width: 0%; background: linear-gradient(to right, var(--lavender), var(--skyblue)); border-radius: 10px; transition: width 0.5s ease; } .tooltip { position: absolute; top: -35px; transform: translateX(-50%); background: white; color: #555; padding: 5px 10px; border-radius: 5px; font-size: 0.75rem; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); opacity: 0; visibility: hidden; transition: all 0.3s ease; } .tooltip::after { content: ''; position: absolute; bottom: -5px; left: 50%; transform: translateX(-50%); border-width: 5px 5px 0; border-style: solid; border-color: white transparent transparent; } @keyframes pulse { 0% { opacity: 0.5; transform: scale(1); } 50% { opacity: 0.8; transform: scale(1.05); } 100% { opacity: 0.5; transform: scale(1); } } @keyframes shimmer { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } } .pattern-overlay { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-image: url("data:image/svg+xml,%3Csvg width='40' height='40' viewBox='0 0 40 40' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%239C92AC' fill-opacity='0.03' fill-rule='evenodd'%3E%3Cpath d='M0 40L40 0H20L0 20M40 40V20L20 40'/%3E%3C/g%3E%3C/svg%3E"); z-index: -1; opacity: 0.8; } @media screen and (max-width: 600px) { .app-container { padding: 1.5rem; height: 100%; } h1 { font-size: 1.5rem; } h2 { font-size: 1.1rem; } .modules-container { grid-template-columns: 1fr; grid-auto-rows: minmax(130px, auto); } } </style> </head> <body> <div class="app-container"> <div class="pattern-overlay"></div> <h1>Interactive Learning Journey</h1> <h2>Begin your customized path to knowledge</h2> <p class="intro-text">Select the learning modules that spark your curiosity. Our adaptive system uses gentle visual cues to guide your educational journey, reducing cognitive load and enhancing focus on what matters most.</p> <div class="progress-bar"> <div class="progress-fill"></div> <div class="tooltip">25% Complete</div> </div> <div class="modules-container"> <div class="module module-1" data-tooltip="Study numerical concepts through interactive visualizations"> <div class="module-icon"> <i>π</i> </div> <h3 class="module-title">Mathematical Thinking</h3> <p class="module-desc">Visual number theory & applied problems</p> </div> <div class="module module-2" data-tooltip="Explore language structures and communication patterns"> <div class="module-icon"> <i>Aa</i> </div> <h3 class="module-title">Language Arts</h3> <p class="module-desc">Effective communication & storytelling</p> </div> <div class="module module-3" data-tooltip="Understand natural systems through interactive models"> <div class="module-icon"> <i>⚗️</i> </div> <h3 class="module-title">Scientific Inquiry</h3> <p class="module-desc">Hands-on experiments & discovery</p> </div> <div class="module module-4" data-tooltip="Develop creative problem-solving skills"> <div class="module-icon"> <i>🧩</i> </div> <h3 class="module-title">Critical Thinking</h3> <p class="module-desc">Logic puzzles & analytical challenges</p> </div> </div> <button class="continue-btn">Continue Your Journey</button> </div> <script> document.addEventListener('DOMContentLoaded', function() { const modules = document.querySelectorAll('.module'); const progressFill = document.querySelector('.progress-fill'); const tooltip = document.querySelector('.tooltip'); const continueBtn = document.querySelector('.continue-btn'); let selectedModules = 0; // Show tooltip on progress bar hover const progressBar = document.querySelector('.progress-bar'); progressBar.addEventListener('mouseover', function() { tooltip.style.opacity = '1'; tooltip.style.visibility = 'visible'; // Position the tooltip tooltip.style.left = `${progressFill.offsetWidth}px`; }); progressBar.addEventListener('mouseout', function() { tooltip.style.opacity = '0'; tooltip.style.visibility = 'hidden'; }); // Module selection modules.forEach(module => { // Create and add tooltip for each module const moduleTooltip = document.createElement('div'); moduleTooltip.className = 'tooltip'; moduleTooltip.textContent = module.dataset.tooltip; module.append(moduleTooltip); module.addEventListener('mouseover', function() { const moduleTooltip = this.querySelector('.tooltip'); moduleTooltip.style.opacity = '1'; moduleTooltip.style.visibility = 'visible'; }); module.addEventListener('mouseout', function() { const moduleTooltip = this.querySelector('.tooltip'); moduleTooltip.style.opacity = '0'; moduleTooltip.style.visibility = 'hidden'; }); module.addEventListener('click', function() { this.classList.toggle('active'); if (this.classList.contains('active')) { selectedModules++; } else { selectedModules--; } // Update progress const progress = (selectedModules / modules.length) * 100; progressFill.style.width = `${progress}%`; tooltip.textContent = `${Math.round(progress)}% Complete`; // Update button state if (selectedModules > 0) { continueBtn.classList.add('ready'); continueBtn.textContent = `Continue Your Journey (${selectedModules} selected)`; } else { continueBtn.classList.remove('ready'); continueBtn.textContent = 'Continue Your Journey'; } // Add soft pulse effect const icon = this.querySelector('.module-icon'); icon.animate([ { transform: 'scale(1)', boxShadow: icon.style.boxShadow }, { transform: 'scale(1.15)', boxShadow: icon.style.boxShadow.replace('25px', '35px') }, { transform: 'scale(1)', boxShadow: icon.style.boxShadow } ], { duration: 600, easing: 'ease-in-out' }); }); }); // Button animation continueBtn.addEventListener('click', function() { if (selectedModules > 0) { // Visual feedback instead of actual submission this.innerHTML = '<span style="opacity: 0;">Continue</span>'; const successText = document.createElement('div'); successText.textContent = "Journey Started!"; successText.style.position = 'absolute'; successText.style.left = '50%'; successText.style.top = '50%'; successText.style.transform = 'translate(-50%, -50%)'; successText.style.color = 'white'; successText.style.fontWeight = 'bold'; successText.style.opacity = '0'; successText.style.transition = 'opacity 0.5s ease'; this.appendChild(successText); setTimeout(() => { successText.style.opacity = '1'; }, 100); // Create ripple effect const ripple = document.createElement('div'); ripple.style.position = 'absolute'; ripple.style.width = '20px'; ripple.style.height = '20px'; ripple.style.borderRadius = '50%'; ripple.style.backgroundColor = 'rgba(255,255,255,0.7)'; ripple.style.transform = 'translate(-50%, -50%)'; ripple.style.animation = 'ripple 1s linear'; // Add ripple style const style = document.createElement('style'); style.textContent = ` @keyframes ripple { 0% { width: 0px; height: 0px; opacity: 0.8; } 100% { width: 500px; height: 500px; opacity: 0; } } `; document.head.appendChild(style); // Position at click ripple.style.left = '50%'; ripple.style.top = '50%'; this.appendChild(ripple); setTimeout(() => { ripple.remove(); this.innerHTML = 'Continue Your Journey'; modules.forEach(module => { module.classList.remove('active'); }); selectedModules = 0; progressFill.style.width = '0%'; }, 1500); } else { // Wiggle animation if no modules selected this.animate([ { transform: 'translateX(0)' }, { transform: 'translateX(-5px)' }, { transform: 'translateX(5px)' }, { transform: 'translateX(-5px)' }, { transform: 'translateX(0)' } ], { duration: 300, easing: 'ease-in-out' }); } }); // Initial animation modules.forEach((module, index) => { setTimeout(() => { module.style.opacity = '0'; module.style.transform = 'translateY(20px)'; module.style.transition = 'opacity 0.5s ease, transform 0.5s ease'; requestAnimationFrame(() => { module.style.opacity = '1'; module.style.transform = 'translateY(0)'; }); }, index * 150); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Resonance - Audio Visualizer</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; } body { background: #0c0c1d; color: #fff; height: 700px; width: 700px; overflow: hidden; position: relative; } .container { height: 100%; width: 100%; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; padding: 2rem; position: relative; z-index: 10; } .header { display: flex; justify-content: space-between; align-items: center; width: 100%; margin-bottom: 1.5rem; } .logo { font-size: 1.8rem; font-weight: 800; letter-spacing: -0.5px; background: linear-gradient(to right, #64e8de, #8a64eb); -webkit-background-clip: text; background-clip: text; color: transparent; } .upload-btn { background: rgba(255, 255, 255, 0.1); border: none; color: white; padding: 0.6rem 1.2rem; border-radius: 30px; font-size: 0.9rem; cursor: pointer; backdrop-filter: blur(10px); transition: all 0.3s ease; display: flex; align-items: center; gap: 8px; } .upload-btn:hover { background: rgba(255, 255, 255, 0.2); transform: translateY(-2px); } .upload-btn svg { width: 16px; height: 16px; fill: white; } .visualizer-container { width: 100%; height: 320px; position: relative; margin-top: 1rem; border-radius: 10px; overflow: hidden; background: rgba(0, 0, 0, 0.2); backdrop-filter: blur(10px); } .canvas-container { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } #visualizer { width: 100%; height: 100%; } .glow-container { position: absolute; top: 0; left: 0; width: 100%; height: 100%; filter: blur(25px); opacity: 0.7; z-index: -1; } #glow-canvas { width: 100%; height: 100%; } .player-info { width: 100%; display: flex; flex-direction: column; align-items: center; margin-top: 1.5rem; position: relative; } .track-info { width: 100%; text-align: left; margin-bottom: 1rem; } .track-title { font-size: 1.3rem; font-weight: 700; margin-bottom: 0.3rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .track-artist { font-size: 0.9rem; color: rgba(255, 255, 255, 0.7); margin-bottom: 0.5rem; } .time-info { width: 100%; display: flex; justify-content: space-between; font-size: 0.8rem; color: rgba(255, 255, 255, 0.6); margin-bottom: 0.5rem; } .progress-container { width: 100%; height: 6px; background: rgba(255, 255, 255, 0.1); border-radius: 3px; overflow: hidden; cursor: pointer; } .progress-bar { height: 100%; width: 45%; background: linear-gradient(to right, #64e8de, #8a64eb); border-radius: 3px; position: relative; } .progress-handle { position: absolute; right: -6px; top: 50%; transform: translateY(-50%); width: 12px; height: 12px; background: white; border-radius: 50%; box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); } .controls { display: flex; align-items: center; justify-content: space-between; width: 100%; margin-top: 1.5rem; } .control-btn { background: transparent; border: none; color: white; cursor: pointer; transition: all 0.2s ease; display: flex; align-items: center; justify-content: center; } .control-btn:hover { transform: scale(1.1); } .control-btn svg { width: 20px; height: 20px; fill: white; } .play-btn { width: 50px; height: 50px; background: rgba(255, 255, 255, 0.1); border-radius: 50%; display: flex; align-items: center; justify-content: center; backdrop-filter: blur(10px); transition: all 0.3s ease; } .play-btn:hover { background: rgba(255, 255, 255, 0.2); transform: scale(1.05); } .play-btn svg { width: 24px; height: 24px; } .volume-container { display: flex; align-items: center; gap: 10px; position: relative; } .volume-slider { width: 80px; height: 5px; -webkit-appearance: none; border-radius: 5px; outline: none; background: rgba(255, 255, 255, 0.2); background-image: linear-gradient(to right, #64e8de, #8a64eb 75%, rgba(255, 255, 255, 0.2) 75%); } .volume-slider::-webkit-slider-thumb { -webkit-appearance: none; width: 12px; height: 12px; background: white; border-radius: 50%; cursor: pointer; } .mode-selector { display: flex; align-items: center; justify-content: center; gap: 10px; margin-top: 1.5rem; } .mode-btn { padding: 0.4rem 0.8rem; background: rgba(255, 255, 255, 0.1); border: none; border-radius: 20px; font-size: 0.8rem; color: rgba(255, 255, 255, 0.7); cursor: pointer; transition: all 0.2s ease; } .mode-btn.active { background: rgba(255, 255, 255, 0.2); color: white; } .mode-btn:hover { background: rgba(255, 255, 255, 0.15); } .background-orbs { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: -2; overflow: hidden; } .orb { position: absolute; border-radius: 50%; filter: blur(30px); opacity: 0.3; transform-origin: center; } .orb-1 { width: 300px; height: 300px; background: #ff5e62; top: -100px; left: -100px; animation: float1 15s infinite alternate ease-in-out; } .orb-2 { width: 250px; height: 250px; background: #5b86e5; bottom: -50px; right: -50px; animation: float2 20s infinite alternate ease-in-out; } .orb-3 { width: 200px; height: 200px; background: #43e97b; top: 70%; left: 30%; animation: float3 15s infinite alternate ease-in-out; } @keyframes float1 { 0% { transform: translate(0, 0); } 100% { transform: translate(50px, 50px); } } @keyframes float2 { 0% { transform: translate(0, 0); } 100% { transform: translate(-60px, -60px); } } @keyframes float3 { 0% { transform: translate(0, 0); } 100% { transform: translate(-40px, 40px); } } .file-input { display: none; } @media (max-width: 600px) { .container { padding: 1rem; } .logo { font-size: 1.5rem; } .visualizer-container { height: 260px; } .controls { margin-top: 1rem; } .play-btn { width: 45px; height: 45px; } } </style> </head> <body> <div class="container"> <div class="header"> <div class="logo">Resonance</div> <label for="audio-file" class="upload-btn"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9 16h6v-6h4l-7-7-7 7h4v6zm-4 2h14v2H5v-2z"/></svg> Upload Track </label> <input type="file" id="audio-file" class="file-input" accept="audio/*"> </div> <div class="visualizer-container"> <div class="canvas-container"> <canvas id="visualizer"></canvas> </div> <div class="glow-container"> <canvas id="glow-canvas"></canvas> </div> </div> <div class="player-info"> <div class="track-info"> <div class="track-title">Midnight Cruise</div> <div class="track-artist">Synthwave Orchestra</div> <div class="time-info"> <span class="current-time">1:45</span> <span class="total-time">3:52</span> </div> <div class="progress-container" id="progress-container"> <div class="progress-bar"> <div class="progress-handle"></div> </div> </div> </div> <div class="controls"> <button class="control-btn" id="prev-btn"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6 6h2v12H6zm3.5 6l8.5 6V6z"/></svg> </button> <button class="control-btn rewind-btn"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z"/></svg> </button> <button class="play-btn" id="play-btn"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8 5v14l11-7z"/></svg> </button> <button class="control-btn forward-btn"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18 13c0 3.31-2.69 6-6 6s-6-2.69-6-6h2c0 2.21 1.79 4 4 4s4-1.79 4-4-1.79-4-4-4v3l-5-5 5-5v3c3.31 0 6 2.69 6 6z"/></svg> </button> <button class="control-btn" id="next-btn"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z"/></svg> </button> </div> <div class="mode-selector"> <button class="mode-btn active" data-mode="bars">Bars</button> <button class="mode-btn" data-mode="circular">Wave</button> <button class="mode-btn" data-mode="particles">Particles</button> <div class="volume-container"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="white"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/></svg> <input type="range" class="volume-slider" min="0" max="100" value="75"> </div> </div> </div> </div> <div class="background-orbs"> <div class="orb orb-1"></div> <div class="orb orb-2"></div> <div class="orb orb-3"></div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Elements const visualizerCanvas = document.getElementById('visualizer'); const glowCanvas = document.getElementById('glow-canvas'); const fileInput = document.getElementById('audio-file'); const playBtn = document.getElementById('play-btn'); const prevBtn = document.getElementById('prev-btn'); const nextBtn = document.getElementById('next-btn'); const progressContainer = document.getElementById('progress-container'); const progressBar = document.querySelector('.progress-bar'); const currentTimeDisplay = document.querySelector('.current-time'); const totalTimeDisplay = document.querySelector('.total-time'); const volumeSlider = document.querySelector('.volume-slider'); const modeBtns = document.querySelectorAll('.mode-btn'); const trackTitle = document.querySelector('.track-title'); const trackArtist = document.querySelector('.track-artist'); // Canvas context setup const ctx = visualizerCanvas.getContext('2d'); const glowCtx = glowCanvas.getContext('2d'); // Set canvas sizes visualizerCanvas.width = visualizerCanvas.offsetWidth; visualizerCanvas.height = visualizerCanvas.offsetHeight; glowCanvas.width = glowCanvas.offsetWidth; glowCanvas.height = glowCanvas.offsetHeight; // Audio setup let audioContext, analyser, source, audioElement, dataArray, bufferLength; let isPlaying = false; let currentMode = 'bars'; // Colors for visualizer const colors = [ { r: 100, g: 232, b: 222 }, // Cyan { r: 138, g: 100, b: 235 }, // Purple { r: 255, g: 94, b: 98 }, // Pink { r: 67, g: 233, b: 123 } // Green ]; // Initialize demo audio const demoAudio = new Audio('https://cdn.pixabay.com/download/audio/2022/01/18/audio_d0c6ff1a89.mp3?filename=electronic-future-beats-117997.mp3'); demoAudio.crossOrigin = "anonymous"; demoAudio.loop = true; // Update progress bar function updateProgress() { if (!audioElement) return; const percent = (audioElement.currentTime / audioElement.duration) * 100; progressBar.style.width = `${percent}%`; // Update time displays currentTimeDisplay.textContent = formatTime(audioElement.currentTime); totalTimeDisplay.textContent = formatTime(audioElement.duration); requestAnimationFrame(updateProgress); } // Format time to mm:ss function formatTime(seconds) { const minutes = Math.floor(seconds / 60); const remainingSeconds = Math.floor(seconds % 60); return `${minutes}:${remainingSeconds < 10 ? '0' : ''}${remainingSeconds}`; } // Initialize audio context and analyzer function initAudio(audio) { if (audioContext) audioContext.close(); audioElement = audio; audioContext = new (window.AudioContext || window.webkitAudioContext)(); analyser = audioContext.createAnalyser(); source = audioContext.createMediaElementSource(audioElement); source.connect(analyser); analyser.connect(audioContext.destination); analyser.fftSize = 256; bufferLength = analyser.frequencyBinCount; dataArray = new Uint8Array(bufferLength); // Start visualizer draw(); updateProgress(); } // Toggle play/pause function togglePlay() { if (!audioElement) { audioElement = demoAudio; initAudio(audioElement); } if (isPlaying) { audioElement.pause(); playBtn.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8 5v14l11-7z"/></svg>'; } else { audioElement.play(); playBtn.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></svg>'; } isPlaying = !isPlaying; } // Draw visualizer based on mode function draw() { if (!analyser) return; requestAnimationFrame(draw); analyser.getByteFrequencyData(dataArray); // Clear canvases ctx.clearRect(0, 0, visualizerCanvas.width, visualizerCanvas.height); glowCtx.clearRect(0, 0, glowCanvas.width, glowCanvas.height); // Draw based on current mode switch(currentMode) { case 'bars': drawBars(); break; case 'circular': drawCircular(); break; case 'particles': drawParticles(); break; } } // Bar visualizer mode function drawBars() { const barWidth = (visualizerCanvas.width / bufferLength) * 2.5; let x = 0; for (let i = 0; i < bufferLength; i++) { const barHeight = dataArray[i] * 0.7; // Calculate color based on frequency const colorIndex = Math.floor((i / bufferLength) * colors.length); const nextColorIndex = (colorIndex + 1) % colors.length; const ratio = (i / bufferLength) * colors.length - colorIndex; const r = Math.floor(colors[colorIndex].r * (1 - ratio) + colors[nextColorIndex].r * ratio); const g = Math.floor(colors[colorIndex].g * (1 - ratio) + colors[nextColorIndex].g * ratio); const b = Math.floor(colors[colorIndex].b * (1 - ratio) + colors[nextColorIndex].b * ratio); // Draw bar on main canvas ctx.fillStyle = `rgb(${r}, ${g}, ${b})`; ctx.fillRect(x, visualizerCanvas.height - barHeight, barWidth, barHeight); // Draw glow effect glowCtx.fillStyle = `rgb(${r}, ${g}, ${b})`; glowCtx.fillRect(x, glowCanvas.height - barHeight, barWidth, barHeight); x += barWidth + 1; } } // Circular wave visualizer mode function drawCircular() { const centerX = visualizerCanvas.width / 2; const centerY = visualizerCanvas.height / 2; const radius = 70; const maxAmplitude = 50; // Draw on main canvas drawWave(ctx, centerX, centerY, radius, maxAmplitude); // Draw on glow canvas drawWave(glowCtx, centerX, centerY, radius, maxAmplitude); } function drawWave(context, centerX, centerY, radius, maxAmplitude) { context.beginPath(); context.lineWidth = 2; for (let i = 0; i < 360; i++) { const index = Math.floor(i * bufferLength / 360); const amplitude = dataArray[index] / 255 * maxAmplitude; const r = radius + amplitude; const x = centerX + r * Math.cos(i * Math.PI / 180); const y = centerY + r * Math.sin(i * Math.PI / 180); if (i === 0) { context.moveTo(x, y); } else { context.lineTo(x, y); } // Calculate color const colorIndex = Math.floor((i / 360) * colors.length); const nextColorIndex = (colorIndex + 1) % colors.length; const ratio = (i / 360) * colors.length - colorIndex; const r_color = Math.floor(colors[colorIndex].r * (1 - ratio) + colors[nextColorIndex].r * ratio); const g_color = Math.floor(colors[colorIndex].g * (1 - ratio) + colors[nextColorIndex].g * ratio); const b_color = Math.floor(colors[colorIndex].b * (1 - ratio) + colors[nextColorIndex].b * ratio); context.strokeStyle = `rgb(${r_color}, ${g_color}, ${b_color})`; } context.closePath(); context.stroke(); } // Particle visualizer mode let particles = []; function drawParticles() { // Create new particles based on audio frequencies const particleCount = 1; const threshold = 50; // Minimum frequency value to spawn a particle for (let i = 0; i < bufferLength; i += 5) { if (dataArray[i] > threshold) { const speed = dataArray[i] / 150; for (let j = 0; j < particleCount; j++) { const colorIndex = Math.floor(Math.random() * colors.length); const size = 2 + Math.random() * 3 + (dataArray[i] / 50); particles.push({ x: visualizerCanvas.width / 2, y: visualizerCanvas.height / 2, size: size, color: colors[colorIndex], speed: speed, angle: Math.random() * Math.PI * 2, life: 100 }); } } } // Update and draw particles for (let i = 0; i < particles.length; i++) { const p = particles[i]; p.x += Math.cos(p.angle) * p.speed; p.y += Math.sin(p.angle) * p.speed; p.life -= 1; if (p.life <= 0 || p.x < 0 || p.x > visualizerCanvas.width || p.y < 0 || p.y > visualizerCanvas.height) { particles.splice(i, 1); i--; continue; } const alpha = p.life / 100; // Draw on main canvas ctx.beginPath(); ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2); ctx.fillStyle = `rgba(${p.color.r}, ${p.color.g}, ${p.color.b}, ${alpha})`; ctx.fill(); // Draw on glow canvas glowCtx.beginPath(); glowCtx.arc(p.x, p.y, p.size * 1.5, 0, Math.PI * 2); glowCtx.fillStyle = `rgba(${p.color.r}, ${p.color.g}, ${p.color.b}, ${alpha * 0.7})`; glowCtx.fill(); } } // Event listeners playBtn.addEventListener('click', togglePlay); fileInput.addEventListener('change', function(e) { const file = e.target.files[0]; if (!file) return; const objectURL = URL.createObjectURL(file); if (audioElement) { audioElement.pause(); audioElement.src = ''; } const audio = new Audio(objectURL); audio.addEventListener('loadedmetadata', function() { trackTitle.textContent = file.name.replace(/\.[^/.]+$/, ""); trackArtist.textContent = "Local File"; initAudio(audio); isPlaying = false; togglePlay(); }); }); progressContainer.addEventListener('click', function(e) { if (!audioElement) return; const percent = e.offsetX / progressContainer.offsetWidth; audioElement.currentTime = percent * audioElement.duration; progressBar.style.width = `${percent * 100}%`; }); volumeSlider.addEventListener('input', function() { if (audioElement) { audioElement.volume = volumeSlider.value / 100; } // Update volume slider background volumeSlider.style.backgroundImage = `linear-gradient(to right, #64e8de, #8a64eb ${volumeSlider.value}%, rgba(255, 255, 255, 0.2) ${volumeSlider.value}%)`; }); modeBtns.forEach(btn => { btn.addEventListener('click', function() { currentMode = this.dataset.mode; modeBtns.forEach(b => b.classList.remove('active')); this.classList.add('active'); if (currentMode === 'particles') { particles = []; } }); }); // Handle window resize window.addEventListener('resize', function() { visualizerCanvas.width = visualizerCanvas.offsetWidth; visualizerCanvas.height = visualizerCanvas.offsetHeight; glowCanvas.width = glowCanvas.offsetWidth; glowCanvas.height = glowCanvas.offsetHeight; }); // Initialize with demo audio initAudio(demoAudio); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Corporate CTA Glow Effect</title> <style> :root { --primary: #0a2540; --secondary: #635bff; --light: #f7fafc; --text: #4a5568; --success: #38a169; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; } body { background-color: var(--light); color: var(--text); height: 100%; width: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 2rem; overflow-x: hidden; } .container { max-width: 650px; width: 100%; background-color: white; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05); border-radius: 12px; padding: 2.5rem; margin: 0 auto; position: relative; overflow: hidden; } .logo { font-weight: 700; font-size: 1.25rem; color: var(--primary); margin-bottom: 1.5rem; display: flex; align-items: center; } .logo-icon { width: 24px; height: 24px; background-color: var(--secondary); border-radius: 6px; margin-right: 0.75rem; position: relative; overflow: hidden; } .logo-icon::after { content: ''; position: absolute; top: 6px; left: 6px; width: 12px; height: 12px; background-color: white; border-radius: 3px; } h1 { font-size: 2rem; font-weight: 700; color: var(--primary); margin-bottom: 1rem; line-height: 1.2; } p { line-height: 1.6; margin-bottom: 2rem; } .section { margin-bottom: 2.5rem; } .feature-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1.5rem; margin-bottom: 2.5rem; } .feature { padding: 1.25rem; border-radius: 8px; background-color: rgba(249, 250, 251, 0.8); border: 1px solid rgba(226, 232, 240, 0.6); transition: transform 0.3s ease, box-shadow 0.3s ease; } .feature:hover { transform: translateY(-3px); box-shadow: 0 8px 15px rgba(0, 0, 0, 0.05); } .feature-title { font-weight: 600; font-size: 1rem; color: var(--primary); margin-bottom: 0.5rem; display: flex; align-items: center; } .feature-title svg { margin-right: 0.5rem; color: var(--secondary); } .feature-desc { font-size: 0.875rem; color: var(--text); margin: 0; } .cta-group { display: flex; gap: 1rem; flex-wrap: wrap; } /* CTA Button with Glow Effect */ .btn { padding: 0.75rem 1.5rem; border-radius: 8px; font-weight: 600; font-size: 0.95rem; cursor: pointer; transition: all 0.3s ease; position: relative; border: none; outline: none; letter-spacing: 0.02em; overflow: hidden; display: inline-flex; align-items: center; justify-content: center; text-decoration: none; } .btn-primary { background-color: var(--secondary); color: white; box-shadow: 0 0 0 0 rgba(99, 91, 255, 0); } .btn-secondary { background-color: transparent; color: var(--primary); border: 1px solid #e2e8f0; } /* The core glow effect */ .btn-glow { position: relative; } .btn-glow::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; border-radius: 8px; background: radial-gradient( circle at center, rgba(255, 255, 255, 0.8) 0%, rgba(255, 255, 255, 0) 70% ); opacity: 0; transform: scale(0.85); filter: blur(10px); transition: opacity 0.4s ease, transform 0.4s ease; z-index: -1; pointer-events: none; } .btn-glow:hover::before { opacity: 0.5; transform: scale(1.2); } .btn-primary.btn-glow:hover { box-shadow: 0 0 20px 5px rgba(99, 91, 255, 0.25); transform: translateY(-2px); } .btn-secondary.btn-glow:hover { background-color: rgba(247, 250, 252, 0.8); transform: translateY(-2px); box-shadow: 0 0 15px rgba(226, 232, 240, 0.6); } .btn svg { margin-left: 0.5rem; transition: transform 0.3s ease; } .btn:hover svg { transform: translateX(3px); } .success-message { display: none; align-items: center; background-color: rgba(56, 161, 105, 0.1); color: var(--success); padding: 0.75rem 1rem; border-radius: 8px; font-size: 0.9rem; font-weight: 500; margin-top: 1rem; animation: fadeIn 0.5s ease forwards; } .success-message svg { margin-right: 0.5rem; flex-shrink: 0; } /* Decorative elements */ .decorative-shape { position: absolute; border-radius: 50%; pointer-events: none; z-index: -1; opacity: 0.4; filter: blur(30px); } .shape-1 { width: 250px; height: 250px; background-color: rgba(99, 91, 255, 0.15); top: -50px; right: -100px; } .shape-2 { width: 200px; height: 200px; background-color: rgba(243, 186, 47, 0.15); bottom: -80px; left: -60px; } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(99, 91, 255, 0.4); } 70% { box-shadow: 0 0 0 10px rgba(99, 91, 255, 0); } 100% { box-shadow: 0 0 0 0 rgba(99, 91, 255, 0); } } /* Responsive styles */ @media (max-width: 640px) { .container { padding: 1.5rem; } h1 { font-size: 1.5rem; } .feature-grid { grid-template-columns: 1fr; } .cta-group { flex-direction: column; } .btn { width: 100%; } } </style> </head> <body> <div class="container"> <div class="logo"> <div class="logo-icon"></div> Quantum </div> <div class="section"> <h1>Enterprise data security that scales with your business</h1> <p>Our integrated compliance platform helps your team meet security requirements while streamlining your workflow. No more checklist fatigue or scattered documentation.</p> </div> <div class="feature-grid"> <div class="feature"> <div class="feature-title"> <svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M9 12L11 14L15 10M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> SOC 2 Compliance </div> <p class="feature-desc">Streamline your audit preparation with automated evidence collection and controls monitoring.</p> </div> <div class="feature"> <div class="feature-title"> <svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M12 15V17M6 21H18C19.1046 21 20 20.1046 20 19V13C20 11.8954 19.1046 11 18 11H6C4.89543 11 4 11.8954 4 13V19C4 20.1046 4.89543 21 6 21ZM16 11V7C16 4.79086 14.2091 3 12 3C9.79086 3 8 4.79086 8 7V11H16Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> Data Protection </div> <p class="feature-desc">Enterprise-grade encryption and access controls safeguard sensitive customer information.</p> </div> <div class="feature"> <div class="feature-title"> <svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M9 5H7C5.89543 5 5 5.89543 5 7V19C5 20.1046 5.89543 21 7 21H17C18.1046 21 19 20.1046 19 19V7C19 5.89543 18.1046 5 17 5H15M9 5C9 6.10457 9.89543 7 11 7H13C14.1046 7 15 6.10457 15 5M9 5C9 3.89543 9.89543 3 11 3H13C14.1046 3 15 3.89543 15 5M12 12H15M12 16H15M9 12H9.01M9 16H9.01" stroke="currentColor" stroke-width="2" stroke-linecap="round"/> </svg> Policy Management </div> <p class="feature-desc">Create, distribute, and track security policies and procedures across your organization.</p> </div> <div class="feature"> <div class="feature-title"> <svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M8 16H6C4.89543 16 4 15.1046 4 14V6C4 4.89543 4.89543 4 6 4H14C15.1046 4 16 4.89543 16 6V8M10 20H18C19.1046 20 20 19.1046 20 18V10C20 8.89543 19.1046 8 18 8H10C8.89543 8 8 8.89543 8 10V18C8 19.1046 8.89543 20 10 20Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> Integration Hub </div> <p class="feature-desc">Connect with 50+ enterprise tools to automate security monitoring and evidence collection.</p> </div> </div> <div class="cta-group"> <button id="demo-btn" class="btn btn-primary btn-glow"> Request Security Demo <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M5 12H19M19 12L12 5M19 12L12 19" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> </button> <button id="docs-btn" class="btn btn-secondary btn-glow"> View Compliance Documentation <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M10 6H6C4.89543 6 4 6.89543 4 8V18C4 19.1046 4.89543 20 6 20H16C17.1046 20 18 19.1046 18 18V14M14 4H20M20 4V10M20 4L10 14" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> </button> </div> <div id="success-message" class="success-message"> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M9 12L11 14L15 10M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> <span id="success-text">Thank you! A security specialist will contact you shortly.</span> </div> <!-- Decorative shapes --> <div class="decorative-shape shape-1"></div> <div class="decorative-shape shape-2"></div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const demoBtn = document.getElementById('demo-btn'); const docsBtn = document.getElementById('docs-btn'); const successMessage = document.getElementById('success-message'); const successText = document.getElementById('success-text'); // Demo button click handler demoBtn.addEventListener('click', function() { successText.textContent = "Thank you! A security specialist will contact you shortly."; successMessage.style.display = "flex"; // Add subtle animation to the button this.style.animation = "pulse 1s"; setTimeout(() => { this.style.animation = ""; }, 1000); }); // Documentation button click handler docsBtn.addEventListener('click', function() { successText.textContent = "Documentation access granted. You'll receive the link shortly."; successMessage.style.display = "flex"; // Add subtle animation to the button this.style.animation = "pulse 1s"; setTimeout(() => { this.style.animation = ""; }, 1000); }); // Create glow effect cursor follow for primary button const btns = document.querySelectorAll('.btn-primary'); btns.forEach(btn => { btn.addEventListener('mousemove', function(e) { const rect = this.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; // Update the radial gradient position based on cursor this.style.background = `radial-gradient(circle at ${x}px ${y}px, #7570ff 0%, var(--secondary) 50%)`; }); btn.addEventListener('mouseleave', function() { // Reset the background this.style.background = "var(--secondary)"; }); }); }); </script> </body> </html>
<html> <head> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; } body { background-color: #f3f4f8; display: flex; justify-content: center; align-items: center; min-height: 700px; overflow: hidden; color: #333; } .container { width: 100%; max-width: 700px; padding: 30px; height: 700px; display: flex; flex-direction: column; position: relative; } .phone-mockup { background-color: #fff; border-radius: 40px; width: 280px; height: 580px; margin: 0 auto; position: relative; overflow: hidden; box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1), 0 3px 8px rgba(0, 0, 0, 0.05), inset 0 0 0 2px rgba(255, 255, 255, 0.1); border: 8px solid #444; } .status-bar { height: 30px; background-color: #1a1a1a; display: flex; justify-content: space-between; padding: 0 15px; align-items: center; color: white; font-size: 12px; } .app-content { padding: 20px 15px; height: calc(100% - 30px); position: relative; background-color: #f9fafc; } .app-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 25px; } .app-title { font-size: 20px; font-weight: 700; color: #2c2d38; } .app-menu { display: flex; gap: 5px; } .menu-dot { width: 6px; height: 6px; border-radius: 50%; background-color: #aaa; } .section-title { font-size: 14px; font-weight: 600; margin-bottom: 15px; color: #5a5c66; } .task-list { display: flex; flex-direction: column; gap: 12px; margin-bottom: 25px; } .task-item { display: flex; align-items: center; padding: 15px; background-color: white; border-radius: 12px; box-shadow: 0 2px 6px rgba(0,0,0,0.03); position: relative; transition: transform 0.2s, box-shadow 0.2s; } .task-item:hover { transform: translateY(-2px); box-shadow: 0 4px 10px rgba(0,0,0,0.06); } .task-checkbox { width: 22px; height: 22px; border-radius: 6px; border: 2px solid #e0e0e0; margin-right: 12px; cursor: pointer; transition: all 0.2s; } .task-item.completed .task-checkbox { background-color: #4e7eff; border-color: #4e7eff; position: relative; } .task-item.completed .task-checkbox:after { content: '✓'; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: white; font-size: 14px; } .task-content { flex: 1; } .task-title { font-size: 14px; font-weight: 500; margin-bottom: 3px; color: #2c2d38; } .task-item.completed .task-title { text-decoration: line-through; color: #a0a0a0; } .task-meta { display: flex; justify-content: space-between; font-size: 12px; color: #9a9da8; } .task-due { display: flex; align-items: center; gap: 4px; } .nav-bar { position: absolute; bottom: 0; left: 0; right: 0; height: 60px; background-color: white; display: flex; justify-content: space-around; align-items: center; border-top: 1px solid #f0f0f0; } .nav-item { display: flex; flex-direction: column; align-items: center; padding: 6px 15px; cursor: pointer; position: relative; } .nav-icon { width: 22px; height: 22px; display: flex; justify-content: center; align-items: center; position: relative; } .nav-icon svg { width: 20px; height: 20px; fill: #a0a0a0; transition: fill 0.2s; } .nav-item.active .nav-icon svg { fill: #4e7eff; } .nav-label { font-size: 10px; color: #9a9da8; margin-top: 4px; transition: color 0.2s; } .nav-item.active .nav-label { color: #4e7eff; } /* Notification Badge with Glow Effect */ .notification-badge { position: absolute; top: -2px; right: -2px; background-color: #4285f4; color: white; font-size: 11px; font-weight: 600; min-width: 18px; height: 18px; border-radius: 9px; display: flex; justify-content: center; align-items: center; box-shadow: 0 0 0 rgba(66, 133, 244, 0.4); animation: pulse 2s infinite; } @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(66, 133, 244, 0.7); } 70% { box-shadow: 0 0 0 8px rgba(66, 133, 244, 0); } 100% { box-shadow: 0 0 0 0 rgba(66, 133, 244, 0); } } /* Different notification badges with different glow colors */ .notification-badge.urgent { background-color: #ea4335; animation: pulse-urgent 2s infinite; } @keyframes pulse-urgent { 0% { box-shadow: 0 0 0 0 rgba(234, 67, 53, 0.7); } 70% { box-shadow: 0 0 0 8px rgba(234, 67, 53, 0); } 100% { box-shadow: 0 0 0 0 rgba(234, 67, 53, 0); } } .notification-badge.reminder { background-color: #34a853; animation: pulse-reminder 2s infinite; } @keyframes pulse-reminder { 0% { box-shadow: 0 0 0 0 rgba(52, 168, 83, 0.7); } 70% { box-shadow: 0 0 0 8px rgba(52, 168, 83, 0); } 100% { box-shadow: 0 0 0 0 rgba(52, 168, 83, 0); } } .notification-badge.mention { background-color: #fbbc05; animation: pulse-mention 2s infinite; } @keyframes pulse-mention { 0% { box-shadow: 0 0 0 0 rgba(251, 188, 5, 0.7); } 70% { box-shadow: 0 0 0 8px rgba(251, 188, 5, 0); } 100% { box-shadow: 0 0 0 0 rgba(251, 188, 5, 0); } } /* Controls for demo */ .controls { position: absolute; bottom: 30px; left: 0; right: 0; display: flex; justify-content: center; gap: 15px; } .control-btn { padding: 10px 20px; background-color: #4e7eff; color: white; border: none; border-radius: 8px; font-size: 14px; font-weight: 500; cursor: pointer; box-shadow: 0 2px 5px rgba(78, 126, 255, 0.3); transition: all 0.2s; } .control-btn:hover { background-color: #3a6aed; transform: translateY(-2px); box-shadow: 0 4px 8px rgba(78, 126, 255, 0.4); } .notification-info { text-align: center; font-size: 14px; color: #666; max-width: 300px; margin: 0 auto 20px; line-height: 1.5; } .title { text-align: center; margin-bottom: 15px; font-size: 24px; font-weight: 700; color: #2c2d38; } .tooltip { position: absolute; background-color: #333; color: white; padding: 8px 12px; border-radius: 6px; font-size: 12px; z-index: 100; opacity: 0; visibility: hidden; transition: opacity 0.3s, visibility 0.3s; white-space: nowrap; } .tooltip:after { content: ''; position: absolute; bottom: -5px; left: 50%; transform: translateX(-50%); width: 0; height: 0; border-left: 6px solid transparent; border-right: 6px solid transparent; border-top: 6px solid #333; } .notification-badge:hover + .tooltip { opacity: 1; visibility: visible; } /* Badge animation when new notifications come in */ @keyframes pop { 0% { transform: scale(0.5); } 50% { transform: scale(1.2); } 100% { transform: scale(1); } } .notification-badge.new { animation: pop 0.3s, pulse 2s infinite; } .demo-section { margin-top: 30px; } .demo-badges { display: flex; justify-content: center; gap: 30px; margin-bottom: 20px; } .badge-demo { display: flex; flex-direction: column; align-items: center; gap: 10px; } .badge-container { width: 50px; height: 50px; background-color: #f0f2f7; border-radius: 12px; display: flex; justify-content: center; align-items: center; position: relative; } .badge-container svg { width: 24px; height: 24px; fill: #6e7179; } .badge-label { font-size: 12px; color: #6e7179; font-weight: 500; } </style> </head> <body> <div class="container"> <h1 class="title">Notification Glow Effect</h1> <p class="notification-info"> Our sleek, modern notification badges use cool shades with an outer glow effect. Each notification type has a unique color and pulsating effect to catch attention without disrupting focus. </p> <div class="demo-section"> <div class="demo-badges"> <div class="badge-demo"> <div class="badge-container"> <svg viewBox="0 0 24 24"> <path d="M12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4M12,10.5A1.5,1.5 0 0,1 13.5,12A1.5,1.5 0 0,1 12,13.5A1.5,1.5 0 0,1 10.5,12A1.5,1.5 0 0,1 12,10.5M7.5,10.5A1.5,1.5 0 0,1 9,12A1.5,1.5 0 0,1 7.5,13.5A1.5,1.5 0 0,1 6,12A1.5,1.5 0 0,1 7.5,10.5M16.5,10.5A1.5,1.5 0 0,1 18,12A1.5,1.5 0 0,1 16.5,13.5A1.5,1.5 0 0,1 15,12A1.5,1.5 0 0,1 16.5,10.5Z" /> </svg> <span class="notification-badge">3</span> <div class="tooltip">Standard messages</div> </div> <span class="badge-label">Messages</span> </div> <div class="badge-demo"> <div class="badge-container"> <svg viewBox="0 0 24 24"> <path d="M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M12,4A8,8 0 0,1 20,12A8,8 0 0,1 12,20A8,8 0 0,1 4,12A8,8 0 0,1 12,4M16.5,11.5H14V16H10V11.5H7.5L12,7L16.5,11.5Z" /> </svg> <span class="notification-badge urgent">5</span> <div class="tooltip">High priority tasks</div> </div> <span class="badge-label">Tasks</span> </div> <div class="badge-demo"> <div class="badge-container"> <svg viewBox="0 0 24 24"> <path d="M12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22C6.47,22 2,17.5 2,12A10,10 0 0,1 12,2M12.5,7V12.25L17,14.92L16.25,16.15L11,13V7H12.5Z" /> </svg> <span class="notification-badge reminder">2</span> <div class="tooltip">Upcoming reminders</div> </div> <span class="badge-label">Reminders</span> </div> <div class="badge-demo"> <div class="badge-container"> <svg viewBox="0 0 24 24"> <path d="M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,14C16.42,14 20,15.79 20,18V20H4V18C4,15.79 7.58,14 12,14Z" /> </svg> <span class="notification-badge mention">7</span> <div class="tooltip">Team mentions</div> </div> <span class="badge-label">Mentions</span> </div> </div> </div> <div class="phone-mockup"> <div class="status-bar"> <span>12:42</span> <span>📶 100%</span> </div> <div class="app-content"> <div class="app-header"> <div class="app-title">Focus Pro</div> <div class="app-menu"> <div class="menu-dot"></div> <div class="menu-dot"></div> <div class="menu-dot"></div> </div> </div> <div class="section-title">Today's Tasks</div> <div class="task-list"> <div class="task-item completed"> <div class="task-checkbox"></div> <div class="task-content"> <div class="task-title">Design team meeting</div> <div class="task-meta"> <div class="task-due">9:30 AM</div> <div class="task-project">Project X</div> </div> </div> </div> <div class="task-item"> <div class="task-checkbox"></div> <div class="task-content"> <div class="task-title">Review client feedback</div> <div class="task-meta"> <div class="task-due">11:00 AM</div> <div class="task-project">Client Portal</div> </div> </div> </div> <div class="task-item"> <div class="task-checkbox"></div> <div class="task-content"> <div class="task-title">Finalize UI components</div> <div class="task-meta"> <div class="task-due">2:30 PM</div> <div class="task-project">Design System</div> </div> </div> </div> </div> <div class="section-title">Upcoming</div> <div class="task-list"> <div class="task-item"> <div class="task-checkbox"></div> <div class="task-content"> <div class="task-title">Weekly retrospective</div> <div class="task-meta"> <div class="task-due">Tomorrow, 4:00 PM</div> <div class="task-project">Team</div> </div> </div> </div> <div class="task-item"> <div class="task-checkbox"></div> <div class="task-content"> <div class="task-title">Submit Q3 budget report</div> <div class="task-meta"> <div class="task-due">Friday, 12:00 PM</div> <div class="task-project">Finance</div> </div> </div> </div> </div> <div class="nav-bar"> <div class="nav-item active"> <div class="nav-icon"> <svg viewBox="0 0 24 24"> <path d="M10,20V14H14V20H19V12H22L12,3L2,12H5V20H10Z" /> </svg> </div> <div class="nav-label">Home</div> </div> <div class="nav-item"> <div class="nav-icon"> <svg viewBox="0 0 24 24"> <path d="M19,19H5V8H19M16,1V3H8V1H6V3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3H18V1" /> </svg> <span class="notification-badge reminder">2</span> <div class="tooltip">2 upcoming deadlines</div> </div> <div class="nav-label">Calendar</div> </div> <div class="nav-item"> <div class="nav-icon"> <svg viewBox="0 0 24 24"> <path d="M21,11.5A8.38,8.38 0 0,0 14.4,1.5A1.5,1.5 0 0,0 12.9,3A1.5,1.5 0 0,0 14.4,4.5C17.75,4.5 20.5,7.25 20.5,10.6C20.5,13.95 17.75,16.7 14.4,16.7A1.5,1.5 0 0,0 12.9,18.2A1.5,1.5 0 0,0 14.4,19.7A8.38,8.38 0 0,0 21,11.5M12.5,11.5A8.38,8.38 0 0,0 5.9,3A1.5,1.5 0 0,0 4.4,4.5A1.5,1.5 0 0,0 5.9,6C9.25,6 12,8.75 12,12.1C12,15.45 9.25,18.2 5.9,18.2A1.5,1.5 0 0,0 4.4,19.7A1.5,1.5 0 0,0 5.9,21.2A8.38,8.38 0 0,0 12.5,12.7" /> </svg> <span class="notification-badge urgent">5</span> <div class="tooltip">5 tasks need attention</div> </div> <div class="nav-label">Projects</div> </div> <div class="nav-item"> <div class="nav-icon"> <svg viewBox="0 0 24 24"> <path d="M12,3C6.5,3 2,6.58 2,11C2,15.42 6.5,19 12,19C14.4,19 16.59,18.07 18.2,16.46L23,21L21.55,19.58L16.75,15.06C15.14,16.66 12.95,17.58 10.55,17.58C7.27,17.58 4.53,15.88 4.53,13.76C4.53,12.65 5.15,11.67 6.18,11C5.15,10.33 4.53,9.35 4.53,8.24C4.53,6.12 7.27,4.42 10.55,4.42C13.83,4.42 16.57,6.12 16.57,8.24C16.57,9.35 15.95,10.33 14.92,11C15.95,11.67 16.57,12.65 16.57,13.76C16.57,14.61 16.03,15.39 15.12,16C16.71,15.34 17.87,14.37 18.35,13.22L18.35,13.22C18.77,12.42 19,11.58 19,10.7C19,7.72 15.87,5.3 12,5.3C8.13,5.3 5,7.72 5,10.7C5,12.06 5.61,13.3 6.64,14.28C6,14.7 5.58,15.14 5.32,15.58C3.9,14.43 3,12.73 3,10.7C3,7.16 7.03,4.3 12,4.3C16.97,4.3 21,7.16 21,10.7C21,12.36 20.3,13.86 19.12,14.96C19.72,14.04 20.05,12.88 20.05,11.66C20.05,8.39 16.41,5.74 12,5.74C7.59,5.74 3.95,8.39 3.95,11.66C3.95,14.93 7.59,17.58 12,17.58C12.92,17.58 13.8,17.44 14.61,17.19L14.61,17.19L14.61,17.19L14.61,17.19L14.61,17.19L14.62,17.19L14.62,17.19C16.36,16.55 17.81,15.35 18.63,13.84C19.11,14.6 19.39,15.46 19.39,16.36C19.39,18.32 18.03,20.01 15.98,20.95C14.82,21.42 13.46,21.66 12.06,21.66C6.53,21.66 2.03,18.08 2.03,13.66C2.03,9.24 6.53,5.66 12.06,5.66C17.59,5.66 22.09,9.24 22.09,13.66" /> </svg> <span class="notification-badge mention">7</span> <div class="tooltip">7 team messages</div> </div> <div class="nav-label">Chat</div> </div> </div> </div> </div> <div class="controls"> <button id="addNotification" class="control-btn">Add New Notification</button> <button id="clearNotifications" class="control-btn">Clear All</button> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Initialize task checkbox behavior const taskCheckboxes = document.querySelectorAll('.task-checkbox'); taskCheckboxes.forEach(checkbox => { checkbox.addEventListener('click', function() { const taskItem = this.closest('.task-item'); taskItem.classList.toggle('completed'); }); }); // Add notification function const addNotificationBtn = document.getElementById('addNotification'); const clearNotificationsBtn = document.getElementById('clearNotifications'); const notificationTypes = ['', 'urgent', 'reminder', 'mention']; const navIcons = document.querySelectorAll('.nav-icon'); addNotificationBtn.addEventListener('click', function() { const randomIcon = navIcons[Math.floor(Math.random() * navIcons.length)]; let badge = randomIcon.querySelector('.notification-badge'); if (badge) { // If badge exists, increment count let count = parseInt(badge.textContent); badge.textContent = count + 1; badge.classList.add('new'); // Remove the new class after animation completes setTimeout(() => { badge.classList.remove('new'); }, 300); } else { // Create new badge if none exists badge = document.createElement('span'); badge.className = 'notification-badge new ' + notificationTypes[Math.floor(Math.random() * notificationTypes.length)]; badge.textContent = '1'; randomIcon.appendChild(badge); // Create tooltip for new badge const tooltip = document.createElement('div'); tooltip.className = 'tooltip'; tooltip.textContent = 'New notification'; randomIcon.appendChild(tooltip); // Remove the new class after animation completes setTimeout(() => { badge.classList.remove('new'); }, 300); } }); // Clear all notifications clearNotificationsBtn.addEventListener('click', function() { const badges = document.querySelectorAll('.notification-badge'); badges.forEach(badge => { badge.classList.add('new'); setTimeout(() => { badge.remove(); }, 300); }); }); // Make nav items clickable const navItems = document.querySelectorAll('.nav-item'); navItems.forEach(item => { item.addEventListener('click', function() { // Remove active class from all items navItems.forEach(navItem => navItem.classList.remove('active')); // Add active class to clicked item this.classList.add('active'); }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Health Tracker Alert Glow</title> <style> :root { --primary-blue: #1a73e8; --secondary-blue: #87ceeb; --primary-green: #34a853; --secondary-green: #8dd28a; --alert-orange: #fbbc05; --alert-red: #ea4335; --neutral-gray: #e0e0e0; --dark-gray: #5f6368; --white: #ffffff; --shadow: 0 4px 12px rgba(0, 0, 0, 0.1); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', 'Roboto', sans-serif; } body { display: flex; justify-content: center; align-items: center; min-height: 100vh; background-color: #f8f9fa; padding: 20px; } .dashboard { width: 100%; max-width: 650px; background-color: var(--white); border-radius: 24px; box-shadow: var(--shadow); overflow: hidden; position: relative; } .header { background: linear-gradient(135deg, var(--primary-blue), var(--primary-green)); color: var(--white); padding: 24px; text-align: center; position: relative; } .header h1 { font-size: 24px; font-weight: 600; margin-bottom: 6px; } .header p { font-size: 14px; opacity: 0.9; } .content { padding: 24px; } .metrics-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; margin-bottom: 24px; } .metric-card { background-color: var(--white); border-radius: 16px; padding: 20px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); position: relative; transition: transform 0.3s ease; border: 1px solid var(--neutral-gray); } .metric-card:hover { transform: translateY(-4px); box-shadow: 0 6px 14px rgba(0, 0, 0, 0.08); } .metric-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; } .metric-title { font-size: 14px; color: var(--dark-gray); } .metric-icon { width: 36px; height: 36px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background-color: #f5f5f5; position: relative; } .metric-icon svg { width: 20px; height: 20px; } .metric-value { font-size: 28px; font-weight: 600; color: #333; margin-bottom: 4px; } .metric-trend { display: flex; align-items: center; font-size: 12px; color: var(--primary-green); } .trend-down { color: var(--alert-red); } .alerts-section { margin-top: 20px; } .section-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; } .section-header h2 { font-size: 18px; font-weight: 600; color: #333; } .view-all { font-size: 13px; color: var(--primary-blue); text-decoration: none; cursor: pointer; } .alerts-list { display: flex; flex-direction: column; gap: 12px; } .alert-item { display: flex; padding: 16px; background-color: var(--white); border-radius: 12px; align-items: center; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); transition: all 0.3s ease; cursor: pointer; border: 1px solid var(--neutral-gray); } .alert-item:hover { background-color: #f8f9fa; } .alert-item.urgent { border-left: 4px solid var(--alert-red); } .alert-item.warning { border-left: 4px solid var(--alert-orange); } .alert-item.info { border-left: 4px solid var(--primary-blue); } .alert-icon { position: relative; margin-right: 16px; } .alert-content { flex: 1; } .alert-title { font-size: 14px; font-weight: 600; margin-bottom: 4px; color: #333; } .alert-desc { font-size: 13px; color: var(--dark-gray); } .alert-time { font-size: 12px; color: var(--dark-gray); white-space: nowrap; margin-left: 16px; } .pulse-effect { position: absolute; width: 100%; height: 100%; border-radius: 50%; animation: pulse 2s infinite ease-in-out; z-index: 0; } .urgent-pulse { background: radial-gradient(circle, rgba(234, 67, 53, 0.6) 0%, rgba(234, 67, 53, 0) 70%); animation-duration: 1.5s; } .warning-pulse { background: radial-gradient(circle, rgba(251, 188, 5, 0.6) 0%, rgba(251, 188, 5, 0) 70%); animation-duration: 2s; } .info-pulse { background: radial-gradient(circle, rgba(26, 115, 232, 0.6) 0%, rgba(26, 115, 232, 0) 70%); animation-duration: 2.5s; } .success-pulse { background: radial-gradient(circle, rgba(52, 168, 83, 0.6) 0%, rgba(52, 168, 83, 0) 70%); animation-duration: 3s; } @keyframes pulse { 0% { transform: scale(0.8); opacity: 0.7; } 50% { transform: scale(1.2); opacity: 0.3; } 100% { transform: scale(0.8); opacity: 0.7; } } .status-badge { position: absolute; top: -3px; right: -3px; width: 12px; height: 12px; border-radius: 50%; border: 2px solid white; } .status-badge.urgent { background-color: var(--alert-red); } .status-badge.warning { background-color: var(--alert-orange); } .status-badge.info { background-color: var(--primary-blue); } .day-toggle { display: flex; justify-content: center; margin-top: 20px; gap: 8px; } .day-toggle button { background: none; border: none; font-size: 13px; padding: 6px 12px; border-radius: 16px; cursor: pointer; color: var(--dark-gray); transition: all 0.2s ease; } .day-toggle button.active { background-color: var(--primary-blue); color: white; } @media (max-width: 600px) { .metrics-grid { grid-template-columns: 1fr; } .metric-card { padding: 16px; } .metric-value { font-size: 24px; } .header h1 { font-size: 20px; } .alert-time { display: none; } } /* Tooltip styles */ .tooltip { position: relative; display: inline-block; } .tooltip-content { visibility: hidden; width: 180px; background-color: #333; color: #fff; text-align: center; border-radius: 6px; padding: 8px; position: absolute; z-index: 1; bottom: 125%; left: 50%; transform: translateX(-50%); opacity: 0; transition: opacity 0.3s; font-size: 12px; } .tooltip:hover .tooltip-content { visibility: visible; opacity: 1; } /* Special Animation */ .wave-animation { position: absolute; bottom: 0; left: 0; width: 100%; height: 80px; overflow: hidden; } .wave { position: absolute; bottom: 0; left: 0; width: 200%; height: 100%; background: url('data:image/svg+xml;utf8,<svg viewBox="0 0 1200 120" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none"><path d="M0,0V46.29c47.79,22.2,103.59,32.17,158,28,70.36-5.37,136.33-33.31,206.8-37.5C438.64,32.43,512.34,53.67,583,72.05c69.27,18,138.3,24.88,209.4,13.08,36.15-6,69.85-17.84,104.45-29.34C989.49,25,1113-14.29,1200,52.47V0Z" opacity=".25" fill="%23ffffff"/><path d="M0,0V15.81C13,36.92,27.64,56.86,47.69,72.05,99.41,111.27,165,111,224.58,91.58c31.15-10.15,60.09-26.07,89.67-39.8,40.92-19,84.73-46,130.83-49.67,36.26-2.85,70.9,9.42,98.6,31.56,31.77,25.39,62.32,62,103.63,73,40.44,10.79,81.35-6.69,119.13-24.28s75.16-39,116.92-43.05c59.73-5.85,113.28,22.88,168.9,38.84,30.2,8.66,59,6.17,87.09-7.5,22.43-10.89,48-26.93,60.65-49.24V0Z" opacity=".5" fill="%23ffffff"/><path d="M0,0V5.63C149.93,59,314.09,71.32,475.83,42.57c43-7.64,84.23-20.12,127.61-26.46,59-8.63,112.48,12.24,165.56,35.4C827.93,77.22,886,95.24,951.2,90c86.53-7,172.46-45.71,248.8-84.81V0Z" fill="%23ffffff"/></svg>'); animation: wave 25s linear infinite; z-index: 1; opacity: 0.3; } .wave:nth-child(2) { animation: wave 20s linear infinite; opacity: 0.2; bottom: 10px; } .wave:nth-child(3) { animation: wave 15s linear infinite; opacity: 0.1; bottom: 20px; } @keyframes wave { 0% { transform: translateX(0); } 100% { transform: translateX(-50%); } } .shimmer-animation { position: relative; overflow: hidden; } .shimmer-animation::after { content: ''; position: absolute; top: 0; right: 0; bottom: 0; left: 0; background: linear-gradient( to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0) 100% ); transform: translateX(-100%); animation: shimmer 3s infinite; } @keyframes shimmer { 100% { transform: translateX(100%); } } /* Custom toggle switch */ .toggle-container { display: flex; justify-content: flex-end; margin-bottom: 16px; align-items: center; } .toggle-label { font-size: 14px; margin-right: 8px; color: var(--dark-gray); } .toggle-switch { position: relative; display: inline-block; width: 48px; height: 24px; } .toggle-switch input { opacity: 0; width: 0; height: 0; } .toggle-slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; transition: .4s; border-radius: 24px; } .toggle-slider:before { position: absolute; content: ""; height: 18px; width: 18px; left: 3px; bottom: 3px; background-color: white; transition: .4s; border-radius: 50%; } input:checked + .toggle-slider { background: linear-gradient(135deg, var(--primary-blue), var(--primary-green)); } input:checked + .toggle-slider:before { transform: translateX(24px); } </style> </head> <body> <div class="dashboard"> <div class="header"> <h1>Health Pulse Monitor</h1> <p>Your wellness insights for today, May 18</p> <div class="wave-animation"> <div class="wave"></div> <div class="wave"></div> <div class="wave"></div> </div> </div> <div class="content"> <div class="toggle-container"> <span class="toggle-label">Show Alerts</span> <label class="toggle-switch"> <input type="checkbox" id="alert-toggle" checked> <span class="toggle-slider"></span> </label> </div> <div class="metrics-grid"> <div class="metric-card shimmer-animation"> <div class="metric-header"> <span class="metric-title">Heart Rate</span> <div class="metric-icon"> <div id="heartRateStatus" class="pulse-effect info-pulse"></div> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#1a73e8"> <path d="M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z"/> </svg> <span id="heartRateBadge" class="status-badge info"></span> </div> </div> <div class="metric-value">72 BPM</div> <div class="metric-trend"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="#34a853"> <path d="M7,10L12,15L17,10H7Z"/> </svg> 3% from yesterday </div> </div> <div class="metric-card shimmer-animation"> <div class="metric-header"> <span class="metric-title">Blood Pressure</span> <div class="metric-icon"> <div id="bpStatus" class="pulse-effect warning-pulse"></div> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#fbbc05"> <path d="M12,2.5L8.42,8.06L2,9.74L6.2,14.88L5.82,21.5L12,19.09L18.18,21.5L17.8,14.88L22,9.74L15.58,8.06L12,2.5M9.38,10.5C10,10.5 10.5,11 10.5,11.63A1.12,1.12 0 0,1 9.38,12.75C8.75,12.75 8.25,12.25 8.25,11.63C8.25,11 8.75,10.5 9.38,10.5M14.63,10.5C15.25,10.5 15.75,11 15.75,11.63A1.12,1.12 0 0,1 14.63,12.75C14,12.75 13.5,12.25 13.5,11.63C13.5,11 14,10.5 14.63,10.5M9,15H15C14.5,16.21 13.31,17 12,17C10.69,17 9.5,16.21 9,15Z"/> </svg> <span id="bpBadge" class="status-badge warning"></span> </div> </div> <div class="metric-value">128/82</div> <div class="metric-trend"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="#ea4335"> <path d="M7,14L12,9L17,14H7Z"/> </svg> <span class="trend-down">5% from yesterday</span> </div> </div> <div class="metric-card shimmer-animation"> <div class="metric-header"> <span class="metric-title">Sleep Quality</span> <div class="metric-icon"> <div id="sleepStatus" class="pulse-effect urgent-pulse"></div> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#ea4335"> <path d="M12,3C7.03,3 3,7.03 3,12C3,16.97 7.03,21 12,21C16.97,21 21,16.97 21,12C21,7.03 16.97,3 12,3M9,17H7V10H9V17M13,17H11V7H13V17M17,17H15V13H17V17Z"/> </svg> <span id="sleepBadge" class="status-badge urgent"></span> </div> </div> <div class="metric-value">5.2 hrs</div> <div class="metric-trend"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="#ea4335"> <path d="M7,14L12,9L17,14H7Z"/> </svg> <span class="trend-down">18% from yesterday</span> </div> </div> <div class="metric-card shimmer-animation"> <div class="metric-header"> <span class="metric-title">Steps</span> <div class="metric-icon"> <div id="stepsStatus" class="pulse-effect success-pulse"></div> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#34a853"> <path d="M12,5.5A2.5,2.5 0 0,1 14.5,8A2.5,2.5 0 0,1 12,10.5A2.5,2.5 0 0,1 9.5,8A2.5,2.5 0 0,1 12,5.5M5,8C5.56,8 6.08,8.15 6.53,8.42C6.38,9.85 6.8,11.27 7.66,12.38C7.16,13.34 6.16,14 5,14A3,3 0 0,1 2,11A3,3 0 0,1 5,8M19,8A3,3 0 0,1 22,11A3,3 0 0,1 19,14C17.84,14 16.84,13.34 16.34,12.38C17.2,11.27 17.62,9.85 17.47,8.42C17.92,8.15 18.44,8 19,8M5.5,18.25C5.5,16.18 8.41,14.5 12,14.5C15.59,14.5 18.5,16.18 18.5,18.25V20H5.5V18.25M0,20V18.5C0,17.11 1.89,15.94 4.45,15.6C3.86,16.28 3.5,17.22 3.5,18.25V20H0M24,20H20.5V18.25C20.5,17.22 20.14,16.28 19.55,15.6C22.11,15.94 24,17.11 24,18.5V20Z"/> </svg> </div> </div> <div class="metric-value">8,427</div> <div class="metric-trend"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="#34a853"> <path d="M7,10L12,15L17,10H7Z"/> </svg> 12% from yesterday </div> </div> </div> <div class="alerts-section"> <div class="section-header"> <h2>Recent Alerts</h2> <span class="view-all">View All</span> </div> <div class="alerts-list"> <div class="alert-item urgent" id="sleep-alert"> <div class="alert-icon"> <div class="pulse-effect urgent-pulse"></div> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#ea4335"> <path d="M20,3H4A1,1 0 0,0 3,4V10A1,1 0 0,0 4,11H20A1,1 0 0,0 21,10V4A1,1 0 0,0 20,3M20,13H4A1,1 0 0,0 3,14V20A1,1 0 0,0 4,21H20A1,1 0 0,0 21,20V14A1,1 0 0,0 20,13M9,7H7V5H9V7M7,19H9V17H7V19M17,7H15V5H17V7M15,19H17V17H15V19Z"/> </svg> </div> <div class="alert-content"> <div class="alert-title">Sleep Pattern Disruption</div> <div class="alert-desc">Your sleep dropped below 6 hours for the third consecutive night</div> </div> <div class="alert-time">2h ago</div> </div> <div class="alert-item warning" id="bp-alert"> <div class="alert-icon"> <div class="pulse-effect warning-pulse"></div> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#fbbc05"> <path d="M3.5,18.5L9.5,12.5L13.5,16.5L22,6.92L20.59,5.5L13.5,13.5L9.5,9.5L2,17L3.5,18.5Z"/> </svg> </div> <div class="alert-content"> <div class="alert-title">Elevated Blood Pressure</div> <div class="alert-desc">Your systolic pressure has been trending upward this week</div> </div> <div class="alert-time">5h ago</div> </div> <div class="alert-item info" id="heart-alert"> <div class="alert-icon tooltip"> <div class="pulse-effect info-pulse"></div> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#1a73e8"> <path d="M3,13H5.79L10.1,4.79L11.28,13.75L14.5,9.59L17.25,13H21V15H16.25L13.5,11.59L9.22,17.25L8.10,8.25L5.21,15H3V13Z"/> </svg> <div class="tooltip-content">Regularly check your heart rate variability for better insights</div> </div> <div class="alert-content"> <div class="alert-title">Resting Heart Rate Update</div> <div class="alert-desc">Your 30-day average has improved by 4 BPM</div> </div> <div class="alert-time">Yesterday</div> </div> </div> </div> <div class="day-toggle"> <button class="active">Today</button> <button>Week</button> <button>Month</button> <button>Year</button> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Toggle alerts visibility const alertToggle = document.getElementById('alert-toggle'); const alertsList = document.querySelector('.alerts-list'); alertToggle.addEventListener('change', function() { if (this.checked) { alertsList.style.display = 'flex'; } else { alertsList.style.display = 'none'; } }); // Day toggle functionality const dayButtons = document.querySelectorAll('.day-toggle button'); dayButtons.forEach(button => { button.addEventListener('click', function() { dayButtons.forEach(btn => btn.classList.remove('active')); this.classList.add('active'); }); }); // Alert item interaction const alertItems = document.querySelectorAll('.alert-item'); alertItems.forEach(item => { item.addEventListener('click', function() { // Visual feedback for interaction this.style.backgroundColor = '#f0f7ff'; setTimeout(() => { this.style.backgroundColor = ''; }, 300); // Connect alerts to metrics if (this.id === 'sleep-alert') { highlightMetric('sleepStatus'); } else if (this.id === 'bp-alert') { highlightMetric('bpStatus'); } else if (this.id === 'heart-alert') { highlightMetric('heartRateStatus'); } }); }); // Function to highlight a specific metric with enhanced pulse animation function highlightMetric(metricId) { const metric = document.getElementById(metricId); metric.style.animationDuration = '0.7s'; metric.style.transform = 'scale(1.2)'; setTimeout(() => { metric.style.animationDuration = ''; metric.style.transform = ''; }, 2000); } // Create subtle pulse variations function randomizePulses() { const pulseEffects = document.querySelectorAll('.pulse-effect'); pulseEffects.forEach(pulse => { // Randomize animation duration slightly to create natural variations const baseSpeed = parseFloat(getComputedStyle(pulse).animationDuration); const variation = (Math.random() * 0.5) - 0.25; // ±25% variation const newDuration = (baseSpeed + variation) + 's'; pulse.style.animationDuration = newDuration; }); } // Initial call and periodic refresh randomizePulses(); setInterval(randomizePulses, 5000); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Portfolio Watercolor Glow Effect</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; } body { background-color: #0f0f13; color: #f2f2f2; height: 100vh; width: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; overflow-x: hidden; padding: 1.5rem; } .container { max-width: 700px; width: 100%; padding: 2rem 1rem; position: relative; } h1 { font-size: clamp(1.5rem, 4vw, 2.2rem); margin-bottom: 1rem; font-weight: 800; background: linear-gradient(90deg, #fff, #bbb); -webkit-background-clip: text; background-clip: text; color: transparent; position: relative; z-index: 2; } p.tagline { color: #9e9ea7; line-height: 1.6; font-size: clamp(0.9rem, 3vw, 1rem); margin-bottom: 2.5rem; max-width: 600px; position: relative; z-index: 2; } .portfolio-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 1.5rem; position: relative; z-index: 2; } .portfolio-item { position: relative; border-radius: 12px; overflow: hidden; transition: transform 0.4s cubic-bezier(0.2, 0.8, 0.2, 1); cursor: pointer; aspect-ratio: 1/1; } .portfolio-item:hover { transform: translateY(-8px) scale(1.02); z-index: 5; } .portfolio-item:before { content: ''; position: absolute; inset: 0; background: rgba(15, 15, 19, 0.2); z-index: 1; transition: opacity 0.4s ease; } .portfolio-item:hover:before { opacity: 0; } .thumbnail { width: 100%; height: 100%; object-fit: cover; position: relative; z-index: 0; transition: transform 0.8s cubic-bezier(0.2, 0.8, 0.2, 1); filter: saturate(0.8); } .portfolio-item:hover .thumbnail { transform: scale(1.08); filter: saturate(1.1); } .watercolor-glow { position: absolute; width: 180%; height: 180%; background: radial-gradient( circle at center, var(--glow-color-1) 0%, var(--glow-color-2) 30%, transparent 70% ); opacity: 0; transform: translate(-25%, -25%) scale(0.8); transition: opacity 0.5s ease, transform 0.5s cubic-bezier(0.2, 0.8, 0.2, 1); mix-blend-mode: soft-light; pointer-events: none; z-index: 2; filter: blur(20px); } .portfolio-item:hover .watercolor-glow { opacity: 0.8; transform: translate(-25%, -25%) scale(1); } .info { position: absolute; bottom: 0; left: 0; width: 100%; padding: 1rem; z-index: 3; transform: translateY(20px); opacity: 0; transition: transform 0.4s cubic-bezier(0.2, 0.8, 0.2, 1), opacity 0.4s ease; background: linear-gradient(to top, rgba(0,0,0,0.8), transparent); } .portfolio-item:hover .info { transform: translateY(0); opacity: 1; } .title { font-size: 0.9rem; font-weight: 600; margin-bottom: 0.3rem; } .category { font-size: 0.75rem; color: rgba(255, 255, 255, 0.7); font-weight: 400; } .ambient-bg { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 1; background: radial-gradient(circle at 30% 20%, #332244 0%, transparent 50%), radial-gradient(circle at 70% 60%, #223344 0%, transparent 50%); opacity: 0.3; } .cursor-glow { width: 300px; height: 300px; border-radius: 50%; background: radial-gradient( circle at center, rgba(85, 103, 208, 0.3) 0%, rgba(69, 117, 166, 0.2) 40%, transparent 70% ); position: fixed; transform: translate(-50%, -50%); pointer-events: none; z-index: 1; filter: blur(25px); opacity: 0; transition: opacity 0.3s ease; } @media (max-width: 550px) { .portfolio-grid { grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 1rem; } h1 { font-size: 1.8rem; } p.tagline { font-size: 0.9rem; margin-bottom: 1.8rem; } } @media (max-width: 380px) { .portfolio-grid { grid-template-columns: repeat(2, 1fr); } } .empty-state { grid-column: 1/-1; text-align: center; padding: 2rem; color: #9e9ea7; display: none; } </style> </head> <body> <div class="ambient-bg"></div> <div class="cursor-glow"></div> <div class="container"> <h1>Chromatic Portfolio</h1> <p class="tagline">A collection of creative works showcasing the interplay of design and motion. Hover over pieces to experience the watercolor glow effect that brings each project to life.</p> <div class="portfolio-grid"> <div class="portfolio-item" data-color-1="#e86af0" data-color-2="#9b6ddf"> <img class="thumbnail" src="https://images.unsplash.com/photo-1518640467707-6811f4a6ab73?w=600&auto=format&fit=crop&q=80" alt="Abstract Pattern Design"> <div class="watercolor-glow"></div> <div class="info"> <div class="title">Abstract Fluidity</div> <div class="category">Digital Artwork</div> </div> </div> <div class="portfolio-item" data-color-1="#5ae0df" data-color-2="#2b86d9"> <img class="thumbnail" src="https://images.unsplash.com/photo-1547119957-637f8679db1e?w=600&auto=format&fit=crop&q=80" alt="Brand Identity Design"> <div class="watercolor-glow"></div> <div class="info"> <div class="title">Ocean Brand</div> <div class="category">Identity Design</div> </div> </div> <div class="portfolio-item" data-color-1="#ffcc66" data-color-2="#ff8866"> <img class="thumbnail" src="https://images.unsplash.com/photo-1462331940025-496dfbfc7564?w=600&auto=format&fit=crop&q=80" alt="Mobile UI Design"> <div class="watercolor-glow"></div> <div class="info"> <div class="title">Amber Glow UI</div> <div class="category">Mobile Interface</div> </div> </div> <div class="portfolio-item" data-color-1="#a2de96" data-color-2="#57c478"> <img class="thumbnail" src="https://images.unsplash.com/photo-1511467687858-23d96c32e4ae?w=600&auto=format&fit=crop&q=80" alt="Product Photography"> <div class="watercolor-glow"></div> <div class="info"> <div class="title">Emerald Studio</div> <div class="category">Photography</div> </div> </div> <div class="portfolio-item" data-color-1="#f06292" data-color-2="#ec407a"> <img class="thumbnail" src="https://images.unsplash.com/photo-1618005198919-177145ed6ebd?w=600&auto=format&fit=crop&q=80" alt="3D Character Design"> <div class="watercolor-glow"></div> <div class="info"> <div class="title">Crimson Form</div> <div class="category">3D Modeling</div> </div> </div> <div class="portfolio-item" data-color-1="#9575cd" data-color-2="#7e57c2"> <img class="thumbnail" src="https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?w=600&auto=format&fit=crop&q=80" alt="Motion Graphics"> <div class="watercolor-glow"></div> <div class="info"> <div class="title">Lavender Motion</div> <div class="category">Animation</div> </div> </div> <div class="empty-state">No portfolio items to display.</div> </div> </div> <script> // Set up watercolor glow effect on portfolio items const portfolioItems = document.querySelectorAll('.portfolio-item'); const cursorGlow = document.querySelector('.cursor-glow'); portfolioItems.forEach(item => { const watercolorGlow = item.querySelector('.watercolor-glow'); // Set custom glow colors based on data attributes const glowColor1 = item.getAttribute('data-color-1'); const glowColor2 = item.getAttribute('data-color-2'); watercolorGlow.style.setProperty('--glow-color-1', glowColor1); watercolorGlow.style.setProperty('--glow-color-2', glowColor2); // Add subtle random rotation to each glow for more organic feel const randomRotation = Math.random() * 360; watercolorGlow.style.transform = `translate(-25%, -25%) scale(0.8) rotate(${randomRotation}deg)`; item.addEventListener('mouseenter', () => { watercolorGlow.style.transform = `translate(-25%, -25%) scale(1) rotate(${randomRotation}deg)`; }); item.addEventListener('mouseleave', () => { watercolorGlow.style.transform = `translate(-25%, -25%) scale(0.8) rotate(${randomRotation}deg)`; }); }); // Add cursor glow effect document.addEventListener('mousemove', (e) => { cursorGlow.style.opacity = '1'; cursorGlow.style.left = `${e.clientX}px`; cursorGlow.style.top = `${e.clientY}px`; }); document.addEventListener('mouseleave', () => { cursorGlow.style.opacity = '0'; }); // Add staggered reveal animation on page load window.addEventListener('load', () => { portfolioItems.forEach((item, index) => { setTimeout(() => { item.style.opacity = '0'; item.style.transform = 'translateY(20px)'; setTimeout(() => { item.style.transition = 'opacity 0.5s ease, transform 0.5s cubic-bezier(0.2, 0.8, 0.2, 1)'; item.style.opacity = '1'; item.style.transform = 'translateY(0)'; }, 100); }, index * 100); }); }); // Check if grid is empty and show empty state if (portfolioItems.length === 0) { document.querySelector('.empty-state').style.display = 'block'; } </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Weather Ambient Glow</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; } body { background-color: #0a0c10; height: 100vh; display: flex; justify-content: center; align-items: center; overflow: hidden; color: #ffffff; } .app-container { width: 100%; max-width: 650px; height: 650px; position: relative; padding: 30px; border-radius: 24px; background: #10141e; box-shadow: 0 20px 45px rgba(0, 0, 0, 0.3); transition: 0.5s all ease; overflow: hidden; } .header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; } .app-title { font-size: 1.6rem; font-weight: 700; opacity: 0.95; letter-spacing: -0.5px; } .location-selector { position: relative; cursor: pointer; } .location-display { font-size: 1rem; font-weight: 600; display: flex; align-items: center; gap: 5px; padding: 8px 16px; background: rgba(255, 255, 255, 0.08); border-radius: 20px; transition: all 0.3s ease; } .location-display:hover { background: rgba(255, 255, 255, 0.12); } .location-dropdown { position: absolute; top: 110%; right: 0; background: #191f2e; border-radius: 12px; width: 180px; overflow: hidden; z-index: 10; box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3); transform-origin: top; transform: scaleY(0); opacity: 0; transition: all 0.25s ease; } .location-dropdown.active { transform: scaleY(1); opacity: 1; } .location-option { padding: 12px 16px; font-size: 0.9rem; transition: all 0.2s; } .location-option:hover { background: rgba(255, 255, 255, 0.1); } .main-weather { display: flex; gap: 30px; margin: 30px 0; align-items: stretch; height: 280px; } .weather-icon-container { flex: 1; display: flex; position: relative; align-items: center; justify-content: center; background: rgba(255, 255, 255, 0.03); border-radius: 20px; overflow: hidden; transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1); } .glow-effect { position: absolute; width: 220px; height: 220px; border-radius: 50%; filter: blur(60px); z-index: 1; transition: all 1.5s cubic-bezier(0.19, 1, 0.22, 1); opacity: 0.7; } .weather-icon { position: relative; z-index: 2; width: 120px; height: 120px; filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.3)); transition: all 0.5s ease; } .weather-data { flex: 1; display: flex; flex-direction: column; justify-content: space-between; padding: 25px; background: rgba(255, 255, 255, 0.03); border-radius: 20px; transition: all 0.5s ease; } .temperature { font-size: 3.5rem; font-weight: 700; margin-bottom: 5px; letter-spacing: -2px; } .weather-condition { font-size: 1.8rem; font-weight: 600; margin-bottom: 20px; letter-spacing: -0.5px; } .details { display: flex; justify-content: space-between; gap: 15px; } .detail-item { display: flex; flex-direction: column; align-items: flex-start; } .detail-label { font-size: 0.8rem; opacity: 0.6; margin-bottom: 5px; } .detail-value { font-size: 1.2rem; font-weight: 600; } .forecast { display: grid; grid-template-columns: repeat(5, 1fr); gap: 15px; margin-top: 20px; } .forecast-day { background: rgba(255, 255, 255, 0.03); border-radius: 15px; padding: 15px; text-align: center; transition: all 0.3s ease; cursor: pointer; } .forecast-day:hover { background: rgba(255, 255, 255, 0.08); transform: translateY(-5px); } .forecast-day-name { font-size: 0.9rem; margin-bottom: 10px; opacity: 0.8; } .forecast-icon { width: 40px; height: 40px; margin: 0 auto 10px; } .forecast-temp { font-size: 1.1rem; font-weight: 600; } .time-selector { display: flex; gap: 10px; margin-top: 25px; overflow-x: auto; padding-bottom: 10px; -ms-overflow-style: none; scrollbar-width: none; } .time-selector::-webkit-scrollbar { display: none; } .time-option { padding: 8px 16px; background: rgba(255, 255, 255, 0.05); border-radius: 20px; font-size: 0.9rem; cursor: pointer; white-space: nowrap; transition: all 0.3s ease; } .time-option.active { background: rgba(255, 255, 255, 0.15); font-weight: 600; } .time-option:hover:not(.active) { background: rgba(255, 255, 255, 0.1); } /* Weather-specific styles */ .sunny .glow-effect { background: radial-gradient(circle, #ffcb4f 0%, #ff9d31 100%); } .cloudy .glow-effect { background: radial-gradient(circle, #c2d7e9 0%, #8ba6b9 100%); } .rainy .glow-effect { background: radial-gradient(circle, #6aa4cc 0%, #2c5d8c 100%); } .thunderstorm .glow-effect { background: radial-gradient(circle, #9d7fe6 0%, #5445ac 100%); } .snowy .glow-effect { background: radial-gradient(circle, #e0f4ff 0%, #a8d1e8 100%); } /* Animation for glow */ @keyframes pulse { 0% { transform: scale(0.95); opacity: 0.7; } 50% { transform: scale(1.05); opacity: 0.9; } 100% { transform: scale(0.95); opacity: 0.7; } } .glow-effect { animation: pulse 8s infinite; } /* Responsiveness */ @media (max-width: 700px) { .app-container { height: auto; padding: 20px; } .main-weather { flex-direction: column; height: auto; gap: 15px; } .weather-icon-container { height: 180px; } .forecast { grid-template-columns: repeat(3, 1fr); } .weather-data { padding: 15px; } .temperature { font-size: 2.5rem; } .weather-condition { font-size: 1.4rem; } } @media (max-width: 480px) { .app-title { font-size: 1.3rem; } .forecast { grid-template-columns: repeat(2, 1fr); } .detail-value { font-size: 1rem; } } /* Interactive visual cue for weather change */ .weather-changes-badge { position: absolute; top: 10px; right: 10px; background: rgba(255, 255, 255, 0.1); border-radius: 20px; padding: 5px 10px; font-size: 0.8rem; opacity: 0; transform: translateY(-10px); transition: all 0.4s ease; } .weather-changes-badge.visible { opacity: 1; transform: translateY(0); } /* Animation when weather changes */ @keyframes weatherChange { 0% { transform: scale(0.9) rotate(-5deg); opacity: 0.5; } 50% { transform: scale(1.1) rotate(5deg); opacity: 1; } 100% { transform: scale(1) rotate(0); opacity: 1; } } .weather-icon.changing { animation: weatherChange 0.8s ease-out; } </style> </head> <body> <div class="app-container"> <div class="header"> <h1 class="app-title">ClimateGlow</h1> <div class="location-selector"> <div class="location-display" id="location-toggle"> <span id="current-location">San Francisco</span> <span>▼</span> </div> <div class="location-dropdown" id="location-dropdown"> <div class="location-option" data-weather="sunny" data-temp="78">San Francisco</div> <div class="location-option" data-weather="rainy" data-temp="65">Seattle</div> <div class="location-option" data-weather="cloudy" data-temp="72">New York</div> <div class="location-option" data-weather="thunderstorm" data-temp="68">Miami</div> <div class="location-option" data-weather="snowy" data-temp="35">Chicago</div> </div> </div> </div> <div class="main-weather"> <div class="weather-icon-container sunny" id="weather-container"> <div class="glow-effect" id="glow-effect"></div> <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 120 120' fill='none'%3E%3Ccircle cx='60' cy='60' r='30' fill='%23FFD54F' stroke='%23FFECB3' stroke-width='2'/%3E%3Cpath d='M60 15V5M60 115V105M20.1 20.1L27.3 27.3M92.7 92.7L99.9 99.9M5 60H15M105 60H115M20.1 99.9L27.3 92.7M92.7 27.3L99.9 20.1' stroke='%23FFD54F' stroke-width='5' stroke-linecap='round'/%3E%3C/svg%3E" alt="Sunny" class="weather-icon" id="weather-icon"> <div class="weather-changes-badge" id="weather-badge">Weather updating...</div> </div> <div class="weather-data"> <div> <h2 class="temperature" id="temperature">78°F</h2> <p class="weather-condition" id="weather-condition">Sunny</p> </div> <div class="details"> <div class="detail-item"> <span class="detail-label">Wind</span> <span class="detail-value">8 mph</span> </div> <div class="detail-item"> <span class="detail-label">Humidity</span> <span class="detail-value">42%</span> </div> <div class="detail-item"> <span class="detail-label">UV Index</span> <span class="detail-value">6 High</span> </div> </div> </div> </div> <div class="time-selector"> <div class="time-option active">Now</div> <div class="time-option">12:00 PM</div> <div class="time-option">3:00 PM</div> <div class="time-option">6:00 PM</div> <div class="time-option">9:00 PM</div> <div class="time-option">12:00 AM</div> </div> <div class="forecast"> <div class="forecast-day"> <div class="forecast-day-name">Today</div> <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 40 40' fill='none'%3E%3Ccircle cx='20' cy='20' r='10' fill='%23FFD54F' stroke='%23FFECB3' stroke-width='1'/%3E%3Cpath d='M20 5V2M20 38V35M7 7L9 9M31 31L33 33M2 20H5M35 20H38M7 33L9 31M31 9L33 7' stroke='%23FFD54F' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E" alt="Sunny" class="forecast-icon"> <div class="forecast-temp">78°F</div> </div> <div class="forecast-day"> <div class="forecast-day-name">Fri</div> <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 40 40' fill='none'%3E%3Ccircle cx='20' cy='20' r='10' fill='%23FFD54F' stroke='%23FFECB3' stroke-width='1'/%3E%3Cpath d='M20 5V2M20 38V35M7 7L9 9M31 31L33 33M2 20H5M35 20H38M7 33L9 31M31 9L33 7' stroke='%23FFD54F' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E" alt="Sunny" class="forecast-icon"> <div class="forecast-temp">75°F</div> </div> <div class="forecast-day"> <div class="forecast-day-name">Sat</div> <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 40 40' fill='none'%3E%3Ccircle cx='12' cy='18' r='4' fill='%23B0BEC5' stroke='%23CFD8DC' stroke-width='1'/%3E%3Ccircle cx='23' cy='18' r='7' fill='%23B0BEC5' stroke='%23CFD8DC' stroke-width='1'/%3E%3Ccircle cx='12' cy='18' r='9' fill='none' stroke='%23B0BEC5' stroke-width='1' stroke-dasharray='2 1'/%3E%3Ccircle cx='30' cy='18' r='5' fill='%23B0BEC5' stroke='%23CFD8DC' stroke-width='1'/%3E%3C/svg%3E" alt="Cloudy" class="forecast-icon"> <div class="forecast-temp">72°F</div> </div> <div class="forecast-day"> <div class="forecast-day-name">Sun</div> <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 40 40' fill='none'%3E%3Ccircle cx='20' cy='15' r='8' fill='%23B0BEC5' stroke='%23CFD8DC' stroke-width='1'/%3E%3Cpath d='M15 25L14 32M20 25L20 32M25 25L26 32' stroke='%236AA4CC' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E" alt="Rainy" class="forecast-icon"> <div class="forecast-temp">68°F</div> </div> <div class="forecast-day"> <div class="forecast-day-name">Mon</div> <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 40 40' fill='none'%3E%3Ccircle cx='20' cy='15' r='8' fill='%23B0BEC5' stroke='%23CFD8DC' stroke-width='1'/%3E%3Cpath d='M15 25L14 32M20 25L20 32M25 25L26 32' stroke='%236AA4CC' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E" alt="Rainy" class="forecast-icon"> <div class="forecast-temp">66°F</div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Weather icon and glow mapping const weatherIcons = { sunny: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 120 120' fill='none'%3E%3Ccircle cx='60' cy='60' r='30' fill='%23FFD54F' stroke='%23FFECB3' stroke-width='2'/%3E%3Cpath d='M60 15V5M60 115V105M20.1 20.1L27.3 27.3M92.7 92.7L99.9 99.9M5 60H15M105 60H115M20.1 99.9L27.3 92.7M92.7 27.3L99.9 20.1' stroke='%23FFD54F' stroke-width='5' stroke-linecap='round'/%3E%3C/svg%3E", cloudy: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 120 120' fill='none'%3E%3Ccircle cx='40' cy='50' r='15' fill='%23B0BEC5' stroke='%23CFD8DC' stroke-width='2'/%3E%3Ccircle cx='70' cy='50' r='25' fill='%23B0BEC5' stroke='%23CFD8DC' stroke-width='2'/%3E%3Ccircle cx='40' cy='50' r='30' fill='none' stroke='%23B0BEC5' stroke-width='2' stroke-dasharray='4 2'/%3E%3Ccircle cx='90' cy='50' r='15' fill='%23B0BEC5' stroke='%23CFD8DC' stroke-width='2'/%3E%3C/svg%3E", rainy: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 120 120' fill='none'%3E%3Ccircle cx='60' cy='45' r='25' fill='%23B0BEC5' stroke='%23CFD8DC' stroke-width='2'/%3E%3Cpath d='M40 75L35 100M60 75L60 100M80 75L85 100' stroke='%236AA4CC' stroke-width='6' stroke-linecap='round'/%3E%3C/svg%3E", thunderstorm: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 120 120' fill='none'%3E%3Ccircle cx='60' cy='40' r='25' fill='%237986CB' stroke='%23C5CAE9' stroke-width='2'/%3E%3Cpath d='M60 70L50 90H65L55 110' stroke='%23FFD54F' stroke-width='6' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M40 60L30 70M80 60L90 70' stroke='%23FFD54F' stroke-width='3' stroke-linecap='round'/%3E%3C/svg%3E", snowy: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 120 120' fill='none'%3E%3Ccircle cx='60' cy='40' r='25' fill='%23B0BEC5' stroke='%23CFD8DC' stroke-width='2'/%3E%3Ccircle cx='45' cy='80' r='5' fill='%23E0F7FA' stroke='%23B2EBF2' stroke-width='2'/%3E%3Ccircle cx='60' cy='95' r='5' fill='%23E0F7FA' stroke='%23B2EBF2' stroke-width='2'/%3E%3Ccircle cx='75' cy='80' r='5' fill='%23E0F7FA' stroke='%23B2EBF2' stroke-width='2'/%3E%3Cpath d='M30 70L40 80M80 80L90 70M60 70V80' stroke='%23E0F7FA' stroke-width='3' stroke-linecap='round'/%3E%3C/svg%3E" }; const weatherConditions = { sunny: "Sunny", cloudy: "Partly Cloudy", rainy: "Rainy", thunderstorm: "Thunderstorm", snowy: "Snowy" }; // Location dropdown toggle const locationToggle = document.getElementById('location-toggle'); const locationDropdown = document.getElementById('location-dropdown'); locationToggle.addEventListener('click', function() { locationDropdown.classList.toggle('active'); }); // Close dropdown when clicking outside document.addEventListener('click', function(event) { if (!locationToggle.contains(event.target) && !locationDropdown.contains(event.target)) { locationDropdown.classList.remove('active'); } }); // Location selection const locationOptions = document.querySelectorAll('.location-option'); const weatherIcon = document.getElementById('weather-icon'); const weatherContainer = document.getElementById('weather-container'); const temperatureEl = document.getElementById('temperature'); const weatherConditionEl = document.getElementById('weather-condition'); const currentLocationEl = document.getElementById('current-location'); const weatherBadge = document.getElementById('weather-badge'); locationOptions.forEach(option => { option.addEventListener('click', function() { const location = this.textContent; const weather = this.dataset.weather; const temp = this.dataset.temp; currentLocationEl.textContent = location; locationDropdown.classList.remove('active'); // Show weather changing badge weatherBadge.textContent = `Weather updating to ${weatherConditions[weather]}...`; weatherBadge.classList.add('visible'); // Add changing animation to weather icon weatherIcon.classList.add('changing'); // Change weather with a slight delay for animation setTimeout(() => { // Update weather class weatherContainer.className = 'weather-icon-container ' + weather; // Update weather icon weatherIcon.src = weatherIcons[weather]; // Update temperature and condition temperatureEl.textContent = `${temp}°F`; weatherConditionEl.textContent = weatherConditions[weather]; // Hide badge after change is complete setTimeout(() => { weatherBadge.classList.remove('visible'); weatherIcon.classList.remove('changing'); }, 1000); }, 500); }); }); // Time selector interaction const timeOptions = document.querySelectorAll('.time-option'); timeOptions.forEach(option => { option.addEventListener('click', function() { timeOptions.forEach(o => o.classList.remove('active')); this.classList.add('active'); }); }); // Forecast day hover effect with adaptive glow const forecastDays = document.querySelectorAll('.forecast-day'); forecastDays.forEach(day => { day.addEventListener('mouseenter', function() { // Get the weather icon source from the forecast day const forecastIconSrc = this.querySelector('.forecast-icon').src; // Apply a subtle pulsing effect to the main weather glow const glowEffect = document.getElementById('glow-effect'); glowEffect.style.animationDuration = '3s'; }); day.addEventListener('mouseleave', function() { // Reset the glow animation const glowEffect = document.getElementById('glow-effect'); glowEffect.style.animationDuration = '8s'; }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Wanderlust Explorer: Interactive Map</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: #1a2639; height: 100vh; width: 100%; overflow: hidden; display: flex; justify-content: center; align-items: center; } .map-container { width: 700px; height: 700px; position: relative; border-radius: 16px; overflow: hidden; box-shadow: 0 15px 35px rgba(0, 0, 0, 0.3); background-color: #213458; } .map-image { width: 100%; height: 100%; object-fit: cover; filter: saturate(1.2) contrast(1.1); transition: transform 1s ease; } .location-markers { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; } .marker { position: absolute; transform: translate(-50%, -50%); cursor: pointer; pointer-events: auto; transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); } .marker:hover { transform: translate(-50%, -50%) scale(1.1); z-index: 10; } .marker-dot { width: 12px; height: 12px; background-color: white; border-radius: 50%; position: relative; z-index: 2; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3); } .marker-glow { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 30px; height: 30px; border-radius: 50%; z-index: 1; opacity: 0.7; animation: pulse 2s infinite; } .marker:hover .marker-glow { animation: pulse-hover 1.5s infinite; } @keyframes pulse { 0% { transform: translate(-50%, -50%) scale(1); opacity: 0.7; } 50% { transform: translate(-50%, -50%) scale(1.2); opacity: 0.5; } 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.7; } } @keyframes pulse-hover { 0% { transform: translate(-50%, -50%) scale(1.2); opacity: 0.8; } 50% { transform: translate(-50%, -50%) scale(1.6); opacity: 0.6; } 100% { transform: translate(-50%, -50%) scale(1.2); opacity: 0.8; } } .info-card { position: absolute; background-color: rgba(255, 255, 255, 0.95); border-radius: 8px; padding: 12px; width: 220px; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); transform: translateY(10px); opacity: 0; pointer-events: none; transition: all 0.3s ease; z-index: 5; } .marker:hover .info-card { opacity: 1; transform: translateY(0); } .info-card h3 { color: #1a2639; font-size: 16px; margin-bottom: 5px; border-bottom: 2px solid; padding-bottom: 4px; font-weight: 600; } .info-card p { color: #444; font-size: 13px; line-height: 1.4; margin-bottom: 8px; } .info-card .tags { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 8px; } .info-card .tag { font-size: 10px; padding: 3px 8px; border-radius: 12px; color: white; background-color: #1a2639; } .controls { position: absolute; bottom: 20px; right: 20px; background-color: rgba(255, 255, 255, 0.9); border-radius: 50px; padding: 10px; display: flex; gap: 10px; box-shadow: 0 3px 10px rgba(0, 0, 0, 0.15); z-index: 5; } .control-btn { width: 40px; height: 40px; border-radius: 50%; background-color: white; border: none; cursor: pointer; display: flex; align-items: center; justify-content: center; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); transition: all 0.2s ease; font-size: 18px; color: #1a2639; } .control-btn:hover { background-color: #f5f5f5; transform: translateY(-2px); } .legend { position: absolute; top: 20px; left: 20px; background-color: rgba(255, 255, 255, 0.9); border-radius: 10px; padding: 12px; z-index: 5; box-shadow: 0 3px 10px rgba(0, 0, 0, 0.15); } .legend h3 { font-size: 14px; margin-bottom: 8px; color: #1a2639; } .legend-item { display: flex; align-items: center; margin-bottom: 5px; } .legend-color { width: 15px; height: 15px; border-radius: 50%; margin-right: 8px; } .legend-text { font-size: 12px; color: #444; } .category-filter { position: absolute; top: 20px; right: 20px; background-color: rgba(255, 255, 255, 0.9); border-radius: 10px; padding: 12px; z-index: 5; box-shadow: 0 3px 10px rgba(0, 0, 0, 0.15); } .category-filter h3 { font-size: 14px; margin-bottom: 8px; color: #1a2639; } .filter-options { display: flex; flex-wrap: wrap; gap: 5px; } .filter-btn { font-size: 11px; padding: 5px 10px; border-radius: 15px; border: none; cursor: pointer; background-color: #eeeeee; transition: all 0.2s ease; } .filter-btn.active { background-color: #1a2639; color: white; } .loader { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: #1a2639; display: flex; justify-content: center; align-items: center; z-index: 100; transition: opacity 0.5s ease, visibility 0.5s ease; } .loader.hidden { opacity: 0; visibility: hidden; } .loader-spinner { width: 50px; height: 50px; border: 5px solid rgba(255, 255, 255, 0.2); border-top-color: white; border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } /* Destination color themes */ .nature { border-color: #4CAF50; } .nature .marker-glow { background-color: rgba(76, 175, 80, 0.6); } .nature h3 { border-color: #4CAF50; } .cultural { border-color: #9C27B0; } .cultural .marker-glow { background-color: rgba(156, 39, 176, 0.6); } .cultural h3 { border-color: #9C27B0; } .historical { border-color: #FF9800; } .historical .marker-glow { background-color: rgba(255, 152, 0, 0.6); } .historical h3 { border-color: #FF9800; } .adventure { border-color: #2196F3; } .adventure .marker-glow { background-color: rgba(33, 150, 243, 0.6); } .adventure h3 { border-color: #2196F3; } .cuisine { border-color: #F44336; } .cuisine .marker-glow { background-color: rgba(244, 67, 54, 0.6); } .cuisine h3 { border-color: #F44336; } /* Responsive adjustments */ @media (max-width: 700px) { .category-filter, .legend { position: static; margin: 10px; width: calc(100% - 20px); } .controls { bottom: 10px; right: 10px; } .info-card { width: 180px; padding: 8px; } .info-card h3 { font-size: 14px; } .info-card p { font-size: 11px; } } </style> </head> <body> <div class="map-container"> <img src="https://images.unsplash.com/photo-1562504208-03d85cc8c23e?ixlib=rb-4.0.3&auto=format&fit=crop&w=1600&q=80" alt="World Map" class="map-image" id="map-image"> <div class="location-markers" id="location-markers"> <!-- Markers will be added here dynamically --> </div> <div class="controls"> <button class="control-btn" id="zoom-in">+</button> <button class="control-btn" id="zoom-out">−</button> <button class="control-btn" id="reset">↺</button> </div> <div class="legend"> <h3>Destination Types</h3> <div class="legend-item"> <div class="legend-color" style="background-color: rgba(76, 175, 80, 0.6);"></div> <div class="legend-text">Natural Wonders</div> </div> <div class="legend-item"> <div class="legend-color" style="background-color: rgba(156, 39, 176, 0.6);"></div> <div class="legend-text">Cultural Gems</div> </div> <div class="legend-item"> <div class="legend-color" style="background-color: rgba(255, 152, 0, 0.6);"></div> <div class="legend-text">Historical Sites</div> </div> <div class="legend-item"> <div class="legend-color" style="background-color: rgba(33, 150, 243, 0.6);"></div> <div class="legend-text">Adventure Spots</div> </div> <div class="legend-item"> <div class="legend-color" style="background-color: rgba(244, 67, 54, 0.6);"></div> <div class="legend-text">Culinary Destinations</div> </div> </div> <div class="category-filter"> <h3>Filter by Category</h3> <div class="filter-options"> <button class="filter-btn active" data-category="all">All</button> <button class="filter-btn" data-category="nature">Natural</button> <button class="filter-btn" data-category="cultural">Cultural</button> <button class="filter-btn" data-category="historical">Historical</button> <button class="filter-btn" data-category="adventure">Adventure</button> <button class="filter-btn" data-category="cuisine">Culinary</button> </div> </div> <div class="loader" id="loader"> <div class="loader-spinner"></div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Define locations with coordinates, descriptions, and categories const locations = [ { name: "Machu Picchu", x: 25, y: 55, category: "historical", description: "Ancient Incan citadel set high in the Andes Mountains of Peru, featuring remarkable stone structures and breathtaking mountain vistas.", tags: ["UNESCO", "Peru", "Ruins"] }, { name: "Santorini", x: 52, y: 40, category: "cultural", description: "Stunning Greek island with iconic blue-domed churches, whitewashed buildings, and dramatic volcanic caldera views.", tags: ["Greece", "Islands", "Views"] }, { name: "Mount Fuji", x: 82, y: 40, category: "nature", description: "Japan's highest peak and most iconic natural landmark, known for its perfectly symmetrical volcanic cone.", tags: ["Japan", "Mountain", "Hiking"] }, { name: "Victoria Falls", x: 52, y: 58, category: "nature", description: "One of the world's most spectacular waterfalls, located on the Zambezi River between Zambia and Zimbabwe.", tags: ["Africa", "Waterfall", "Natural Wonder"] }, { name: "New Orleans", x: 20, y: 40, category: "cuisine", description: "A melting pot of Creole and Cajun flavors, from gumbo and jambalaya to beignets and po'boys, with vibrant food culture.", tags: ["USA", "Cajun", "Jazz"] }, { name: "Great Barrier Reef", x: 85, y: 60, category: "adventure", description: "World's largest coral reef system offering incredible diving and snorkeling among thousands of marine species.", tags: ["Australia", "Diving", "Marine Life"] }, { name: "Kyoto", x: 80, y: 38, category: "cultural", description: "Former capital of Japan with over 1,600 Buddhist temples, Shinto shrines, and beautifully preserved gardens.", tags: ["Japan", "Temples", "Traditional"] }, { name: "Petra", x: 58, y: 44, category: "historical", description: "Ancient city carved into rose-colored rock faces, featuring the iconic Treasury façade and monumental tombs.", tags: ["Jordan", "Ancient", "UNESCO"] }, { name: "Bangkok", x: 75, y: 48, category: "cuisine", description: "Street food paradise offering complex flavors from pad thai to tom yum soup in vibrant market settings.", tags: ["Thailand", "Street Food", "Spicy"] }, { name: "Swiss Alps", x: 48, y: 35, category: "adventure", description: "Pristine mountain range offering world-class skiing, hiking, and breathtaking alpine landscapes.", tags: ["Switzerland", "Mountains", "Winter Sports"] } ]; // Set initial map state let currentZoom = 1; let isDragging = false; let startPosX, startPosY, startTranslateX = 0, startTranslateY = 0; let currentTranslateX = 0, currentTranslateY = 0; const mapImage = document.getElementById('map-image'); const locationMarkersContainer = document.getElementById('location-markers'); const loader = document.getElementById('loader'); // Create markers dynamically function createMarkers() { locations.forEach(location => { const marker = document.createElement('div'); marker.className = `marker ${location.category}`; marker.style.left = `${location.x}%`; marker.style.top = `${location.y}%`; marker.dataset.category = location.category; const dot = document.createElement('div'); dot.className = 'marker-dot'; const glow = document.createElement('div'); glow.className = 'marker-glow'; const infoCard = document.createElement('div'); infoCard.className = 'info-card'; infoCard.innerHTML = ` <h3>${location.name}</h3> <p>${location.description}</p> <div class="tags"> ${location.tags.map(tag => `<span class="tag">${tag}</span>`).join('')} </div> `; // Calculate info card position to keep it on screen if (location.x > 70) { infoCard.style.right = '0'; infoCard.style.left = 'auto'; } else { infoCard.style.left = '0'; infoCard.style.right = 'auto'; } if (location.y > 70) { infoCard.style.bottom = '30px'; infoCard.style.top = 'auto'; } else { infoCard.style.top = '30px'; infoCard.style.bottom = 'auto'; } marker.appendChild(glow); marker.appendChild(dot); marker.appendChild(infoCard); locationMarkersContainer.appendChild(marker); }); } // Initialize zoom and pan controls function initControls() { document.getElementById('zoom-in').addEventListener('click', () => { if (currentZoom < 2) { currentZoom += 0.25; updateMapTransform(); } }); document.getElementById('zoom-out').addEventListener('click', () => { if (currentZoom > 1) { currentZoom -= 0.25; updateMapTransform(); } }); document.getElementById('reset').addEventListener('click', () => { currentZoom = 1; currentTranslateX = 0; currentTranslateY = 0; updateMapTransform(); }); // Filter buttons const filterButtons = document.querySelectorAll('.filter-btn'); filterButtons.forEach(button => { button.addEventListener('click', () => { // Update active button filterButtons.forEach(btn => btn.classList.remove('active')); button.classList.add('active'); // Filter markers const category = button.dataset.category; const markers = document.querySelectorAll('.marker'); markers.forEach(marker => { if (category === 'all' || marker.dataset.category === category) { marker.style.display = 'block'; } else { marker.style.display = 'none'; } }); }); }); } // Update map transformation function updateMapTransform() { mapImage.style.transform = `scale(${currentZoom}) translate(${currentTranslateX}px, ${currentTranslateY}px)`; } // Setup pan functionality function setupPan() { const container = document.querySelector('.map-container'); container.addEventListener('mousedown', startDrag); container.addEventListener('touchstart', e => { const touch = e.touches[0]; startDrag({ clientX: touch.clientX, clientY: touch.clientY }); }, { passive: true }); document.addEventListener('mousemove', drag); document.addEventListener('touchmove', e => { if (isDragging) { e.preventDefault(); const touch = e.touches[0]; drag({ clientX: touch.clientX, clientY: touch.clientY }); } }, { passive: false }); document.addEventListener('mouseup', endDrag); document.addEventListener('touchend', endDrag); function startDrag(e) { if (e.target.closest('.marker, .controls, .legend, .category-filter, .filter-btn')) { return; } isDragging = true; startPosX = e.clientX; startPosY = e.clientY; startTranslateX = currentTranslateX; startTranslateY = currentTranslateY; mapImage.style.transition = 'none'; } function drag(e) { if (!isDragging) return; const dx = (e.clientX - startPosX) / currentZoom; const dy = (e.clientY - startPosY) / currentZoom; // Limit the dragging range based on zoom level const maxTranslate = 100 * (currentZoom - 1); currentTranslateX = Math.max(Math.min(startTranslateX + dx, maxTranslate), -maxTranslate); currentTranslateY = Math.max(Math.min(startTranslateY + dy, maxTranslate), -maxTranslate); updateMapTransform(); } function endDrag() { isDragging = false; mapImage.style.transition = 'transform 0.3s ease'; } } // Simulate loading setTimeout(() => { loader.classList.add('hidden'); createMarkers(); initControls(); setupPan(); }, 1500); }); </script> </body> </html>