Winter brings a magical touch to digital designs, and snow effects can transform a simple interface into a captivating experience. From subtle flurries to intense blizzards, these effects add a seasonal charm that engages users.
In this article, we explore ten stunning snow effect examples that showcase the versatility and beauty of this design element. Whether you're looking to enhance a holiday campaign or simply add a touch of winter wonder, these examples will inspire your creativity.
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
Designers and developers, elevate your winter projects with Subframe's drag-and-drop interface. Its intuitive, responsive canvas ensures pixel-perfect UI every time, making it a favorite among professionals.
Ready to create your own stunning snow effect? Start for free 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
Unlock the power of Subframe and design pixel-perfect UIs with ease. From stunning snow effects to intricate interfaces, Subframe's drag-and-drop editor ensures efficiency and precision.
Ready to elevate your projects? Start for free and begin creating immediately!
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Winter Wonderland Collection</title> <style> :root { --primary-blue: #2D5D7B; --accent-blue: #3A7CA5; --ice-blue: #D6E6F2; --silver: #C0CFD8; --white: #FFFFFF; --glow: rgba(255, 255, 255, 0.5); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Montserrat', sans-serif; } body { background: linear-gradient(135deg, var(--primary-blue), var(--accent-blue)); color: var(--white); overflow-x: hidden; height: 100vh; width: 100%; display: flex; flex-direction: column; align-items: center; } .container { width: 100%; max-width: 700px; padding: 20px; position: relative; overflow-y: auto; max-height: 700px; scrollbar-width: thin; scrollbar-color: var(--ice-blue) transparent; } .container::-webkit-scrollbar { width: 6px; } .container::-webkit-scrollbar-thumb { background-color: var(--ice-blue); border-radius: 6px; } header { text-align: center; padding: 20px 0; position: relative; z-index: 10; } h1 { font-size: 32px; margin-bottom: 10px; letter-spacing: 2px; text-shadow: 0 0 10px var(--glow); position: relative; } h1::after { content: ''; position: absolute; bottom: -8px; left: 50%; transform: translateX(-50%); width: 60px; height: 2px; background: var(--ice-blue); box-shadow: 0 0 8px var(--glow); } .tagline { font-size: 16px; margin-bottom: 20px; opacity: 0.9; } .featured-products { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 25px; margin-top: 30px; } .product-card { background: rgba(255, 255, 255, 0.1); backdrop-filter: blur(8px); border-radius: 12px; overflow: hidden; transition: transform 0.3s, box-shadow 0.3s; position: relative; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); } .product-card:hover { transform: translateY(-10px); box-shadow: 0 12px 20px rgba(0, 0, 0, 0.15), 0 0 15px var(--glow); } .product-image-container { position: relative; overflow: hidden; height: 180px; } .product-image { width: 100%; height: 100%; object-fit: cover; transition: transform 0.5s; } .product-card:hover .product-image { transform: scale(1.08); } .product-details { padding: 15px; } .product-name { font-size: 16px; font-weight: 600; margin-bottom: 8px; } .product-description { font-size: 14px; margin-bottom: 15px; opacity: 0.8; line-height: 1.5; } .product-price { display: flex; justify-content: space-between; align-items: center; } .price { font-size: 18px; font-weight: 700; color: var(--ice-blue); } .price span { font-size: 14px; text-decoration: line-through; margin-left: 5px; opacity: 0.7; } .add-to-cart { background: var(--ice-blue); color: var(--primary-blue); border: none; padding: 8px 15px; border-radius: 5px; font-weight: 600; cursor: pointer; transition: all 0.3s; box-shadow: 0 0 10px rgba(214, 230, 242, 0.3); } .add-to-cart:hover { background: var(--white); box-shadow: 0 0 15px rgba(255, 255, 255, 0.5); } .deal-countdown { margin-top: 30px; text-align: center; background: rgba(255, 255, 255, 0.1); backdrop-filter: blur(8px); padding: 20px; border-radius: 12px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); } .countdown-title { font-size: 20px; margin-bottom: 15px; } .countdown { display: flex; justify-content: center; gap: 15px; } .time-unit { background: var(--primary-blue); border-radius: 8px; padding: 12px; min-width: 60px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); } .time-value { font-size: 24px; font-weight: 700; } .time-label { font-size: 12px; opacity: 0.8; margin-top: 5px; } .snowflakes { position: fixed; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 1; } .snowflake { position: absolute; background: var(--white); border-radius: 50%; opacity: 0.8; box-shadow: 0 0 5px var(--glow); } .jingle-bell { position: absolute; bottom: 20px; right: 20px; width: 40px; height: 40px; background: var(--ice-blue); border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; box-shadow: 0 0 15px var(--glow); z-index: 100; transition: transform 0.3s; } .jingle-bell:hover { transform: scale(1.1) rotate(15deg); } .jingle-bell i { color: var(--primary-blue); font-size: 20px; } .highlight-tag { position: absolute; top: 10px; right: 10px; background: var(--ice-blue); color: var(--primary-blue); padding: 5px 10px; border-radius: 20px; font-size: 12px; font-weight: 600; z-index: 5; box-shadow: 0 0 10px rgba(214, 230, 242, 0.5); transform: rotate(3deg); } .call-to-action { margin-top: 40px; text-align: center; } .shop-now-btn { background: linear-gradient(135deg, var(--ice-blue), var(--silver)); color: var(--primary-blue); border: none; padding: 15px 40px; border-radius: 30px; font-size: 18px; font-weight: 700; cursor: pointer; transition: all 0.3s; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1), 0 0 20px rgba(255, 255, 255, 0.2); position: relative; overflow: hidden; } .shop-now-btn::before { content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background: linear-gradient( rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.3) ); transform: rotate(45deg); transition: transform 0.5s; z-index: -1; } .shop-now-btn:hover { transform: translateY(-5px); box-shadow: 0 7px 20px rgba(0, 0, 0, 0.2), 0 0 30px rgba(255, 255, 255, 0.3); } .shop-now-btn:hover::before { transform: translateX(100%) rotate(45deg); } @media (max-width: 600px) { h1 { font-size: 26px; } .tagline { font-size: 14px; } .featured-products { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 15px; } .product-image-container { height: 150px; } .product-name { font-size: 14px; } .product-description { font-size: 12px; } .time-unit { min-width: 50px; padding: 8px; } .time-value { font-size: 20px; } .shop-now-btn { padding: 12px 30px; font-size: 16px; } } </style> </head> <body> <div class="container"> <header> <h1>WINTER WONDERLAND</h1> <p class="tagline">Embrace the magic of the season with our exclusive winter collection</p> </header> <div class="featured-products"> <div class="product-card"> <div class="product-image-container"> <div class="highlight-tag">BESTSELLER</div> <img src="https://images.unsplash.com/photo-1542272604-787c3835535d?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60" alt="Silver Frost Earrings" class="product-image"> </div> <div class="product-details"> <h3 class="product-name">Silver Frost Earrings</h3> <p class="product-description">Hand-crafted sterling silver earrings with snowflake-inspired design and delicate crystal accents.</p> <div class="product-price"> <div class="price">$42.99 <span>$59.99</span></div> <button class="add-to-cart">Add</button> </div> </div> </div> <div class="product-card"> <div class="product-image-container"> <img src="https://images.unsplash.com/photo-1543076447-215ad9ba6923?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60" alt="Nordic Cashmere Scarf" class="product-image"> </div> <div class="product-details"> <h3 class="product-name">Nordic Cashmere Scarf</h3> <p class="product-description">Ultra-soft cashmere blend with traditional Nordic pattern, perfect for chilly winter evenings.</p> <div class="product-price"> <div class="price">$68.50 <span>$85.00</span></div> <button class="add-to-cart">Add</button> </div> </div> </div> <div class="product-card"> <div class="product-image-container"> <div class="highlight-tag">LIMITED</div> <img src="https://images.unsplash.com/photo-1517677129300-07b130802f46?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60" alt="Winter Frost Candle Set" class="product-image"> </div> <div class="product-details"> <h3 class="product-name">Winter Frost Candle Set</h3> <p class="product-description">Set of 3 premium soy candles with pine, cedar, and vanilla frost scents in frosted glass holders.</p> <div class="product-price"> <div class="price">$36.99 <span>$49.99</span></div> <button class="add-to-cart">Add</button> </div> </div> </div> </div> <div class="deal-countdown"> <h3 class="countdown-title">Holiday Special Ends In:</h3> <div class="countdown"> <div class="time-unit"> <div class="time-value" id="days">02</div> <div class="time-label">Days</div> </div> <div class="time-unit"> <div class="time-value" id="hours">18</div> <div class="time-label">Hours</div> </div> <div class="time-unit"> <div class="time-value" id="minutes">45</div> <div class="time-label">Minutes</div> </div> <div class="time-unit"> <div class="time-value" id="seconds">33</div> <div class="time-label">Seconds</div> </div> </div> </div> <div class="call-to-action"> <button class="shop-now-btn">Explore The Collection</button> </div> </div> <div class="snowflakes" id="snowflakes"></div> <div class="jingle-bell" id="jingle-bell"> <i>❄</i> </div> <script> // Create snowflakes const snowflakesContainer = document.getElementById('snowflakes'); const containerWidth = window.innerWidth; const containerHeight = window.innerHeight; const snowflakeCount = 50; let scrollSpeedFactor = 1; // Create initial snowflakes for (let i = 0; i < snowflakeCount; i++) { createSnowflake(); } function createSnowflake() { const snowflake = document.createElement('div'); snowflake.classList.add('snowflake'); // Randomize snowflake properties const size = Math.random() * 5 + 2; const startPositionX = Math.random() * containerWidth; const startPositionY = Math.random() * containerHeight * -1; const duration = Math.random() * 10 + 8; const delay = Math.random() * 5; // Set snowflake styles snowflake.style.width = `${size}px`; snowflake.style.height = `${size}px`; snowflake.style.left = `${startPositionX}px`; snowflake.style.top = `${startPositionY}px`; snowflake.style.opacity = Math.random() * 0.7 + 0.3; // Store snowflake properties for animation snowflake.setAttribute('data-speed', Math.random() * 2 + 1); snowflake.setAttribute('data-amplitude', Math.random() * 30 + 5); snowflake.setAttribute('data-x', startPositionX); snowflake.setAttribute('data-y', startPositionY); snowflakesContainer.appendChild(snowflake); animateSnowflake(snowflake); } function animateSnowflake(snowflake) { const speed = parseFloat(snowflake.getAttribute('data-speed')); const amplitude = parseFloat(snowflake.getAttribute('data-amplitude')); let x = parseFloat(snowflake.getAttribute('data-x')); let y = parseFloat(snowflake.getAttribute('data-y')); function update() { // Update position with scroll speed factor y += speed * scrollSpeedFactor; x += Math.sin(y / amplitude) * 0.5; // Set new position snowflake.style.transform = `translate(${Math.sin(y / 50) * amplitude}px, ${y}px)`; // Reset if snowflake moves out of view if (y > containerHeight) { y = -10; x = Math.random() * containerWidth; snowflake.setAttribute('data-x', x); snowflake.setAttribute('data-y', y); } else { snowflake.setAttribute('data-y', y); } requestAnimationFrame(update); } update(); } // Adjust snowfall speed based on scroll const container = document.querySelector('.container'); container.addEventListener('scroll', () => { const scrollPosition = container.scrollTop; const maxScroll = container.scrollHeight - container.clientHeight; scrollSpeedFactor = 1 + (scrollPosition / maxScroll) * 1.5; }); // Jingle bell interaction const jingleBell = document.getElementById('jingle-bell'); jingleBell.addEventListener('click', () => { // Create an explosion of snowflakes for (let i = 0; i < 15; i++) { setTimeout(() => { createSnowflake(); }, i * 100); } // Add animation to jingle bell jingleBell.style.animation = 'jingle 0.5s ease-in-out'; setTimeout(() => { jingleBell.style.animation = ''; }, 500); }); // Countdown timer const countdownDate = new Date(); countdownDate.setDate(countdownDate.getDate() + 2); countdownDate.setHours(countdownDate.getHours() + 18); countdownDate.setMinutes(countdownDate.getMinutes() + 45); countdownDate.setSeconds(countdownDate.getSeconds() + 33); function updateCountdown() { const now = new Date().getTime(); const distance = countdownDate - now; const days = Math.floor(distance / (1000 * 60 * 60 * 24)); const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)); const seconds = Math.floor((distance % (1000 * 60)) / 1000); document.getElementById('days').textContent = days.toString().padStart(2, '0'); document.getElementById('hours').textContent = hours.toString().padStart(2, '0'); document.getElementById('minutes').textContent = minutes.toString().padStart(2, '0'); document.getElementById('seconds').textContent = seconds.toString().padStart(2, '0'); if (distance < 0) { clearInterval(countdownInterval); document.getElementById('days').textContent = '00'; document.getElementById('hours').textContent = '00'; document.getElementById('minutes').textContent = '00'; document.getElementById('seconds').textContent = '00'; } } const countdownInterval = setInterval(updateCountdown, 1000); updateCountdown(); // Product card hover effects const productCards = document.querySelectorAll('.product-card'); productCards.forEach(card => { card.addEventListener('mouseenter', () => { // Create localized snowflakes over the product image const imageContainer = card.querySelector('.product-image-container'); const rect = imageContainer.getBoundingClientRect(); for (let i = 0; i < 5; i++) { const localSnowflake = document.createElement('div'); localSnowflake.classList.add('snowflake'); localSnowflake.style.width = `${Math.random() * 4 + 2}px`; localSnowflake.style.height = localSnowflake.style.width; localSnowflake.style.left = `${rect.left + Math.random() * rect.width}px`; localSnowflake.style.top = `${rect.top - 10}px`; localSnowflake.style.opacity = Math.random() * 0.8 + 0.2; snowflakesContainer.appendChild(localSnowflake); let startY = rect.top - 10; function animateLocal() { startY += 1.5; localSnowflake.style.top = `${startY}px`; localSnowflake.style.transform = `translateX(${Math.sin(startY / 20) * 10}px)`; if (startY < rect.bottom) { requestAnimationFrame(animateLocal); } else { localSnowflake.remove(); } } animateLocal(); } }); }); // Add to cart button const addToCartButtons = document.querySelectorAll('.add-to-cart'); addToCartButtons.forEach(button => { button.addEventListener('click', (e) => { e.preventDefault(); button.textContent = '✓'; button.style.background = '#2D5D7B'; button.style.color = '#fff'; setTimeout(() => { button.textContent = 'Add'; button.style.background = ''; button.style.color = ''; }, 1500); }); }); // Shop now button shine effect const shopNowBtn = document.querySelector('.shop-now-btn'); shopNowBtn.addEventListener('click', (e) => { e.preventDefault(); // Create a ripple effect const ripple = document.createElement('span'); ripple.classList.add('ripple'); ripple.style.position = 'absolute'; ripple.style.borderRadius = '50%'; ripple.style.transform = 'scale(0)'; ripple.style.background = 'rgba(255, 255, 255, 0.4)'; ripple.style.width = '100%'; ripple.style.height = '100%'; ripple.style.top = '0'; ripple.style.left = '0'; ripple.style.pointerEvents = 'none'; shopNowBtn.appendChild(ripple); ripple.style.animation = 'ripple 0.8s ease-out'; setTimeout(() => { ripple.remove(); }, 800); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Montserrat', sans-serif; } body { background-color: #f5f7fa; color: #2c3e50; min-height: 700px; overflow-x: hidden; position: relative; } .app-container { max-width: 700px; min-height: 700px; margin: 0 auto; display: flex; flex-direction: column; background-color: #f5f7fa; position: relative; overflow: hidden; } .header { position: relative; height: 200px; overflow: hidden; border-radius: 0 0 30px 30px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); } .header-bg { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(135deg, #3498db, #8e44ad); z-index: 1; } .snow-container { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 2; pointer-events: none; } .snow { position: absolute; background-color: rgba(255, 255, 255, 0.8); border-radius: 50%; filter: blur(1px); opacity: 0; animation: snowfall linear infinite; } @keyframes snowfall { 0% { transform: translateY(-10px) translateX(0); opacity: 0; } 10% { opacity: 0.8; } 90% { opacity: 0.7; } 100% { transform: translateY(calc(100vh + 10px)) translateX(20px); opacity: 0; } } .header-content { position: relative; z-index: 3; display: flex; flex-direction: column; justify-content: center; height: 100%; padding: 20px; color: white; text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); } .header-content h1 { font-size: 2rem; font-weight: 700; margin-bottom: 10px; transform: translateY(0); transition: transform 0.5s ease; } .header-content p { font-size: 1rem; max-width: 80%; opacity: 0.9; } .search-bar { background-color: white; border-radius: 20px; padding: 15px 20px; margin: -25px 20px 20px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); position: relative; z-index: 4; display: flex; flex-direction: column; gap: 15px; transition: transform 0.3s ease, box-shadow 0.3s ease; } .search-bar:hover { transform: translateY(-5px); box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15); } .search-inputs { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; } .search-field { position: relative; } .search-field label { display: block; font-size: 0.7rem; font-weight: 600; color: #7f8c8d; margin-bottom: 5px; text-transform: uppercase; letter-spacing: 0.5px; } .search-field input, .search-field select { width: 100%; padding: 10px 15px; border: 1px solid #e1e5e8; border-radius: 10px; font-size: 0.9rem; background-color: #f8f9fa; color: #2c3e50; transition: all 0.3s ease; } .search-field input:focus, .search-field select:focus { outline: none; border-color: #3498db; background-color: white; box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.1); } .search-button { margin-top: 10px; background: linear-gradient(135deg, #3498db, #8e44ad); color: white; border: none; border-radius: 10px; padding: 12px; font-weight: 600; cursor: pointer; transition: all 0.3s ease; text-transform: uppercase; letter-spacing: 1px; font-size: 0.9rem; } .search-button:hover { transform: translateY(-2px); box-shadow: 0 4px 15px rgba(52, 152, 219, 0.3); } .search-button:active { transform: translateY(0); } .destinations { padding: 20px; } .section-title { font-size: 1.2rem; font-weight: 700; margin-bottom: 15px; color: #2c3e50; position: relative; display: inline-block; } .section-title:after { content: ''; position: absolute; bottom: -5px; left: 0; width: 40px; height: 3px; background: linear-gradient(135deg, #3498db, #8e44ad); border-radius: 3px; } .destinations-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 15px; margin-bottom: 30px; } .destination-card { position: relative; border-radius: 15px; overflow: hidden; height: 160px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); cursor: pointer; transition: transform 0.3s ease, box-shadow 0.3s ease; } .destination-card:hover { transform: translateY(-5px) scale(1.02); box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15); } .destination-card:hover .snow-overlay { opacity: 1; } .destination-img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.5s ease; } .destination-card:hover .destination-img { transform: scale(1.1); } .snow-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; opacity: 0.6; transition: opacity 0.3s ease; z-index: 2; } .destination-info { position: absolute; bottom: 0; left: 0; right: 0; padding: 15px; background: linear-gradient(0deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0) 100%); color: white; z-index: 3; } .destination-name { font-size: 1rem; font-weight: 600; margin-bottom: 5px; } .destination-price { font-size: 0.9rem; opacity: 0.9; } .winter-specials { margin-top: 10px; background-color: white; border-radius: 20px; padding: 20px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05); } .special-title { display: flex; align-items: center; gap: 10px; margin-bottom: 15px; } .special-title i { color: #3498db; font-size: 1.2rem; } .special-card { display: flex; align-items: center; gap: 15px; padding: 15px; border-radius: 15px; background-color: #f5f7fa; margin-bottom: 10px; transition: transform 0.3s ease, box-shadow 0.3s ease; position: relative; overflow: hidden; } .special-card:hover { transform: translateX(5px); box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); } .special-image { width: 70px; height: 70px; border-radius: 10px; object-fit: cover; } .special-info { flex: 1; } .special-name { font-weight: 600; margin-bottom: 5px; color: #2c3e50; } .special-desc { font-size: 0.8rem; color: #7f8c8d; margin-bottom: 5px; } .special-price { font-weight: 700; color: #3498db; } .special-card:before { content: ''; position: absolute; left: 0; top: 0; height: 100%; width: 3px; background: linear-gradient(135deg, #3498db, #8e44ad); opacity: 0; transition: opacity 0.3s ease; } .special-card:hover:before { opacity: 1; } /* Snow Individual Particle Styling */ .snow-particle { position: absolute; background-color: white; border-radius: 50%; filter: blur(1px); opacity: 0.8; animation: snowDrift linear infinite; } @keyframes snowDrift { 0% { transform: translateY(0) translateX(0); opacity: 0; } 10% { opacity: 0.8; } 90% { opacity: 0.6; } 100% { opacity: 0; } } @media (max-width: 500px) { .header-content h1 { font-size: 1.5rem; } .search-inputs { grid-template-columns: 1fr; } .destinations-grid { grid-template-columns: 1fr; } } .loading-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: #f5f7fa; display: flex; justify-content: center; align-items: center; z-index: 1000; transition: opacity 0.5s ease; } .snowflake-loader { width: 50px; height: 50px; position: relative; animation: loaderRotate 2s linear infinite; } .snowflake-loader:before, .snowflake-loader:after { content: ''; position: absolute; width: 100%; height: 100%; border-radius: 50%; background-color: #3498db; opacity: 0.6; animation: loaderPulse 2s ease-in-out infinite alternate; } .snowflake-loader:after { animation-delay: 1s; background-color: #8e44ad; } @keyframes loaderRotate { 100% { transform: rotate(360deg); } } @keyframes loaderPulse { 0% { transform: scale(0.2); opacity: 0.6; } 100% { transform: scale(1); opacity: 0.1; } } </style> </head> <body> <div class="loading-overlay"> <div class="snowflake-loader"></div> </div> <div class="app-container"> <header class="header"> <div class="header-bg"></div> <div class="snow-container" id="header-snow"></div> <div class="header-content"> <h1>Winter Wanderlust Awaits</h1> <p>Discover magical winter getaways with seasonal discounts</p> </div> </header> <div class="search-bar"> <div class="search-inputs"> <div class="search-field"> <label for="destination">Destination</label> <input type="text" id="destination" placeholder="Mountain retreat, city escape..."> </div> <div class="search-field"> <label for="dates">Travel Dates</label> <input type="text" id="dates" placeholder="Dec 24 - Jan 2"> </div> <div class="search-field"> <label for="travelers">Travelers</label> <select id="travelers"> <option value="1">1 Traveler</option> <option value="2" selected>2 Travelers</option> <option value="3">3 Travelers</option> <option value="4">4+ Travelers</option> </select> </div> <div class="search-field"> <label for="experience">Experience</label> <select id="experience"> <option value="any">Any Experience</option> <option value="snow" selected>Snow Activities</option> <option value="chalet">Chalet Stay</option> <option value="festival">Winter Festivals</option> </select> </div> </div> <button class="search-button" id="search-btn">Find Winter Magic</button> </div> <section class="destinations"> <h2 class="section-title">Trending Winter Destinations</h2> <div class="destinations-grid"> <div class="destination-card"> <img src="https://images.unsplash.com/photo-1551582045-6ec9c11d8697?ixlib=rb-1.2.1&auto=format&fit=crop&w=400&q=80" alt="Aspen, Colorado" class="destination-img"> <div class="snow-overlay" id="snow-1"></div> <div class="destination-info"> <div class="destination-name">Aspen, Colorado</div> <div class="destination-price">from $349/night</div> </div> </div> <div class="destination-card"> <img src="https://images.unsplash.com/photo-1513407030348-c983a97b98d8?ixlib=rb-1.2.1&auto=format&fit=crop&w=400&q=80" alt="Reykjavik, Iceland" class="destination-img"> <div class="snow-overlay" id="snow-2"></div> <div class="destination-info"> <div class="destination-name">Reykjavik, Iceland</div> <div class="destination-price">from $299/night</div> </div> </div> <div class="destination-card"> <img src="https://images.unsplash.com/photo-1605540436563-5bca919ae766?ixlib=rb-1.2.1&auto=format&fit=crop&w=400&q=80" alt="Zermatt, Switzerland" class="destination-img"> <div class="snow-overlay" id="snow-3"></div> <div class="destination-info"> <div class="destination-name">Zermatt, Switzerland</div> <div class="destination-price">from $419/night</div> </div> </div> <div class="destination-card"> <img src="https://images.unsplash.com/photo-1543429776-2782fc8e1acd?ixlib=rb-1.2.1&auto=format&fit=crop&w=400&q=80" alt="Kyoto, Japan" class="destination-img"> <div class="snow-overlay" id="snow-4"></div> <div class="destination-info"> <div class="destination-name">Kyoto, Japan</div> <div class="destination-price">from $279/night</div> </div> </div> </div> <div class="winter-specials"> <div class="special-title"> <i>❄️</i> <h2 class="section-title">Limited-Time Winter Offers</h2> </div> <div class="special-card"> <img src="https://images.unsplash.com/photo-1578645510447-e20b4311e3ce?ixlib=rb-1.2.1&auto=format&fit=crop&w=200&q=80" alt="Nordic Ski Package" class="special-image"> <div class="special-info"> <div class="special-name">Nordic Ski Adventure</div> <div class="special-desc">7 nights in a luxury cabin + daily ski passes</div> <div class="special-price">Save 30% until Dec 15</div> </div> </div> <div class="special-card"> <img src="https://images.unsplash.com/photo-1610058612092-01e9a172d85e?ixlib=rb-1.2.1&auto=format&fit=crop&w=200&q=80" alt="Northern Lights" class="special-image"> <div class="special-info"> <div class="special-name">Aurora Borealis Expedition</div> <div class="special-desc">5 nights in glass igloo + guided tours</div> <div class="special-price">Save 25% for January bookings</div> </div> </div> </div> </section> </div> <script> // Create snow particles in header and destination overlays document.addEventListener('DOMContentLoaded', function() { setTimeout(() => { const loadingOverlay = document.querySelector('.loading-overlay'); loadingOverlay.style.opacity = '0'; setTimeout(() => { loadingOverlay.style.display = 'none'; }, 500); }, 1500); // Header snow createSnow('header-snow', 30); // Snow overlays for destination cards createSnow('snow-1', 20); createSnow('snow-2', 20); createSnow('snow-3', 20); createSnow('snow-4', 20); // Add search interaction const searchBtn = document.getElementById('search-btn'); searchBtn.addEventListener('click', function() { searchBtn.innerText = 'Searching...'; setTimeout(() => { searchBtn.innerText = 'Find Winter Magic'; // Add a gentle snowfall to the whole page for 3 seconds createPageSnowfall(); }, 1500); }); // Add interaction to destination cards const destinationCards = document.querySelectorAll('.destination-card'); destinationCards.forEach(card => { card.addEventListener('click', function() { card.style.transform = 'translateY(-8px) scale(1.03)'; setTimeout(() => { card.style.transform = ''; }, 300); }); }); // Add scroll effect to header window.addEventListener('scroll', function() { const headerContent = document.querySelector('.header-content h1'); const scrollPos = window.scrollY; if (scrollPos > 10) { headerContent.style.transform = `translateY(${scrollPos * 0.2}px)`; } else { headerContent.style.transform = 'translateY(0)'; } }); }); function createSnow(containerId, count) { const container = document.getElementById(containerId); const containerWidth = container.offsetWidth; const containerHeight = container.offsetHeight; for (let i = 0; i < count; i++) { const snow = document.createElement('div'); snow.className = 'snow'; // Randomize snow properties const size = Math.random() * 8 + 2; const posX = Math.random() * containerWidth; const delay = Math.random() * 5; const duration = Math.random() * 10 + 10; // Apply styles snow.style.width = `${size}px`; snow.style.height = `${size}px`; snow.style.left = `${posX}px`; snow.style.animationDelay = `${delay}s`; snow.style.animationDuration = `${duration}s`; container.appendChild(snow); } } function createPageSnowfall() { const snowfallContainer = document.createElement('div'); snowfallContainer.style.position = 'fixed'; snowfallContainer.style.top = '0'; snowfallContainer.style.left = '0'; snowfallContainer.style.width = '100%'; snowfallContainer.style.height = '100%'; snowfallContainer.style.pointerEvents = 'none'; snowfallContainer.style.zIndex = '999'; for (let i = 0; i < 50; i++) { const snow = document.createElement('div'); snow.className = 'snow-particle'; // Randomize snow properties const size = Math.random() * 7 + 3; const posX = Math.random() * window.innerWidth; const posY = Math.random() * -100; const duration = Math.random() * 5 + 5; const delay = Math.random() * 2; const endPosX = posX + (Math.random() * 100 - 50); const endPosY = window.innerHeight + 50; // Apply styles snow.style.width = `${size}px`; snow.style.height = `${size}px`; snow.style.left = `${posX}px`; snow.style.top = `${posY}px`; snow.style.animationDuration = `${duration}s`; snow.style.animationDelay = `${delay}s`; // Create custom keyframe animation for this snow particle const styleElement = document.createElement('style'); styleElement.textContent = ` @keyframes snow${i} { 0% { transform: translate(0, 0); opacity: 0; } 10% { opacity: 0.8; } 100% { transform: translate(${endPosX - posX}px, ${endPosY}px); opacity: 0; } } `; document.head.appendChild(styleElement); snow.style.animation = `snow${i} ${duration}s ease-in-out forwards`; snowfallContainer.appendChild(snow); } document.body.appendChild(snowfallContainer); // Remove after 5 seconds setTimeout(() => { snowfallContainer.style.transition = 'opacity 1s ease'; snowfallContainer.style.opacity = '0'; setTimeout(() => { document.body.removeChild(snowfallContainer); }, 1000); }, 3000); } </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Winter Wonderland</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Montserrat', sans-serif; } @import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;600;700&family=Playfair+Display:wght@400;700&display=swap'); :root { --primary-color: #1a2a3a; --accent-color: #4e89ae; --light-color: #e8f1f5; --dark-accent: #2b4c7e; --highlight: #7ecefd; } body { background-color: var(--light-color); color: var(--primary-color); overflow-x: hidden; max-width: 700px; margin: 0 auto; position: relative; height: 100vh; } .snowflake { position: absolute; width: 10px; height: 10px; background: transparent; border-radius: 50%; pointer-events: none; z-index: 9999; } .snowflake svg { width: 100%; height: 100%; fill: white; opacity: 0.8; } .container { max-width: 700px; margin: 0 auto; padding: 20px; position: relative; overflow: hidden; height: 100vh; scroll-behavior: smooth; } .hero { height: 100vh; display: flex; flex-direction: column; justify-content: center; align-items: center; text-align: center; position: relative; z-index: 10; padding: 0 20px; } .hero__title { font-family: 'Playfair Display', serif; font-size: 3.5rem; color: var(--primary-color); margin-bottom: 20px; line-height: 1.2; transform: translateY(20px); opacity: 0; animation: fadeUp 1s forwards 0.5s; } .hero__subtitle { font-size: 1.2rem; font-weight: 300; margin-bottom: 30px; max-width: 600px; transform: translateY(20px); opacity: 0; animation: fadeUp 1s forwards 0.8s; } .cta-button { background-color: var(--accent-color); color: white; border: none; padding: 15px 30px; font-size: 1rem; font-weight: 600; border-radius: 30px; cursor: pointer; transition: all 0.3s ease; position: relative; overflow: hidden; z-index: 1; transform: translateY(20px); opacity: 0; animation: fadeUp 1s forwards 1.1s; } .cta-button:hover { background-color: var(--dark-accent); transform: translateY(-3px); box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1); } .cta-button:after { content: ""; position: absolute; left: 0; top: 0; height: 490%; width: 140%; background: var(--highlight); transition: all .5s ease-in-out; transform: translateX(-98%) translateY(-25%) rotate(45deg); z-index: -1; } .cta-button:hover:after { transform: translateX(-9%) translateY(-25%) rotate(45deg); } .scroll-indicator { position: absolute; bottom: 30px; left: 50%; transform: translateX(-50%); animation: bounce 2s infinite; opacity: 0; animation-delay: 1.5s; animation-fill-mode: forwards; } .scroll-indicator svg { width: 30px; height: 30px; fill: var(--primary-color); } .features { min-height: 100vh; display: flex; flex-direction: column; justify-content: center; position: relative; z-index: 10; padding: 60px 20px; } .feature-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 30px; margin-top: 50px; } .feature-card { background: rgba(255, 255, 255, 0.8); backdrop-filter: blur(10px); border-radius: 15px; padding: 30px; transition: all 0.3s ease; transform: translateY(50px); opacity: 0; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05); position: relative; overflow: hidden; height: 100%; } .feature-card.visible { transform: translateY(0); opacity: 1; } .feature-card:hover { transform: translateY(-10px); box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1); } .feature-card:before { content: ""; position: absolute; top: 0; left: 0; width: 5px; height: 100%; background: var(--accent-color); transition: all 0.3s ease; } .feature-card:hover:before { width: 10px; } .feature-icon { font-size: 2.5rem; color: var(--accent-color); margin-bottom: 20px; } .feature-card h3 { font-size: 1.5rem; margin-bottom: 15px; font-family: 'Playfair Display', serif; } .feature-card p { line-height: 1.6; margin-bottom: 15px; } .section-title { font-family: 'Playfair Display', serif; font-size: 2.5rem; margin-bottom: 20px; position: relative; display: inline-block; } .section-title:after { content: ""; position: absolute; bottom: -10px; left: 0; width: 60%; height: 4px; background: var(--accent-color); } .section-subtitle { max-width: 600px; margin-bottom: 50px; line-height: 1.6; } .snowflake-canvas { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none; } .custom-cursor { width: 30px; height: 30px; border-radius: 50%; position: fixed; pointer-events: none; z-index: 9999; mix-blend-mode: difference; transition: transform 0.2s ease; transform: translate(-50%, -50%) scale(1); background: var(--highlight); opacity: 0.7; } .cursor-text { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 8px; color: white; font-weight: bold; text-transform: uppercase; white-space: nowrap; } @keyframes fadeUp { to { opacity: 1; transform: translateY(0); } } @keyframes fadeIn { to { opacity: 1; } } @keyframes bounce { 0%, 20%, 50%, 80%, 100% { transform: translateX(-50%) translateY(0); opacity: 1; } 40% { transform: translateX(-50%) translateY(-20px); opacity: 1; } 60% { transform: translateX(-50%) translateY(-10px); opacity: 1; } } /* Responsive adjustments */ @media (max-width: 700px) { .hero__title { font-size: 2.5rem; } .hero__subtitle { font-size: 1rem; } .section-title { font-size: 2rem; } .feature-grid { grid-template-columns: 1fr; } } /* Custom snowflake animation */ .hand-drawn-snowflake { position: fixed; width: 30px; height: 30px; z-index: 5; opacity: 0.6; pointer-events: none; will-change: transform; } /* Winter theme toggle switch */ .theme-toggle { position: fixed; top: 20px; right: 20px; z-index: 100; background: rgba(255, 255, 255, 0.2); border-radius: 30px; padding: 5px; cursor: pointer; transition: all 0.3s ease; backdrop-filter: blur(5px); border: 1px solid rgba(255, 255, 255, 0.3); display: flex; align-items: center; opacity: 0; animation: fadeIn 1s forwards 1.5s; } .theme-toggle .icon { padding: 5px 10px; border-radius: 25px; transition: all 0.3s ease; } .theme-toggle .icon.active { background: white; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); } .theme-toggle .icon svg { width: 20px; height: 20px; fill: var(--primary-color); } /* Dark theme */ body.dark-theme { background-color: var(--primary-color); color: var(--light-color); } body.dark-theme .hero__title, body.dark-theme .section-title { color: var(--light-color); } body.dark-theme .feature-card { background: rgba(30, 45, 60, 0.8); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); } body.dark-theme .scroll-indicator svg { fill: var(--light-color); } /* Loading animation */ .loader { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: var(--light-color); display: flex; justify-content: center; align-items: center; z-index: 9999; transition: opacity 0.5s ease, visibility 0.5s ease; } .loader.hidden { opacity: 0; visibility: hidden; } .loader svg { width: 50px; height: 50px; animation: rotate 2s linear infinite; } @keyframes rotate { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } </style> </head> <body> <div class="loader"> <svg viewBox="0 0 100 100"> <path d="M10,50 A40,40 0 1,1 90,50 A40,40 0 1,1 10,50" fill="none" stroke="#4e89ae" stroke-width="8" stroke-linecap="round" stroke-dasharray="180 240" /> </svg> </div> <div class="custom-cursor"> <span class="cursor-text">❄️</span> </div> <div class="snowflake-canvas"></div> <div class="theme-toggle"> <div class="icon light active"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zm0 2c1.65 0 3 1.35 3 3s-1.35 3-3 3-3-1.35-3-3 1.35-3 3-3zm0-7c.56 0 1 .44 1 1v2c0 .56-.44 1-1 1s-1-.44-1-1V3c0-.56.44-1 1-1zm0 18c-.56 0-1-.44-1-1v-2c0-.56.44-1 1-1s1 .44 1 1v2c0 .56-.44 1-1 1zm7-9c0 .56-.44 1-1 1h-2c-.56 0-1-.44-1-1s.44-1 1-1h2c.56 0 1 .44 1 1zM8 12c0-.56.44-1 1-1h2c.56 0 1 .44 1 1s-.44 1-1 1H9c-.56 0-1-.44-1-1zm9.7 5.3c-.39.39-1.02.39-1.41 0l-1.42-1.42c-.39-.39-.39-1.02 0-1.41s1.02-.39 1.41 0l1.42 1.42c.39.38.39 1.01 0 1.41zM7.7 6.7c.39-.39 1.02-.39 1.41 0l1.42 1.42c.39.39.39 1.02 0 1.41s-1.02.39-1.41 0L7.7 8.11c-.39-.38-.39-1.02 0-1.41zm0 10.6c-.39-.39-.39-1.02 0-1.41l1.42-1.42c.39-.39 1.02-.39 1.41 0s.39 1.02 0 1.41L9.11 17.3c-.38.39-1.02.39-1.41 0zM17.3 7.7c.39.39.39 1.02 0 1.41l-1.42 1.42c-.39.39-1.02.39-1.41 0s-.39-1.02 0-1.41l1.42-1.42c.38-.39 1.02-.39 1.41 0z"/></svg> </div> <div class="icon dark"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9 9-4.03 9-9c0-.46-.04-.92-.1-1.36-.98 1.37-2.58 2.26-4.4 2.26-2.98 0-5.4-2.42-5.4-5.4 0-1.81.89-3.42 2.26-4.4-.44-.06-.9-.1-1.36-.1z"/></svg> </div> </div> <div class="container"> <section class="hero"> <h1 class="hero__title">Embrace the Winter<br>Magic</h1> <p class="hero__subtitle">Explore our handcrafted collection of winter treasures, where each snowflake tells a unique story. Let the season's wonder transform your everyday moments.</p> <button class="cta-button">Discover Winter Wonders</button> <div class="scroll-indicator"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8z" transform="rotate(90 12 12)"/></svg> </div> </section> <section class="features"> <h2 class="section-title">Winter Highlights</h2> <p class="section-subtitle">Our seasonal treasures combine artisanal craftsmanship with the purest elements of winter, creating an experience that resonates with the season's quiet beauty.</p> <div class="feature-grid"> <div class="feature-card"> <div class="feature-icon">❄️</div> <h3>Crystalline Collections</h3> <p>Each piece in our winter collection captures a moment of crystalline perfection, hand-illustrated to preserve the ephemeral beauty of real snowflakes.</p> </div> <div class="feature-card"> <div class="feature-icon">🌨️</div> <h3>Alpine Inspirations</h3> <p>Drawn from the majestic silence of alpine summits, our designs translate the geometric precision of nature into elegant seasonal accents.</p> </div> <div class="feature-card"> <div class="feature-icon">✨</div> <h3>Frost-Kissed Finishes</h3> <p>The distinctive shimmer of winter mornings influences our signature frost technique, bringing subtle luminescence to each carefully crafted element.</p> </div> <div class="feature-card"> <div class="feature-icon">🏔️</div> <h3>Seasonal Storytelling</h3> <p>Behind every pattern lies a narrative of winter's transformative journey, connecting you to the timeless cycle of seasonal renewal.</p> </div> </div> </section> </div> <script> // Snow effect with hand-drawn snowflakes document.addEventListener('DOMContentLoaded', function() { // Snowflake SVGs const snowflakeSVGs = [ `<svg viewBox="0 0 32 32"><path d="M16 0 L16 32 M0 16 L32 16 M4.5 4.5 L27.5 27.5 M4.5 27.5 L27.5 4.5 M8 2 L24 2 M2 8 L2 24 M8 30 L24 30 M30 8 L30 24"/></svg>`, `<svg viewBox="0 0 32 32"><path d="M16 0 L16 32 M0 16 L32 16 M8 8 L24 24 M8 24 L24 8 M12 2 L20 2 M2 12 L2 20 M12 30 L20 30 M30 12 L30 20"/></svg>`, `<svg viewBox="0 0 32 32"><path d="M16 0 L16 32 M0 16 L32 16 M4 8 L28 24 M4 24 L28 8 M10 4 L22 4 M4 10 L4 22 M10 28 L22 28 M28 10 L28 22"/></svg>` ]; // Create snowflakes const snowflakeCanvas = document.querySelector('.snowflake-canvas'); const numSnowflakes = 30; for (let i = 0; i < numSnowflakes; i++) { createSnowflake(); } function createSnowflake() { const snowflake = document.createElement('div'); snowflake.classList.add('hand-drawn-snowflake'); // Randomly select one of the SVG designs const svgIndex = Math.floor(Math.random() * snowflakeSVGs.length); snowflake.innerHTML = snowflakeSVGs[svgIndex]; // Set random size const size = Math.random() * 20 + 10; snowflake.style.width = `${size}px`; snowflake.style.height = `${size}px`; // Set random starting position const startX = Math.random() * window.innerWidth; const startY = -100; // Start above the viewport // Set random fall properties const fallDuration = Math.random() * 10 + 10; // seconds const swayAmount = Math.random() * 150 + 50; // pixels const swayDuration = Math.random() * 5 + 4; // seconds const delay = Math.random() * 20; // seconds // Apply styles snowflake.style.fill = 'none'; snowflake.style.stroke = 'white'; snowflake.style.strokeWidth = '1.5'; snowflake.style.left = `${startX}px`; snowflake.style.top = `${startY}px`; snowflake.style.opacity = Math.random() * 0.5 + 0.3; // Apply animation snowflake.style.animation = ` fall ${fallDuration}s linear ${delay}s infinite, sway ${swayDuration}s ease-in-out ${delay}s infinite alternate `; // Add keyframes for the specific snowflake const style = document.createElement('style'); style.textContent = ` @keyframes fall { to { transform: translateY(${window.innerHeight + 100}px) rotate(${Math.random() * 360}deg); } } @keyframes sway { from { transform: translateX(-${swayAmount / 2}px) rotate(${Math.random() * 180}deg); } to { transform: translateX(${swayAmount / 2}px) rotate(${Math.random() * 180}deg); } } `; document.head.appendChild(style); snowflakeCanvas.appendChild(snowflake); } // Parallax effect on scroll window.addEventListener('scroll', function() { const scrollValue = window.pageYOffset; const hero = document.querySelector('.hero'); const features = document.querySelector('.features'); // Parallax effect for hero section hero.style.transform = `translateY(${scrollValue * 0.3}px)`; // Check if feature cards are visible const featureCards = document.querySelectorAll('.feature-card'); featureCards.forEach(card => { const cardTop = card.getBoundingClientRect().top; if (cardTop < window.innerHeight - 100) { card.classList.add('visible'); } }); }); // Custom cursor const cursor = document.querySelector('.custom-cursor'); document.addEventListener('mousemove', function(e) { cursor.style.left = e.clientX + 'px'; cursor.style.top = e.clientY + 'px'; }); document.addEventListener('mousedown', function() { cursor.style.transform = 'translate(-50%, -50%) scale(0.8)'; }); document.addEventListener('mouseup', function() { cursor.style.transform = 'translate(-50%, -50%) scale(1)'; }); // Hover effect for interactive elements const interactiveElements = document.querySelectorAll('button, .feature-card, .theme-toggle'); interactiveElements.forEach(element => { element.addEventListener('mouseenter', function() { cursor.style.transform = 'translate(-50%, -50%) scale(1.5)'; cursor.querySelector('.cursor-text').textContent = element.tagName === 'BUTTON' ? 'Click' : 'View'; }); element.addEventListener('mouseleave', function() { cursor.style.transform = 'translate(-50%, -50%) scale(1)'; cursor.querySelector('.cursor-text').textContent = '❄️'; }); }); // Theme toggle const themeToggle = document.querySelector('.theme-toggle'); const lightIcon = document.querySelector('.icon.light'); const darkIcon = document.querySelector('.icon.dark'); themeToggle.addEventListener('click', function() { document.body.classList.toggle('dark-theme'); lightIcon.classList.toggle('active'); darkIcon.classList.toggle('active'); // Update snowflake colors const snowflakes = document.querySelectorAll('.hand-drawn-snowflake svg'); snowflakes.forEach(snowflake => { if (document.body.classList.contains('dark-theme')) { snowflake.style.stroke = '#7ecefd'; } else { snowflake.style.stroke = 'white'; } }); }); // Button click effect const ctaButton = document.querySelector('.cta-button'); ctaButton.addEventListener('click', function(e) { // Create ripple effect const ripple = document.createElement('span'); ripple.classList.add('ripple'); this.appendChild(ripple); const rect = this.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; ripple.style.left = x + 'px'; ripple.style.top = y + 'px'; setTimeout(function() { ripple.remove(); }, 600); // Scroll to features section document.querySelector('.features').scrollIntoView({ behavior: 'smooth' }); }); // Fade out loader setTimeout(() => { document.querySelector('.loader').classList.add('hidden'); }, 1500); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Ephemeral Fragments | Digital Art Portfolio</title> <style> :root { --primary-dark: #0a0a0e; --secondary-dark: #121218; --accent-blue: #2a3a8f; --accent-purple: #4d2c91; --text-primary: #f0f0f2; --text-secondary: #9a9aa9; --transition-standard: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', sans-serif; } body { background: var(--primary-dark); color: var(--text-primary); overflow-x: hidden; height: 100vh; width: 100%; position: relative; } #app { width: 100%; height: 100%; overflow: hidden; position: relative; } #particle-container { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 0; } .content { position: relative; z-index: 2; height: 100%; padding: 2rem; display: flex; flex-direction: column; justify-content: space-between; overflow-y: auto; -ms-overflow-style: none; scrollbar-width: none; } .content::-webkit-scrollbar { display: none; } header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem; } .logo { font-size: 1.2rem; font-weight: 700; position: relative; letter-spacing: 0.5px; } .logo::after { content: ""; position: absolute; bottom: -4px; left: 0; width: 0; height: 1px; background: var(--text-primary); transition: var(--transition-standard); } .logo:hover::after { width: 100%; } .nav-toggle { width: 30px; height: 20px; display: flex; flex-direction: column; justify-content: space-between; cursor: pointer; } .nav-toggle span { width: 100%; height: 2px; background: var(--text-primary); transition: var(--transition-standard); transform-origin: left; } .nav-toggle:hover span:nth-child(1) { transform: scaleX(0.7); } .nav-toggle:hover span:nth-child(2) { transform: scaleX(0.5); } main { flex-grow: 1; display: flex; flex-direction: column; justify-content: center; align-items: flex-start; padding: 1rem 0; } .intro { margin-bottom: 3rem; max-width: 600px; } h1 { font-size: 2.5rem; font-weight: 700; margin-bottom: 1rem; background: linear-gradient(90deg, var(--text-primary), var(--text-secondary)); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; line-height: 1.1; } p { color: var(--text-secondary); line-height: 1.6; margin-bottom: 1.5rem; max-width: 550px; } .gallery { width: 100%; display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 1rem; margin-bottom: 2rem; } .artwork { position: relative; aspect-ratio: 1; overflow: hidden; border-radius: 4px; background: var(--secondary-dark); cursor: pointer; transition: var(--transition-standard); } .artwork:hover { transform: translateY(-5px); box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2); } .artwork img { width: 100%; height: 100%; object-fit: cover; opacity: 0.9; transition: var(--transition-standard); } .artwork:hover img { opacity: 1; transform: scale(1.05); } .artwork-info { position: absolute; bottom: 0; left: 0; width: 100%; padding: 1rem; background: linear-gradient(to top, rgba(10, 10, 14, 0.8), transparent); opacity: 0; transform: translateY(10px); transition: var(--transition-standard); } .artwork:hover .artwork-info { opacity: 1; transform: translateY(0); } .artwork-title { font-size: 0.9rem; font-weight: 600; margin-bottom: 0.2rem; } .artwork-desc { font-size: 0.7rem; color: var(--text-secondary); } .view-button { display: inline-block; padding: 0.75rem 1.5rem; margin-top: 1rem; background: var(--accent-blue); color: var(--text-primary); border: none; border-radius: 4px; font-size: 0.9rem; font-weight: 500; cursor: pointer; transition: var(--transition-standard); position: relative; overflow: hidden; } .view-button::before { content: ""; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); transition: all 0.6s; } .view-button:hover { background: var(--accent-purple); transform: translateY(-2px); box-shadow: 0 5px 15px rgba(77, 44, 145, 0.3); } .view-button:hover::before { left: 100%; } footer { font-size: 0.8rem; color: var(--text-secondary); margin-top: 2rem; display: flex; justify-content: space-between; align-items: center; } .social-links { display: flex; gap: 1rem; } .social-links a { color: var(--text-secondary); text-decoration: none; transition: var(--transition-standard); } .social-links a:hover { color: var(--text-primary); transform: translateY(-2px); } /* Modal */ .modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(10, 10, 14, 0.9); display: flex; justify-content: center; align-items: center; z-index: 100; opacity: 0; pointer-events: none; transition: opacity 0.3s ease; } .modal.active { opacity: 1; pointer-events: all; } .modal-content { position: relative; width: 80%; max-width: 600px; background: var(--secondary-dark); border-radius: 8px; padding: 2rem; transform: scale(0.9); opacity: 0; transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); } .modal.active .modal-content { transform: scale(1); opacity: 1; } .modal-close { position: absolute; top: 1rem; right: 1rem; background: none; border: none; color: var(--text-secondary); font-size: 1.5rem; cursor: pointer; transition: var(--transition-standard); } .modal-close:hover { color: var(--text-primary); transform: rotate(90deg); } .modal-image { width: 100%; border-radius: 4px; margin-bottom: 1.5rem; } .modal-title { font-size: 1.5rem; margin-bottom: 0.5rem; } .modal-desc { color: var(--text-secondary); line-height: 1.6; } .modal-meta { margin-top: 1.5rem; display: flex; flex-wrap: wrap; gap: 1rem; } .meta-item { font-size: 0.8rem; color: var(--text-secondary); } .meta-item span { color: var(--text-primary); font-weight: 500; } /* Responsive Styles */ @media (max-width: 768px) { h1 { font-size: 2rem; } .gallery { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); } .intro { margin-bottom: 2rem; } } @media (max-width: 480px) { .content { padding: 1.5rem; } h1 { font-size: 1.8rem; } .gallery { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); } } </style> </head> <body> <div id="app"> <div id="particle-container"></div> <div class="content"> <header> <div class="logo">FRAGMENTS</div> <div class="nav-toggle"> <span></span> <span></span> <span></span> </div> </header> <main> <div class="intro"> <h1>Ephemeral States: Digital Fragmentation</h1> <p>An exploration of impermanence through particle physics and digital decay. Each piece captures fleeting moments where order dissolves into abstraction—much like snowflakes transitioning between states of being and non-being.</p> <p>The collection employs varied opacity animations and choreographed drift patterns to visualize the delicate balance between structure and chaos.</p> </div> <div class="gallery"> <div class="artwork" data-id="1"> <img src="https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?w=400&q=80" alt="Dissolution I"> <div class="artwork-info"> <div class="artwork-title">Dissolution I</div> <div class="artwork-desc">Particle system study with fragmented opacity</div> </div> </div> <div class="artwork" data-id="2"> <img src="https://images.unsplash.com/photo-1633218388467-539651fdcf80?w=400&q=80" alt="Liminal Drift"> <div class="artwork-info"> <div class="artwork-title">Liminal Drift</div> <div class="artwork-desc">Abstract motion study in fragmented space</div> </div> </div> <div class="artwork" data-id="3"> <img src="https://images.unsplash.com/photo-1574169208507-84376144848b?w=400&q=80" alt="Frozen Moment"> <div class="artwork-info"> <div class="artwork-title">Frozen Moment</div> <div class="artwork-desc">Suspended particles in temporal flux</div> </div> </div> <div class="artwork" data-id="4"> <img src="https://images.unsplash.com/photo-1506452305024-9d3f2e555a5d?w=400&q=80" alt="Ephemeral Construct"> <div class="artwork-info"> <div class="artwork-title">Ephemeral Construct</div> <div class="artwork-desc">Geometric patterns dissolving into chaos</div> </div> </div> </div> <button class="view-button">View Full Collection</button> </main> <footer> <div class="copyright">© 2023 Fragments Studio</div> <div class="social-links"> <a href="#" class="social-link">Artstation</a> <a href="#" class="social-link">Behance</a> </div> </footer> </div> <div class="modal" id="artwork-modal"> <div class="modal-content"> <button class="modal-close">×</button> <img class="modal-image" src="" alt=""> <h2 class="modal-title"></h2> <p class="modal-desc"></p> <div class="modal-meta"> <div class="meta-item">Technique: <span>Particle simulation</span></div> <div class="meta-item">Resolution: <span>4K (3840×2160)</span></div> <div class="meta-item">Year: <span>2023</span></div> </div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', () => { const particleContainer = document.getElementById('particle-container'); const modal = document.getElementById('artwork-modal'); const artworks = document.querySelectorAll('.artwork'); const modalClose = document.querySelector('.modal-close'); const modalImage = document.querySelector('.modal-image'); const modalTitle = document.querySelector('.modal-title'); const modalDesc = document.querySelector('.modal-desc'); const viewButton = document.querySelector('.view-button'); // Particle system setup const TOTAL_PARTICLES = window.innerWidth < 768 ? 100 : 200; const particles = []; class Particle { constructor() { this.reset(); } reset() { this.x = Math.random() * window.innerWidth; this.y = Math.random() * window.innerHeight; this.size = Math.random() * 5 + 1; this.opacity = Math.random() * 0.5 + 0.1; this.speedX = Math.random() * 0.6 - 0.3; this.speedY = Math.random() * 0.6 - 0.1; this.blur = Math.random() * 2; this.fragment = Math.random() > 0.7; this.fragmentSize = Math.random() * 3 + 2; this.fragmentAngle = Math.random() * 360; this.pulse = Math.random() * 0.05; this.pulseSpeed = 0.01 + Math.random() * 0.02; this.pulseDirection = 1; this.hue = Math.random() > 0.8 ? Math.floor(Math.random() * 60) + 220 : // Blue-purple range Math.floor(Math.random() * 20) + 200; // Mostly blue } update() { this.x += this.speedX; this.y += this.speedY; // Pulse opacity this.opacity += this.pulse * this.pulseDirection; if (this.opacity > 0.7 || this.opacity < 0.1) { this.pulseDirection *= -1; } // Reset if out of bounds if (this.x < 0 || this.x > window.innerWidth || this.y < 0 || this.y > window.innerHeight) { this.reset(); this.x = Math.random() > 0.5 ? 0 : window.innerWidth; this.y = Math.random() * window.innerHeight; } } draw(ctx) { ctx.beginPath(); ctx.fillStyle = this.fragment ? `hsla(${this.hue}, 80%, 70%, ${this.opacity})` : `rgba(255, 255, 255, ${this.opacity})`; ctx.shadowColor = `hsla(${this.hue}, 80%, 70%, ${this.opacity * 0.5})`; ctx.shadowBlur = this.blur; if (this.fragment) { // Draw a fragment shape const fragment = new Path2D(); ctx.save(); ctx.translate(this.x, this.y); ctx.rotate(this.fragmentAngle * Math.PI / 180); // Random fragment shape if (Math.random() > 0.5) { fragment.rect(-this.fragmentSize/2, -this.fragmentSize/2, this.fragmentSize, this.fragmentSize); } else { fragment.moveTo(0, -this.fragmentSize/2); fragment.lineTo(this.fragmentSize/2, this.fragmentSize/2); fragment.lineTo(-this.fragmentSize/2, this.fragmentSize/2); fragment.closePath(); } ctx.fill(fragment); ctx.restore(); } else { // Draw a snow/particle circle ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2); ctx.fill(); } ctx.closePath(); } } // Create canvas and context const canvas = document.createElement('canvas'); canvas.width = window.innerWidth; canvas.height = window.innerHeight; particleContainer.appendChild(canvas); const ctx = canvas.getContext('2d'); // Initialize particles for (let i = 0; i < TOTAL_PARTICLES; i++) { particles.push(new Particle()); } // Animation loop function animate() { ctx.clearRect(0, 0, canvas.width, canvas.height); particles.forEach(particle => { particle.update(); particle.draw(ctx); }); requestAnimationFrame(animate); } animate(); // Handle window resize window.addEventListener('resize', () => { canvas.width = window.innerWidth; canvas.height = window.innerHeight; }); // Modal functionality artworks.forEach(artwork => { artwork.addEventListener('click', () => { const img = artwork.querySelector('img'); const title = artwork.querySelector('.artwork-title').textContent; const desc = artwork.querySelector('.artwork-desc').textContent; modalImage.src = img.src; modalTitle.textContent = title; modalDesc.textContent = desc + '. This piece explores the digital representation of ephemeral states through carefully choreographed particle systems and opacity animations. The interplay between form and void creates a metaphor for the impermanence inherent in both digital and physical realms.'; modal.classList.add('active'); }); }); modalClose.addEventListener('click', () => { modal.classList.remove('active'); }); // Close modal when clicking outside modal.addEventListener('click', (e) => { if (e.target === modal) { modal.classList.remove('active'); } }); // View button interaction viewButton.addEventListener('click', () => { // Scroll to gallery with animation const gallery = document.querySelector('.gallery'); gallery.scrollIntoView({ behavior: 'smooth' }); // Add visual feedback viewButton.textContent = 'Viewing Collection'; setTimeout(() => { viewButton.textContent = 'View Full Collection'; }, 2000); }); // Nav toggle interaction const navToggle = document.querySelector('.nav-toggle'); navToggle.addEventListener('click', () => { navToggle.classList.toggle('active'); // Visual feedback const spans = navToggle.querySelectorAll('span'); if (navToggle.classList.contains('active')) { spans[0].style.transform = 'rotate(45deg)'; spans[1].style.opacity = '0'; spans[2].style.transform = 'rotate(-45deg)'; } else { spans[0].style.transform = 'rotate(0)'; spans[1].style.opacity = '1'; spans[2].style.transform = 'rotate(0)'; } }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Frostival App Onboarding</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Montserrat', sans-serif; } body { overflow: hidden; background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%); width: 100%; height: 700px; position: relative; display: flex; justify-content: center; align-items: center; color: white; } #snow-container { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 1; } .snowflake { position: absolute; background-color: rgba(255, 255, 255, 0.8); border-radius: 50%; pointer-events: none; z-index: 1; filter: blur(1px); box-shadow: 0 0 5px rgba(255, 255, 255, 0.8); } .onboarding-container { position: relative; z-index: 2; width: 90%; max-width: 500px; height: 80%; display: flex; flex-direction: column; align-items: center; justify-content: space-between; padding: 2rem; background-color: rgba(255, 255, 255, 0.1); backdrop-filter: blur(8px); border-radius: 20px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); overflow: hidden; } .snowflake-large { position: absolute; opacity: 0.15; z-index: -1; } .header { width: 100%; text-align: center; position: relative; } .festival-logo { width: 120px; height: 120px; margin-bottom: 10px; position: relative; display: flex; align-items: center; justify-content: center; margin: 0 auto 20px; } .logo-inner { width: 100%; height: 100%; background: radial-gradient(circle, rgba(255,255,255,0.9) 0%, rgba(173,216,230,0.5) 100%); border-radius: 50%; display: flex; align-items: center; justify-content: center; transform-origin: center; box-shadow: 0 0 20px rgba(255, 255, 255, 0.5); animation: pulse 3s infinite ease-in-out; } .logo-inner svg { width: 60%; height: 60%; } @keyframes pulse { 0% { transform: scale(1); box-shadow: 0 0 20px rgba(255, 255, 255, 0.5); } 50% { transform: scale(1.05); box-shadow: 0 0 30px rgba(255, 255, 255, 0.7); } 100% { transform: scale(1); box-shadow: 0 0 20px rgba(255, 255, 255, 0.5); } } h1 { font-size: 2.2rem; font-weight: 700; margin-bottom: 10px; text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); background: linear-gradient(to right, #ffffff, #b3e0ff); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; } p.subtitle { font-size: 1rem; line-height: 1.5; margin-bottom: 30px; color: rgba(255, 255, 255, 0.9); } .onboarding-slider { width: 100%; height: 320px; position: relative; overflow: hidden; border-radius: 15px; } .slides { display: flex; width: 300%; height: 100%; transition: transform 0.5s ease-in-out; } .slide { width: 33.333%; height: 100%; padding: 20px 30px; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; text-align: center; background-color: rgba(255, 255, 255, 0.05); border-radius: 15px; } .slide-icon { width: 80px; height: 80px; margin-bottom: 20px; display: flex; align-items: center; justify-content: center; background-color: rgba(255, 255, 255, 0.1); border-radius: 50%; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); } .slide-icon svg { width: 50%; height: 50%; fill: white; } .slide h2 { font-size: 1.5rem; margin-bottom: 15px; color: white; font-weight: 600; } .slide p { font-size: 0.95rem; line-height: 1.6; color: rgba(255, 255, 255, 0.9); } .feature-item { display: flex; align-items: center; margin: 10px 0; width: 100%; } .feature-item svg { width: 20px; height: 20px; margin-right: 10px; fill: #a0d2eb; } .feature-text { text-align: left; font-size: 0.9rem; } .pagination { display: flex; justify-content: center; margin-top: 20px; } .dot { width: 8px; height: 8px; border-radius: 50%; background-color: rgba(255, 255, 255, 0.3); margin: 0 5px; cursor: pointer; transition: all 0.3s ease; } .dot.active { background-color: white; transform: scale(1.3); } .nav-buttons { display: flex; justify-content: space-between; width: 100%; margin-top: 20px; } .nav-btn { padding: 12px 25px; border: none; border-radius: 50px; background: transparent; color: white; font-weight: 600; cursor: pointer; transition: all 0.3s ease; display: flex; align-items: center; font-size: 0.9rem; } .btn-prev { background-color: rgba(255, 255, 255, 0.1); } .btn-next, .btn-start { background: linear-gradient(45deg, #4facfe 0%, #00f2fe 100%); box-shadow: 0 4px 15px rgba(79, 172, 254, 0.4); } .btn-next:hover, .btn-start:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(79, 172, 254, 0.6); } .btn-prev:hover { background-color: rgba(255, 255, 255, 0.2); } .btn-prev svg, .btn-next svg { width: 16px; height: 16px; fill: currentColor; } .btn-prev svg { margin-right: 8px; } .btn-next svg { margin-left: 8px; } .btn-start { padding: 14px 40px; font-size: 1rem; letter-spacing: 0.5px; } .hint-text { position: absolute; bottom: 20px; font-size: 0.9rem; color: rgba(255, 255, 255, 0.7); animation: fadeInOut 3s infinite; display: flex; align-items: center; } .hint-text svg { width: 16px; height: 16px; margin-right: 8px; fill: currentColor; } @keyframes fadeInOut { 0% { opacity: 0.5; } 50% { opacity: 1; } 100% { opacity: 0.5; } } /* Touch animation overlay */ .touch-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 3; cursor: pointer; } .touch-circle { position: absolute; border-radius: 50%; pointer-events: none; background: radial-gradient(circle, rgba(255,255,255,0.9) 0%, rgba(255,255,255,0) 70%); transform: translate(-50%, -50%); animation: touchFade 1s forwards; } @keyframes touchFade { 0% { opacity: 1; width: 0; height: 0; } 100% { opacity: 0; width: 150px; height: 150px; } } .snow-toggle { position: absolute; top: 15px; right: 15px; background: rgba(255, 255, 255, 0.2); border: none; border-radius: 50%; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: all 0.3s ease; z-index: 4; } .snow-toggle:hover { background: rgba(255, 255, 255, 0.3); } .snow-toggle svg { width: 20px; height: 20px; fill: white; } @media (max-width: 500px) { .onboarding-container { width: 95%; padding: 1.5rem; } h1 { font-size: 1.8rem; } .festival-logo { width: 100px; height: 100px; } .slide { padding: 15px; } .slide h2 { font-size: 1.3rem; } .nav-btn { padding: 10px 20px; font-size: 0.85rem; } .btn-start { padding: 12px 30px; } } </style> </head> <body> <div id="snow-container"></div> <button class="snow-toggle" id="snow-toggle" title="Toggle snow effect"> <svg viewBox="0 0 24 24"><path d="M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4M7,10L12,15L17,10H7Z"/></svg> </button> <div class="onboarding-container"> <div class="snowflake-large" style="top: 20px; right: 50px; width: 100px; height: 100px;"> <svg viewBox="0 0 24 24"><path d="M22.23,12c0,.11,0,.22,0,.33a2.45,2.45,0,0,1-2.33,2.54h0l-2.24-.17-.75,1.3,1.68,1.46a2.44,2.44,0,0,1,.81,1.76,2.48,2.48,0,0,1-.81,1.75,2.49,2.49,0,0,1-3.52,0l-1.68-1.46H12l-1.69,1.46a2.51,2.51,0,0,1-3.52,0,2.48,2.48,0,0,1,0-3.51l1.68-1.46-.75-1.3L5.48,14.9a2.47,2.47,0,0,1-.64.07,2.44,2.44,0,0,1-2.35-2.63A2.46,2.46,0,0,1,5,10.08l2.24.18.75-1.3L6.32,7.49a2.48,2.48,0,0,1,0-3.51,2.51,2.51,0,0,1,3.52,0L11.52,5.5h1.34l1.68-1.46a2.47,2.47,0,0,1,1.75-.72,2.49,2.49,0,0,1,1.77.72,2.48,2.48,0,0,1,0,3.51l-1.68,1.47.75,1.3,2.24-.18a2.46,2.46,0,0,1,1.76.72A2.42,2.42,0,0,1,22.23,12Z"/></svg> </div> <div class="snowflake-large" style="bottom: 40px; left: 30px; width: 80px; height: 80px;"> <svg viewBox="0 0 24 24"><path d="M22.23,12c0,.11,0,.22,0,.33a2.45,2.45,0,0,1-2.33,2.54h0l-2.24-.17-.75,1.3,1.68,1.46a2.44,2.44,0,0,1,.81,1.76,2.48,2.48,0,0,1-.81,1.75,2.49,2.49,0,0,1-3.52,0l-1.68-1.46H12l-1.69,1.46a2.51,2.51,0,0,1-3.52,0,2.48,2.48,0,0,1,0-3.51l1.68-1.46-.75-1.3L5.48,14.9a2.47,2.47,0,0,1-.64.07,2.44,2.44,0,0,1-2.35-2.63A2.46,2.46,0,0,1,5,10.08l2.24.18.75-1.3L6.32,7.49a2.48,2.48,0,0,1,0-3.51,2.51,2.51,0,0,1,3.52,0L11.52,5.5h1.34l1.68-1.46a2.47,2.47,0,0,1,1.75-.72,2.49,2.49,0,0,1,1.77.72,2.48,2.48,0,0,1,0,3.51l-1.68,1.47.75,1.3,2.24-.18a2.46,2.46,0,0,1,1.76.72A2.42,2.42,0,0,1,22.23,12Z"/></svg> </div> <div class="header"> <div class="festival-logo"> <div class="logo-inner"> <svg viewBox="0 0 24 24"> <path fill="#1e3c72" d="M12,3.5L7.5,7.5L9,9L12,6V16.17L9.83,14L8.41,15.41L12,19L15.59,15.41L14.17,14L12,16.17V6L15,9L16.5,7.5L12,3.5M4.5,9.5L1.77,12.23L4.5,14.97L5.91,13.56L4.56,12.21L5.92,10.86L4.5,9.5M19.5,9.5L18.09,10.91L19.44,12.26L18.08,13.62L19.5,15.03L22.23,12.29L19.5,9.5Z"/> </svg> </div> </div> <h1>Frostival 2024</h1> <p class="subtitle">Experience winter magic like never before.<br>Touch the screen to discover the snowfall.</p> </div> <div class="onboarding-slider"> <div class="slides" id="slides"> <div class="slide"> <div class="slide-icon"> <svg viewBox="0 0 24 24"><path d="M12,16.5L6,12L12,7.5L18,12L12,16.5M12,3.75L3,10.5L12,17.25L21,10.5L12,3.75M2,14V22H22V14M4,16H6V20H4V16M8,16H12V20H8V16M14,16H18V20H14V16M20,16V20H18V16"/></svg> </div> <h2>Interactive Winter Playground</h2> <p>Create your own winter wonderland with our responsive snowfall. Each touch brings the festival to life right at your fingertips.</p> <div class="feature-item"> <svg viewBox="0 0 24 24"><path d="M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4M11,16.5L6.5,12L7.91,10.59L11,13.67L16.59,8.09L18,9.5L11,16.5Z"/></svg> <span class="feature-text">Touch-responsive snowflakes</span> </div> <div class="feature-item"> <svg viewBox="0 0 24 24"><path d="M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4M11,16.5L6.5,12L7.91,10.59L11,13.67L16.59,8.09L18,9.5L11,16.5Z"/></svg> <span class="feature-text">Dynamic light effects</span> </div> <div class="feature-item"> <svg viewBox="0 0 24 24"><path d="M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4M11,16.5L6.5,12L7.91,10.59L11,13.67L16.59,8.09L18,9.5L11,16.5Z"/></svg> <span class="feature-text">Realistic motion physics</span> </div> </div> <div class="slide"> <div class="slide-icon"> <svg viewBox="0 0 24 24"><path d="M20,20H4A2,2 0 0,1 2,18V6A2,2 0 0,1 4,4H20A2,2 0 0,1 22,6V18A2,2 0 0,1 20,20M4,6V18H20V6H4M6,9H18V11H6V9M6,13H16V15H6V13Z"/></svg> </div> <h2>Personalized Festival Guide</h2> <p>Discover curated experiences based on your preferences. Our AI creates a unique itinerary for your perfect Frostival adventure.</p> <div class="feature-item"> <svg viewBox="0 0 24 24"><path d="M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4M11,16.5L6.5,12L7.91,10.59L11,13.67L16.59,8.09L18,9.5L11,16.5Z"/></svg> <span class="feature-text">Custom event recommendations</span> </div> <div class="feature-item"> <svg viewBox="0 0 24 24"><path d="M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4M11,16.5L6.5,12L7.91,10.59L11,13.67L16.59,8.09L18,9.5L11,16.5Z"/></svg> <span class="feature-text">Interactive festival map</span> </div> <div class="feature-item"> <svg viewBox="0 0 24 24"><path d="M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4M11,16.5L6.5,12L7.91,10.59L11,13.67L16.59,8.09L18,9.5L11,16.5Z"/></svg> <span class="feature-text">Real-time activity schedules</span> </div> </div> <div class="slide"> <div class="slide-icon"> <svg viewBox="0 0 24 24"><path d="M12,5.5A3.5,3.5 0 0,1 15.5,9A3.5,3.5 0 0,1 12,12.5A3.5,3.5 0 0,1 8.5,9A3.5,3.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> <h2>Social Winter Community</h2> <p>Connect with fellow festival-goers through our winter-themed social features. Share moments and discover new friends with shared interests.</p> <div class="feature-item"> <svg viewBox="0 0 24 24"><path d="M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4M11,16.5L6.5,12L7.91,10.59L11,13.67L16.59,8.09L18,9.5L11,16.5Z"/></svg> <span class="feature-text">Photo snow effects for sharing</span> </div> <div class="feature-item"> <svg viewBox="0 0 24 24"><path d="M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4M11,16.5L6.5,12L7.91,10.59L11,13.67L16.59,8.09L18,9.5L11,16.5Z"/></svg> <span class="feature-text">Group event coordination</span> </div> <div class="feature-item"> <svg viewBox="0 0 24 24"><path d="M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4M11,16.5L6.5,12L7.91,10.59L11,13.67L16.59,8.09L18,9.5L11,16.5Z"/></svg> <span class="feature-text">Festival memories timeline</span> </div> </div> </div> <div class="pagination"> <span class="dot active" data-index="0"></span> <span class="dot" data-index="1"></span> <span class="dot" data-index="2"></span> </div> </div> <div class="nav-buttons"> <button class="nav-btn btn-prev" id="prev" style="visibility: hidden;"> <svg viewBox="0 0 24 24"><path d="M20,11V13H8L13.5,18.5L12.08,19.92L4.16,12L12.08,4.08L13.5,5.5L8,11H20Z"/></svg> Previous </button> <button class="nav-btn btn-next" id="next"> Next <svg viewBox="0 0 24 24"><path d="M4,11V13H16L10.5,18.5L11.92,19.92L19.84,12L11.92,4.08L10.5,5.5L16,11H4Z"/></svg> </button> <button class="nav-btn btn-start" id="start" style="display: none;">Get Started</button> </div> <div class="hint-text"> <svg viewBox="0 0 24 24"><path d="M9,11.24V7.5C9,6.12 10.12,5 11.5,5S14,6.12 14,7.5V8H15V7.5C15,5.57 13.43,4 11.5,4S8,5.57 8,7.5V11.24C7.36,11.63 7,12.27 7,13C7,14.1 7.9,15 9,15S11,14.1 11,13C11,12.27 10.64,11.63 10,11.24V7.5C10,6.67 10.67,6 11.5,6S13,6.67 13,7.5V8H14V7.5C14,6.12 12.88,5 11.5,5S9,6.12 9,7.5V11.24Z"/></svg> Touch anywhere to interact with the snow </div> </div> <div class="touch-overlay" id="touch-overlay"></div> <script> document.addEventListener('DOMContentLoaded', function() { // Slider navigation const slides = document.getElementById('slides'); const dots = document.querySelectorAll('.dot'); const prevBtn = document.getElementById('prev'); const nextBtn = document.getElementById('next'); const startBtn = document.getElementById('start'); let currentSlide = 0; const totalSlides = 3; function updateSlider() { slides.style.transform = `translateX(-${currentSlide * 33.333}%)`; // Update pagination dots dots.forEach((dot, index) => { dot.classList.toggle('active', index === currentSlide); }); // Update buttons prevBtn.style.visibility = currentSlide === 0 ? 'hidden' : 'visible'; if (currentSlide === totalSlides - 1) { nextBtn.style.display = 'none'; startBtn.style.display = 'flex'; } else { nextBtn.style.display = 'flex'; startBtn.style.display = 'none'; } } // Set up event listeners for dots dots.forEach(dot => { dot.addEventListener('click', function() { currentSlide = parseInt(this.getAttribute('data-index')); updateSlider(); }); }); // Set up event listeners for navigation buttons prevBtn.addEventListener('click', function() { if (currentSlide > 0) { currentSlide--; updateSlider(); } }); nextBtn.addEventListener('click', function() { if (currentSlide < totalSlides - 1) { currentSlide++; updateSlider(); } }); startBtn.addEventListener('click', function() { alert('Frostival app would launch here! This is just a demo.'); }); // Snowfall effect const snowContainer = document.getElementById('snow-container'); const snowToggle = document.getElementById('snow-toggle'); let snowEnabled = true; const snowflakes = []; const maxSnowflakes = 80; function createSnowflake() { if (!snowEnabled) return; const snowflake = document.createElement('div'); snowflake.classList.add('snowflake'); // Random properties const size = Math.random() * 6 + 2; const posX = Math.random() * window.innerWidth; const posY = -20; const opacity = Math.random() * 0.6 + 0.3; const speedY = Math.random() * 1 + 0.5; const speedX = Math.random() * 1 - 0.5; const delay = Math.random() * 5; // Set styles snowflake.style.width = `${size}px`; snowflake.style.height = `${size}px`; snowflake.style.left = `${posX}px`; snowflake.style.top = `${posY}px`; snowflake.style.opacity = opacity; // Add to DOM snowContainer.appendChild(snowflake); // Store properties for animation const flakeData = { element: snowflake, posX, posY, speedX, speedY, wobble: Math.random() * 2 - 1, wobbleSpeed: Math.random() * 0.1, wobbleFactor: Math.random() * 3 }; snowflakes.push(flakeData); // Remove excess snowflakes if (snowflakes.length > maxSnowflakes) { const oldFlake = snowflakes.shift(); oldFlake.element.remove(); } } function animateSnowflakes() { if (!snowEnabled) return; snowflakes.forEach(flake => { flake.posY += flake.speedY; flake.posX += flake.speedX + Math.sin(flake.posY * flake.wobbleSpeed) * flake.wobbleFactor; flake.element.style.transform = `translate(${flake.wobble * Math.sin(flake.posY * 0.05) * 1}px, 0)`; flake.element.style.left = `${flake.posX}px`; flake.element.style.top = `${flake.posY}px`; // Reset if out of view if (flake.posY > window.innerHeight + 20 || flake.posX < -20 || flake.posX > window.innerWidth + 20) { flake.posY = -20; flake.posX = Math.random() * window.innerWidth; } }); if (snowEnabled) { requestAnimationFrame(animateSnowflakes); } } // Create snowflakes at interval const snowfallInterval = setInterval(() => { if (snowEnabled) { createSnowflake(); } }, 200); // Start animation animateSnowflakes(); // Touch/click interaction for snow burst const touchOverlay = document.getElementById('touch-overlay'); touchOverlay.addEventListener('pointerdown', function(e) { if (!snowEnabled) return; // Create touch circle const touchCircle = document.createElement('div'); touchCircle.classList.add('touch-circle'); touchCircle.style.left = `${e.clientX}px`; touchCircle.style.top = `${e.clientY}px`; touchOverlay.appendChild(touchCircle); // Remove circle after animation completes setTimeout(() => { touchCircle.remove(); }, 1000); // Create burst of snowflakes const burstCount = 15; for (let i = 0; i < burstCount; i++) { const snowflake = document.createElement('div'); snowflake.classList.add('snowflake'); // Random properties for burst const size = Math.random() * 8 + 3; const angle = Math.random() * Math.PI * 2; const speed = Math.random() * 2 + 2; const posX = e.clientX; const posY = e.clientY; const opacity = Math.random() * 0.8 +
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>GLACÉ | Winter Collection</title> <style> @import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@300;400;500;600&family=Montserrat:wght@200;300;400;500&display=swap'); :root { --ivory: #f8f7f4; --platinum: #e5e7e6; --silver: #c4c9c7; --charcoal: #293340; --midnight: #131b26; --gold: #c4b08a; --silver-metallic: #a8a9ad; } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Montserrat', sans-serif; background: linear-gradient(135deg, var(--midnight), var(--charcoal)); color: var(--ivory); height: 700px; width: 700px; max-width: 100%; max-height: 100%; overflow: hidden; position: relative; } .microsite-container { position: relative; width: 100%; height: 100%; padding: 2rem; overflow: hidden; } .gradient-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: radial-gradient(circle at center, transparent 30%, var(--midnight) 100%); opacity: 0.6; pointer-events: none; z-index: 1; } .snow-container { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 3; opacity: 0.6; } .snow { position: absolute; background-color: var(--ivory); border-radius: 50%; opacity: 0; animation: fall linear infinite; } h1, h2, h3, h4 { font-family: 'Cormorant Garamond', serif; font-weight: 400; letter-spacing: 1px; } h1 { font-size: clamp(2.5rem, 7vw, 3.5rem); line-height: 1; margin-bottom: 0.5rem; font-weight: 300; } h2 { font-size: clamp(1.5rem, 4vw, 2rem); font-weight: 300; color: var(--silver); margin-bottom: 2rem; } .headline-accent { color: var(--gold); font-style: italic; } .header { position: relative; z-index: 2; display: flex; justify-content: space-between; align-items: center; margin-bottom: 2rem; } .logo { font-family: 'Cormorant Garamond', serif; font-size: 1.8rem; letter-spacing: 5px; color: var(--ivory); text-decoration: none; position: relative; } .logo::after { content: ''; position: absolute; bottom: -5px; left: 0; width: 100%; height: 1px; background: linear-gradient(90deg, transparent, var(--gold), transparent); } .main-content { position: relative; z-index: 2; display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; height: calc(100% - 4rem); } .showcase { position: relative; overflow: hidden; border-radius: 3px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4); transition: transform 0.5s ease; } .showcase img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.8s ease; transform-origin: center; } .showcase:hover img { transform: scale(1.03); } .showcase::after { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(to bottom, transparent 50%, rgba(19, 27, 38, 0.8) 100%); pointer-events: none; } .showcase-info { position: absolute; bottom: 1.5rem; left: 1.5rem; z-index: 2; opacity: 0; transform: translateY(10px); transition: all 0.5s ease; } .showcase:hover .showcase-info { opacity: 1; transform: translateY(0); } .product-name { font-family: 'Cormorant Garamond', serif; font-size: 1.4rem; color: var(--ivory); margin-bottom: 0.25rem; } .product-price { color: var(--silver); font-size: 0.9rem; font-weight: 300; } .content-section { display: flex; flex-direction: column; justify-content: center; } .copy { line-height: 1.6; font-weight: 300; font-size: 0.95rem; color: var(--silver); margin-bottom: 2rem; } .cta-button { display: inline-block; background: transparent; color: var(--ivory); border: 1px solid var(--silver); padding: 0.8rem 1.5rem; font-size: 0.8rem; text-transform: uppercase; letter-spacing: 2px; cursor: pointer; transition: all 0.3s ease; position: relative; overflow: hidden; align-self: flex-start; } .cta-button::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(196, 176, 138, 0.2), transparent); transition: all 0.5s ease; } .cta-button:hover { border-color: var(--gold); color: var(--gold); } .cta-button:hover::before { left: 100%; } .metallic-accent { position: absolute; background: linear-gradient(45deg, var(--silver-metallic), var(--gold), var(--silver-metallic)); border-radius: 50%; filter: blur(20px); opacity: 0.15; z-index: 0; } .accent-1 { width: 200px; height: 200px; top: -50px; right: -50px; } .accent-2 { width: 300px; height: 300px; bottom: -100px; left: -100px; } .products-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1rem; margin-top: 1rem; } .product-thumbnail { position: relative; height: 120px; border-radius: 2px; overflow: hidden; cursor: pointer; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); transition: transform 0.3s ease; } .product-thumbnail img { width: 100%; height: 100%; object-fit: cover; transition: all 0.3s ease; } .product-thumbnail::after { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(to bottom, transparent 60%, rgba(19, 27, 38, 0.7) 100%); } .product-thumbnail:hover { transform: translateY(-3px); } .product-thumbnail:hover img { transform: scale(1.05); } .product-thumbnail p { position: absolute; bottom: 0.5rem; left: 0.5rem; font-size: 0.7rem; color: var(--ivory); z-index: 2; text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5); } .season-tag { position: absolute; top: 1rem; right: 1rem; background: rgba(19, 27, 38, 0.8); color: var(--gold); padding: 0.3rem 0.6rem; font-size: 0.6rem; text-transform: uppercase; letter-spacing: 1px; border-radius: 2px; z-index: 2; backdrop-filter: blur(5px); } @keyframes fall { 0% { transform: translateY(-10px) translateX(0); opacity: 0; } 10% { opacity: 0.8; } 100% { transform: translateY(var(--fall-height)) translateX(var(--fall-distance)); opacity: 0; } } @media (max-width: 700px) { .microsite-container { padding: 1.5rem; } .main-content { grid-template-columns: 1fr; gap: 1.5rem; margin-top: 1rem; } .showcase { height: 220px; } .copy { font-size: 0.85rem; margin-bottom: 1.5rem; } h1 { font-size: 2.2rem; } h2 { font-size: 1.3rem; margin-bottom: 1rem; } .products-grid { grid-template-columns: 1fr 1fr; } .product-thumbnail { height: 90px; } } </style> </head> <body> <div class="microsite-container"> <div class="gradient-overlay"></div> <div class="snow-container" id="snowContainer"></div> <div class="metallic-accent accent-1"></div> <div class="metallic-accent accent-2"></div> <header class="header"> <a href="#" class="logo">GLACÉ</a> </header> <div class="main-content"> <div class="content-section"> <h1>Winter <span class="headline-accent">Lumière</span></h1> <h2>Refined Radiance for the Season</h2> <p class="copy">Introducing our curated collection where luxury meets winter's ethereal beauty. Each piece captures the crystalline elegance of frost and snow, reinterpreted through precious stones and artisanal metalwork. Designed to illuminate the darkest winter evenings with subtle brilliance.</p> <button class="cta-button">Explore Collection</button> </div> <div class="showcase"> <div class="season-tag">Winter 2023</div> <img src="https://images.unsplash.com/photo-1551349709-56c55a6b7ba5?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=987&q=80" alt="Crystalline Pendant Necklace"> <div class="showcase-info"> <h3 class="product-name">Crystalline Pendant</h3> <p class="product-price">€2,450</p> </div> </div> </div> <div class="products-grid"> <div class="product-thumbnail"> <img src="https://images.unsplash.com/photo-1610694955371-d4a3e0ce4b52?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=987&q=80" alt="Frost Diamond Earrings"> <p>Frost Diamond Earrings</p> </div> <div class="product-thumbnail"> <img src="https://images.unsplash.com/photo-1535632066927-ab7c9ab60908?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=987&q=80" alt="Platinum Ice Bracelet"> <p>Platinum Ice Bracelet</p> </div> <div class="product-thumbnail"> <img src="https://images.unsplash.com/photo-1599643478518-a784e5dc4c8f?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=987&q=80" alt="Icicle Ring Collection"> <p>Icicle Ring Collection</p> </div> <div class="product-thumbnail"> <img src="https://images.unsplash.com/photo-1611591437281-460bfbe1220a?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=987&q=80" alt="Moonlit Pearl Watch"> <p>Moonlit Pearl Watch</p> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Create refined snow effect const snowContainer = document.getElementById('snowContainer'); const snowflakeCount = 80; function createSnowflakes() { for (let i = 0; i < snowflakeCount; i++) { const snowflake = document.createElement('div'); snowflake.classList.add('snow'); // Random properties for natural effect const size = Math.random() * 4 + 1; const posX = Math.random() * 100; const delay = Math.random() * 5; const duration = Math.random() * 10 + 10; const fallDistance = (Math.random() - 0.5) * 100; const fallHeight = window.innerHeight + 10; snowflake.style.width = `${size}px`; snowflake.style.height = `${size}px`; snowflake.style.left = `${posX}%`; snowflake.style.top = '0px'; snowflake.style.opacity = Math.random() * 0.6 + 0.2; snowflake.style.animationDelay = `${delay}s`; snowflake.style.animationDuration = `${duration}s`; snowflake.style.setProperty('--fall-distance', `${fallDistance}px`); snowflake.style.setProperty('--fall-height', `${fallHeight}px`); snowContainer.appendChild(snowflake); } } createSnowflakes(); // Parallax effect for snow on mouse movement document.addEventListener('mousemove', function(e) { const moveX = (e.clientX - window.innerWidth / 2) * 0.01; const moveY = (e.clientY - window.innerHeight / 2) * 0.01; snowContainer.style.transform = `translate(${moveX}px, ${moveY}px)`; // Also apply subtle movement to metallic accents const accents = document.querySelectorAll('.metallic-accent'); accents.forEach(accent => { accent.style.transform = `translate(${moveX * 1.5}px, ${moveY * 1.5}px)`; }); }); // Product interaction - show current showcase const thumbnails = document.querySelectorAll('.product-thumbnail'); const showcase = document.querySelector('.showcase img'); const productName = document.querySelector('.showcase-info .product-name'); const productPrice = document.querySelector('.showcase-info .product-price'); const products = [ { name: "Frost Diamond Earrings", price: "€1,850", image: "https://images.unsplash.com/photo-1610694955371-d4a3e0ce4b52?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=987&q=80" }, { name: "Platinum Ice Bracelet", price: "€3,250", image: "https://images.unsplash.com/photo-1535632066927-ab7c9ab60908?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=987&q=80" }, { name: "Icicle Ring Collection", price: "€1,950", image: "https://images.unsplash.com/photo-1599643478518-a784e5dc4c8f?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=987&q=80" }, { name: "Moonlit Pearl Watch", price: "€4,750", image: "https://images.unsplash.com/photo-1611591437281-460bfbe1220a?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=987&q=80" } ]; thumbnails.forEach((thumbnail, index) => { thumbnail.addEventListener('click', () => { // Fade out effect showcase.style.opacity = 0; setTimeout(() => { showcase.src = products[index].image; productName.textContent = products[index].name; productPrice.textContent = products[index].price; // Fade in effect showcase.style.opacity = 1; }, 200); }); }); // Button interaction const ctaButton = document.querySelector('.cta-button'); ctaButton.addEventListener('click', function() { this.textContent = "Coming Soon"; this.style.borderColor = "var(--gold)"; this.style.color = "var(--gold)"; setTimeout(() => { this.textContent = "Explore Collection"; this.style.borderColor = "var(--silver)"; this.style.color = "var(--ivory)"; }, 2000); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Snowflake Learning Adventure</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Nunito', sans-serif; } body { background: linear-gradient(135deg, #0a2965 0%, #1d4faa 100%); overflow: hidden; width: 100%; height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; } .game-container { width: 100%; max-width: 700px; height: 700px; position: relative; overflow: hidden; } .header { width: 100%; padding: 15px 20px; background: rgba(255, 255, 255, 0.2); backdrop-filter: blur(10px); border-radius: 15px; margin-bottom: 10px; margin-top: 10px; display: flex; justify-content: space-between; align-items: center; position: relative; z-index: 10; } .title { color: #ffffff; font-size: 24px; font-weight: 700; text-shadow: 0 2px 4px rgba(0,0,0,0.3); } .score-container { display: flex; align-items: center; gap: 10px; } .score { background: rgba(255, 255, 255, 0.25); border-radius: 10px; padding: 8px 15px; color: #ffffff; font-size: 18px; font-weight: 600; box-shadow: 0 4px 8px rgba(0,0,0,0.2); } .info-panel { position: absolute; top: 70px; left: 20px; background: rgba(255, 255, 255, 0.95); border-radius: 15px; padding: 15px; box-shadow: 0 6px 12px rgba(0,0,0,0.2); max-width: 280px; z-index: 10; transform: translateY(-10px); opacity: 0; transition: transform 0.3s ease, opacity 0.3s ease; } .info-panel.active { transform: translateY(0); opacity: 1; } .info-panel h3 { color: #0a2965; margin-bottom: 10px; font-size: 18px; } .info-panel p { color: #333; font-size: 14px; line-height: 1.4; } .fact-container { position: absolute; bottom: 20px; left: 0; right: 0; background: rgba(255, 255, 255, 0.9); padding: 15px; border-radius: 15px; margin: 0 20px; text-align: center; transform: translateY(100px); opacity: 0; transition: transform 0.5s ease, opacity 0.5s ease; box-shadow: 0 -4px 20px rgba(0,0,0,0.15); max-width: 600px; margin-left: auto; margin-right: auto; z-index: 5; } .fact-container.show { transform: translateY(0); opacity: 1; } .fact-title { font-weight: 700; color: #0a2965; margin-bottom: 5px; font-size: 18px; } .fact-text { color: #333; font-size: 14px; line-height: 1.5; } .snowflake { position: absolute; background-size: contain; background-repeat: no-repeat; background-position: center; cursor: pointer; filter: drop-shadow(0 3px 5px rgba(0,0,0,0.2)); transition: transform 0.2s ease; will-change: transform; transform-origin: center; } .snowflake:hover { transform: scale(1.1) rotate(10deg); } .snowflake.clicked { animation: burst 0.6s ease-out forwards; } @keyframes burst { 0% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.5); opacity: 0.8; } 100% { transform: scale(0); opacity: 0; } } .particle { position: absolute; border-radius: 50%; pointer-events: none; opacity: 0.8; animation: particleAnimation 1s ease-out forwards; } @keyframes particleAnimation { 0% { transform: scale(1) translate(0, 0); opacity: 0.8; } 100% { transform: scale(0) translate(var(--tx), var(--ty)); opacity: 0; } } .info-button { background: rgba(255, 255, 255, 0.3); border: none; width: 36px; height: 36px; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: white; font-size: 20px; font-weight: bold; cursor: pointer; transition: background 0.3s ease; box-shadow: 0 2px 6px rgba(0,0,0,0.2); } .info-button:hover { background: rgba(255, 255, 255, 0.5); } .level-indicator { position: absolute; top: 20px; right: 20px; background: rgba(255, 255, 255, 0.25); border-radius: 10px; padding: 8px 15px; color: #ffffff; font-size: 16px; font-weight: 600; box-shadow: 0 4px 8px rgba(0,0,0,0.2); z-index: 10; } .progress-bar { height: 10px; background: rgba(255, 255, 255, 0.2); border-radius: 5px; overflow: hidden; margin-top: 5px; } .progress { height: 100%; background: linear-gradient(90deg, #4CE0B3 0%, #3E8BFF 100%); width: 0%; transition: width 0.3s ease; } @media (max-width: 700px) { .title { font-size: 20px; } .score { font-size: 16px; padding: 6px 12px; } .info-panel { max-width: 220px; } .info-panel h3 { font-size: 16px; } .info-panel p { font-size: 12px; } .fact-container { padding: 12px; } .fact-title { font-size: 16px; } .fact-text { font-size: 12px; } } /* Animation for level completion */ @keyframes celebrateLevel { 0%, 100% { background-color: rgba(255, 255, 255, 0.2); } 50% { background-color: rgba(76, 224, 179, 0.4); } } .celebrating { animation: celebrateLevel 1s ease 3; } </style> </head> <body> <div class="game-container"> <div class="header"> <div class="title">Snowflake Science Explorer</div> <div class="score-container"> <div class="score">Score: <span id="score-value">0</span></div> <button class="info-button" id="info-button">i</button> </div> </div> <div class="info-panel" id="info-panel"> <h3>How to Play</h3> <p>Click on the falling snowflakes to learn fascinating scientific facts! Each snowflake contains unique knowledge about winter science, geometry, and water properties. Complete levels by catching enough snowflakes before they melt away.</p> </div> <div class="level-indicator"> <div>Level <span id="level-number">1</span></div> <div class="progress-bar"> <div class="progress" id="level-progress"></div> </div> </div> <div class="fact-container" id="fact-container"> <div class="fact-title">Snowflake Fact</div> <div class="fact-text" id="fact-text">Click on a snowflake to discover amazing science facts!</div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const gameContainer = document.querySelector('.game-container'); const scoreValue = document.getElementById('score-value'); const infoButton = document.getElementById('info-button'); const infoPanel = document.getElementById('info-panel'); const factContainer = document.getElementById('fact-container'); const factText = document.getElementById('fact-text'); const levelNumber = document.getElementById('level-number'); const levelProgress = document.getElementById('level-progress'); const header = document.querySelector('.header'); let score = 0; let level = 1; let levelGoal = 10; let levelProgress_value = 0; let snowflakeCount = 0; let maxSnowflakes = 7; // Maximum active snowflakes let snowflakeInterval; let gameActive = true; // Snowflake colors - vibrant palette for children const colors = [ '#FF5E7A', // Pink '#4CE0B3', // Teal '#FF9E3D', // Orange '#3E8BFF', // Blue '#B275FF', // Purple '#FFD53E', // Yellow '#FF5252', // Red ]; // Educational facts about snowflakes and winter science const facts = [ "Snowflakes always have six sides because of the way water molecules connect when they freeze!", "No two snowflakes are exactly alike due to the unique path they take through different temperatures and humidity levels.", "The largest snowflake ever recorded was 15 inches wide and 8 inches thick, spotted in Montana in 1887!", "Snow isn't actually white! Each snowflake crystal is clear, but the light reflecting off all the surfaces makes it appear white.", "When snowflakes form in very cold temperatures, they create simpler shapes. Warmer temperatures create more complex patterns!", "Scientists call the study of snowflakes 'crystallography' - it helps us understand how molecules organize themselves.", "Snowflakes can fall at speeds between 1-4 miles per hour, depending on their size and the weather conditions.", "The word 'snow' comes from the Old English 'snāw', which is related to similar words in many Germanic languages.", "Fresh snow is made up of 90-95% trapped air, which makes it a great insulator – animals use snow as shelter in winter!", "Snow can fall even when the temperature is above freezing if the air higher up is cold enough for snowflakes to form.", "The pattern of a snowflake is determined by temperature and humidity as it falls through the atmosphere.", "When it's too cold (below -40°F), snow doesn't fall because there's very little moisture in the air!", "Snowflakes grow by collecting water vapor as they fall through clouds.", "The Inuit people have over 50 different words for snow to describe its many forms!", "A single snowstorm can drop more than 40 million tons of snow, containing billions of snowflakes!", "Snowflakes are actually complex ice crystals that reflect the molecular structure of water.", "The symmetry in snowflakes happens because they grow outward from a central point, with all six arms experiencing the same conditions.", "When conditions change as a snowflake falls, rings of different patterns can form in the crystal structure.", "Snowflakes are made of about 10 quintillion (10,000,000,000,000,000,000) water molecules.", "In perfect conditions, a snowflake can take up to an hour to reach the ground from a cloud." ]; // Toggle info panel visibility infoButton.addEventListener('click', function() { infoPanel.classList.toggle('active'); }); // Initialize the game function initGame() { score = 0; level = 1; levelGoal = 10; levelProgress_value = 0; snowflakeCount = 0; updateScore(); updateLevelIndicator(); clearInterval(snowflakeInterval); // Remove any existing snowflakes document.querySelectorAll('.snowflake').forEach(flake => { flake.remove(); }); // Start creating snowflakes snowflakeInterval = setInterval(createSnowflake, 1000); // Show initial hint showFactContainer("Click on the colorful snowflakes to learn cool scientific facts and earn points!"); } // Update score display function updateScore() { scoreValue.textContent = score; } // Update level progress function updateLevelIndicator() { levelNumber.textContent = level; levelProgress.style.width = `${(levelProgress_value / levelGoal) * 100}%`; } // Create a snowflake with random properties function createSnowflake() { if (!gameActive || document.querySelectorAll('.snowflake').length >= maxSnowflakes) { return; } const snowflake = document.createElement('div'); snowflake.className = 'snowflake'; // Randomize snowflake appearance const size = 40 + Math.random() * 40; // Size between 40-80px const colorIndex = Math.floor(Math.random() * colors.length); snowflake.style.width = `${size}px`; snowflake.style.height = `${size}px`; // Use SVG for the snowflake to ensure crisp rendering const svgColor = colors[colorIndex]; const svgPath = generateSnowflakeSVG(svgColor); snowflake.style.backgroundImage = `url("data:image/svg+xml;utf8,${encodeURIComponent(svgPath)}")`; // Set starting position (horizontal) and slight rotation const startX = Math.random() * (gameContainer.offsetWidth - size); const rotation = Math.random() * 360; snowflake.style.left = `${startX}px`; snowflake.style.top = '-80px'; // Start above the visible area snowflake.style.transform = `rotate(${rotation}deg)`; // Add click handler snowflake.addEventListener('click', function() { if (!snowflake.classList.contains('clicked')) { snowflake.classList.add('clicked'); score += 10; levelProgress_value += 1; updateScore(); updateLevelIndicator(); createParticles(snowflake); showRandomFact(); // Check if level is complete if (levelProgress_value >= levelGoal) { levelUp(); } } }); gameContainer.appendChild(snowflake); // Animate the snowflake falling with bouncy physics animateSnowflake(snowflake, startX); } // Generate SVG snowflake with the given color function generateSnowflakeSVG(color) { // Create a variety of unique snowflake designs const designs = [ `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> <path d="M50 0 L50 100 M0 50 L100 50 M15 15 L85 85 M15 85 L85 15" stroke="${color}" stroke-width="4" fill="none"/> <circle cx="50" cy="50" r="10" fill="${color}"/> <path d="M50 20 L55 30 L45 30 Z" fill="${color}" transform="rotate(0 50 50)"/> <path d="M50 20 L55 30 L45 30 Z" fill="${color}" transform="rotate(60 50 50)"/> <path d="M50 20 L55 30 L45 30 Z" fill="${color}" transform="rotate(120 50 50)"/> <path d="M50 20 L55 30 L45 30 Z" fill="${color}" transform="rotate(180 50 50)"/> <path d="M50 20 L55 30 L45 30 Z" fill="${color}" transform="rotate(240 50 50)"/> <path d="M50 20 L55 30 L45 30 Z" fill="${color}" transform="rotate(300 50 50)"/> </svg>`, `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> <path d="M50 5 L50 95 M5 50 L95 50 M25 25 L75 75 M25 75 L75 25" stroke="${color}" stroke-width="3" fill="none"/> <circle cx="50" cy="50" r="8" fill="${color}"/> <circle cx="50" cy="20" r="4" fill="${color}"/> <circle cx="50" cy="80" r="4" fill="${color}"/> <circle cx="20" cy="50" r="4" fill="${color}"/> <circle cx="80" cy="50" r="4" fill="${color}"/> <circle cx="30" cy="30" r="4" fill="${color}"/> <circle cx="70" cy="70" r="4" fill="${color}"/> <circle cx="30" cy="70" r="4" fill="${color}"/> <circle cx="70" cy="30" r="4" fill="${color}"/> </svg>`, `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> <path d="M50 0 L50 100 M0 50 L100 50 M15 15 L85 85 M15 85 L85 15" stroke="${color}" stroke-width="3" fill="none"/> <path d="M50 10 L53 20 L47 20 Z" fill="${color}" transform="rotate(0 50 50)"/> <path d="M50 10 L53 20 L47 20 Z" fill="${color}" transform="rotate(60 50 50)"/> <path d="M50 10 L53 20 L47 20 Z" fill="${color}" transform="rotate(120 50 50)"/> <path d="M50 10 L53 20 L47 20 Z" fill="${color}" transform="rotate(180 50 50)"/> <path d="M50 10 L53 20 L47 20 Z" fill="${color}" transform="rotate(240 50 50)"/> <path d="M50 10 L53 20 L47 20 Z" fill="${color}" transform="rotate(300 50 50)"/> <polygon points="44,44 50,40 56,44 56,50 50,54 44,50" fill="${color}"/> </svg>` ]; // Pick a random design return designs[Math.floor(Math.random() * designs.length)]; } // Animate the snowflake falling with a bouncy effect function animateSnowflake(snowflake, startX) { const duration = 8000 + Math.random() * 5000; // 8-13 seconds to fall const containerHeight = gameContainer.offsetHeight; let position = -80; // Starting position (above the viewport) let velocity = 0.5 + Math.random() * 0.5; // Starting falling speed let sway = 0; // Horizontal sway let swayDirection = Math.random() > 0.5 ? 1 : -1; let swayAmount = 0.5 + Math.random() * 1.5; // Amount of horizontal sway let x = startX; let rotation = Math.random() * 360; let rotationSpeed = (Math.random() - 0.5) * 2; // Rotation speed const animate = () => { // Update position position += velocity; velocity += 0.02; // Gravity effect // Bounce effect if needed if (position > containerHeight - 50 && velocity > 0) { position = containerHeight - 50; velocity = -velocity * 0.4; // Bounce with dampening } // Update sway (horizontal movement) sway += swayDirection * swayAmount; if (Math.abs(sway) > 30) { swayDirection *= -1; // Reverse direction when sway gets too large } // Update rotation rotation += rotationSpeed; // Apply new position x = startX + sway; snowflake.style.top = `${position}px`; snowflake.style.left = `${x}px`; snowflake.style.transform = `rotate(${rotation}deg)`; // Continue animation if snowflake is still in game and not clicked if (position < containerHeight + 100 && !snowflake.classList.contains('clicked') && gameActive) { requestAnimationFrame(animate); } else if (!snowflake.classList.contains('clicked')) { // Remove the snowflake if it's off screen or game is inactive snowflake.remove(); } }; requestAnimationFrame(animate); // Set a timeout to remove the snowflake after its animation duration setTimeout(() => { if (!snowflake.classList.contains('clicked') && gameActive) { snowflake.remove(); } }, duration); } // Create particle explosion effect when clicking a snowflake function createParticles(snowflake) { const rect = snowflake.getBoundingClientRect(); const containerRect = gameContainer.getBoundingClientRect(); const centerX = rect.left - containerRect.left + rect.width / 2; const centerY = rect.top - containerRect.top + rect.height / 2; // Create multiple particles for (let i = 0; i < 20; i++) { const particle = document.createElement('div'); particle.className = 'particle'; // Random particle properties const size = 3 + Math.random() * 7; const colorIndex = Math.floor(Math.random() * colors.length); // Set random direction for particle to fly const angle = Math.random() * Math.PI * 2; const distance = 30 + Math.random() * 60; const translateX = Math.cos(angle) * distance; const translateY = Math.sin(angle) * distance; particle.style.width = `${size}px`; particle.style.height = `${size}px`; particle.style.backgroundColor = colors[colorIndex]; particle.style.left = `${centerX}px`; particle.style.top = `${centerY}px`; particle.style.setProperty('--tx', `${translateX}px`); particle.style.setProperty('--ty', `${translateY}px`); gameContainer.appendChild(particle); // Remove particle after animation completes setTimeout(() => { particle.remove(); }, 1000); } } // Show fact container with the given text function showFactContainer(text) { factText.textContent = text; factContainer.classList.add('show'); // Hide fact after 5 seconds setTimeout(() => { factContainer.classList.remove('show'); }, 5000); } // Display a random fact function showRandomFact() { const randomIndex = Math.floor(Math.random() * facts.length); showFactContainer(facts[randomIndex]); } // Level up function function levelUp() { // Celebrate level completion header.classList.add('celebrating'); setTimeout(() => header.classList.remove('celebrating'), 3000); level++; levelProgress_value = 0; levelGoal = Math.min(10 + (level * 2), 30); // Increase goal with each level, cap at 30 // Increase difficulty with level maxSnowflakes = Math.min(7 + Math.floor(level / 2), 15); // More concurrent snowflakes updateLevelIndicator(); // Show level up message showFactContainer(`Great job! You've reached Level ${level}! Can you catch ${levelGoal} snowflakes to advance?`); // Adjust intervals for higher levels clearInterval(snowflakeInterval); const interval = Math.max(1000 - (level * 50), 400); // Faster snowflakes with level, minimum 400ms snowflakeInterval = setInterval(createSnowflake, interval); } // Initialize the game when the page loads initGame(); // Make sure to clean up when the component is unmounted return () => { clearInterval(snowflakeInterval); gameActive = false; }; }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Nature Conservation Campaign</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Montserrat', sans-serif; } body { width: 100%; height: 100vh; background: linear-gradient(135deg, #2c3e50, #1a2a38); overflow: hidden; color: #fff; } .container { position: relative; width: 100%; height: 100%; max-width: 700px; max-height: 700px; margin: 0 auto; overflow: hidden; } .content { position: relative; z-index: 10; padding: 2rem; height: 100%; display: flex; flex-direction: column; justify-content: center; } h1 { font-size: 2.5rem; margin-bottom: 1.5rem; line-height: 1.2; font-weight: 700; text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3); opacity: 0; transform: translateY(20px); animation: fadeUp 1s ease forwards; animation-delay: 0.5s; } p { font-size: 1rem; line-height: 1.6; margin-bottom: 1.5rem; max-width: 500px; font-weight: 300; text-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); opacity: 0; transform: translateY(20px); animation: fadeUp 1s ease forwards; animation-delay: 0.8s; } .stat-container { display: flex; justify-content: space-between; margin-top: 2rem; margin-bottom: 2rem; opacity: 0; transform: translateY(20px); animation: fadeUp 1s ease forwards; animation-delay: 1.1s; } .stat { flex: 1; margin-right: 1rem; background: rgba(255, 255, 255, 0.1); backdrop-filter: blur(10px); padding: 1rem; border-radius: 10px; transition: transform 0.3s ease, background 0.3s ease; } .stat:hover { background: rgba(255, 255, 255, 0.2); transform: translateY(-5px); } .stat h3 { font-size: 1.8rem; margin-bottom: 0.5rem; color: #4ecdc4; } .stat p { font-size: 0.8rem; margin-bottom: 0; } .btn { display: inline-block; padding: 0.8rem 2rem; background: #4ecdc4; color: #1a2a38; border: none; border-radius: 30px; font-weight: 600; cursor: pointer; text-transform: uppercase; font-size: 0.9rem; letter-spacing: 1px; transition: all 0.3s ease; box-shadow: 0 4px 15px rgba(78, 205, 196, 0.3); opacity: 0; transform: translateY(20px); animation: fadeUp 1s ease forwards; animation-delay: 1.4s; } .btn:hover { background: #3db9b1; transform: translateY(-3px); box-shadow: 0 6px 20px rgba(78, 205, 196, 0.4); } .btn:active { transform: translateY(-1px); } .water-ripple { position: absolute; bottom: -100px; left: 0; width: 100%; height: 100px; background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320"><path fill="%234ecdc4" fill-opacity="0.2" d="M0,192L48,176C96,160,192,128,288,133.3C384,139,480,181,576,192C672,203,768,181,864,154.7C960,128,1056,96,1152,90.7C1248,85,1344,107,1392,117.3L1440,128L1440,320L1392,320C1344,320,1248,320,1152,320C1056,320,960,320,864,320C768,320,672,320,576,320C480,320,384,320,288,320C192,320,96,320,48,320L0,320Z"></path></svg>'); background-size: cover; opacity: 0.7; z-index: 1; animation: waveMove 15s linear infinite; } .water-ripple:nth-child(2) { bottom: -90px; opacity: 0.5; animation: waveMove 12s linear infinite reverse; filter: hue-rotate(10deg); } .water-ripple:nth-child(3) { bottom: -80px; opacity: 0.3; animation: waveMove 10s linear infinite; filter: hue-rotate(20deg); } .snow-container { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 2; pointer-events: none; } .leaf { position: absolute; width: 10px; height: 10px; background: rgba(255, 255, 255, 0.1); border-radius: 50%; pointer-events: none; backdrop-filter: blur(1px); } .scroll-indicator { position: absolute; bottom: 30px; left: 50%; transform: translateX(-50%); width: 30px; height: 50px; border: 2px solid rgba(255, 255, 255, 0.3); border-radius: 15px; z-index: 20; opacity: 0; animation: fadeIn 1s ease forwards, bounce 2s ease infinite; animation-delay: 2s; } .scroll-indicator::after { content: ''; position: absolute; top: 10px; left: 50%; transform: translateX(-50%); width: 6px; height: 6px; background: rgba(255, 255, 255, 0.6); border-radius: 50%; animation: scrollDown 2s ease infinite; } @keyframes fadeUp { to { opacity: 1; transform: translateY(0); } } @keyframes fadeIn { to { opacity: 1; } } @keyframes waveMove { 0% { transform: translateX(0) translateZ(0); } 50% { transform: translateX(-25%) translateZ(0); } 100% { transform: translateX(0) translateZ(0); } } @keyframes bounce { 0%, 100% { transform: translateX(-50%) translateY(0); } 50% { transform: translateX(-50%) translateY(-10px); } } @keyframes scrollDown { 0% { opacity: 0; top: 10px; } 50% { opacity: 1; } 100% { opacity: 0; top: 30px; } } @media (max-width: 700px) { h1 { font-size: 2rem; } p { font-size: 0.9rem; } .stat-container { flex-direction: column; } .stat { margin-right: 0; margin-bottom: 1rem; } } .progress-bar { position: absolute; bottom: 0; left: 0; height: 5px; width: 0%; background: linear-gradient(90deg, #4ecdc4, #6ab7ff); z-index: 15; transition: width 0.5s ease; } /* Nature texture overlay */ .nature-texture { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><rect width="100" height="100" fill="none"/><path d="M0,0 L100,100 M0,100 L100,0" stroke="rgba(255,255,255,0.03)" stroke-width="0.5"/></svg>'); opacity: 0.4; z-index: 3; pointer-events: none; } </style> </head> <body> <div class="container"> <div class="snow-container" id="snowContainer"></div> <div class="nature-texture"></div> <div class="water-ripple"></div> <div class="water-ripple"></div> <div class="water-ripple"></div> <div class="content"> <h1>Preserving Our Watersheds</h1> <p>Our ecosystems depend on healthy water cycles. Every year, we lose critical wetland habitats at an alarming rate, threatening biodiversity and natural water filtration systems that protect our communities.</p> <div class="stat-container"> <div class="stat"> <h3>35%</h3> <p>Reduction in global wetlands over the last 50 years</p> </div> <div class="stat"> <h3>1,000+</h3> <p>Species rely on clean watershed ecosystems</p> </div> <div class="stat"> <h3>70%</h3> <p>Of freshwater is used for agriculture</p> </div> </div> <p>Join our grassroots movement to preserve natural watershed boundaries, restore wetland habitats, and implement sustainable water management practices that benefit both communities and ecosystems.</p> <button class="btn" id="learnMore">Join the movement</button> </div> <div class="scroll-indicator"></div> <div class="progress-bar" id="progressBar"></div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Snow effect const snowContainer = document.getElementById('snowContainer'); const maxLeaves = 40; const colors = ['#b1e9e4', '#4ecdc4', '#c1f7dc', '#ffffff', '#d2f8e9']; // Create leaves with random sizes and colors for (let i = 0; i < maxLeaves; i++) { createLeaf(); } function createLeaf() { const leaf = document.createElement('div'); leaf.classList.add('leaf'); // Randomize leaf properties const size = Math.random() * 8 + 3; // Size between 3-11px const opacity = Math.random() * 0.5 + 0.1; // Opacity between 0.1-0.6 const colorIndex = Math.floor(Math.random() * colors.length); leaf.style.width = `${size}px`; leaf.style.height = `${size}px`; leaf.style.opacity = opacity; leaf.style.background = colors[colorIndex]; // Starting position const startLeft = Math.random() * 100; const startTop = -20; leaf.style.left = `${startLeft}%`; leaf.style.top = `${startTop}px`; // Animation properties const duration = Math.random() * 15 + 10; // 10-25 seconds const delay = Math.random() * 10; // 0-10 seconds delay leaf.style.animation = `fallDown ${duration}s linear ${delay}s infinite`; // Create the animation dynamically const animationName = `fallDown-${i}`; const keyframes = ` @keyframes ${animationName} { 0% { transform: translateY(0) rotate(0deg) translateX(0); opacity: ${opacity}; } 50% { transform: translateY(${Math.random() * 100 + 200}px) rotate(${Math.random() * 360}deg) translateX(${Math.random() * 40 - 20}px); opacity: ${opacity}; } 100% { transform: translateY(${Math.random() * 100 + 500}px) rotate(${Math.random() * 720}deg) translateX(${Math.random() * 100 - 50}px); opacity: 0; } } `; // Add keyframes to document const styleSheet = document.createElement('style'); styleSheet.textContent = keyframes; document.head.appendChild(styleSheet); leaf.style.animation = `${animationName} ${duration}s linear ${delay}s infinite`; snowContainer.appendChild(leaf); // Remove and recreate leaves that have fallen off screen setTimeout(() => { leaf.remove(); createLeaf(); }, (duration + delay) * 1000); } // Button interaction effect const button = document.getElementById('learnMore'); button.addEventListener('click', function() { this.innerHTML = '<span style="opacity: 0.8;">✓</span> Thank you for joining'; this.style.background = '#2ecc71'; // Create water ripple effect on click const ripple = document.createElement('div'); ripple.style.position = 'absolute'; ripple.style.borderRadius = '50%'; ripple.style.backgroundColor = 'rgba(255, 255, 255, 0.4)'; ripple.style.width = '20px'; ripple.style.height = '20px'; ripple.style.transform = 'scale(0)'; ripple.style.animation = 'ripple 1s ease-out'; // Positioning relative to button const rect = button.getBoundingClientRect(); ripple.style.left = `${rect.width / 2}px`; ripple.style.top = `${rect.height / 2}px`; // Add ripple animation const rippleKeyframes = ` @keyframes ripple { to { transform: scale(15); opacity: 0; } } `; const styleSheet = document.createElement('style'); styleSheet.textContent = rippleKeyframes; document.head.appendChild(styleSheet); button.style.overflow = 'hidden'; button.style.position = 'relative'; button.appendChild(ripple); // Clean up setTimeout(() => { ripple.remove(); }, 1000); // Create more leaves for celebration for (let i = 0; i < 20; i++) { setTimeout(() => { createLeaf(); }, i * 100); } }); // Progress bar update on scroll const progressBar = document.getElementById('progressBar'); let scrollPosition = 0; let targetScrollPosition = 0; window.addEventListener('wheel', function(e) { e.preventDefault(); // Update target scroll position targetScrollPosition += e.deltaY / 10; targetScrollPosition = Math.max(0, Math.min(100, targetScrollPosition)); // Update progress bar updateProgress(); }); // Touch scroll support let touchStartY = 0; window.addEventListener('touchstart', function(e) { touchStartY = e.touches[0].clientY; }); window.addEventListener('touchmove', function(e) { e.preventDefault(); const touchY = e.touches[0].clientY; const deltaY = touchStartY - touchY; targetScrollPosition += deltaY / 20; targetScrollPosition = Math.max(0, Math.min(100, targetScrollPosition)); touchStartY = touchY; updateProgress(); }); function updateProgress() { // Smooth animation for scroll position requestAnimationFrame(function animate() { scrollPosition += (targetScrollPosition - scrollPosition) * 0.1; if (Math.abs(targetScrollPosition - scrollPosition) > 0.1) { requestAnimationFrame(animate); } progressBar.style.width = `${scrollPosition}%`; // Parallax effect for content const content = document.querySelector('.content'); content.style.transform = `translateY(-${scrollPosition * 0.5}%)`; // Opacity effect for water ripples const ripples = document.querySelectorAll('.water-ripple'); ripples.forEach((ripple, index) => { ripple.style.opacity = Math.max(0, 0.7 - (scrollPosition / 100) * 0.5 * (index + 1)); }); }); } }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Whitespace Architects</title> <style> @import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@300;500;700&family=Inter:wght@300;400;500;600&display=swap'); :root { --color-primary: #282b2d; --color-secondary: #f7f7f7; --color-accent: #a0a7ad; --color-hover: #e4e9ef; --color-snow: #ffffff; --font-display: 'Cormorant Garamond', serif; --font-body: 'Inter', sans-serif; } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: var(--font-body); background-color: var(--color-secondary); color: var(--color-primary); line-height: 1.6; font-weight: 300; overflow-x: hidden; position: relative; height: 100vh; width: 100%; } .snow-container { position: fixed; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 10; opacity: 0.7; } .snowflake { position: absolute; background-color: var(--color-snow); border-radius: 50%; opacity: 0.8; pointer-events: none; } .container { max-width: 700px; margin: 0 auto; padding: 2rem; position: relative; z-index: 2; height: 100%; overflow-y: auto; scrollbar-width: thin; } .container::-webkit-scrollbar { width: 4px; } .container::-webkit-scrollbar-thumb { background-color: var(--color-accent); border-radius: 4px; } header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 3rem; position: relative; } .logo { font-family: var(--font-display); font-size: 1.5rem; font-weight: 300; letter-spacing: 0.15em; color: var(--color-primary); position: relative; cursor: pointer; transition: all 0.3s ease; } .logo::after { content: ""; position: absolute; bottom: -5px; left: 0; width: 0; height: 1px; background-color: var(--color-accent); transition: width 0.3s ease; } .logo:hover::after { width: 100%; } nav { position: relative; } .menu-toggle { width: 30px; height: 20px; cursor: pointer; position: relative; z-index: 5; } .menu-toggle span { display: block; width: 100%; height: 1px; background-color: var(--color-primary); position: absolute; transition: all 0.3s ease; } .menu-toggle span:nth-child(1) { top: 0; } .menu-toggle span:nth-child(2) { top: 9px; width: 70%; right: 0; } .menu-toggle span:nth-child(3) { bottom: 0; } .menu-toggle:hover span:nth-child(2) { width: 100%; } .menu-toggle.active span:nth-child(1) { transform: rotate(45deg); top: 9px; } .menu-toggle.active span:nth-child(2) { opacity: 0; } .menu-toggle.active span:nth-child(3) { transform: rotate(-45deg); bottom: 9px; } .menu { position: absolute; top: 40px; right: 0; background-color: var(--color-secondary); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05); padding: 1.5rem; border-radius: 4px; min-width: 180px; opacity: 0; transform: translateY(-10px); visibility: hidden; transition: all 0.3s ease; z-index: 4; } .menu.show { opacity: 1; transform: translateY(0); visibility: visible; } .menu ul { list-style: none; } .menu li { margin-bottom: 1rem; } .menu li:last-child { margin-bottom: 0; } .menu a { color: var(--color-primary); text-decoration: none; font-size: 0.9rem; font-weight: 400; transition: all 0.3s ease; display: block; position: relative; padding: 0.3rem 0; } .menu a::after { content: ""; position: absolute; bottom: 0; left: 0; width: 0; height: 1px; background-color: var(--color-accent); transition: width 0.3s ease; } .menu a:hover { color: var(--color-primary); } .menu a:hover::after { width: 100%; } .hero { margin-bottom: 4rem; padding-bottom: 2rem; border-bottom: 1px solid rgba(160, 167, 173, 0.2); position: relative; } h1 { font-family: var(--font-display); font-size: 3.2rem; font-weight: 300; line-height: 1.2; margin-bottom: 1.5rem; color: var(--color-primary); } .hero p { font-size: 1.1rem; color: var(--color-primary); max-width: 90%; line-height: 1.7; margin-bottom: 2rem; } .cta { display: inline-block; background-color: transparent; border: 1px solid var(--color-primary); color: var(--color-primary); padding: 0.8rem 2rem; font-size: 0.9rem; text-decoration: none; letter-spacing: 0.05em; transition: all 0.3s ease; position: relative; overflow: hidden; } .cta::after { content: ""; position: absolute; bottom: 0; left: 0; width: 100%; height: 0; background-color: var(--color-primary); transition: all 0.3s ease; z-index: -1; } .cta:hover { color: var(--color-secondary); } .cta:hover::after { height: 100%; } .projects { display: grid; grid-template-columns: 1fr; gap: 3rem; margin-bottom: 4rem; } .project { position: relative; cursor: pointer; overflow: hidden; border-radius: 2px; box-shadow: 0 10px 20px rgba(0, 0, 0, 0.05); height: 250px; transition: transform 0.3s ease, box-shadow 0.3s ease; } .project:hover { transform: translateY(-5px); box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1); } .project-image { width: 100%; height: 100%; object-fit: cover; transition: transform 0.5s ease; } .project:hover .project-image { transform: scale(1.05); } .project-overlay { position: absolute; bottom: 0; left: 0; width: 100%; padding: 1.5rem; background: linear-gradient(to top, rgba(40, 43, 45, 0.9), rgba(40, 43, 45, 0)); color: var(--color-secondary); transform: translateY(30px); opacity: 0; transition: all 0.3s ease; } .project:hover .project-overlay { transform: translateY(0); opacity: 1; } .project-title { font-family: var(--font-display); font-size: 1.5rem; font-weight: 300; margin-bottom: 0.5rem; } .project-location { font-size: 0.85rem; opacity: 0.8; } .about { margin-bottom: 4rem; display: grid; grid-template-columns: 1fr; gap: 2rem; } h2 { font-family: var(--font-display); font-size: 2rem; font-weight: 300; margin-bottom: 1.5rem; position: relative; display: inline-block; } h2::after { content: ""; position: absolute; bottom: -5px; left: 0; width: 40px; height: 1px; background-color: var(--color-accent); } .about p { font-size: 1rem; line-height: 1.8; margin-bottom: 1.5rem; } .quote { font-family: var(--font-display); font-size: 1.5rem; font-style: italic; color: var(--color-accent); margin: 2rem 0; padding-left: 1.5rem; border-left: 1px solid var(--color-accent); line-height: 1.5; } footer { padding-top: 2rem; border-top: 1px solid rgba(160, 167, 173, 0.2); font-size: 0.85rem; color: var(--color-accent); display: flex; justify-content: space-between; align-items: center; } .footer-nav a { color: var(--color-accent); text-decoration: none; margin-left: 1.5rem; transition: color 0.3s ease; } .footer-nav a:hover { color: var(--color-primary); } @media (max-width: 600px) { h1 { font-size: 2.5rem; } .hero p { font-size: 1rem; } .container { padding: 1.5rem; } footer { flex-direction: column; gap: 1rem; align-items: flex-start; } .footer-nav a { margin-left: 0; margin-right: 1.5rem; } } @media (min-width: 601px) { .projects { grid-template-columns: repeat(2, 1fr); } } /* Cursor effect */ .custom-cursor { position: fixed; width: 20px; height: 20px; border: 1px solid var(--color-accent); border-radius: 50%; transform: translate(-50%, -50%); pointer-events: none; mix-blend-mode: difference; z-index: 9999; transition: transform 0.2s ease; } .custom-cursor.active { transform: translate(-50%, -50%) scale(1.5); background-color: rgba(160, 167, 173, 0.1); } </style> </head> <body> <div class="snow-container"></div> <div class="custom-cursor"></div> <div class="container"> <header> <div class="logo">WHITESPACE ARCHITECTS</div> <nav> <div class="menu-toggle"> <span></span> <span></span> <span></span> </div> <div class="menu"> <ul> <li><a href="#">Projects</a></li> <li><a href="#">Studio</a></li> <li><a href="#">Process</a></li> <li><a href="#">Recognition</a></li> <li><a href="#">Contact</a></li> </ul> </div> </nav> </header> <section class="hero"> <h1>Crafting spaces that<br>embrace the elements</h1> <p>We design environments that harmonize with their surroundings, where light, material, and form create experiences that evolve with the seasons.</p> <a href="#" class="cta">View Winter Collection</a> </section> <section class="projects"> <div class="project"> <img src="https://images.unsplash.com/photo-1600585154340-be6161a56a0c?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80" alt="Nordic Retreat" class="project-image"> <div class="project-overlay"> <h3 class="project-title">Nordic Retreat</h3> <p class="project-location">Oslo, Norway</p> </div> </div> <div class="project"> <img src="https://images.unsplash.com/photo-1510798831971-661eb04b3739?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1374&q=80" alt="Alpine Observatory" class="project-image"> <div class="project-overlay"> <h3 class="project-title">Alpine Observatory</h3> <p class="project-location">Chamonix, France</p> </div> </div> </section> <section class="about"> <div> <h2>Our Approach</h2> <p>We believe architectural spaces should respond to their environment with both resilience and grace. Our winter designs particularly embrace natural light, creating interiors that remain warm and inviting even during the darkest months of the year.</p> <p>Our team integrates sustainable technologies and time-honored materials to create buildings that stand as thoughtful participants in their surroundings rather than mere occupants.</p> <div class="quote">"Architecture is the thoughtful making of space, considering how it breathes through all seasons."</div> </div> </section> <footer> <div>© 2023 Whitespace Architects. All rights reserved.</div> <div class="footer-nav"> <a href="#">Instagram</a> <a href="#">LinkedIn</a> <a href="#">Privacy</a> </div> </footer> </div> <script> // Menu toggle functionality const menuToggle = document.querySelector('.menu-toggle'); const menu = document.querySelector('.menu'); menuToggle.addEventListener('click', () => { menuToggle.classList.toggle('active'); menu.classList.toggle('show'); }); // Close menu when clicking outside document.addEventListener('click', (e) => { if (!menu.contains(e.target) && !menuToggle.contains(e.target)) { menuToggle.classList.remove('active'); menu.classList.remove('show'); } }); // Custom cursor const cursor = document.createElement('div'); cursor.classList.add('custom-cursor'); document.body.appendChild(cursor); document.addEventListener('mousemove', (e) => { cursor.style.left = e.clientX + 'px'; cursor.style.top = e.clientY + 'px'; }); document.addEventListener('mousedown', () => { cursor.classList.add('active'); }); document.addEventListener('mouseup', () => { cursor.classList.remove('active'); }); // Interactive elements cursor effect const interactiveElements = document.querySelectorAll('a, .menu-toggle, .project'); interactiveElements.forEach(el => { el.addEventListener('mouseenter', () => { cursor.classList.add('active'); }); el.addEventListener('mouseleave', () => { cursor.classList.remove('active'); }); }); // Snowfall effect function createSnowflakes() { const snowContainer = document.querySelector('.snow-container'); const numberOfSnowflakes = 50; for (let i = 0; i < numberOfSnowflakes; i++) { createSnowflake(snowContainer); } } function createSnowflake(container) { const snowflake = document.createElement('div'); snowflake.classList.add('snowflake'); // Random properties const size = Math.random() * 5 + 1; const posX = Math.random() * window.innerWidth; const delay = Math.random() * 5; const duration = Math.random() * 10 + 8; snowflake.style.width = `${size}px`; snowflake.style.height = `${size}px`; snowflake.style.left = `${posX}px`; snowflake.style.animationDelay = `${delay}s`; snowflake.style.opacity = Math.random() * 0.7 + 0.3; container.appendChild(snowflake); // Animation animateSnowflake(snowflake, container, duration); } function animateSnowflake(snowflake, container, duration) { let posY = -20; const endPosY = window.innerHeight + 20; const posX = parseFloat(snowflake.style.left); const deltaX = Math.random() * 40 - 20; // Random horizontal drift function animate() { if (posY < endPosY) { posY += 100 / (duration * 60); // Speed based on duration const waveFactor = Math.sin(posY * 0.02) * 2; // Gentle wave pattern const newPosX = posX + waveFactor + (deltaX * posY / endPosY); snowflake.style.top = `${posY}px`; snowflake.style.left = `${newPosX}px`; requestAnimationFrame(animate); } else { container.removeChild(snowflake); createSnowflake(container); } } requestAnimationFrame(animate); } // Initialize snowfall window.addEventListener('load', createSnowflakes); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Winter Lumière Collection</title> <style> :root { --primary-color: #f5f5f7; --secondary-color: #e8e8ff; --accent-color: #c0c0d8; --text-color: #414158; --highlight-color: #a8a8c8; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Cormorant Garamond', Georgia, serif; } body { width: 100%; height: 700px; overflow: hidden; background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); color: var(--text-color); } .lookbook-container { width: 100%; height: 100%; position: relative; overflow: hidden; display: flex; flex-direction: column; } header { text-align: center; padding: 20px 0; opacity: 0; animation: fadeIn 1.5s 0.5s forwards; } h1 { font-size: 2.2rem; font-weight: 300; letter-spacing: 6px; margin-bottom: 4px; } .subtitle { font-size: 0.9rem; letter-spacing: 2px; font-style: italic; opacity: 0.8; } .gallery { display: flex; height: calc(100% - 120px); position: relative; transition: transform 0.8s cubic-bezier(0.77, 0, 0.175, 1); } .image-container { min-width: 100%; padding: 0 40px; display: flex; position: relative; transition: all 0.5s ease; } .image-wrapper { flex: 1; position: relative; overflow: hidden; border-radius: 2px; box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1); transition: transform 0.5s ease; } .image-wrapper:hover { transform: scale(1.02); } .product-image { width: 100%; height: 100%; object-fit: cover; transition: transform 0.7s ease; } .image-wrapper:hover .product-image { transform: scale(1.05); } .product-info { position: absolute; bottom: 0; left: 0; width: 100%; padding: 20px; background: linear-gradient(to top, rgba(0, 0, 0, 0.5), transparent); color: white; opacity: 0; transform: translateY(20px); transition: all 0.5s ease; } .image-wrapper:hover .product-info { opacity: 1; transform: translateY(0); } .product-name { font-size: 1.2rem; margin-bottom: 5px; font-weight: 300; letter-spacing: 2px; } .product-description { font-size: 0.8rem; line-height: 1.4; opacity: 0.9; } .caption { position: absolute; top: 50%; right: 50px; transform: translateY(-50%); width: 200px; padding: 25px; background: rgba(255, 255, 255, 0.85); backdrop-filter: blur(5px); border-radius: 2px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); opacity: 0; transition: opacity 0.8s ease, transform 0.8s ease; } .active .caption { opacity: 1; transform: translateY(-50%) translateX(0); } .caption-title { font-size: 1.1rem; margin-bottom: 10px; letter-spacing: 1px; } .caption-text { font-size: 0.9rem; line-height: 1.6; color: #505060; } .navigation { display: flex; justify-content: center; gap: 15px; margin-top: 20px; position: relative; z-index: 10; opacity: 0; animation: fadeIn 1.5s 1.5s forwards; } .nav-btn { width: 40px; height: 40px; border-radius: 50%; background: rgba(255, 255, 255, 0.8); border: none; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.3s ease; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); } .nav-btn:hover { background: white; transform: translateY(-2px); box-shadow: 0 7px 20px rgba(0, 0, 0, 0.15); } .nav-btn:active { transform: translateY(0); } .nav-btn svg { width: 20px; height: 20px; fill: var(--text-color); } .page-indicator { position: absolute; bottom: 20px; left: 0; width: 100%; display: flex; justify-content: center; gap: 8px; opacity: 0; animation: fadeIn 1.5s 1.8s forwards; } .indicator { width: 8px; height: 8px; border-radius: 50%; background: var(--accent-color); opacity: 0.4; transition: all 0.3s ease; cursor: pointer; } .indicator.active { opacity: 1; transform: scale(1.3); background: var(--highlight-color); } .snowflake { position: absolute; color: white; pointer-events: none; text-shadow: 0 0 3px rgba(255,255,255,0.8); animation: fall linear forwards; } @keyframes fall { to { transform: translateY(700px) rotate(360deg); } } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } /* Shimmer effect for reflective highlights */ .image-wrapper::before { content: ''; position: absolute; top: -100%; left: -100%; width: 50%; height: 50%; background: linear-gradient( to bottom right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.3) 50%, rgba(255, 255, 255, 0) 100% ); transform: rotate(45deg); animation: shimmer 5s infinite; z-index: 2; pointer-events: none; } @keyframes shimmer { 0% { top: -100%; left: -100%; } 100% { top: 200%; left: 200%; } } /* Responsive design */ @media (max-width: 700px) { h1 { font-size: 1.8rem; } .subtitle { font-size: 0.8rem; } .image-container { padding: 0 20px; } .caption { right: 20px; width: 160px; padding: 15px; } .caption-title { font-size: 1rem; } .caption-text { font-size: 0.8rem; } } /* Custom Scroll Style */ ::-webkit-scrollbar { width: 5px; } ::-webkit-scrollbar-track { background: var(--primary-color); } ::-webkit-scrollbar-thumb { background: var(--highlight-color); border-radius: 5px; } </style> </head> <body> <div class="lookbook-container"> <header> <h1>WINTER LUMIÈRE</h1> <div class="subtitle">Reflections of Elegance • Winter 2024</div> </header> <div class="gallery"> <div class="image-container active"> <div class="image-wrapper"> <img src="https://images.unsplash.com/photo-1581044777550-4cfa60707c03?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1286&q=80" alt="Crystal Organza Gown" class="product-image"> <div class="product-info"> <h3 class="product-name">CRYSTAL ORGANZA GOWN</h3> <p class="product-description">Hand-embellished with silver beading</p> </div> </div> <div class="caption" style="transform: translateY(-50%) translateX(20px);"> <h4 class="caption-title">Prismatic Ice</h4> <p class="caption-text">Diaphanous layers capture light like frozen crystals, creating a shimmering silhouette that transforms with every step.</p> </div> </div> <div class="image-container"> <div class="image-wrapper"> <img src="https://images.unsplash.com/photo-1549062572-544a64fb0c56?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1287&q=80" alt="Frost Velvet Ensemble" class="product-image"> <div class="product-info"> <h3 class="product-name">FROST VELVET ENSEMBLE</h3> <p class="product-description">Precision-tailored with pearl accents</p> </div> </div> <div class="caption" style="transform: translateY(-50%) translateX(20px);"> <h4 class="caption-title">Winter's Embrace</h4> <p class="caption-text">Plush velvet in glacier blue envelops the form with structured elegance, evoking the serene stillness of a winter morning.</p> </div> </div> <div class="image-container"> <div class="image-wrapper"> <img src="https://images.unsplash.com/photo-1515886657613-9f3515b0c78f?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1320&q=80" alt="Iridescent Silk Coat" class="product-image"> <div class="product-info"> <h3 class="product-name">IRIDESCENT SILK COAT</h3> <p class="product-description">Metallic thread detailing</p> </div> </div> <div class="caption" style="transform: translateY(-50%) translateX(20px);"> <h4 class="caption-title">Aurora Reverie</h4> <p class="caption-text">Shifting tones cascade across lustrous silk, mimicking the ethereal dance of northern lights against a midnight sky.</p> </div> </div> <div class="image-container"> <div class="image-wrapper"> <img src="https://images.unsplash.com/photo-1566206091558-7f218b696731?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1364&q=80" alt="Snow Blossom Dress" class="product-image"> <div class="product-info"> <h3 class="product-name">SNOW BLOSSOM DRESS</h3> <p class="product-description">Delicate cutwork embroidery</p> </div> </div> <div class="caption" style="transform: translateY(-50%) translateX(20px);"> <h4 class="caption-title">Crystalline Bloom</h4> <p class="caption-text">Intricate patterns unfold like frost flowers across gossamer fabric, celebrating nature's most elegant geometry.</p> </div> </div> </div> <div class="navigation"> <button class="nav-btn prev-btn"> <svg viewBox="0 0 24 24"> <path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/> </svg> </button> <button class="nav-btn next-btn"> <svg viewBox="0 0 24 24"> <path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/> </svg> </button> </div> <div class="page-indicator"> <span class="indicator active" data-index="0"></span> <span class="indicator" data-index="1"></span> <span class="indicator" data-index="2"></span> <span class="indicator" data-index="3"></span> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const gallery = document.querySelector('.gallery'); const containers = document.querySelectorAll('.image-container'); const prevBtn = document.querySelector('.prev-btn'); const nextBtn = document.querySelector('.next-btn'); const indicators = document.querySelectorAll('.indicator'); let currentIndex = 0; const totalSlides = containers.length; // Snowflake animation function createSnowflake() { const snowflake = document.createElement('div'); snowflake.classList.add('snowflake'); snowflake.innerHTML = '❄'; snowflake.style.left = Math.random() * 100 + '%'; snowflake.style.opacity = Math.random() * 0.7 + 0.3; snowflake.style.fontSize = Math.random() * 15 + 8 + 'px'; const animationDuration = Math.random() * 5 + 5; snowflake.style.animationDuration = animationDuration + 's'; document.querySelector('.lookbook-container').appendChild(snowflake); // Remove snowflake after animation completes setTimeout(() => { snowflake.remove(); }, animationDuration * 1000); } // Create snowflakes at random intervals setInterval(createSnowflake, 300); // Initialize with several snowflakes for (let i = 0; i < 15; i++) { setTimeout(createSnowflake, Math.random() * 2000); } function updateGallery() { gallery.style.transform = `translateX(-${currentIndex * 100}%)`; // Update active states containers.forEach((container, index) => { if (index === currentIndex) { container.classList.add('active'); } else { container.classList.remove('active'); } }); // Update indicators indicators.forEach((indicator, index) => { if (index === currentIndex) { indicator.classList.add('active'); } else { indicator.classList.remove('active'); } }); } function goToNext() { currentIndex = (currentIndex + 1) % totalSlides; updateGallery(); } function goToPrev() { currentIndex = (currentIndex - 1 + totalSlides) % totalSlides; updateGallery(); } // Event listeners prevBtn.addEventListener('click', goToPrev); nextBtn.addEventListener('click', goToNext); indicators.forEach(indicator => { indicator.addEventListener('click', () => { currentIndex = parseInt(indicator.dataset.index); updateGallery(); }); }); // Auto-advance carousel let autoplayInterval = setInterval(goToNext, 5000); // Pause autoplay on hover gallery.addEventListener('mouseenter', () => { clearInterval(autoplayInterval); }); gallery.addEventListener('mouseleave', () => { autoplayInterval = setInterval(goToNext, 5000); }); // Touch events for mobile let touchStartX = 0; let touchEndX = 0; gallery.addEventListener('touchstart', e => { touchStartX = e.changedTouches[0].screenX; }); gallery.addEventListener('touchend', e => { touchEndX = e.changedTouches[0].screenX; handleGesture(); }); function handleGesture() { if (touchEndX < touchStartX - 50) { goToNext(); } else if (touchEndX > touchStartX + 50) { goToPrev(); } } // Initialize gallery updateGallery(); }); </script> </body> </html>