Arrows are more than just simple directional indicators; they are versatile design elements that can enhance user experience and interface aesthetics. From guiding users through a website to highlighting important information, arrows play a crucial role in modern UI design.
In this article, we will explore ten compelling examples of arrow usage in various contexts. These examples will demonstrate how arrows can be effectively integrated into your design projects to improve navigation and user engagement.
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
Designing your own arrow has never been easier with Subframe. Its drag-and-drop interface and intuitive, responsive canvas ensure you create pixel-perfect UI every time. Loved by designers and developers alike, Subframe makes the design process seamless and enjoyable.
Start for free and experience the difference today!
CODE6
Here's the code:
CODETEXT6
CODE7
Here's the code:
CODETEXT7
CODE8
Here's the code:
CODETEXT8
CODE9
Here's the code:
CODETEXT9
CODE10
Here's the code:
CODETEXT10
Ready to elevate your UI design game? With Subframe, you can create stunning, pixel-perfect interfaces, including arrows, in minutes. Its drag-and-drop editor ensures efficiency and precision.
Don't wait! Start for free and begin designing immediately. Experience the ease and power of Subframe today!
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Minimalist Photography Carousel</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Helvetica Neue', Arial, sans-serif; } body { width: 100%; height: 100%; background-color: #f5f5f5; display: flex; justify-content: center; align-items: center; overflow: hidden; } .carousel-container { position: relative; width: 100%; max-width: 700px; height: 700px; overflow: hidden; background-color: #111; } .carousel { display: flex; width: 100%; height: 100%; transition: transform 0.7s cubic-bezier(0.25, 0.1, 0.25, 1); } .slide { flex: 0 0 100%; position: relative; opacity: 0; transition: opacity 0.5s ease; } .slide.active { opacity: 1; } .slide img { width: 100%; height: 100%; object-fit: cover; filter: grayscale(0.2) contrast(1.1); } .slide-content { position: absolute; bottom: 60px; left: 50px; max-width: 70%; color: white; text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3); opacity: 0; transform: translateY(20px); transition: opacity 0.8s ease, transform 0.8s ease; transition-delay: 0.3s; } .slide.active .slide-content { opacity: 1; transform: translateY(0); } .slide-content h2 { font-size: 28px; font-weight: 300; margin-bottom: 10px; letter-spacing: 1px; } .slide-content p { font-size: 16px; line-height: 1.5; font-weight: 300; opacity: 0.9; } .navigation { position: absolute; width: 100%; display: flex; justify-content: space-between; top: 50%; transform: translateY(-50%); padding: 0 20px; z-index: 10; pointer-events: none; } .arrow { width: 50px; height: 50px; border-radius: 50%; background-color: rgba(255, 255, 255, 0.1); backdrop-filter: blur(5px); display: flex; align-items: center; justify-content: center; cursor: pointer; transition: all 0.3s ease; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); pointer-events: auto; opacity: 0.7; } .arrow:hover { background-color: rgba(255, 255, 255, 0.2); box-shadow: 0 6px 16px rgba(0, 0, 0, 0.25); transform: translateY(-2px) scale(1.05); opacity: 1; } .arrow:active { transform: translateY(0) scale(0.98); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2); } .arrow svg { width: 24px; height: 24px; fill: none; stroke: white; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; } .left-arrow svg { margin-left: -2px; } .right-arrow svg { margin-right: -2px; } .indicators { position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); display: flex; gap: 8px; z-index: 10; } .indicator { width: 30px; height: 2px; background-color: rgba(255, 255, 255, 0.3); cursor: pointer; transition: all 0.3s ease; } .indicator.active { background-color: white; width: 40px; } .progress-bar { position: absolute; top: 0; left: 0; height: 2px; width: 100%; background-color: rgba(255, 255, 255, 0.1); z-index: 10; } .progress { height: 100%; width: 0; background-color: white; transition: width 0.3s linear; } .label { position: absolute; top: 20px; left: 20px; color: white; font-size: 12px; letter-spacing: 2px; text-transform: uppercase; opacity: 0.7; z-index: 10; } @media (max-width: 600px) { .slide-content { left: 30px; bottom: 40px; max-width: 80%; } .slide-content h2 { font-size: 22px; } .slide-content p { font-size: 14px; } .arrow { width: 40px; height: 40px; } .arrow svg { width: 20px; height: 20px; } .indicators { bottom: 15px; } .indicator { width: 25px; } .indicator.active { width: 35px; } } @media (max-height: 500px) { .slide-content { bottom: 20px; } } </style> </head> <body> <div class="carousel-container"> <div class="label">Monochrome Series</div> <div class="progress-bar"> <div class="progress" id="progress"></div> </div> <div class="carousel" id="carousel"> <div class="slide active"> <img src="https://images.unsplash.com/photo-1601887389937-0b02c26b602c?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1374&q=80" alt="Architectural Shadows"> <div class="slide-content"> <h2>Architectural Shadows</h2> <p>Exploring the interplay between light and concrete structures, this series captures ephemeral moments where shadows create fleeting geometrical patterns.</p> </div> </div> <div class="slide"> <img src="https://images.unsplash.com/photo-1602521879205-88d5e825b0de?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1376&q=80" alt="Urban Silhouettes"> <div class="slide-content"> <h2>Urban Silhouettes</h2> <p>The quiet observation of human forms moving through metropolitan spaces, where individuals become anonymous shapes against the urban backdrop.</p> </div> </div> <div class="slide"> <img src="https://images.unsplash.com/photo-1588097291255-57dafc99f180?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1376&q=80" alt="Textural Contrasts"> <div class="slide-content"> <h2>Textural Contrasts</h2> <p>Examining the tactile quality of surfaces through monochromatic photography, revealing intricate details often overlooked in color perception.</p> </div> </div> <div class="slide"> <img src="https://images.unsplash.com/photo-1542708993627-b6e5facaa68f?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1480&q=80" alt="Negative Space"> <div class="slide-content"> <h2>Negative Space</h2> <p>A study in minimalism where what's absent becomes as significant as what's present, creating visual poetry through carefully composed emptiness.</p> </div> </div> <div class="slide"> <img src="https://images.unsplash.com/photo-1520699667410-784595f72f2e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80" alt="Abstract Reflections"> <div class="slide-content"> <h2>Abstract Reflections</h2> <p>Capturing the distorted realities created when light interacts with reflective surfaces, transforming familiar scenes into enigmatic visual puzzles.</p> </div> </div> </div> <div class="navigation"> <div class="arrow left-arrow" id="prevBtn"> <svg viewBox="0 0 24 24"> <path d="M19 12H5M12 19l-7-7 7-7"></path> </svg> </div> <div class="arrow right-arrow" id="nextBtn"> <svg viewBox="0 0 24 24"> <path d="M5 12h14M12 5l7 7-7 7"></path> </svg> </div> </div> <div class="indicators" id="indicators"></div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const carousel = document.getElementById('carousel'); const slides = document.querySelectorAll('.slide'); const prevBtn = document.getElementById('prevBtn'); const nextBtn = document.getElementById('nextBtn'); const indicators = document.getElementById('indicators'); const progress = document.getElementById('progress'); let currentIndex = 0; let autoSlideInterval; const autoSlideDelay = 5000; // 5 seconds // Create indicators slides.forEach((_, index) => { const indicator = document.createElement('div'); indicator.classList.add('indicator'); if (index === 0) indicator.classList.add('active'); indicator.addEventListener('click', () => goToSlide(index)); indicators.appendChild(indicator); }); const indicatorElements = document.querySelectorAll('.indicator'); function updateSlides() { slides.forEach(slide => slide.classList.remove('active')); slides[currentIndex].classList.add('active'); indicatorElements.forEach(ind => ind.classList.remove('active')); indicatorElements[currentIndex].classList.add('active'); resetProgress(); } function goToSlide(index) { currentIndex = index; updateSlides(); resetAutoSlide(); } function goToNextSlide() { currentIndex = (currentIndex + 1) % slides.length; updateSlides(); resetAutoSlide(); } function goToPrevSlide() { currentIndex = (currentIndex - 1 + slides.length) % slides.length; updateSlides(); resetAutoSlide(); } function startAutoSlide() { autoSlideInterval = setInterval(() => { goToNextSlide(); }, autoSlideDelay); } function resetAutoSlide() { clearInterval(autoSlideInterval); startAutoSlide(); } function resetProgress() { progress.style.width = '0%'; animateProgress(); } function animateProgress() { progress.style.transition = `width ${autoSlideDelay}ms linear`; setTimeout(() => { progress.style.width = '100%'; }, 50); } // Event listeners prevBtn.addEventListener('click', goToPrevSlide); nextBtn.addEventListener('click', goToNextSlide); // Touch support let touchStartX = 0; let touchEndX = 0; carousel.addEventListener('touchstart', e => { touchStartX = e.changedTouches[0].screenX; }, { passive: true }); carousel.addEventListener('touchend', e => { touchEndX = e.changedTouches[0].screenX; handleSwipe(); }, { passive: true }); function handleSwipe() { const threshold = 50; if (touchStartX - touchEndX > threshold) { goToNextSlide(); } else if (touchEndX - touchStartX > threshold) { goToPrevSlide(); } } // Add hover effect for better navigation visibility on different image backgrounds const navigation = document.querySelector('.navigation'); carousel.addEventListener('mousemove', function(e) { const rect = carousel.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; // Show arrows more prominently when near the sides if (x < rect.width * 0.3 || x > rect.width * 0.7) { navigation.style.opacity = '1'; } else { navigation.style.opacity = '0.7'; } }); carousel.addEventListener('mouseleave', function() { navigation.style.opacity = '0.7'; }); // Initialize updateSlides(); startAutoSlide(); animateProgress(); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Urban Explorer Interactive Map</title> <style> :root { --primary-color: #3a86ff; --secondary-color: #8338ec; --accent-color: #ff006e; --text-color: #2b2d42; --light-color: #f8f9fa; --dark-color: #212529; --success-color: #38b000; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { width: 100%; height: 100vh; overflow: hidden; background-color: var(--light-color); display: flex; justify-content: center; align-items: center; } .map-container { width: 700px; height: 700px; position: relative; overflow: hidden; border-radius: 12px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); } .map { width: 100%; height: 100%; background: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MDAiIGhlaWdodD0iNzAwIiB2aWV3Qm94PSIwIDAgNzAwIDcwMCI+CiAgPGRlZnM+CiAgICA8bGluZWFyR3JhZGllbnQgaWQ9ImdyYWQxIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjEwMCUiIHkyPSIxMDAlIj4KICAgICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3R5bGU9InN0b3AtY29sb3I6I2VkZjJmYjsiIC8+CiAgICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3R5bGU9InN0b3AtY29sb3I6I2U2ZTZlNjsiIC8+CiAgICA8L2xpbmVhckdyYWRpZW50PgogIDwvZGVmcz4KICA8cmVjdCB3aWR0aD0iNzAwIiBoZWlnaHQ9IjcwMCIgZmlsbD0idXJsKCNncmFkMSkiLz4KICA8IS0tIFJvYWRzIC0tPgogIDxwYXRoIGQ9Ik0xMDAsMTUwIEw2MDAsNDUwIiBzdHJva2U9IiNkZGRkZGQiIHN0cm9rZS13aWR0aD0iMTgiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgogIDxwYXRoIGQ9Ik02MCwzMDAgTDY0MCwzMDAiIHN0cm9rZT0iI2RkZGRkZCIgc3Ryb2tlLXdpZHRoPSIyNSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+CiAgPHBhdGggZD0iTTI1MCwxMDAgTDQ1MCw2MDAiIHN0cm9rZT0iI2RkZGRkZCIgc3Ryb2tlLXdpZHRoPSIxNSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+CiAgPHBhdGggZD0iTTM1MCw1MCBMIDM1MCw2NTAiIHN0cm9rZT0iI2RkZGRkZCIgc3Ryb2tlLXdpZHRoPSIyMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+CiAgCiAgPCEtLSBQYXJrcyAtLT4KICA8Y2lyY2xlIGN4PSIyMDAiIGN5PSIyMDAiIHI9IjQwIiBmaWxsPSIjYzdmOWNjIi8+CiAgPGNpcmNsZSBjeD0iNTAwIiBjeT0iNDAwIiByPSI2MCIgZmlsbD0iI2M3ZjljYyIvPgogIDxjaXJjbGUgY3g9IjMwMCIgY3k9IjUwMCIgcj0iMzUiIGZpbGw9IiNjN2Y5Y2MiLz4KICAKICA8IS0tIEJ1aWxkaW5ncyAtLT4KICA8cmVjdCB4PSIxNjAiIHk9IjM0MCIgd2lkdGg9IjQwIiBoZWlnaHQ9IjQwIiBmaWxsPSIjYjFhN2E2IiAvPgogIDxyZWN0IHg9IjQwMCIgeT0iMTYwIiB3aWR0aD0iODAiIGhlaWdodD0iNDAiIGZpbGw9IiNiMWE3YTYiIC8+CiAgPHJlY3QgeD0iNDgwIiB5PSIyMjAiIHdpZHRoPSI2MCIgaGVpZ2h0PSI2MCIgZmlsbD0iI2IxYTdhNiIgLz4KICA8cmVjdCB4PSIyMDAiIHk9IjQyMCIgd2lkdGg9IjUwIiBoZWlnaHQ9IjUwIiBmaWxsPSIjYjFhN2E2IiAvPgogIDxyZWN0IHg9IjUwMCIgeT0iNTAwIiB3aWR0aD0iNzAiIGhlaWdodD0iMzAiIGZpbGw9IiNiMWE3YTYiIC8+CiAgCiAgPCEtLSBXYXRlciAtLT4KICA8cGF0aCBkPSJNMTAwLDYwMCBMNjAwLDYwMCBMNjAwLDY1MCBMMTAwLDY1MCBaIiBmaWxsPSIjYTllM2ZhIiAvPgogIDxjaXJjbGUgY3g9IjEwMCIgY3k9IjEwMCIgcj0iNTAiIGZpbGw9IiNhOWUzZmEiIC8+Cjwvc3ZnPg==') no-repeat center center; background-size: cover; position: relative; transition: transform 0.5s ease-out; transform-origin: center; } .overlay { position: absolute; top: 0; left: 0; right: 0; bottom: 0; pointer-events: none; } .controls { position: absolute; bottom: 20px; left: 20px; z-index: 10; display: flex; flex-direction: column; gap: 10px; } .zoom-controls { display: flex; flex-direction: column; background: rgba(255, 255, 255, 0.95); border-radius: 8px; overflow: hidden; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); } .zoom-btn { border: none; background: none; font-size: 1.4rem; padding: 8px 15px; cursor: pointer; color: var(--dark-color); transition: all 0.2s ease; } .zoom-btn:hover { background-color: var(--primary-color); color: white; } .legend { background: rgba(255, 255, 255, 0.95); border-radius: 8px; padding: 10px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); } .legend h3 { font-size: 0.9rem; margin-bottom: 8px; color: var(--dark-color); } .legend-item { display: flex; align-items: center; margin-bottom: 5px; font-size: 0.8rem; color: var(--text-color); } .legend-color { width: 12px; height: 12px; border-radius: 2px; margin-right: 8px; } .direction-arrow { position: absolute; width: 40px; height: 40px; background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); border-radius: 50%; display: flex; justify-content: center; align-items: center; color: white; cursor: pointer; transform: scale(1); transition: transform 0.3s ease, box-shadow 0.3s ease; box-shadow: 0 3px 8px rgba(0, 0, 0, 0.2); z-index: 5; } .direction-arrow::before { content: ''; position: absolute; width: 100%; height: 100%; background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); border-radius: 50%; opacity: 0; transform: scale(1); z-index: -1; transition: transform 0.5s ease, opacity 0.5s ease; } .direction-arrow:hover { transform: scale(1.1); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); } .direction-arrow:hover::before { opacity: 0.5; transform: scale(1.5); animation: pulseWave 1.5s ease-out infinite; } .direction-arrow i { font-size: 1.2rem; } .arrow-north { top: 20px; left: 50%; transform: translateX(-50%); } .arrow-east { top: 50%; right: 20px; transform: translateY(-50%); } .arrow-south { bottom: 20px; left: 50%; transform: translateX(-50%); } .arrow-west { top: 50%; left: 20px; transform: translateY(-50%); } .popup { position: absolute; background: white; border-radius: 8px; padding: 15px; box-shadow: 0 5px 20px rgba(0, 0, 0, 0.15); max-width: 250px; z-index: 20; opacity: 0; pointer-events: none; transition: opacity 0.3s ease, transform 0.3s ease; transform: translateY(10px); } .popup.show { opacity: 1; pointer-events: auto; transform: translateY(0); } .popup h3 { margin-bottom: 10px; color: var(--dark-color); border-bottom: 2px solid var(--primary-color); padding-bottom: 5px; font-size: 1rem; } .popup p { font-size: 0.9rem; color: var(--text-color); margin-bottom: 10px; line-height: 1.4; } .popup-close { position: absolute; top: 8px; right: 8px; background: none; border: none; font-size: 1rem; cursor: pointer; color: var(--dark-color); opacity: 0.7; transition: opacity 0.2s; } .popup-close:hover { opacity: 1; } .popup-action { display: inline-block; background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); color: white; padding: 6px 12px; border-radius: 4px; text-decoration: none; font-size: 0.85rem; font-weight: 500; cursor: pointer; transition: all 0.2s ease; } .popup-action:hover { transform: translateY(-2px); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.2); } .poi { position: absolute; width: 20px; height: 20px; background: var(--accent-color); border-radius: 50%; cursor: pointer; transform: scale(1); transition: transform 0.3s ease; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); z-index: 4; } .poi::after { content: ''; position: absolute; width: 10px; height: 10px; background: white; border-radius: 50%; top: 50%; left: 50%; transform: translate(-50%, -50%); } .poi:hover { transform: scale(1.2); } .search-bar { position: absolute; top: 20px; left: 50%; transform: translateX(-50%); z-index: 10; width: 80%; max-width: 350px; } .search-input { width: 100%; padding: 12px 20px; border: none; border-radius: 30px; background: white; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); font-size: 0.9rem; color: var(--text-color); transition: all 0.3s ease; } .search-input:focus { outline: none; box-shadow: 0 4px 15px rgba(58, 134, 255, 0.3); } .search-input::placeholder { color: #a8a8a8; } @keyframes pulseWave { 0% { transform: scale(1); opacity: 0.7; } 100% { transform: scale(2); opacity: 0; } } .compass { position: absolute; top: 20px; right: 20px; width: 60px; height: 60px; background: white; border-radius: 50%; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); display: flex; justify-content: center; align-items: center; z-index: 10; } .compass-inner { width: 70%; height: 70%; background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); border-radius: 50%; position: relative; display: flex; justify-content: center; align-items: center; } .compass-needle { position: absolute; width: 2px; height: 70%; background: white; transform-origin: center; transition: transform 0.5s ease; } .compass-needle::before { content: ''; position: absolute; top: 0; left: 50%; transform: translateX(-50%); width: 0; height: 0; border-left: 5px solid transparent; border-right: 5px solid transparent; border-bottom: 10px solid var(--accent-color); } .compass-center { width: 10px; height: 10px; background: white; border-radius: 50%; z-index: 1; } /* Responsive Adjustments */ @media (max-width: 600px) { .direction-arrow { width: 35px; height: 35px; } .compass { width: 50px; height: 50px; } .search-bar { width: 90%; } .controls { bottom: 15px; left: 15px; } .zoom-btn { padding: 6px 12px; font-size: 1.2rem; } .legend { padding: 8px; } .legend h3 { font-size: 0.8rem; } .legend-item { font-size: 0.7rem; } } </style> </head> <body> <div class="map-container"> <div class="map" id="map"> <!-- Points of Interest --> <div class="poi" style="top: 200px; left: 200px;" data-name="Central Park" data-description="A tranquil urban oasis with scenic walking paths and recreational facilities."></div> <div class="poi" style="top: 400px; left: 500px;" data-name="Riverside Gardens" data-description="Beautiful waterfront park featuring seasonal flowers and riverside walking trails."></div> <div class="poi" style="top: 160px; left: 400px;" data-name="Museum Quarter" data-description="Cultural district hosting the city's finest art and historical exhibitions."></div> <div class="poi" style="top: 420px; left: 200px;" data-name="Historic District" data-description="Well-preserved neighborhood showcasing the city's architectural heritage."></div> <div class="poi" style="top: 500px; left: 500px;" data-name="Tech Hub" data-description="Modern business district with innovation centers and tech startups."></div> </div> <!-- Direction Arrows --> <div class="overlay"> <div class="direction-arrow arrow-north" data-direction="north"> <i>↑</i> </div> <div class="direction-arrow arrow-east" data-direction="east"> <i>→</i> </div> <div class="direction-arrow arrow-south" data-direction="south"> <i>↓</i> </div> <div class="direction-arrow arrow-west" data-direction="west"> <i>←</i> </div> </div> <!-- UI Elements --> <div class="search-bar"> <input type="text" class="search-input" placeholder="Search locations, landmarks..." id="search-input"> </div> <div class="compass"> <div class="compass-inner"> <div class="compass-needle" id="compass-needle"></div> <div class="compass-center"></div> </div> </div> <div class="controls"> <div class="zoom-controls"> <button class="zoom-btn" id="zoom-in">+</button> <button class="zoom-btn" id="zoom-out">−</button> </div> <div class="legend"> <h3>Map Legend</h3> <div class="legend-item"> <div class="legend-color" style="background: #c7f9cc;"></div> <span>Parks & Green Spaces</span> </div> <div class="legend-item"> <div class="legend-color" style="background: #b1a7a6;"></div> <span>Buildings</span> </div> <div class="legend-item"> <div class="legend-color" style="background: #a9e3fa;"></div> <span>Water Bodies</span> </div> <div class="legend-item"> <div class="legend-color" style="background: var(--accent-color);"></div> <span>Points of Interest</span> </div> </div> </div> <!-- Information Popup --> <div class="popup" id="info-popup"> <button class="popup-close" id="popup-close">×</button> <h3 id="popup-title">Location Name</h3> <p id="popup-description">Description goes here.</p> <div class="popup-action" id="popup-action">Explore Area</div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Map Variables const map = document.getElementById('map'); const zoomInBtn = document.getElementById('zoom-in'); const zoomOutBtn = document.getElementById('zoom-out'); const compassNeedle = document.getElementById('compass-needle'); const popup = document.getElementById('info-popup'); const popupTitle = document.getElementById('popup-title'); const popupDescription = document.getElementById('popup-description'); const popupClose = document.getElementById('popup-close'); const searchInput = document.getElementById('search-input'); const pois = document.querySelectorAll('.poi'); const directionArrows = document.querySelectorAll('.direction-arrow'); // Map State let currentScale = 1; let isDragging = false; let startPos = { x: 0, y: 0 }; let currentPos = { x: 0, y: 0 }; let rotation = 0; // Zoom Functions zoomInBtn.addEventListener('click', () => { if (currentScale < 2) { currentScale += 0.2; updateMapTransform(); } }); zoomOutBtn.addEventListener('click', () => { if (currentScale > 0.8) { currentScale -= 0.2; updateMapTransform(); } }); // Direction Arrow Navigation directionArrows.forEach(arrow => { arrow.addEventListener('click', () => { const direction = arrow.getAttribute('data-direction'); let moveX = 0; let moveY = 0; const moveAmount = 100; switch(direction) { case 'north': moveY = moveAmount; break; case 'east': moveX = -moveAmount; break; case 'south': moveY = -moveAmount; break; case 'west': moveX = moveAmount; break; } currentPos.x += moveX; currentPos.y += moveY; updateMapTransform(); }); }); // Update Map Transform function updateMapTransform() { const limitedX = limitPan(currentPos.x, window.innerWidth, currentScale); const limitedY = limitPan(currentPos.y, window.innerHeight, currentScale); currentPos.x = limitedX; currentPos.y = limitedY; map.style.transform = `translate(${limitedX}px, ${limitedY}px) scale(${currentScale}) rotate(${rotation}deg)`; compassNeedle.style.transform = `rotate(${-rotation}deg)`; } function limitPan(position, size, scale) { const margin = 100; // Limit how far you can pan const maxPan = size * (scale - 1) + margin; return Math.min(Math.max(position, -maxPan), maxPan); } // Map Dragging map.addEventListener('mousedown', (e) => { isDragging = true; startPos = { x: e.clientX - currentPos.x, y: e.clientY - currentPos.y }; map.style.cursor = 'grabbing'; }); document.addEventListener('mousemove', (e) => { if (!isDragging) return; currentPos = { x: e.clientX - startPos.x, y: e.clientY - startPos.y }; updateMapTransform(); }); document.addEventListener('mouseup', () => { isDragging = false; map.style.cursor = 'grab'; }); // Point of Interest Interaction pois.forEach(poi => { poi.addEventListener('click', (e) => { e.stopPropagation(); const name = poi.getAttribute('data-name'); const description = poi.getAttribute('data-description'); popupTitle.textContent = name; popupDescription.textContent = description; // Position popup near the POI const poiRect = poi.getBoundingClientRect(); const mapRect = map.getBoundingClientRect(); popup.style.top = `${poiRect.top - mapRect.top + 30}px`; popup.style.left = `${poiRect.left - mapRect.left}px`; popup.classList.add('show'); }); }); // Close popup popupClose.addEventListener('click', () => { popup.classList.remove('show'); }); // Rotate compass interaction document.querySelector('.compass').addEventListener('click', () => { rotation = (rotation + 45) % 360; updateMapTransform(); }); // Search functionality searchInput.addEventListener('keyup', (e) => { if (e.key === 'Enter') { const searchTerm = searchInput.value.toLowerCase(); if (searchTerm.trim() === '') return; // Find matching POI let foundPoi = null; pois.forEach(poi => { const poiName = poi.getAttribute('data-name').toLowerCase(); if (poiName.includes(searchTerm)) { foundPoi = poi; } }); if (foundPoi) { // Center map on found POI const poiRect = foundPoi.getBoundingClientRect(); const mapRect = map.getBoundingClientRect(); // Calculate center position const centerX = mapRect.width / 2; const centerY = mapRect.height / 2; // Update position to center on POI currentPos.x = centerX - (poiRect.left - mapRect.left) - poiRect.width / 2; currentPos.y = centerY - (poiRect.top - mapRect.top) - poiRect.height / 2; // Highlight with animation foundPoi.style.transform = 'scale(1.5)'; foundPoi.style.boxShadow = '0 0 15px var(--accent-color)'; // Reset highlight after delay setTimeout(() => { foundPoi.style.transform = 'scale(1)'; foundPoi.style.boxShadow = '0 2px 5px rgba(0, 0, 0, 0.2)'; }, 1500); // Update transform with a zoom in effect currentScale = 1.5; updateMapTransform(); // Display popup for the found location setTimeout(() => { const clickEvent = new Event('click'); foundPoi.dispatchEvent(clickEvent); }, 300); } else { // Show not found effect on search input searchInput.classList.add('error'); searchInput.style.boxShadow = '0 4px 15px rgba(255, 0, 110, 0.3)'; setTimeout(() => { searchInput.classList.remove('error'); searchInput.style.boxShadow = ''; }, 1000); } searchInput.value = ''; } }); // Popup explore action document.getElementById('popup-action').addEventListener('click', () => { // Simulate exploring by zooming in more if (currentScale < 1.8) { currentScale += 0.3; updateMapTransform(); } popup.classList.remove('show'); }); // Touch support for mobile map.addEventListener('touchstart', (e) => { isDragging = true; startPos = { x: e.touches[0].clientX - currentPos.x, y: e.touches[0].clientY - currentPos.y }; }); document.addEventListener('touchmove', (e) => { if (!isDragging) return; currentPos = { x: e.touches[0].clientX - startPos.x, y: e.touches[0].clientY - startPos.y }; updateMapTransform(); }); document.addEventListener('touchend', () => { isDragging = false; }); // Initial setup updateMapTransform(); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Form Step Navigator</title> <style> :root { --primary: #a4d4dc; --primary-hover: #8ecbd5; --secondary: #ffd6e0; --tertiary: #ffefbd; --accent: #c5a3ff; --text: #4a5568; --text-light: #718096; --background: #f9fafb; --success: #9ae6b4; --error: #feb2b2; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', 'Roboto', sans-serif; } body { width: 100%; height: 100vh; background-color: var(--background); display: flex; justify-content: center; align-items: center; overflow: hidden; color: var(--text); padding: 20px; } .container { width: 100%; max-width: 650px; background: white; border-radius: 16px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08); overflow: hidden; position: relative; } .form-header { padding: 24px; background: linear-gradient(135deg, var(--primary) 0%, var(--accent) 100%); color: white; text-align: center; position: relative; } .form-header h1 { font-size: 1.5rem; margin-bottom: 8px; font-weight: 600; } .form-header p { font-size: 0.9rem; opacity: 0.9; } .form-body { padding: 30px; position: relative; } .steps-container { display: flex; justify-content: space-between; margin-bottom: 30px; position: relative; } .step-line { position: absolute; top: 25px; left: 10%; right: 10%; height: 3px; background-color: #e2e8f0; z-index: 1; } .progress-line { position: absolute; top: 25px; left: 10%; width: 0%; height: 3px; background-color: var(--primary); z-index: 2; transition: width 0.5s ease; } .step { width: 50px; text-align: center; z-index: 3; position: relative; } .step-circle { width: 50px; height: 50px; border-radius: 50%; background-color: #e2e8f0; display: flex; justify-content: center; align-items: center; margin: 0 auto; color: var(--text-light); font-weight: 600; position: relative; transition: all 0.3s ease; } .step.active .step-circle { background-color: var(--primary); color: white; transform: scale(1.1); box-shadow: 0 4px 10px rgba(164, 212, 220, 0.4); } .step.completed .step-circle { background-color: var(--primary); color: white; } .step.completed .step-circle::after { content: '✓'; position: absolute; font-size: 1.2rem; } .step-label { margin-top: 8px; font-size: 0.75rem; color: var(--text-light); transition: color 0.3s ease; } .step.active .step-label { color: var(--text); font-weight: 600; } .step-content { display: none; animation: fadeIn 0.5s ease forwards; } .step-content.active { display: block; } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .form-group { margin-bottom: 20px; } .form-group label { display: block; margin-bottom: 6px; font-size: 0.9rem; color: var(--text); } .form-input { width: 100%; padding: 12px 16px; border: 2px solid #e2e8f0; border-radius: 8px; font-size: 0.95rem; transition: all 0.3s ease; color: var(--text); } .form-input:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px rgba(164, 212, 220, 0.3); } .form-select { width: 100%; padding: 12px 16px; border: 2px solid #e2e8f0; border-radius: 8px; font-size: 0.95rem; transition: all 0.3s ease; color: var(--text); background-color: white; cursor: pointer; appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%234a5568' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 16px center; } .form-select:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px rgba(164, 212, 220, 0.3); } .radio-group { display: flex; flex-wrap: wrap; gap: 12px; } .radio-option { flex: 1; min-width: 120px; } .radio-option input[type="radio"] { display: none; } .radio-option label { display: block; padding: 12px 16px; border: 2px solid #e2e8f0; border-radius: 8px; text-align: center; cursor: pointer; transition: all 0.3s ease; } .radio-option input[type="radio"]:checked + label { border-color: var(--primary); background-color: rgba(164, 212, 220, 0.1); color: var(--primary); font-weight: 600; } .checkbox-group { margin-top: 10px; } .checkbox-option { display: flex; align-items: center; margin-bottom: 10px; } .checkbox-option input[type="checkbox"] { margin-right: 10px; width: 18px; height: 18px; accent-color: var(--primary); } .form-navigation { display: flex; justify-content: space-between; margin-top: 30px; } .btn { padding: 12px 24px; border: none; border-radius: 8px; cursor: pointer; font-size: 0.95rem; font-weight: 600; transition: all 0.3s ease; display: flex; align-items: center; justify-content: center; gap: 8px; } .btn-prev { background-color: white; color: var(--text); border: 2px solid #e2e8f0; } .btn-prev:hover { border-color: var(--primary); color: var(--primary); transform: scale(1.02); } .btn-next, .btn-submit { background-color: var(--primary); color: white; } .btn-next:hover, .btn-submit:hover { background-color: var(--primary-hover); transform: scale(1.02); box-shadow: 0 4px 10px rgba(164, 212, 220, 0.4); } .btn-submit { position: relative; overflow: hidden; } .btn-submit.loading::before { content: ''; position: absolute; width: 100%; height: 3px; background: linear-gradient(to right, transparent, white, transparent); top: 0; left: -100%; animation: loading 1.5s infinite linear; } @keyframes loading { 0% { left: -100%; } 100% { left: 100%; } } .hidden { display: none; } .status-message { text-align: center; padding: 20px; border-radius: 8px; margin-bottom: 20px; display: none; } .success-message { background-color: var(--success); color: #276749; } .error-message { background-color: var(--error); color: #9b2c2c; } .confetti { position: absolute; width: 10px; height: 10px; opacity: 0; pointer-events: none; } /* Responsive styles */ @media (max-width: 600px) { .container { width: 100%; border-radius: 12px; } .form-body { padding: 20px; } .step-circle { width: 40px; height: 40px; font-size: 0.85rem; } .step-label { font-size: 0.7rem; } .form-header h1 { font-size: 1.3rem; } .btn { padding: 10px 16px; font-size: 0.85rem; } } /* Thank you screen */ .thank-you { text-align: center; padding: 40px 20px; display: none; } .thank-you svg { width: 80px; height: 80px; margin-bottom: 20px; color: var(--primary); } .thank-you h2 { margin-bottom: 15px; color: var(--text); } .thank-you p { margin-bottom: 25px; color: var(--text-light); } /* Floating shapes animation */ .shapes-container { position: absolute; width: 100%; height: 100%; overflow: hidden; top: 0; left: 0; z-index: 0; pointer-events: none; } .shape { position: absolute; z-index: -1; opacity: 0.4; } .shape1 { top: 10%; left: 10%; width: 50px; height: 50px; border-radius: 50%; background: var(--secondary); animation: float 8s ease-in-out infinite; } .shape2 { top: 20%; right: 10%; width: 40px; height: 40px; background: var(--tertiary); transform: rotate(45deg); animation: float 10s ease-in-out infinite 1s; } .shape3 { bottom: 15%; left: 15%; width: 35px; height: 35px; background: var(--accent); border-radius: 5px; animation: float 7s ease-in-out infinite 2s; } @keyframes float { 0% { transform: translateY(0) rotate(0deg); } 50% { transform: translateY(-20px) rotate(10deg); } 100% { transform: translateY(0) rotate(0deg); } } </style> </head> <body> <div class="container"> <div class="shapes-container"> <div class="shape shape1"></div> <div class="shape shape2"></div> <div class="shape shape3"></div> </div> <div class="form-header"> <h1>Travel Preferences Questionnaire</h1> <p>Help us create your perfect travel experience</p> </div> <div class="form-body"> <div class="steps-container"> <div class="step-line"></div> <div class="progress-line"></div> <div class="step active" data-step="1"> <div class="step-circle">1</div> <div class="step-label">Basic Info</div> </div> <div class="step" data-step="2"> <div class="step-circle">2</div> <div class="step-label">Preferences</div> </div> <div class="step" data-step="3"> <div class="step-circle">3</div> <div class="step-label">Activities</div> </div> <div class="step" data-step="4"> <div class="step-circle">4</div> <div class="step-label">Finalize</div> </div> </div> <div id="status" class="status-message"></div> <div class="step-content active" data-step="1"> <h2>Tell us about yourself</h2> <p>We'll use this information to personalize your travel experience</p> <div class="form-group"> <label for="fullname">Full Name</label> <input type="text" id="fullname" class="form-input" placeholder="Enter your full name"> </div> <div class="form-group"> <label for="email">Email Address</label> <input type="email" id="email" class="form-input" placeholder="[email protected]"> </div> <div class="form-group"> <label>Travel Experience Level</label> <div class="radio-group"> <div class="radio-option"> <input type="radio" id="beginner" name="experience" value="beginner"> <label for="beginner">Novice</label> </div> <div class="radio-option"> <input type="radio" id="intermediate" name="experience" value="intermediate"> <label for="intermediate">Intermediate</label> </div> <div class="radio-option"> <input type="radio" id="expert" name="experience" value="expert"> <label for="expert">Seasoned</label> </div> </div> </div> </div> <div class="step-content" data-step="2"> <h2>Travel Preferences</h2> <p>Help us understand what makes your ideal trip</p> <div class="form-group"> <label for="destination">Preferred Continent</label> <select id="destination" class="form-select"> <option value="" selected disabled>Select continent</option> <option value="europe">Europe</option> <option value="asia">Asia</option> <option value="north-america">North America</option> <option value="south-america">South America</option> <option value="africa">Africa</option> <option value="oceania">Oceania</option> <option value="antarctica">Antarctica</option> </select> </div> <div class="form-group"> <label for="duration">Trip Duration</label> <select id="duration" class="form-select"> <option value="" selected disabled>Select duration</option> <option value="weekend">Weekend Getaway (1-3 days)</option> <option value="short">Short Trip (4-7 days)</option> <option value="medium">Medium Trip (8-14 days)</option> <option value="long">Extended Journey (15+ days)</option> </select> </div> <div class="form-group"> <label>Accommodation Style</label> <div class="radio-group"> <div class="radio-option"> <input type="radio" id="luxury" name="accommodation" value="luxury"> <label for="luxury">Luxury</label> </div> <div class="radio-option"> <input type="radio" id="mid-range" name="accommodation" value="mid-range"> <label for="mid-range">Mid-range</label> </div> <div class="radio-option"> <input type="radio" id="budget" name="accommodation" value="budget"> <label for="budget">Budget</label> </div> </div> </div> </div> <div class="step-content" data-step="3"> <h2>Activity Preferences</h2> <p>Select the activities you enjoy while traveling</p> <div class="form-group"> <div class="checkbox-group"> <div class="checkbox-option"> <input type="checkbox" id="cultural" name="activities" value="cultural"> <label for="cultural">Cultural Experiences (museums, historical sites)</label> </div> <div class="checkbox-option"> <input type="checkbox" id="nature" name="activities" value="nature"> <label for="nature">Nature & Outdoor Activities</label> </div> <div class="checkbox-option"> <input type="checkbox" id="food" name="activities" value="food"> <label for="food">Culinary Experiences</label> </div> <div class="checkbox-option"> <input type="checkbox" id="adventure" name="activities" value="adventure"> <label for="adventure">Adventure Sports</label> </div> <div class="checkbox-option"> <input type="checkbox" id="relaxation" name="activities" value="relaxation"> <label for="relaxation">Relaxation & Wellness</label> </div> </div> </div> <div class="form-group"> <label for="special-interests">Any specific activities you're particularly interested in?</label> <input type="text" id="special-interests" class="form-input" placeholder="e.g., Scuba diving, wine tasting, cooking classes..."> </div> </div> <div class="step-content" data-step="4"> <h2>Almost Done!</h2> <p>Just a few final details to perfect your experience</p> <div class="form-group"> <label for="budget">Approximate Budget per Person</label> <select id="budget" class="form-select"> <option value="" selected disabled>Select budget range</option> <option value="economy">Economy ($1,000 - $2,500)</option> <option value="standard">Standard ($2,500 - $5,000)</option> <option value="premium">Premium ($5,000 - $10,000)</option> <option value="luxury">Luxury ($10,000+)</option> </select> </div> <div class="form-group"> <label for="travel-companions">Who will you be traveling with?</label> <select id="travel-companions" class="form-select"> <option value="" selected disabled>Select option</option> <option value="solo">Solo Adventure</option> <option value="partner">With Partner</option> <option value="family">Family with Children</option> <option value="friends">Group of Friends</option> </select> </div> <div class="form-group"> <div class="checkbox-option"> <input type="checkbox" id="newsletter" name="newsletter" value="yes"> <label for="newsletter">Send me personalized travel recommendations</label> </div> </div> </div> <div class="thank-you"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path> <polyline points="22 4 12 14.01 9 11.01"></polyline> </svg> <h2>Thank You!</h2> <p>Your preferences have been saved. We'll craft the perfect travel experience based on your inputs.</p> <button id="restart-form" class="btn btn-next">Start Another Questionnaire</button> </div> <div class="form-navigation"> <button id="prev-btn" class="btn btn-prev hidden"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <line x1="19" y1="12" x2="5" y2="12"></line> <polyline points="12 19 5 12 12 5"></polyline> </svg> Previous </button> <button id="next-btn" class="btn btn-next"> Next <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <line x1="5" y1="12" x2="19" y2="12"></line> <polyline points="12 5 19 12 12 19"></polyline> </svg> </button> <button id="submit-btn" class="btn btn-submit hidden"> Submit <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path> <polyline points="22 4 12 14.01 9 11.01"></polyline> </svg> </button> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const steps = document.querySelectorAll('.step'); const stepContents = document.querySelectorAll('.step-content'); const prevBtn = document.getElementById('prev-btn'); const nextBtn = document.getElementById('next-btn'); const submitBtn = document.getElementById('submit-btn'); const restartBtn = document.getElementById('restart-form'); const progressLine = document.querySelector('.progress-line'); const thankYouScreen = document.querySelector('.thank-you'); const statusMessage = document.getElementById('status'); let currentStep = 1; const totalSteps = steps.length; // Initialize updateButtons(); updateProgressLine(); // Step hover effect with subtle scale steps.forEach(step => { step.addEventListener('mouseenter', function() { if (!this.classList.contains('active')) { const circle = this.querySelector('.step-circle'); circle.style.transform = 'scale(1.05)'; } }); step.addEventListener('mouseleave', function() { if (!this.classList.contains('active')) { const circle = this.querySelector('.step-circle'); circle.style.transform = 'scale(1)'; } }); }); // Next button click handler nextBtn.addEventListener('click', function() { if (currentStep < totalSteps) { if (validateStep(currentStep)) { goToStep(currentStep + 1); } } }); // Previous button click handler prevBtn.addEventListener('click', function() { if (currentStep > 1) { goToStep(currentStep - 1); } }); // Submit button click handler submitBtn.addEventListener('click', function() { if (validateStep(currentStep)) { // Add loading state submitBtn.classList.add('loading'); submitBtn.disabled = true; // Simulate form submission setTimeout(() => { submitBtn.classList.remove('loading'); submitBtn.disabled = false; // Hide form and show thank you message document.querySelector('.steps-container').style.display = 'none'; document.querySelector('.form-navigation').style.display = 'none'; stepContents.forEach(content => content.style.display = 'none'); thankYouScreen.style.display = 'block'; // Create confetti celebration effect createConfetti(); }, 1500); } }); // Restart form button restartBtn.addEventListener('click', function() { // Reset form document.querySelector('.steps-container').style.display = 'flex'; document.querySelector('.form-navigation').style.display = 'flex'; thankYouScreen.style.display = 'none'; // Clear all inputs document.querySelectorAll('input').forEach(input => { if (input.type === 'text' || input.type === 'email') { input.value = ''; } else if (input.type === 'radio' || input.type === 'checkbox') { input.checked = false; } }); document.querySelectorAll('select').forEach(select => { select.selectedIndex = 0; }); // Go back to step 1 goToStep(1); }); // Function to navigate to a specific step function goToStep(stepNumber) { // Hide current step content document.querySelector(`.step-content[data-step="${currentStep}"]`).classList.remove('active'); document.querySelector(`.step[data-step="${currentStep}"]`).classList.remove('active'); // Mark previous steps as completed if (stepNumber > currentStep) { document.querySelector(`.step[data-step="${currentStep}"]`).classList.add('completed'); } // Update current step currentStep = stepNumber; // Show new step content document.querySelector(`.step-content[data-step="${currentStep}"]`).classList.add('active'); document.querySelector(`.step[data-step="${currentStep}"]`).classList.add('active'); // Remove completed class if going backwards for (let i = currentStep; i <= totalSteps; i++) { document.querySelector(`.step[data-step="${i}"]`).classList.remove('completed'); } // Update UI updateButtons(); updateProgressLine(); // Hide status message when changing steps statusMessage.style.display = 'none'; } // Update the navigation buttons based on current step function updateButtons() { if (currentStep === 1) { prevBtn.classList.add('hidden'); } else { prevBtn.classList.remove('hidden'); } if (currentStep === totalSteps) { nextBtn.classList.add('hidden'); submitBtn.classList.remove('hidden'); } else { nextBtn.classList.remove('hidden'); submitBtn.classList.add('hidden'); } } // Update progress line function updateProgressLine() { const progressPercentage = ((currentStep - 1) / (totalSteps - 1)) * 100; progressLine.style.width = `${progressPercentage}%`; } // Validate step fields function validateStep(step) { let isValid = true; const stepContent = document.querySelector(`.step-content[data-step="${step}"]`); // Very simple validation - just checking if required fields have values // In a real application, you'd want more robust validation if (step === 1) { const fullname = document.getElementById('fullname').value; const email = document.getElementById('email').value; if (!fullname || !email) { showError("Please fill in all required fields"); isValid = false; } } else if (step === 4) { // Check at least one option in step 4 const budget = document.getElementById('budget').value; if (!budget) { showError("Please select a budget range"); isValid = false; } } return isValid; } function showError(message) { statusMessage.textContent = message; statusMessage.className = 'status-message error-message'; statusMessage.style.display = 'block'; // Auto-hide the message after 3 seconds setTimeout(() => { statusMessage.style.display = 'none'; }, 3000); } // Create confetti celebration effect function createConfetti() { const colors = [ 'var(--primary)', 'var(--secondary)', 'var(--tertiary)', 'var(--accent)' ]; for (let i = 0; i < 100; i++) { const confetti = document.createElement('div'); confetti.className = 'confetti'; confetti.style.left = Math.random() * 100 + '%'; confetti.style.top = -20 + 'px'; confetti.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)]; confetti.style.transform = `rotate(${Math.random() * 360}deg)`; document.body.appendChild(confetti); // Animate the confetti const animation = confetti.animate([ { top: '-20px', opacity: 1, transform: `rotate(0deg) translateX(0)` }, { top: '100vh', opacity: 0, transform: `rotate(${Math.random() * 720}deg) translateX(${Math.random() * 200 - 100}px)` } ], { duration: 1500 + Math.random() * 3000, easing: 'cubic-bezier(0.215, 0.61, 0.355, 1)' }); animation.onfinish = () => confetti.remove(); } } // Enable clicking on step circles for navigation (only to completed steps) steps.forEach(step => { step.addEventListener('click', function() { const stepNumber = parseInt(this.getAttribute('data-step')); // Allow clicking only on completed steps or the next immediate step if (stepNumber < currentStep || stepNumber === currentStep + 1) { goToStep(stepNumber); } }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Mobile Dashboard Menu Toggle</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: #f8f9fa; display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; padding: 20px; overflow-x: hidden; } .dashboard-container { width: 100%; max-width: 600px; background: #ffffff; border-radius: 16px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08); overflow: hidden; position: relative; } .dashboard-header { padding: 20px; background: linear-gradient(135deg, #6b5ce7, #8075e5); color: white; display: flex; justify-content: space-between; align-items: center; } .dashboard-header h1 { font-size: 1.5rem; font-weight: 600; } .menu-toggle { display: flex; align-items: center; gap: 8px; background: none; border: none; color: white; font-weight: 500; cursor: pointer; padding: 8px 12px; border-radius: 8px; transition: all 0.3s; position: relative; outline: none; } .menu-toggle:hover { background: rgba(255, 255, 255, 0.15); } .menu-toggle:focus-visible { box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.3); } .menu-toggle .toggle-text { font-size: 1rem; } .arrow-container { position: relative; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; } .arrow { position: relative; width: 16px; height: 16px; display: flex; align-items: center; justify-content: center; transform-origin: center; transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); } .arrow::before, .arrow::after { content: ''; position: absolute; width: 10px; height: 2px; background-color: white; border-radius: 1px; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); transition: all 0.3s; } .arrow::before { transform: rotate(45deg); left: 1px; } .arrow::after { transform: rotate(-45deg); right: 1px; } .menu-open .arrow { transform: rotate(180deg); } .menu-open .arrow::before, .menu-open .arrow::after { width: 10px; } .ripple { position: absolute; border-radius: 50%; background-color: rgba(255, 255, 255, 0.3); transform: scale(0); animation: ripple 0.6s ease-out; } @keyframes ripple { to { transform: scale(2.5); opacity: 0; } } .menu-container { height: 0; overflow: hidden; transition: height 0.4s cubic-bezier(0.4, 0, 0.2, 1); } .menu { padding: 10px 0; list-style: none; } .menu-item { padding: 0; margin-bottom: 5px; } .menu-link { display: flex; align-items: center; padding: 12px 20px; color: #4a5568; text-decoration: none; transition: all 0.3s; border-left: 3px solid transparent; position: relative; overflow: hidden; } .menu-link:hover { background-color: #f3f4f6; border-left-color: #6b5ce7; padding-left: 25px; } .menu-link:active { background-color: #e9eaec; } .menu-link .menu-icon { margin-right: 12px; background: linear-gradient(135deg, #6b5ce7, #8075e5); -webkit-background-clip: text; -webkit-text-fill-color: transparent; font-size: 1.2rem; } .menu-link .sub-arrow { margin-left: auto; width: 18px; height: 18px; position: relative; opacity: 0.6; transition: transform 0.3s, opacity 0.3s; } .menu-link:hover .sub-arrow { opacity: 1; transform: translateX(4px); } .menu-link .sub-arrow::before, .menu-link .sub-arrow::after { content: ''; position: absolute; width: 8px; height: 2px; background-color: #6b5ce7; border-radius: 1px; top: 50%; } .menu-link .sub-arrow::before { transform: rotate(45deg); right: 4px; } .menu-link .sub-arrow::after { transform: rotate(-45deg); right: 9px; } .dashboard-content { padding: 20px; text-align: center; } .dashboard-content h2 { color: #4a5568; margin-bottom: 16px; font-weight: 600; } .dashboard-content p { color: #718096; line-height: 1.6; margin-bottom: 20px; } .touch-hint { display: inline-block; background: linear-gradient(135deg, #6b5ce7, #8075e5); color: white; padding: 8px 16px; border-radius: 20px; font-size: 0.9rem; margin-top: 20px; box-shadow: 0 4px 12px rgba(107, 92, 231, 0.2); animation: pulse 2s infinite; } @keyframes pulse { 0% { transform: scale(1); box-shadow: 0 4px 12px rgba(107, 92, 231, 0.2); } 50% { transform: scale(1.05); box-shadow: 0 6px 16px rgba(107, 92, 231, 0.3); } 100% { transform: scale(1); box-shadow: 0 4px 12px rgba(107, 92, 231, 0.2); } } @media (max-width: 480px) { .dashboard-header h1 { font-size: 1.3rem; } } </style> </head> <body> <div class="dashboard-container"> <div class="dashboard-header"> <h1>Productivity Dashboard</h1> <button class="menu-toggle" id="menuToggle" aria-expanded="false" aria-controls="dashboardMenu"> <span class="toggle-text">Navigation</span> <div class="arrow-container"> <div class="arrow"></div> </div> </button> </div> <div class="menu-container" id="menuContainer"> <ul class="menu" id="dashboardMenu"> <li class="menu-item"> <a href="#" class="menu-link"> <span class="menu-icon">☵</span> Dashboard Overview <span class="sub-arrow"></span> </a> </li> <li class="menu-item"> <a href="#" class="menu-link"> <span class="menu-icon">⚒</span> Project Analytics <span class="sub-arrow"></span> </a> </li> <li class="menu-item"> <a href="#" class="menu-link"> <span class="menu-icon">✉</span> Message Center <span class="sub-arrow"></span> </a> </li> <li class="menu-item"> <a href="#" class="menu-link"> <span class="menu-icon">⚙</span> User Settings <span class="sub-arrow"></span> </a> </li> <li class="menu-item"> <a href="#" class="menu-link"> <span class="menu-icon">📊</span> Performance Metrics <span class="sub-arrow"></span> </a> </li> </ul> </div> <div class="dashboard-content"> <h2>Welcome to your Dashboard</h2> <p>This mobile-optimized menu uses directional arrows with bounce animations to provide clear feedback. The gradient material design delivers a modern interface that's intuitive and accessible.</p> <div class="touch-hint">Tap the menu button to explore</div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const menuToggle = document.getElementById('menuToggle'); const menuContainer = document.getElementById('menuContainer'); const menu = document.getElementById('dashboardMenu'); // Set initial height to 0 menuContainer.style.height = '0px'; function createRipple(event) { const button = event.currentTarget; const ripple = document.createElement('span'); const rect = button.getBoundingClientRect(); const size = Math.max(rect.width, rect.height); const x = event.clientX - rect.left - size / 2; const y = event.clientY - rect.top - size / 2; ripple.style.width = ripple.style.height = `${size}px`; ripple.style.left = `${x}px`; ripple.style.top = `${y}px`; ripple.classList.add('ripple'); button.appendChild(ripple); // Remove the ripple after animation completes setTimeout(() => { ripple.remove(); }, 600); } menuToggle.addEventListener('click', function(e) { createRipple(e); // Toggle menu visibility this.classList.toggle('menu-open'); const isExpanded = this.classList.contains('menu-open'); this.setAttribute('aria-expanded', isExpanded); // Toggle height if (isExpanded) { menuContainer.style.height = `${menu.offsetHeight}px`; } else { menuContainer.style.height = '0px'; } // Add bounce animation to arrow const arrow = this.querySelector('.arrow'); arrow.style.transform = isExpanded ? 'rotate(180deg) scale(1.2)' : 'rotate(0) scale(1.2)'; setTimeout(() => { arrow.style.transform = isExpanded ? 'rotate(180deg) scale(1)' : 'rotate(0) scale(1)'; }, 300); }); // Prevent form submission and page refresh on menu item clicks const menuLinks = document.querySelectorAll('.menu-link'); menuLinks.forEach(link => { link.addEventListener('click', function(e) { e.preventDefault(); // Add a subtle animation to indicate the click this.style.backgroundColor = '#e9eaec'; setTimeout(() => { this.style.backgroundColor = ''; }, 200); }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> :root { --primary: #3a7bd5; --secondary: #00d2ff; --dark: #1f3c6a; --light: #f8f9fa; --accent: #ff4d5a; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: #f1f5f9; display: flex; justify-content: center; align-items: center; height: 100%; padding: 20px; } .container { max-width: 700px; width: 100%; background: white; border-radius: 20px; overflow: hidden; box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1); position: relative; } .gallery-wrapper { position: relative; overflow: hidden; } .gallery { display: flex; transition: transform 0.5s cubic-bezier(0.25, 1, 0.5, 1); } .gallery-item { flex: 0 0 100%; height: 460px; position: relative; } .gallery-item img { width: 100%; height: 100%; object-fit: cover; display: block; } .product-tag { position: absolute; top: 20px; right: 20px; background: var(--accent); color: white; padding: 8px 16px; border-radius: 30px; font-weight: 600; letter-spacing: 0.5px; font-size: 0.875rem; box-shadow: 0 4px 12px rgba(255, 77, 90, 0.3); transform: translateY(0); transition: transform 0.3s ease; } .gallery-item:hover .product-tag { transform: translateY(-5px); } .controls { position: absolute; bottom: 30px; left: 0; right: 0; display: flex; justify-content: space-between; padding: 0 40px; z-index: 10; } .arrow { width: 60px; height: 60px; border-radius: 50%; background: linear-gradient(135deg, var(--primary), var(--secondary)); display: flex; justify-content: center; align-items: center; cursor: pointer; box-shadow: 0 6px 20px rgba(58, 123, 213, 0.3); transition: all 0.3s ease, transform 0.2s ease; position: relative; overflow: hidden; } .arrow:before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(135deg, rgba(255, 255, 255, 0.2), transparent); border-radius: 50%; opacity: 0; transition: opacity 0.3s ease; } .arrow:hover { transform: scale(1.1); box-shadow: 0 8px 25px rgba(58, 123, 213, 0.4); } .arrow:hover:before { opacity: 1; } .arrow:active { transform: scale(0.95) rotate(10deg); } .arrow svg { width: 24px; height: 24px; fill: white; transition: transform 0.3s ease; } .arrow.prev svg { transform: translateX(-2px); } .arrow.next svg { transform: translateX(2px); } .arrow:hover.prev svg { transform: translateX(-5px); } .arrow:hover.next svg { transform: translateX(5px); } .pagination { position: absolute; bottom: 20px; left: 0; right: 0; display: flex; justify-content: center; gap: 8px; } .dot { width: 8px; height: 8px; border-radius: 50%; background-color: rgba(255, 255, 255, 0.5); transition: all 0.3s ease; cursor: pointer; } .dot.active { width: 24px; border-radius: 4px; background-color: white; box-shadow: 0 0 10px rgba(255, 255, 255, 0.5); } .product-info { padding: 20px 30px 30px; } .product-title { font-size: 1.5rem; font-weight: 700; color: var(--dark); margin-bottom: 8px; line-height: 1.3; } .product-desc { font-size: 0.95rem; color: #64748b; line-height: 1.6; margin-bottom: 20px; } .product-price { display: flex; align-items: center; gap: 12px; margin-bottom: 20px; } .current-price { font-size: 1.5rem; font-weight: 700; color: var(--primary); } .old-price { font-size: 1rem; color: #94a3b8; text-decoration: line-through; } .discount { background-color: #ebf5ff; color: var(--primary); padding: 4px 10px; border-radius: 4px; font-size: 0.875rem; font-weight: 600; } @media (max-width: 600px) { .gallery-item { height: 380px; } .arrow { width: 50px; height: 50px; } .controls { padding: 0 20px; } .product-title { font-size: 1.25rem; } } /* Loading animation */ .loading-overlay { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(255, 255, 255, 0.8); display: flex; justify-content: center; align-items: center; z-index: 20; opacity: 1; transition: opacity 0.5s ease; } .loading-overlay.hidden { opacity: 0; pointer-events: none; } .loading-spinner { width: 40px; height: 40px; border: 3px solid var(--light); border-top-color: var(--primary); border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } /* Product colors */ .color-options { display: flex; gap: 10px; margin-bottom: 24px; } .color-option { width: 30px; height: 30px; border-radius: 50%; cursor: pointer; position: relative; transition: transform 0.3s ease; } .color-option::after { content: ''; position: absolute; top: -4px; left: -4px; right: -4px; bottom: -4px; border: 2px solid var(--primary); border-radius: 50%; opacity: 0; transition: opacity 0.3s ease; } .color-option.active::after { opacity: 1; } .color-option:hover { transform: scale(1.1); } .color-blue { background: linear-gradient(135deg, var(--primary), var(--secondary)); } .color-red { background: linear-gradient(135deg, #ff416c, #ff4b2b); } .color-green { background: linear-gradient(135deg, #11998e, #38ef7d); } .color-purple { background: linear-gradient(135deg, #8e2de2, #4a00e0); } /* Image zoom effect */ .zoom-container { position: relative; overflow: hidden; height: 100%; } .zoom-image { width: 100%; height: 100%; object-fit: cover; transition: transform 0.5s ease; } .gallery-item:hover .zoom-image { transform: scale(1.05); } .gallery-item::after { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(0deg, rgba(0,0,0,0.2) 0%, rgba(0,0,0,0) 50%); pointer-events: none; } </style> </head> <body> <div class="container"> <div class="loading-overlay"> <div class="loading-spinner"></div> </div> <div class="gallery-wrapper"> <div class="gallery"> <div class="gallery-item"> <div class="zoom-container"> <img class="zoom-image" src="https://images.unsplash.com/photo-1611930022073-b7a4ba5fcccd?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=800&q=80" alt="Apex Wireless Earbuds - Cobalt Blue"> </div> <div class="product-tag">BEST SELLER</div> </div> <div class="gallery-item"> <div class="zoom-container"> <img class="zoom-image" src="https://images.unsplash.com/photo-1631176260217-dfdf5c775fe1?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=800&q=80" alt="Apex Wireless Earbuds - Side View"> </div> <div class="product-tag">NOISE CANCELING</div> </div> <div class="gallery-item"> <div class="zoom-container"> <img class="zoom-image" src="https://images.unsplash.com/photo-1590658268037-6bf12165a8df?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=800&q=80" alt="Apex Wireless Earbuds - Case"> </div> <div class="product-tag">24H BATTERY</div> </div> <div class="gallery-item"> <div class="zoom-container"> <img class="zoom-image" src="https://images.unsplash.com/photo-1606220588913-b3aacb4d2f46?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=800&q=80" alt="Apex Wireless Earbuds - In Ear"> </div> <div class="product-tag">ERGONOMIC FIT</div> </div> </div> <div class="controls"> <div class="arrow prev"> <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/> </svg> </div> <div class="arrow next"> <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/> </svg> </div> </div> <div class="pagination"> <div class="dot active"></div> <div class="dot"></div> <div class="dot"></div> <div class="dot"></div> </div> </div> <div class="product-info"> <h1 class="product-title">Apex Pro Wireless Earbuds</h1> <p class="product-desc">True wireless with active noise cancellation, immersive 3D audio, and seamless device connectivity for an exceptional listening experience.</p> <div class="product-price"> <span class="current-price">$149.99</span> <span class="old-price">$199.99</span> <span class="discount">25% OFF</span> </div> <div class="color-options"> <div class="color-option color-blue active" data-color="blue"></div> <div class="color-option color-red" data-color="red"></div> <div class="color-option color-green" data-color="green"></div> <div class="color-option color-purple" data-color="purple"></div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Variables const gallery = document.querySelector('.gallery'); const items = document.querySelectorAll('.gallery-item'); const prevBtn = document.querySelector('.arrow.prev'); const nextBtn = document.querySelector('.arrow.next'); const dots = document.querySelectorAll('.dot'); const colorOptions = document.querySelectorAll('.color-option'); const loadingOverlay = document.querySelector('.loading-overlay'); let currentIndex = 0; const itemCount = items.length; // Initialize updateGallery(); // Hide loading overlay after images are loaded setTimeout(() => { loadingOverlay.classList.add('hidden'); }, 800); // Event listeners prevBtn.addEventListener('click', () => { navigateGallery(-1); animateArrow(prevBtn, -10); }); nextBtn.addEventListener('click', () => { navigateGallery(1); animateArrow(nextBtn, 10); }); dots.forEach((dot, index) => { dot.addEventListener('click', () => { currentIndex = index; updateGallery(); }); }); colorOptions.forEach(option => { option.addEventListener('click', () => { // Remove active class from all options colorOptions.forEach(o => o.classList.remove('active')); // Add active class to clicked option option.classList.add('active'); // Simulate color change with a brief loading state loadingOverlay.classList.remove('hidden'); setTimeout(() => { loadingOverlay.classList.add('hidden'); }, 500); }); }); // Touch events for mobile swiping let touchStartX = 0; let touchEndX = 0; gallery.addEventListener('touchstart', e => { touchStartX = e.changedTouches[0].screenX; }); gallery.addEventListener('touchend', e => { touchEndX = e.changedTouches[0].screenX; handleSwipe(); }); function handleSwipe() { const threshold = 50; if (touchStartX - touchEndX > threshold) { navigateGallery(1); // Swipe left, go to next } else if (touchEndX - touchStartX > threshold) { navigateGallery(-1); // Swipe right, go to previous } } // Arrow animation function function animateArrow(arrow, deg) { arrow.style.transform = `scale(0.95) rotate(${deg}deg)`; setTimeout(() => { arrow.style.transform = ''; }, 200); } // Navigate gallery function function navigateGallery(direction) { currentIndex = (currentIndex + direction + itemCount) % itemCount; updateGallery(); } // Update gallery function function updateGallery() { gallery.style.transform = `translateX(-${currentIndex * 100}%)`; // Update dots dots.forEach((dot, index) => { dot.classList.toggle('active', index === currentIndex); }); } // Auto-play (optional) let autoplayInterval; function startAutoplay() { autoplayInterval = setInterval(() => { navigateGallery(1); }, 5000); } function stopAutoplay() { clearInterval(autoplayInterval); } // Start autoplay startAutoplay(); // Stop autoplay on user interaction gallery.addEventListener('mouseenter', stopAutoplay); gallery.addEventListener('touchstart', stopAutoplay); // Resume autoplay when user leaves gallery.addEventListener('mouseleave', startAutoplay); gallery.addEventListener('touchend', startAutoplay); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>StreamFX Player Controls</title> <style> :root { --primary-color: #6c5ce7; --secondary-color: #00cec9; --background-color: #2d3436; --text-color: #f1f2f6; --disabled-color: #636e72; --glow-color: rgba(108, 92, 231, 0.4); --progress-filled: #00b894; } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background-color: var(--background-color); color: var(--text-color); height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; overflow: hidden; padding: 20px; } .player-container { position: relative; width: 100%; max-width: 660px; aspect-ratio: 16/9; margin-bottom: 20px; border-radius: 12px; overflow: hidden; box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5); } .video-preview { width: 100%; height: 100%; object-fit: cover; transition: filter 0.3s ease; } .controls-overlay { position: absolute; bottom: 0; left: 0; right: 0; padding: 20px; background: linear-gradient(transparent, rgba(0, 0, 0, 0.8)); opacity: 0; transition: opacity 0.3s ease; display: flex; flex-direction: column; gap: 15px; } .player-container:hover .controls-overlay { opacity: 1; } .progress-container { width: 100%; height: 6px; background-color: rgba(255, 255, 255, 0.2); border-radius: 3px; cursor: pointer; position: relative; overflow: hidden; } .progress-bar { height: 100%; width: 35%; background-color: var(--progress-filled); border-radius: 3px; position: relative; transition: width 0.2s ease; } .progress-bar::after { content: ''; position: absolute; right: -6px; top: -3px; width: 12px; height: 12px; background-color: var(--text-color); border-radius: 50%; box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); transform: scale(0); transition: transform 0.2s ease; } .progress-container:hover .progress-bar::after { transform: scale(1); } .controls-row { display: flex; justify-content: space-between; align-items: center; } .time-display { font-size: 14px; letter-spacing: 0.5px; font-variant-numeric: tabular-nums; } .control-buttons { display: flex; gap: 20px; align-items: center; } .control-btn { background-color: transparent; border: none; cursor: pointer; display: flex; align-items: center; justify-content: center; position: relative; width: 46px; height: 46px; border-radius: 50%; transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); backdrop-filter: blur(5px); background-color: rgba(255, 255, 255, 0.1); } .control-btn:hover { background-color: rgba(255, 255, 255, 0.2); transform: scale(1.05); } .control-btn:active { transform: scale(0.95); } .control-btn svg { width: 24px; height: 24px; fill: var(--text-color); filter: drop-shadow(0 0 8px var(--glow-color)); transition: all 0.2s ease; } .control-btn:hover svg { filter: drop-shadow(0 0 12px var(--glow-color)); } .control-btn.disabled { cursor: not-allowed; background-color: rgba(255, 255, 255, 0.05); } .control-btn.disabled svg { fill: var(--disabled-color); filter: none; } .control-btn.play-pause { width: 60px; height: 60px; background-color: rgba(108, 92, 231, 0.3); } .control-btn.play-pause:hover { background-color: rgba(108, 92, 231, 0.5); } .control-btn.play-pause svg { width: 28px; height: 28px; } .ripple { position: absolute; width: 100%; height: 100%; background-color: rgba(255, 255, 255, 0.7); border-radius: 50%; transform: scale(0); opacity: 1; animation: ripple 0.6s linear; } @keyframes ripple { to { transform: scale(2); opacity: 0; } } .feature-tag { position: absolute; top: 15px; right: 15px; background-color: var(--secondary-color); color: #2d3436; font-size: 12px; font-weight: 600; padding: 6px 12px; border-radius: 20px; text-transform: uppercase; letter-spacing: 1px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); opacity: 0; transform: translateY(-10px); transition: all 0.3s ease; } .player-container:hover .feature-tag { opacity: 1; transform: translateY(0); } .controls-info { margin-top: 15px; text-align: center; font-size: 14px; color: var(--text-color); opacity: 0.8; max-width: 660px; line-height: 1.6; } .keyboard-shortcuts { display: flex; justify-content: center; gap: 15px; margin-top: 15px; flex-wrap: wrap; } .shortcut { display: flex; align-items: center; gap: 8px; font-size: 13px; } .key { display: inline-block; background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; padding: 3px 8px; font-family: monospace; font-size: 12px; font-weight: bold; color: var(--secondary-color); border: 1px solid rgba(255, 255, 255, 0.1); } .feature-pulse { position: absolute; width: 64px; height: 64px; border-radius: 50%; background: transparent; border: 2px solid var(--secondary-color); opacity: 0; transform: translate(-50%, -50%); pointer-events: none; animation: pulse 1.5s infinite; } @keyframes pulse { 0% { transform: translate(-50%, -50%) scale(0.7); opacity: 0; } 50% { opacity: 0.5; } 100% { transform: translate(-50%, -50%) scale(1.3); opacity: 0; } } @media (max-width: 500px) { .player-container { border-radius: 8px; } .controls-overlay { padding: 15px; } .control-btn { width: 40px; height: 40px; } .control-btn.play-pause { width: 50px; height: 50px; } .control-buttons { gap: 10px; } .time-display { font-size: 12px; } .controls-info { font-size: 12px; } } </style> </head> <body> <div class="player-container"> <img src="https://source.unsplash.com/random/1280x720/?movie" alt="Video Preview" class="video-preview"> <div class="feature-tag">StreamFX 4K</div> <div class="controls-overlay"> <div class="progress-container" id="progress-bar"> <div class="progress-bar"></div> </div> <div class="controls-row"> <div class="time-display">01:24 / 03:45</div> <div class="control-buttons"> <button class="control-btn rewind-btn" title="Rewind 10 seconds"> <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="M12.5,3C17.15,3 21.08,6.03 22.47,10.22L20.1,11C19.05,7.81 16.04,5.5 12.5,5.5C8.46,5.5 5.14,8.5 4.57,12.5H6.5L2.5,18L0,12.5H2.57C3.15,7.39 7.39,3 12.5,3M13,7V12.25L17.62,16.13L16.38,17.87L11,13.25V7H13Z"/> </svg> </button> <button class="control-btn play-pause" title="Play/Pause"> <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="M8,5.14V19.14L19,12.14L8,5.14Z"/> </svg> </button> <button class="control-btn forward-btn" title="Fast forward 10 seconds"> <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="M10,9.9l1.56,0.25l-1.56,0.25V9.9z M12.5,3c-4.96,0-9.06,4.01-9.46,9H0.5l3,5.5L7,12.5H3.5c0.46-3.42,3.4-6,6.94-6c3.86,0,7,3.14,7,7s-3.14,7-7,7c-3.57,0-6.5-2.68-6.93-6.13L1.53,14.34C2.24,18.27,6.3,21,10.94,21c5.52,0,10-4.48,10-10S18.02,3,12.5,3 M12.5,7V12.25L16.5,14.62L15.5,16.37L10.5,13V7H12.5z"/> </svg> </button> </div> </div> </div> <div id="feature-pulse" class="feature-pulse"></div> </div> <div class="controls-info"> StreamFX's intelligent navigation controls adapt to your viewing habits. Double-tap the edges for quick 10-second jumps, or use our precision frame-by-frame navigation for those critical moments. </div> <div class="keyboard-shortcuts"> <div class="shortcut"> <span class="key">J</span> <span>Rewind</span> </div> <div class="shortcut"> <span class="key">K</span> <span>Play/Pause</span> </div> <div class="shortcut"> <span class="key">L</span> <span>Forward</span> </div> <div class="shortcut"> <span class="key">←</span> <span>-5s</span> </div> <div class="shortcut"> <span class="key">→</span> <span>+5s</span> </div> </div> <script> document.addEventListener('DOMContentLoaded', () => { const playPauseBtn = document.querySelector('.play-pause'); const rewindBtn = document.querySelector('.rewind-btn'); const forwardBtn = document.querySelector('.forward-btn'); const progressContainer = document.getElementById('progress-bar'); const progressBar = document.querySelector('.progress-bar'); const videoPreview = document.querySelector('.video-preview'); const featurePulse = document.getElementById('feature-pulse'); let isPlaying = false; // Function to create ripple effect function createRipple(e) { const button = e.currentTarget; const ripple = document.createElement('span'); ripple.classList.add('ripple'); button.appendChild(ripple); setTimeout(() => { ripple.remove(); }, 600); } // Play/Pause functionality playPauseBtn.addEventListener('click', (e) => { createRipple(e); isPlaying = !isPlaying; if (isPlaying) { playPauseBtn.innerHTML = ` <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="M14,19H18V5H14M6,19H10V5H6V19Z"/> </svg> `; videoPreview.style.filter = 'brightness(1)'; } else { playPauseBtn.innerHTML = ` <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="M8,5.14V19.14L19,12.14L8,5.14Z"/> </svg> `; videoPreview.style.filter = 'brightness(0.7)'; } }); // Rewind functionality rewindBtn.addEventListener('click', (e) => { createRipple(e); // Simulate rewinding by decreasing progress bar let currentWidth = parseFloat(getComputedStyle(progressBar).width); let containerWidth = parseFloat(getComputedStyle(progressContainer).width); let percentage = (currentWidth / containerWidth) * 100; // Decrease by 10% percentage = Math.max(0, percentage - 10); progressBar.style.width = percentage + '%'; // Show feature pulse at button position showFeaturePulse(e.currentTarget); }); // Forward functionality forwardBtn.addEventListener('click', (e) => { createRipple(e); // Simulate forwarding by increasing progress bar let currentWidth = parseFloat(getComputedStyle(progressBar).width); let containerWidth = parseFloat(getComputedStyle(progressContainer).width); let percentage = (currentWidth / containerWidth) * 100; // Increase by 10% percentage = Math.min(100, percentage + 10); progressBar.style.width = percentage + '%'; // Show feature pulse at button position showFeaturePulse(e.currentTarget); }); // Progress bar interaction progressContainer.addEventListener('click', (e) => { const rect = progressContainer.getBoundingClientRect(); const position = (e.clientX - rect.left) / rect.width; progressBar.style.width = position * 100 + '%'; }); // Show feature pulse function showFeaturePulse(element) { const rect = element.getBoundingClientRect(); const x = rect.left + rect.width / 2; const y = rect.top + rect.height / 2; featurePulse.style.left = x + 'px'; featurePulse.style.top = y + 'px'; featurePulse.style.opacity = '1'; setTimeout(() => { featurePulse.style.opacity = '0'; }, 1500); } // Keyboard shortcuts document.addEventListener('keydown', (e) => { switch(e.key) { case 'j': case 'J': case 'ArrowLeft': rewindBtn.click(); break; case 'k': case 'K': case ' ': playPauseBtn.click(); break; case 'l': case 'L': case 'ArrowRight': forwardBtn.click(); break; } }); // Double tap detection for mobile let lastTap = 0; document.addEventListener('touchend', (e) => { const currentTime = new Date().getTime(); const tapLength = currentTime - lastTap; if (tapLength < 500 && tapLength > 0) { // Double tap detected const windowWidth = window.innerWidth; const touchX = e.changedTouches[0].pageX; if (touchX < windowWidth / 3) { // Left side - rewind rewindBtn.click(); } else if (touchX > (windowWidth / 3) * 2) { // Right side - forward forwardBtn.click(); } else { // Center - play/pause playPauseBtn.click(); } } lastTap = currentTime; }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Climate Change Impact Flow</title> <style> :root { --primary: #34b3a7; --secondary: #f76c5e; --dark: #2d3e50; --light: #f5f7fa; --highlight: #ffd166; --contrast: #9b5de5; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: var(--light); overflow: hidden; width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; } .container { width: 700px; height: 700px; position: relative; display: flex; flex-direction: column; justify-content: center; align-items: center; padding: 20px; overflow: hidden; } .title { text-align: center; margin-bottom: 20px; position: relative; z-index: 10; } .title h1 { font-size: 2rem; color: var(--dark); font-weight: 700; margin-bottom: 10px; } .title p { color: var(--dark); font-size: 1rem; max-width: 500px; margin: 0 auto; } .infographic { width: 100%; height: 500px; position: relative; } .node { position: absolute; width: 120px; height: 120px; border-radius: 50%; display: flex; flex-direction: column; justify-content: center; align-items: center; transition: transform 0.3s ease, box-shadow 0.3s ease; cursor: pointer; z-index: 5; background-color: var(--light); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); overflow: hidden; padding: 10px; text-align: center; } .node:hover { transform: scale(1.05); box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2); z-index: 10; } .node.node-1 { top: 10%; left: 10%; background-color: rgba(52, 179, 167, 0.2); border: 2px solid var(--primary); } .node.node-2 { top: 15%; left: 50%; background-color: rgba(247, 108, 94, 0.2); border: 2px solid var(--secondary); } .node.node-3 { top: 45%; left: 25%; background-color: rgba(255, 209, 102, 0.2); border: 2px solid var(--highlight); } .node.node-4 { top: 45%; left: 70%; background-color: rgba(155, 93, 229, 0.2); border: 2px solid var(--contrast); } .node.node-5 { top: 75%; left: 50%; background-color: rgba(45, 62, 80, 0.2); border: 2px solid var(--dark); } .node-icon { font-size: 2rem; margin-bottom: 5px; } .node-title { font-size: 0.9rem; font-weight: 700; margin-bottom: 3px; } .node-text { font-size: 0.7rem; display: none; } .node:hover .node-text { display: block; } .arrow { position: absolute; stroke-dasharray: 1000; stroke-dashoffset: 1000; z-index: 2; pointer-events: none; } .tooltip { position: absolute; background-color: var(--dark); color: white; padding: 10px 15px; border-radius: 4px; font-size: 0.8rem; max-width: 250px; z-index: 20; opacity: 0; transform: translateY(10px); transition: opacity 0.3s, transform 0.3s; pointer-events: none; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); } .tooltip:after { content: ""; position: absolute; top: 100%; left: 50%; margin-left: -8px; border-width: 8px; border-style: solid; border-color: var(--dark) transparent transparent transparent; } .legend { position: absolute; bottom: 20px; left: 20px; display: flex; flex-wrap: wrap; gap: 10px; font-size: 0.8rem; } .legend-item { display: flex; align-items: center; gap: 5px; } .legend-color { width: 15px; height: 15px; border-radius: 3px; } .btn-reset { position: absolute; bottom: 20px; right: 20px; padding: 8px 16px; background-color: var(--dark); color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 0.9rem; transition: all 0.3s ease; } .btn-reset:hover { background-color: var(--primary); } .animated-bg { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 1; opacity: 0.2; } @media (max-width: 700px) { .title h1 { font-size: 1.5rem; } .title p { font-size: 0.9rem; } .node { width: 100px; height: 100px; } .node-icon { font-size: 1.5rem; } .node-title { font-size: 0.8rem; } .node.node-1 { top: 10%; left: 5%; } .node.node-2 { top: 15%; left: 45%; } .node.node-3 { top: 45%; left: 15%; } .node.node-4 { top: 45%; left: 65%; } .node.node-5 { top: 75%; left: 40%; } } </style> </head> <body> <div class="container"> <div class="title"> <h1>Climate Change Cascade Effect</h1> <p>Explore how greenhouse gas emissions trigger a series of environmental impacts leading to societal challenges</p> </div> <div class="infographic"> <div class="animated-bg"></div> <div class="node node-1" data-id="1"> <div class="node-icon">🏭</div> <div class="node-title">Emissions</div> <div class="node-text">Human activities release 51 billion tons of greenhouse gases annually</div> </div> <div class="node node-2" data-id="2"> <div class="node-icon">🌡️</div> <div class="node-title">Temperature Rise</div> <div class="node-text">Global temperatures have increased by 1.1°C since pre-industrial times</div> </div> <div class="node node-3" data-id="3"> <div class="node-icon">🌊</div> <div class="node-title">Ocean Impact</div> <div class="node-text">Sea levels rising 3.6mm per year with 30% increase in ocean acidity</div> </div> <div class="node node-4" data-id="4"> <div class="node-icon">🌪️</div> <div class="node-title">Extreme Weather</div> <div class="node-text">5× increase in climate-related disasters over the past 50 years</div> </div> <div class="node node-5" data-id="5"> <div class="node-icon">👥</div> <div class="node-title">Social Impact</div> <div class="node-text">By 2050, up to 200 million people may become climate refugees</div> </div> <svg class="arrow arrow-1-2" width="700" height="700" viewBox="0 0 700 700"> <path d="" fill="none" stroke="#34b3a7" stroke-width="3" stroke-linecap="round"></path> </svg> <svg class="arrow arrow-2-3" width="700" height="700" viewBox="0 0 700 700"> <path d="" fill="none" stroke="#f76c5e" stroke-width="3" stroke-linecap="round"></path> </svg> <svg class="arrow arrow-2-4" width="700" height="700" viewBox="0 0 700 700"> <path d="" fill="none" stroke="#f76c5e" stroke-width="3" stroke-linecap="round"></path> </svg> <svg class="arrow arrow-3-5" width="700" height="700" viewBox="0 0 700 700"> <path d="" fill="none" stroke="#ffd166" stroke-width="3" stroke-linecap="round"></path> </svg> <svg class="arrow arrow-4-5" width="700" height="700" viewBox="0 0 700 700"> <path d="" fill="none" stroke="#9b5de5" stroke-width="3" stroke-linecap="round"></path> </svg> </div> <div class="tooltip"></div> <div class="legend"> <div class="legend-item"> <div class="legend-color" style="background-color: var(--primary);"></div> <span>Emissions</span> </div> <div class="legend-item"> <div class="legend-color" style="background-color: var(--secondary);"></div> <span>Temperature</span> </div> <div class="legend-item"> <div class="legend-color" style="background-color: var(--highlight);"></div> <span>Ocean</span> </div> <div class="legend-item"> <div class="legend-color" style="background-color: var(--contrast);"></div> <span>Weather</span> </div> </div> <button class="btn-reset">Reset Animation</button> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Define node positions for arrows const nodes = { "1": { x: 70, y: 70 }, "2": { x: 350, y: 90 }, "3": { x: 175, y: 315 }, "4": { x: 490, y: 315 }, "5": { x: 350, y: 525 } }; // Draw SVG arrows with hand-drawn style function drawArrow(className, startId, endId) { const start = nodes[startId]; const end = nodes[endId]; // Calculate control points for curvy, hand-drawn effect const dx = end.x - start.x; const dy = end.y - start.y; // Add some randomness for hand-drawn effect const midX = start.x + dx * 0.5 + (Math.random() * 20 - 10); const midY = start.y + dy * 0.5 + (Math.random() * 20 - 10); const cp1x = start.x + dx * 0.25 + (Math.random() * 30 - 15); const cp1y = start.y + dy * 0.25 + (Math.random() * 30 - 15); const cp2x = start.x + dx * 0.75 + (Math.random() * 30 - 15); const cp2y = start.y + dy * 0.75 + (Math.random() * 30 - 15); // Create arrow path with a slight wiggle const path = `M${start.x},${start.y} C${cp1x},${cp1y} ${midX},${midY} ${cp2x},${cp2y} S${end.x - 10},${end.y - 10} ${end.x},${end.y}`; // Set the path const arrow = document.querySelector(`.${className} path`); arrow.setAttribute('d', path); // Set arrow marker arrow.setAttribute('marker-end', 'url(#arrowhead)'); return arrow; } // Create arrowhead marker in SVG const svgs = document.querySelectorAll('svg.arrow'); svgs.forEach(svg => { const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs'); const marker = document.createElementNS('http://www.w3.org/2000/svg', 'marker'); marker.setAttribute('id', 'arrowhead'); marker.setAttribute('markerWidth', '10'); marker.setAttribute('markerHeight', '7'); marker.setAttribute('refX', '9'); marker.setAttribute('refY', '3.5'); marker.setAttribute('orient', 'auto'); const polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon'); polygon.setAttribute('points', '0 0, 10 3.5, 0 7'); polygon.setAttribute('fill', '#2d3e50'); marker.appendChild(polygon); defs.appendChild(marker); svg.appendChild(defs); }); // Draw all the arrows const arrows = [ drawArrow('arrow-1-2', '1', '2'), drawArrow('arrow-2-3', '2', '3'), drawArrow('arrow-2-4', '2', '4'), drawArrow('arrow-3-5', '3', '5'), drawArrow('arrow-4-5', '4', '5') ]; // Animate the arrows function animateArrows() { arrows.forEach((arrow, i) => { setTimeout(() => { arrow.style.animation = 'drawArrow 1.5s ease-out forwards'; arrow.style.strokeDashoffset = '0'; }, i * 700); }); } // Tooltip content const tooltipContent = { "1-2": "Greenhouse gases trap heat in the atmosphere, directly causing global temperature increases", "2-3": "Higher temperatures melt ice caps and warm ocean water, causing thermal expansion", "2-4": "Warmer atmosphere holds more moisture and energy, intensifying weather patterns", "3-5": "Rising seas threaten coastal communities, forcing migration from low-lying areas", "4-5": "Extreme weather events destroy infrastructure and agriculture, creating resource scarcity" }; // Show tooltip on arrow hover document.querySelectorAll('.arrow').forEach(arrow => { arrow.addEventListener('mouseover', function(e) { const classes = this.classList; let arrowClass = ''; for (let i = 0; i < classes.length; i++) { if (classes[i].startsWith('arrow-')) { arrowClass = classes[i].substring(6); break; } } if (tooltipContent[arrowClass]) { const tooltip = document.querySelector('.tooltip'); tooltip.textContent = tooltipContent[arrowClass]; tooltip.style.opacity = '1'; tooltip.style.transform = 'translateY(0)'; // Position tooltip near the middle of the arrow const rect = this.getBoundingClientRect(); const container = document.querySelector('.container').getBoundingClientRect(); const posX = rect.left + rect.width/2 - container.left - tooltip.offsetWidth/2; const posY = rect.top + rect.height/2 - container.top - tooltip.offsetHeight - 15; tooltip.style.left = `${Math.max(10, Math.min(posX, 700 - tooltip.offsetWidth - 10))}px`; tooltip.style.top = `${Math.max(10, posY)}px`; } }); arrow.addEventListener('mouseout', function() { const tooltip = document.querySelector('.tooltip'); tooltip.style.opacity = '0'; tooltip.style.transform = 'translateY(10px)'; }); }); // Add interactivity to nodes document.querySelectorAll('.node').forEach(node => { node.addEventListener('click', function() { // Highlight connected arrows const nodeId = this.getAttribute('data-id'); document.querySelectorAll('.arrow').forEach(arrow => { const classes = arrow.classList; let arrowClass = ''; for (let i = 0; i < classes.length; i++) { if (classes[i].startsWith('arrow-')) { arrowClass = classes[i].substring(6); break; } } const [startId, endId] = arrowClass.split('-'); if (startId === nodeId || endId === nodeId) { arrow.querySelector('path').style.strokeWidth = '5'; arrow.querySelector('path').style.filter = 'drop-shadow(0 0 3px rgba(0,0,0,0.3))'; } else { arrow.querySelector('path').style.strokeWidth = '3'; arrow.querySelector('path').style.filter = 'none'; } }); // Add pulse effect to selected node document.querySelectorAll('.node').forEach(n => { n.style.animation = 'none'; }); this.style.animation = 'pulse 1.5s infinite'; }); }); // Reset button document.querySelector('.btn-reset').addEventListener('click', function() { // Reset arrows arrows.forEach(arrow => { arrow.style.strokeDashoffset = '1000'; arrow.style.animation = 'none'; arrow.style.strokeWidth = '3'; arrow.style.filter = 'none'; // Force reflow arrow.offsetWidth; }); // Reset nodes document.querySelectorAll('.node').forEach(node => { node.style.animation = 'none'; }); // Restart animation setTimeout(animateArrows, 300); }); // Create animated background pattern function createBackgroundPattern() { const bg = document.querySelector('.animated-bg'); const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); svg.setAttribute('width', '100%'); svg.setAttribute('height', '100%'); svg.style.position = 'absolute'; // Create dynamic pattern for (let i = 0; i < 15; i++) { const x1 = Math.random() * 100 + '%'; const y1 = Math.random() * 100 + '%'; const x2 = Math.random() * 100 + '%'; const y2 = Math.random() * 100 + '%'; const line = document.createElementNS('http://www.w3.org/2000/svg', 'line'); line.setAttribute('x1', x1); line.setAttribute('y1', y1); line.setAttribute('x2', x2); line.setAttribute('y2', y2); line.setAttribute('stroke', '#2d3e50'); line.setAttribute('stroke-width', '1'); line.setAttribute('stroke-opacity', '0.1'); svg.appendChild(line); } // Add circles for (let i = 0; i < 10; i++) { const cx = Math.random() * 100 + '%'; const cy = Math.random() * 100 + '%'; const r = Math.random() * 20 + 5; const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); circle.setAttribute('cx', cx); circle.setAttribute('cy', cy); circle.setAttribute('r', r); circle.setAttribute('fill', 'none'); circle.setAttribute('stroke', '#34b3a7'); circle.setAttribute('stroke-width', '1'); circle.setAttribute('stroke-opacity', '0.1'); svg.appendChild(circle); } bg.appendChild(svg); } createBackgroundPattern(); // Start animation setTimeout(animateArrows, 500); // Add CSS animation to <style> const styleSheet = document.styleSheets[0]; styleSheet.insertRule(` @keyframes drawArrow { from { stroke-dashoffset: 1000; } to { stroke-dashoffset: 0; } } `, styleSheet.cssRules.length); styleSheet.insertRule(` @keyframes pulse { 0% { transform: scale(1); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); } 50% { transform: scale(1.1); box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2); } 100% { transform: scale(1); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); } } `, styleSheet.cssRules.length); // Adjust positions for responsive design function adjustPositions() { const width = window.innerWidth; const container = document.querySelector('.container'); const containerWidth = container.offsetWidth; if (width <= 700) { nodes["1"].x = containerWidth * 0.05 + 50; nodes["2"].x = containerWidth * 0.45 + 50; nodes["3"].x = containerWidth * 0.15 + 50; nodes["4"].x = containerWidth * 0.65 + 50; nodes["5"].x = containerWidth * 0.4 + 50; } else { nodes["1"].x = 70; nodes["2"].x = 350; nodes["3"].x = 175; nodes["4"].x = 490; nodes["5"].x = 350; } // Redraw arrows drawArrow('arrow-1-2', '1', '2'); drawArrow('arrow-2-3', '2', '3'); drawArrow('arrow-2-4', '2', '4'); drawArrow('arrow-3-5', '3', '5'); drawArrow('arrow-4-5', '4', '5'); } window.addEventListener('resize', adjustPositions); adjustPositions(); }); </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: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; } body { background-color: #f8f9fa; display: flex; justify-content: center; align-items: center; height: 100vh; color: #2d3748; } .dashboard { width: 100%; max-width: 600px; background-color: #fff; border-radius: 16px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.05); overflow: hidden; display: grid; grid-template-rows: auto 1fr; height: auto; max-height: 650px; } .dashboard-header { padding: 24px 32px; border-bottom: 1px solid #edf2f7; display: flex; justify-content: space-between; align-items: center; } .dashboard-title { font-size: 20px; font-weight: 600; color: #1a202c; } .dashboard-subtitle { font-size: 14px; color: #718096; margin-top: 4px; } .theme-toggle { width: 44px; height: 22px; background: #e2e8f0; border-radius: 22px; position: relative; cursor: pointer; transition: background 0.3s ease; display: flex; align-items: center; } .theme-toggle.dark { background: #4a5568; } .toggle-circle { width: 18px; height: 18px; background: white; border-radius: 50%; position: absolute; left: 2px; transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); } .theme-toggle.dark .toggle-circle { transform: translateX(22px); } .dashboard-content { padding: 24px 32px; overflow-y: auto; display: grid; grid-template-rows: repeat(auto-fill, minmax(70px, auto)); gap: 16px; } .widget { background: #fff; border-radius: 12px; border: 1px solid #edf2f7; transition: all 0.3s ease; cursor: pointer; } .widget:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(0, 0, 0, 0.04); } .widget-header { padding: 16px 20px; display: flex; justify-content: space-between; align-items: center; } .widget-title { font-weight: 600; font-size: 16px; color: #2d3748; display: flex; align-items: center; gap: 10px; } .widget-icon { width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; border-radius: 6px; } .widget-dropdown { width: 28px; height: 28px; border-radius: 8px; display: flex; align-items: center; justify-content: center; transition: background 0.2s ease; position: relative; cursor: pointer; } .widget-dropdown:hover { background: #f7fafc; } .arrow-container { position: relative; width: 14px; height: 14px; overflow: hidden; display: flex; align-items: center; justify-content: center; } .arrow { width: 10px; height: 10px; border-right: 2px solid #718096; border-bottom: 2px solid #718096; transform: rotate(45deg) translateY(-2px); transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); } .widget-dropdown.active .arrow { transform: rotate(-135deg) translateY(-2px); } .widget-content { max-height: 0; overflow: hidden; transition: max-height 0.3s ease, padding 0.3s ease; padding: 0 20px; opacity: 0; } .widget-content.open { max-height: 300px; padding: 0 20px 16px; opacity: 1; } .widget-content-inner { padding-top: 8px; border-top: 1px solid #edf2f7; } .stats-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; margin-top: 12px; } .stat-item { padding: 12px; border-radius: 8px; background: #f7fafc; } .stat-title { font-size: 13px; color: #718096; margin-bottom: 4px; } .stat-value { font-size: 18px; font-weight: 600; color: #2d3748; } .progress-container { margin-top: 16px; width: 100%; height: 8px; background: #edf2f7; border-radius: 4px; overflow: hidden; } .progress-bar { height: 100%; background: linear-gradient(to right, #4299e1, #667eea); border-radius: 4px; width: 0; transition: width 1s ease; } .task-list { margin-top: 12px; } .task-item { display: flex; align-items: center; padding: 8px 0; border-bottom: 1px solid #edf2f7; opacity: 0; transform: translateY(10px); transition: all 0.3s ease; } .task-item:last-child { border-bottom: none; } .task-checkbox { width: 18px; height: 18px; border: 2px solid #cbd5e0; border-radius: 4px; margin-right: 12px; position: relative; cursor: pointer; transition: all 0.2s ease; } .task-checkbox.checked { background: #4299e1; border-color: #4299e1; } .task-checkbox.checked:after { content: ''; position: absolute; top: 2px; left: 6px; width: 4px; height: 8px; border: solid white; border-width: 0 2px 2px 0; transform: rotate(45deg); } .task-content { flex: 1; } .task-title { font-size: 14px; margin-bottom: 2px; transition: all 0.2s ease; } .task-checkbox.checked + .task-content .task-title { text-decoration: line-through; color: #a0aec0; } .task-meta { font-size: 12px; color: #a0aec0; } .dark-mode .dashboard { background-color: #1a202c; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); } .dark-mode .dashboard-header { border-bottom: 1px solid #2d3748; } .dark-mode .dashboard-title { color: #f7fafc; } .dark-mode .dashboard-subtitle { color: #a0aec0; } .dark-mode .widget { background: #2d3748; border-color: #4a5568; } .dark-mode .widget-title { color: #e2e8f0; } .dark-mode .widget-dropdown:hover { background: #4a5568; } .dark-mode .arrow { border-color: #a0aec0; } .dark-mode .widget-content-inner { border-top: 1px solid #4a5568; } .dark-mode .stat-item { background: #4a5568; } .dark-mode .stat-title { color: #a0aec0; } .dark-mode .stat-value { color: #e2e8f0; } .dark-mode .progress-container { background: #4a5568; } .dark-mode .task-item { border-bottom: 1px solid #4a5568; } .dark-mode .task-checkbox { border-color: #718096; } .dark-mode .task-title { color: #e2e8f0; } .dark-mode .task-meta { color: #718096; } @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(0.97); } 100% { transform: scale(1); } } .widget-dropdown.active { animation: pulse 0.5s ease-in-out; } .widget-performance .widget-icon { background: rgba(66, 153, 225, 0.1); color: #4299e1; } .widget-tasks .widget-icon { background: rgba(237, 100, 166, 0.1); color: #ed64a6; } .widget-reports .widget-icon { background: rgba(72, 187, 120, 0.1); color: #48bb78; } @media (max-width: 500px) { .dashboard { border-radius: 0; max-height: 100vh; height: 100vh; } .dashboard-header { padding: 20px; } .dashboard-content { padding: 16px; } .stats-grid { grid-template-columns: 1fr; } } </style> </head> <body> <div class="dashboard"> <div class="dashboard-header"> <div> <div class="dashboard-title">Analytics Dashboard</div> <div class="dashboard-subtitle">Explore your key metrics</div> </div> <div class="theme-toggle"> <div class="toggle-circle"></div> </div> </div> <div class="dashboard-content"> <div class="widget widget-performance"> <div class="widget-header"> <div class="widget-title"> <div class="widget-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="22 12 18 12 15 21 9 3 6 12 2 12"></polyline> </svg> </div> Performance Metrics </div> <div class="widget-dropdown"> <div class="arrow-container"> <div class="arrow"></div> </div> </div> </div> <div class="widget-content"> <div class="widget-content-inner"> <div class="stats-grid"> <div class="stat-item"> <div class="stat-title">Conversion Rate</div> <div class="stat-value">3.7%</div> </div> <div class="stat-item"> <div class="stat-title">Avg. Session</div> <div class="stat-value">4:32</div> </div> <div class="stat-item"> <div class="stat-title">Bounce Rate</div> <div class="stat-value">28.3%</div> </div> <div class="stat-item"> <div class="stat-title">Active Users</div> <div class="stat-value">8,642</div> </div> </div> <div class="progress-container"> <div class="progress-bar" data-value="67"></div> </div> </div> </div> </div> <div class="widget widget-tasks"> <div class="widget-header"> <div class="widget-title"> <div class="widget-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M9 11l3 3L22 4"></path> <path d="M21 12v7a2 2 0 01-2 2H5a2 2 0 01-2-2V5a2 2 0 012-2h11"></path> </svg> </div> Pending Tasks </div> <div class="widget-dropdown"> <div class="arrow-container"> <div class="arrow"></div> </div> </div> </div> <div class="widget-content"> <div class="widget-content-inner"> <div class="task-list"> <div class="task-item"> <div class="task-checkbox"></div> <div class="task-content"> <div class="task-title">Review Q4 Marketing Strategy</div> <div class="task-meta">Due: Today</div> </div> </div> <div class="task-item"> <div class="task-checkbox"></div> <div class="task-content"> <div class="task-title">Update user onboarding flow</div> <div class="task-meta">Due: Tomorrow</div> </div> </div> <div class="task-item"> <div class="task-checkbox"></div> <div class="task-content"> <div class="task-title">Finalize new dashboard widgets</div> <div class="task-meta">Due: Sep 28</div> </div> </div> </div> </div> </div> </div> <div class="widget widget-reports"> <div class="widget-header"> <div class="widget-title"> <div class="widget-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"></path> <polyline points="14 2 14 8 20 8"></polyline> <line x1="16" y1="13" x2="8" y2="13"></line> <line x1="16" y1="17" x2="8" y2="17"></line> <polyline points="10 9 9 9 8 9"></polyline> </svg> </div> Monthly Reports </div> <div class="widget-dropdown"> <div class="arrow-container"> <div class="arrow"></div> </div> </div> </div> <div class="widget-content"> <div class="widget-content-inner"> <div class="stats-grid"> <div class="stat-item"> <div class="stat-title">Revenue Growth</div> <div class="stat-value">+12.8%</div> </div> <div class="stat-item"> <div class="stat-title">New Customers</div> <div class="stat-value">386</div> </div> </div> <div class="progress-container"> <div class="progress-bar" data-value="83"></div> </div> </div> </div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Set up dropdowns const dropdowns = document.querySelectorAll('.widget-dropdown'); dropdowns.forEach(dropdown => { dropdown.addEventListener('click', function() { const widgetContent = this.closest('.widget').querySelector('.widget-content'); // Toggle active state and classes if (this.classList.contains('active')) { this.classList.remove('active'); widgetContent.classList.remove('open'); } else { this.classList.add('active'); widgetContent.classList.add('open'); // Animate task items when the tasks widget opens if (this.closest('.widget-tasks')) { const taskItems = widgetContent.querySelectorAll('.task-item'); taskItems.forEach((item, index) => { setTimeout(() => { item.style.opacity = 1; item.style.transform = 'translateY(0)'; }, 100 * index); }); } // Animate progress bars when widget opens const progressBars = widgetContent.querySelectorAll('.progress-bar'); progressBars.forEach(bar => { setTimeout(() => { const value = bar.getAttribute('data-value'); bar.style.width = `${value}%`; }, 300); }); } }); }); // Task checkboxes const taskCheckboxes = document.querySelectorAll('.task-checkbox'); taskCheckboxes.forEach(checkbox => { checkbox.addEventListener('click', function() { this.classList.toggle('checked'); }); }); // Theme toggle const themeToggle = document.querySelector('.theme-toggle'); themeToggle.addEventListener('click', function() { this.classList.toggle('dark'); document.body.classList.toggle('dark-mode'); }); // Make the first widget open by default setTimeout(() => { document.querySelector('.widget-dropdown').click(); }, 500); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Elegant Breadcrumb Navigation</title> <style> :root { --primary-color: #4a6fa1; --secondary-color: #2c3e50; --accent-color: #e67e22; --light-color: #f9f9f9; --dark-color: #333; --transition-speed: 0.25s; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; } body { display: flex; flex-direction: column; justify-content: center; align-items: center; min-height: 100vh; background: linear-gradient(135deg, #f5f7fa 0%, #e2e6ea 100%); padding: 1rem; } .site-container { width: 100%; max-width: 680px; display: flex; flex-direction: column; gap: 2rem; } h1 { font-size: 1.8rem; color: var(--dark-color); font-weight: 600; margin-bottom: 0.5rem; } p { color: #666; line-height: 1.6; margin-bottom: 1.5rem; } .breadcrumb-container { width: 100%; position: relative; perspective: 800px; } .breadcrumb { display: flex; flex-wrap: wrap; padding: 0.8rem 1.2rem; background: white; border-radius: 10px; box-shadow: 0 8px 30px rgba(0, 0, 0, 0.08); position: relative; overflow: hidden; transition: all 0.3s ease; } .breadcrumb::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 3px; background: linear-gradient(90deg, var(--primary-color), var(--accent-color)); opacity: 0.8; } .breadcrumb:hover { box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1); transform: translateY(-2px); } .breadcrumb-item { display: flex; align-items: center; color: #777; font-size: 0.9rem; font-weight: 500; text-decoration: none; transition: all var(--transition-speed) ease; position: relative; } .breadcrumb-item:not(:last-child) { margin-right: 0.7rem; } .breadcrumb-item:hover { color: var(--primary-color); } .breadcrumb-item.active { color: var(--primary-color); font-weight: 600; } .breadcrumb-arrow { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; margin: 0 0.6rem; position: relative; } .breadcrumb-arrow svg { width: 12px; height: 12px; fill: none; stroke: #aaa; stroke-width: 2; transition: all var(--transition-speed) ease; } .breadcrumb-arrow::before { content: ''; position: absolute; width: 100%; height: 100%; background: linear-gradient(135deg, rgba(74, 111, 161, 0.08), rgba(230, 126, 34, 0.08)); border-radius: 50%; transform: scale(0); transition: transform 0.2s ease; z-index: 0; } .breadcrumb-item:hover + .breadcrumb-arrow svg, .breadcrumb-arrow:hover svg { stroke: var(--accent-color); transform: translateX(1px); } .breadcrumb-item:active { transform: scale(0.97); } .breadcrumb-arrow:hover::before { transform: scale(1); } .content-area { background: white; padding: 2rem; border-radius: 10px; box-shadow: 0 8px 30px rgba(0, 0, 0, 0.08); transition: all 0.3s ease; } .content-area:hover { box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1); } .example-section { margin-top: 2rem; } .example-section h2 { color: var(--primary-color); font-size: 1.3rem; margin-bottom: 1rem; font-weight: 600; } .product-preview { display: flex; gap: 1.5rem; margin-top: 1rem; flex-wrap: wrap; } .product-card { flex: 1; min-width: 180px; border-radius: 8px; overflow: hidden; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.08); transition: all 0.3s ease; cursor: pointer; } .product-card:hover { transform: translateY(-5px); box-shadow: 0 8px 25px rgba(0, 0, 0, 0.12); } .product-image { height: 140px; background-color: #f5f5f5; display: flex; align-items: center; justify-content: center; overflow: hidden; } .product-image img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.5s ease; } .product-card:hover .product-image img { transform: scale(1.05); } .product-info { padding: 1rem; } .product-title { font-size: 0.9rem; font-weight: 600; color: var(--dark-color); margin-bottom: 0.3rem; } .product-price { font-size: 0.85rem; color: var(--accent-color); font-weight: 600; } @media (max-width: 600px) { .breadcrumb { padding: 0.6rem 1rem; } .breadcrumb-item { font-size: 0.8rem; } .breadcrumb-arrow { width: 16px; height: 16px; margin: 0 0.4rem; } h1 { font-size: 1.5rem; } .content-area { padding: 1.5rem; } } /* Special animation for the active breadcrumb */ .breadcrumb-item.active::after { content: ''; position: absolute; bottom: -5px; left: 0; width: 100%; height: 2px; background: linear-gradient(90deg, var(--primary-color), var(--accent-color)); transform: scaleX(0); transform-origin: left; transition: transform 0.3s ease; } .breadcrumb-item.active:hover::after { transform: scaleX(1); } /* Subtle shimmer effect on breadcrumb container */ .breadcrumb::after { content: ''; position: absolute; top: 0; left: -100%; width: 50%; height: 100%; background: linear-gradient( to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.3) 50%, rgba(255, 255, 255, 0) 100% ); transform: skewX(-25deg); animation: shimmer 6s infinite; } @keyframes shimmer { 0% { left: -100%; } 100% { left: 200%; } } /* Skip to content accessibility button */ .skip-link { position: absolute; top: -40px; left: 0; background: var(--primary-color); color: white; padding: 8px 16px; z-index: 100; transition: top 0.3s; } .skip-link:focus { top: 0; } /* High contrast mode support */ @media (prefers-contrast: high) { .breadcrumb-item { color: #000; } .breadcrumb-arrow svg { stroke: #000; } .breadcrumb-item.active { color: var(--dark-color); } } </style> </head> <body> <a href="#main-content" class="skip-link">Skip to content</a> <div class="site-container"> <div class="breadcrumb-container" role="navigation" aria-label="Breadcrumb"> <nav class="breadcrumb"> <a href="#" class="breadcrumb-item" aria-label="Home">Home</a> <div class="breadcrumb-arrow" aria-hidden="true"> <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="M9 6l6 6-6 6"></path> </svg> </div> <a href="#" class="breadcrumb-item" aria-label="Furniture">Furniture</a> <div class="breadcrumb-arrow" aria-hidden="true"> <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="M9 6l6 6-6 6"></path> </svg> </div> <a href="#" class="breadcrumb-item" aria-label="Living Room">Living Room</a> <div class="breadcrumb-arrow" aria-hidden="true"> <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="M9 6l6 6-6 6"></path> </svg> </div> <a href="#" class="breadcrumb-item active" aria-label="Modern Sofas" aria-current="page">Modern Sofas</a> </nav> </div> <div class="content-area" id="main-content"> <h1>Modern Sofas Collection</h1> <p>Explore our curated selection of contemporary sofas designed for both comfort and aesthetics. Each piece offers exceptional craftsmanship with premium materials that complement modern living spaces.</p> <div class="example-section"> <h2>Featured Designs</h2> <div class="product-preview"> <div class="product-card"> <div class="product-image"> <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='140' viewBox='0 0 200 140'%3E%3Crect width='200' height='120' fill='%23dae1e7'/%3E%3Crect x='40' y='40' width='120' height='30' rx='5' fill='%234a6fa1'/%3E%3Crect x='30' y='70' width='140' height='15' rx='3' fill='%232c3e50'/%3E%3C/svg%3E" alt="Meridian Linen Sofa"> </div> <div class="product-info"> <div class="product-title">Meridian Linen Sofa</div> <div class="product-price">$1,299</div> </div> </div> <div class="product-card"> <div class="product-image"> <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='140' viewBox='0 0 200 140'%3E%3Crect width='200' height='120' fill='%23e2e6ea'/%3E%3Crect x='30' y='45' width='140' height='25' rx='6' fill='%23e67e22'/%3E%3Crect x='20' y='70' width='160' height='15' rx='4' fill='%232c3e50'/%3E%3C/svg%3E" alt="Oslo Velvet Loveseat"> </div> <div class="product-info"> <div class="product-title">Oslo Velvet Loveseat</div> <div class="product-price">$949</div> </div> </div> </div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const breadcrumbItems = document.querySelectorAll('.breadcrumb-item'); // Add click effects to breadcrumb items breadcrumbItems.forEach(item => { item.addEventListener('click', function(e) { if (!this.classList.contains('active')) { e.preventDefault(); // Remove active class from all items breadcrumbItems.forEach(i => i.classList.remove('active')); // Add active class to clicked item this.classList.add('active'); // Visual click feedback this.style.transform = 'scale(0.97)'; setTimeout(() => { this.style.transform = ''; }, 150); // Update aria-current attribute for accessibility breadcrumbItems.forEach(i => i.removeAttribute('aria-current')); this.setAttribute('aria-current', 'page'); // Add subtle animation to the breadcrumb container const container = document.querySelector('.breadcrumb'); container.style.boxShadow = '0 10px 40px rgba(0, 0, 0, 0.15)'; setTimeout(() => { container.style.boxShadow = ''; }, 300); } }); }); // Add hover effects to product cards for demonstration const productCards = document.querySelectorAll('.product-card'); productCards.forEach(card => { card.addEventListener('click', function() { // Simulate a product selection with breadcrumb update const productName = this.querySelector('.product-title').textContent; const lastBreadcrumb = document.querySelector('.breadcrumb-item.active'); // Create new breadcrumb item const newItem = document.createElement('a'); newItem.href = '#'; newItem.className = 'breadcrumb-item active'; newItem.setAttribute('aria-current', 'page'); newItem.textContent = productName; // Create new arrow const newArrow = document.createElement('div'); newArrow.className = 'breadcrumb-arrow'; newArrow.setAttribute('aria-hidden', 'true'); newArrow.innerHTML = `<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="M9 6l6 6-6 6"></path> </svg>`; // Update breadcrumb const breadcrumb = document.querySelector('.breadcrumb'); lastBreadcrumb.classList.remove('active'); lastBreadcrumb.removeAttribute('aria-current'); breadcrumb.appendChild(newArrow); breadcrumb.appendChild(newItem); // Add animation effect to new breadcrumb item newItem.style.opacity = '0'; newItem.style.transform = 'translateX(10px)'; setTimeout(() => { newItem.style.opacity = '1'; newItem.style.transform = 'translateX(0)'; }, 10); // Update page title dynamically document.querySelector('h1').textContent = productName; }); }); // Add keyboard navigation for breadcrumbs document.addEventListener('keydown', function(e) { if (e.key === 'Tab' && !e.shiftKey) { const focusedElement = document.activeElement; if (focusedElement.classList.contains('breadcrumb-item')) { const nextSibling = focusedElement.nextElementSibling; if (nextSibling && nextSibling.nextElementSibling && nextSibling.nextElementSibling.classList.contains('breadcrumb-item')) { e.preventDefault(); nextSibling.nextElementSibling.focus(); } } } }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Enterprise Sidebar Toggle</title> <style> :root { --primary-color: #3a7bd5; --secondary-color: #00d2ff; --text-color: #333; --sidebar-bg: #f8f9fa; --main-bg: #ffffff; --border-color: #e9ecef; --hover-color: #f1f5f9; --accent-color: #ff6b6b; --success-color: #20c997; --shadow-color: rgba(0, 0, 0, 0.1); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background: var(--main-bg); color: var(--text-color); height: 100vh; display: flex; overflow: hidden; } .sidebar { height: 100%; width: 280px; background: var(--sidebar-bg); border-right: 1px solid var(--border-color); transition: transform 0.4s cubic-bezier(0.77, 0, 0.18, 1); position: relative; overflow-y: auto; overflow-x: hidden; box-shadow: 2px 0 5px var(--shadow-color); z-index: 100; } .sidebar.collapsed { transform: translateX(-280px); } .sidebar-header { display: flex; align-items: center; padding: 20px; border-bottom: 1px solid var(--border-color); background: linear-gradient(to right, var(--primary-color), var(--secondary-color)); color: white; } .logo { font-size: 22px; font-weight: 600; letter-spacing: 0.5px; } .sidebar-menu { padding: 20px 0; } .menu-section { margin-bottom: 15px; } .section-title { display: flex; align-items: center; justify-content: space-between; padding: 10px 20px; cursor: pointer; font-weight: 500; transition: all 0.3s ease; border-radius: 4px; margin: 0 10px 5px; position: relative; overflow: hidden; } .section-title::before { content: ''; position: absolute; left: 0; top: 0; height: 100%; width: 3px; background: transparent; transition: background 0.3s ease; } .section-title:hover { background: var(--hover-color); } .section-title:hover::before { background: var(--primary-color); } .section-title.active { background: var(--hover-color); } .section-title.active::before { background: var(--primary-color); } .arrow-icon { width: 20px; height: 20px; background: var(--primary-color); display: flex; align-items: center; justify-content: center; border-radius: 4px; position: relative; transition: transform 0.3s ease, background 0.3s ease; } .arrow-icon::before, .arrow-icon::after { content: ''; position: absolute; background: white; transition: transform 0.3s ease; } .arrow-icon::before { width: 10px; height: 2px; transform: rotate(45deg) translate(1px, 3px); } .arrow-icon::after { width: 10px; height: 2px; transform: rotate(-45deg) translate(1px, -3px); } .section-title.active .arrow-icon { transform: rotate(90deg); background: var(--accent-color); } .section-content { max-height: 0; overflow: hidden; transition: max-height 0.4s cubic-bezier(0.77, 0, 0.18, 1); } .section-content.open { max-height: 300px; } .menu-item { padding: 10px 30px; display: flex; align-items: center; cursor: pointer; transition: background 0.3s ease; border-radius: 4px; margin: 2px 10px; } .menu-item:hover { background: var(--hover-color); } .menu-item-icon { width: 16px; height: 16px; margin-right: 10px; display: inline-block; opacity: 0.7; } .menu-item.active { background: rgba(58, 123, 213, 0.1); position: relative; } .menu-item.active::before { content: ''; position: absolute; left: 0; top: 0; height: 100%; width: 3px; background: var(--primary-color); border-radius: 0 2px 2px 0; } .main-content { flex: 1; padding: 20px; background: var(--main-bg); position: relative; overflow-y: auto; } .toggle-button { position: absolute; right: -50px; top: 20px; width: 40px; height: 40px; background: white; border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; border: 1px solid var(--border-color); box-shadow: 0 2px 5px var(--shadow-color); z-index: 101; transition: transform 0.3s ease, background 0.3s ease; } .toggle-button:hover { background: var(--hover-color); } .toggle-icon { width: 20px; height: 20px; position: relative; transition: transform 0.4s cubic-bezier(0.77, 0, 0.18, 1); } .toggle-icon::before, .toggle-icon::after { content: ''; position: absolute; background: var(--primary-color); transition: transform 0.3s ease; } .toggle-icon::before { width: 12px; height: 2px; top: 9px; left: 4px; transform: rotate(45deg); } .toggle-icon::after { width: 12px; height: 2px; top: 9px; left: 4px; transform: rotate(-45deg); } .sidebar.collapsed .toggle-icon { transform: rotate(180deg); } .user-section { padding: 15px 20px; display: flex; align-items: center; border-top: 1px solid var(--border-color); margin-top: auto; background: rgba(58, 123, 213, 0.05); } .user-avatar { width: 40px; height: 40px; border-radius: 50%; background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); display: flex; align-items: center; justify-content: center; color: white; font-weight: 600; margin-right: 10px; } .user-info { flex: 1; } .user-name { font-weight: 500; font-size: 14px; } .user-role { color: #6c757d; font-size: 12px; } .status-badge { width: 8px; height: 8px; border-radius: 50%; background: var(--success-color); display: inline-block; margin-right: 5px; } .dashboard-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; margin-top: 20px; } .dashboard-card { background: white; border-radius: 8px; padding: 20px; box-shadow: 0 2px 10px var(--shadow-color); transition: transform 0.3s ease, box-shadow 0.3s ease; } .dashboard-card:hover { transform: translateY(-5px); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); } .card-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; } .card-title { font-weight: 600; color: var(--text-color); } .card-content { font-size: 24px; font-weight: 700; color: var(--primary-color); margin-bottom: 10px; } .card-footer { font-size: 12px; color: #6c757d; } .progress-container { margin-top: 10px; height: 6px; background: #e9ecef; border-radius: 3px; overflow: hidden; } .progress-bar { height: 100%; background: linear-gradient(to right, var(--primary-color), var(--secondary-color)); border-radius: 3px; transition: width 1s ease; } .notification-bell { position: relative; margin-left: 15px; cursor: pointer; } .notification-dot { position: absolute; top: -2px; right: -2px; width: 8px; height: 8px; background: var(--accent-color); border-radius: 50%; border: 2px solid white; } .breadcrumb { display: flex; align-items: center; padding: 10px 0; margin-bottom: 20px; font-size: 14px; } .breadcrumb-item { color: #6c757d; } .breadcrumb-item.active { color: var(--text-color); font-weight: 500; } .breadcrumb-separator { margin: 0 8px; color: #6c757d; } @media (max-width: 768px) { .sidebar { position: fixed; left: 0; top: 0; width: 240px; } .sidebar.collapsed { transform: translateX(-240px); } .main-content { margin-left: 0; } .dashboard-grid { grid-template-columns: 1fr; } } /* Animation for menu items */ @keyframes slideIn { from { opacity: 0; transform: translateX(-20px); } to { opacity: 1; transform: translateX(0); } } .menu-item { animation: slideIn 0.3s forwards; opacity: 0; } .menu-item:nth-child(1) { animation-delay: 0.1s; } .menu-item:nth-child(2) { animation-delay: 0.15s; } .menu-item:nth-child(3) { animation-delay: 0.2s; } .menu-item:nth-child(4) { animation-delay: 0.25s; } /* Interactive pulse effect for notification dot */ @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.2); } 100% { transform: scale(1); } } .notification-dot { animation: pulse 1.5s infinite; } /* Badge for new items */ .badge-new { background: var(--accent-color); color: white; font-size: 10px; padding: 2px 6px; border-radius: 10px; margin-left: 8px; font-weight: 600; } </style> </head> <body> <div class="sidebar"> <div class="sidebar-header"> <div class="logo">DataVision Pro</div> <div class="notification-bell"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"></path> <path d="M13.73 21a2 2 0 0 1-3.46 0"></path> </svg> <div class="notification-dot"></div> </div> </div> <div class="sidebar-menu"> <div class="menu-section"> <div class="section-title active"> <span>Dashboard</span> <div class="arrow-icon"></div> </div> <div class="section-content open"> <div class="menu-item active"> <span class="menu-item-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <rect x="3" y="3" width="7" height="7"></rect> <rect x="14" y="3" width="7" height="7"></rect> <rect x="14" y="14" width="7" height="7"></rect> <rect x="3" y="14" width="7" height="7"></rect> </svg> </span> Overview </div> <div class="menu-item"> <span class="menu-item-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="22 12 18 12 15 21 9 3 6 12 2 12"></polyline> </svg> </span> Analytics </div> <div class="menu-item"> <span class="menu-item-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"></path> </svg> </span> Reports <span class="badge-new">New</span> </div> </div> </div> <div class="menu-section"> <div class="section-title"> <span>Data Management</span> <div class="arrow-icon"></div> </div> <div class="section-content"> <div class="menu-item"> <span class="menu-item-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <ellipse cx="12" cy="5" rx="9" ry="3"></ellipse> <path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3"></path> <path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"></path> </svg> </span> Databases </div> <div class="menu-item"> <span class="menu-item-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path> <polyline points="14 2 14 8 20 8"></polyline> <line x1="16" y1="13" x2="8" y2="13"></line> <line x1="16" y1="17" x2="8" y2="17"></line> <polyline points="10 9 9 9 8 9"></polyline> </svg> </span> Data Sources </div> <div class="menu-item"> <span class="menu-item-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="16 3 21 3 21 8"></polyline> <line x1="4" y1="20" x2="21" y2="3"></line> <polyline points="21 16 21 21 16 21"></polyline> <line x1="15" y1="15" x2="21" y2="21"></line> <line x1="4" y1="4" x2="9" y2="9"></line> </svg> </span> Data Integration </div> </div> </div> <div class="menu-section"> <div class="section-title"> <span>Visualization</span> <div class="arrow-icon"></div> </div> <div class="section-content"> <div class="menu-item"> <span class="menu-item-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect> <line x1="3" y1="9" x2="21" y2="9"></line> <line x1="9" y1="21" x2="9" y2="9"></line> </svg> </span> Dashboards </div> <div class="menu-item"> <span class="menu-item-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"></path> <line x1="4" y1="22" x2="4" y2="15"></line> </svg> </span> Charts </div> </div> </div> <div class="menu-section"> <div class="section-title"> <span>Settings</span> <div class="arrow-icon"></div> </div> <div class="section-content"> <div class="menu-item"> <span class="menu-item-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="3"></circle> <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path> </svg> </span> Preferences </div> <div class="menu-item"> <span class="menu-item-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path> <circle cx="9" cy="7" r="4"></circle> <path d="M23 21v-2a4 4 0 0 0-3-3.87"></path> <path d="M16 3.13a4 4 0 0 1 0 7.75"></path> </svg> </span> User Management </div> </div> </div> </div> <div class="user-section"> <div class="user-avatar">JD</div> <div class="user-info"> <div class="user-name">Jane Doe</div> <div class="user-role"> <span class="status-badge"></span> System Administrator </div> </div> </div> <div class="toggle-button"> <div class="toggle-icon"></div> </div> </div> <div class="main-content"> <div class="breadcrumb"> <span class="breadcrumb-item">Home</span> <span class="breadcrumb-separator">/</span> <span class="breadcrumb-item active">Dashboard</span> </div> <h2>Enterprise Dashboard</h2> <p>Welcome to the DataVision Pro enterprise dashboard. Quickly access your key metrics and manage your data visualization needs.</p> <div class="dashboard-grid"> <div class="dashboard-card"> <div class="card-header"> <div class="card-title">Active Users</div> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path> <circle cx="9" cy="7" r="4"></circle> <path d="M23 21v-2a4 4 0 0 0-3-3.87"></path> <path d="M16 3.13a4 4 0 0 1 0 7.75"></path> </svg> </div> <div class="card-content">876</div> <div class="card-footer"> <span>+15% from last week</span> <div class="progress-container"> <div class="progress-bar" style="width: 72%"></div> </div> </div> </div> <div class="dashboard-card"> <div class="card-header"> <div class="card-title">Data Processing</div> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <line x1="12" y1="2" x2="12" y2="6"></line> <line x1="12" y1="18" x2="12" y2="22"></line> <line x1="4.93" y1="4.93" x2="7.76" y2="7.76"></line> <line x1="16.24" y1="16.24" x2="19.07" y2="19.07"></line> <line x1="2" y1="12" x2="6" y2="12"></line> <line x1="18" y1="12" x2="22" y2="12"></line> <line x1="4.93" y1="19.07" x2="7.76" y2="16.24"></line> <line x1="16.24" y1="7.76" x2="19.07" y2="4.93"></line> </svg> </div> <div class="card-content">94%</div> <div class="card-footer"> <span>5,234 requests processed</span> <div class="progress-container"> <div class="progress-bar" style="width: 94%"></div> </div> </div> </div> <div class="dashboard-card"> <div class="card-header"> <div class="card-title">System Uptime</div> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <rect x="2" y="3" width="20" height="14" rx="2" ry="2"></rect> <line x1="8" y1="21" x2="16" y2="21"></line> <line x1="12" y1="17" x2="12" y2="21"></line> </svg> </div> <div class="card-content">99.9%</div> <div class="card-footer"> <span>Last 30 days performance</span> <div class="progress-container"> <div class="progress-bar" style="width: 99.9%"></div> </div> </div> </div> <div class="dashboard-card"> <div class="card-header"> <div class="card-title">Data Storage</div> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"></path> <polyline points="3.27 6.96 12 12.01 20.73 6.96"></polyline> <line x1="12" y1="22.08" x2="12" y2="12"></line> </svg> </div> <div class="card-content">2.4 TB</div> <div class="card-footer"> <span>68% of total capacity</span> <div class="progress-container"> <div class="progress-bar" style="width: 68%"></div> </div> </div> </div> </div> </div> <script> // Toggle sidebar const toggleButton = document.querySelector('.toggle-button'); const sidebar = document.querySelector('.sidebar'); toggleButton.addEventListener('click', () => { sidebar.classList.toggle('collapsed'); }); // Toggle section content const sectionTitles = document.querySelectorAll('.section-title'); sectionTitles.forEach(title => { title.addEventListener('click', () => { title.classList.toggle('active'); const content = title.nextElementSibling; content.classList.toggle('open'); // If this title is being activated, deactivate others if (title.classList.contains('active')) { sectionTitles.forEach(otherTitle => { if (otherTitle !== title && otherTitle.classList.contains('active')) { otherTitle.classList.remove('active'); otherTitle.nextElementSibling.classList.remove('open'); } }); } }); }); // Handle menu item clicks const menuItems = document.querySelectorAll('.menu-item'); menuItems.forEach(item => { item.addEventListener('click', () => { // Remove active class from all menu items menuItems.forEach(i => i.classList.remove('active')); // Add active class to clicked item item.classList.add('active'); }); }); // Animate progress bars on load document.addEventListener('DOMContentLoaded', () => { const progressBars = document.querySelectorAll('.progress-bar'); progressBars.forEach(bar => { const width = bar.style.width; bar.style.width = '0'; setTimeout(() => { bar.style.width = width; }, 300); }); }); </script> </body> </html>