Understanding different perspectives can significantly enhance our problem-solving skills and creativity. By examining various viewpoints, we can gain a more comprehensive understanding of any given situation.
In this article, we will explore ten compelling examples of perspective. These examples will illustrate how shifting our viewpoint can lead to innovative solutions and deeper insights.
CODE1
Here's the code:
CODETEXT1
CODE2
Here's the code:
CODETEXT2
CODE3
Here's the code:
CODETEXT3
CODE4
Here's the code:
CODETEXT4
CODE5
Here's the code:
CODETEXT5
Subframe's drag-and-drop interface and intuitive, responsive canvas empower designers and developers to create pixel-perfect UI effortlessly. Loved by professionals across the industry, Subframe ensures your designs are both stunning and functional.
Start for free and experience the magic of seamless design 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 revolutionize your UI design process? With Subframe, you can create pixel-perfect interfaces and stunning perspectives effortlessly. Our drag-and-drop editor ensures efficiency and precision.
Don't wait! Start for free and begin designing immediately. Experience the power of seamless, intuitive design today!
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>3D Product Carousel</title> <style> :root { --primary-color: #f8f8f8; --accent-color: #2a2a2a; --text-color: #333; --highlight-color: #4a90e2; --shadow-color: rgba(0, 0, 0, 0.1); --transition-time: 0.4s; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', sans-serif; } body { background-color: var(--primary-color); color: var(--text-color); width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; overflow: hidden; perspective: 1200px; } .container { width: 100%; max-width: 700px; height: 700px; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 20px; position: relative; } .header { text-align: center; margin-bottom: 30px; z-index: 100; } h1 { font-size: 2.2rem; font-weight: 700; letter-spacing: -0.5px; margin-bottom: 8px; color: var(--accent-color); } .subtitle { font-size: 1rem; font-weight: 400; color: #666; max-width: 500px; } .carousel-container { width: 100%; height: 450px; position: relative; display: flex; justify-content: center; align-items: center; perspective: 1200px; } .carousel { position: relative; width: 100%; height: 100%; transform-style: preserve-3d; transition: transform 1s ease; } .product-card { position: absolute; width: 250px; height: 350px; border-radius: 16px; background: white; overflow: hidden; box-shadow: 0 10px 30px var(--shadow-color); display: flex; flex-direction: column; cursor: pointer; transform-style: preserve-3d; transition: all var(--transition-time) cubic-bezier(0.33, 1, 0.68, 1); transform: translate3d(0, 0, 0) rotateY(0) scale(1); opacity: 0.9; backface-visibility: hidden; } .product-card.active { opacity: 1; transform: translate3d(0, -20px, 100px) rotateY(0deg) scale(1.1); z-index: 10; } .product-image { height: 220px; width: 100%; background-position: center; background-size: cover; transition: transform var(--transition-time) ease; position: relative; } .product-card:hover .product-image { transform: scale(1.05); } .product-tag { position: absolute; top: 15px; left: 15px; padding: 5px 10px; background-color: var(--highlight-color); color: white; font-size: 0.7rem; font-weight: 600; border-radius: 100px; letter-spacing: 0.5px; transform: translateZ(20px); } .product-details { padding: 20px; display: flex; flex-direction: column; flex-grow: 1; justify-content: space-between; } .product-title { font-weight: 600; margin-bottom: 8px; font-size: 1rem; color: var(--accent-color); } .product-description { font-size: 0.8rem; color: #666; line-height: 1.4; margin-bottom: 15px; } .product-meta { display: flex; justify-content: space-between; align-items: center; margin-top: auto; } .product-price { font-weight: 700; font-size: 1.1rem; color: var(--accent-color); } .view-btn { padding: 8px 12px; background-color: var(--accent-color); color: white; border: none; border-radius: 6px; font-size: 0.75rem; font-weight: 600; cursor: pointer; transition: all 0.2s ease; } .view-btn:hover { background-color: var(--highlight-color); transform: translateY(-2px); } .controls { display: flex; justify-content: center; gap: 30px; margin-top: 30px; z-index: 100; } .control-btn { background: none; border: none; color: var(--accent-color); font-size: 2.5rem; cursor: pointer; transition: all 0.2s ease; width: 50px; height: 50px; display: flex; align-items: center; justify-content: center; border-radius: 50%; } .control-btn:hover { color: var(--highlight-color); transform: translateY(-3px); } .progress-dots { display: flex; justify-content: center; gap: 10px; margin-top: 20px; } .dot { width: 8px; height: 8px; border-radius: 50%; background-color: #ddd; transition: all 0.3s ease; } .dot.active { background-color: var(--highlight-color); transform: scale(1.3); } @media (max-width: 700px) { h1 { font-size: 1.8rem; } .subtitle { font-size: 0.9rem; padding: 0 20px; } .carousel-container { height: 400px; } .product-card { width: 220px; height: 320px; } .product-image { height: 180px; } } @media (max-width: 500px) { .product-card { width: 200px; height: 300px; } .product-image { height: 160px; } .product-details { padding: 15px; } .product-title { font-size: 0.9rem; } .product-description { font-size: 0.75rem; } } /* Custom animation for "breathing" effect */ @keyframes breathe { 0% { transform: scale(1); } 50% { transform: scale(1.02); } 100% { transform: scale(1); } } .breathe { animation: breathe 4s infinite ease-in-out; } /* Custom loading animation */ .loading-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: var(--primary-color); display: flex; justify-content: center; align-items: center; z-index: 1000; transition: opacity 0.5s ease, visibility 0.5s; } .loader { width: 48px; height: 48px; border: 5px solid var(--accent-color); border-bottom-color: transparent; border-radius: 50%; animation: rotation 1s linear infinite; } @keyframes rotation { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .loading-overlay.hidden { opacity: 0; visibility: hidden; } </style> </head> <body> <div class="loading-overlay"> <div class="loader"></div> </div> <div class="container"> <div class="header"> <h1>Discover Premium Products</h1> <p class="subtitle">Explore our collection from every angle with our interactive 3D viewer</p> </div> <div class="carousel-container"> <div class="carousel" id="carousel"> <!-- Product cards will be dynamically added here --> </div> </div> <div class="controls"> <button class="control-btn prev">⟨</button> <button class="control-btn next">⟩</button> </div> <div class="progress-dots" id="progress-dots"> <!-- Dots will be added dynamically --> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Products data const products = [ { title: "Eco-Friendly Water Bottle", description: "Triple-insulated stainless steel design keeps drinks cold for 24 hours or hot for 12 hours.", price: "$32.99", image: "https://images.unsplash.com/photo-1602143407151-7111542de6e8?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1587&q=80", tag: "Bestseller" }, { title: "Modern Minimalist Watch", description: "Swiss movement, sapphire crystal, and Italian leather band. Water-resistant to 50 meters.", price: "$149.95", image: "https://images.unsplash.com/photo-1542496658-e33a6d0d50f6?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80", tag: "New Arrival" }, { title: "Smart Home Speaker", description: "Room-filling sound with advanced voice recognition and smart home integration.", price: "$89.99", image: "https://images.unsplash.com/photo-1589003077984-894e133dabab?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1364&q=80", tag: "Limited Edition" }, { title: "Premium Leather Wallet", description: "Full-grain leather with RFID blocking technology and minimalist design.", price: "$59.95", image: "https://images.unsplash.com/photo-1627123424574-724758594e93?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1587&q=80", tag: "Handcrafted" }, { title: "Noise-Cancelling Headphones", description: "40-hour battery life with industry-leading noise cancellation and sound quality.", price: "$249.00", image: "https://images.unsplash.com/photo-1546435770-a3e426bf472b?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1465&q=80", tag: "Premium" } ]; const carousel = document.getElementById('carousel'); const progressDots = document.getElementById('progress-dots'); const prevBtn = document.querySelector('.prev'); const nextBtn = document.querySelector('.next'); const loadingOverlay = document.querySelector('.loading-overlay'); let activeIndex = 0; const cardCount = products.length; // Create product cards function createProductCards() { products.forEach((product, index) => { const productCard = document.createElement('div'); productCard.className = 'product-card'; if (index === activeIndex) { productCard.classList.add('active'); } productCard.innerHTML = ` <div class="product-image" style="background-image: url('${product.image}')"> <div class="product-tag">${product.tag}</div> </div> <div class="product-details"> <div> <h3 class="product-title">${product.title}</h3> <p class="product-description">${product.description}</p> </div> <div class="product-meta"> <div class="product-price">${product.price}</div> <button class="view-btn">View Details</button> </div> </div> `; carousel.appendChild(productCard); // Create progress dot const dot = document.createElement('div'); dot.className = 'dot'; if (index === activeIndex) { dot.classList.add('active'); } progressDots.appendChild(dot); }); } // Position cards in 3D space function positionCards() { const cards = document.querySelectorAll('.product-card'); cards.forEach((card, index) => { const theta = (2 * Math.PI / cardCount) * index; const radius = 300; const x = Math.sin(theta) * radius; const z = Math.cos(theta) * radius; const rotY = (theta * 180) / Math.PI; card.style.transform = `translate3d(${x}px, 0, ${z}px) rotateY(${rotY}deg)`; // Add 3D tilt effect on hover card.addEventListener('mousemove', (e) => { if (!card.classList.contains('active')) return; const cardRect = card.getBoundingClientRect(); const cardCenterX = cardRect.left + cardRect.width / 2; const cardCenterY = cardRect.top + cardRect.height / 2; // Calculate mouse position relative to card center const mouseX = e.clientX - cardCenterX; const mouseY = e.clientY - cardCenterY; // Calculate tilt angles (limited range for subtle effect) const tiltX = (mouseY / (cardRect.height / 2)) * 5; // -5 to 5 degrees const tiltY = (mouseX / (cardRect.width / 2)) * -5; // -5 to 5 degrees card.style.transform = `translate3d(${x}px, -20px, ${z + 100}px) rotateY(${rotY + tiltY}deg) rotateX(${tiltX}deg) scale(1.1)`; }); card.addEventListener('mouseleave', () => { if (card.classList.contains('active')) { card.style.transform = `translate3d(${x}px, -20px, ${z + 100}px) rotateY(${rotY}deg) rotateX(0) scale(1.1)`; } else { card.style.transform = `translate3d(${x}px, 0, ${z}px) rotateY(${rotY}deg)`; } }); // Add click handler to make a card active card.addEventListener('click', () => { if (!card.classList.contains('active')) { rotateCarousel(index); } }); }); } // Rotate carousel to specific index function rotateCarousel(newIndex) { activeIndex = newIndex; const theta = (2 * Math.PI / cardCount) * activeIndex; const rotY = (theta * 180) / Math.PI; carousel.style.transform = `rotateY(${-rotY}deg)`; // Update active states const cards = document.querySelectorAll('.product-card'); const dots = document.querySelectorAll('.dot'); cards.forEach((card, index) => { if (index === activeIndex) { card.classList.add('active'); // Reposition the active card with a slight elevation const theta = (2 * Math.PI / cardCount) * index; const radius = 300; const x = Math.sin(theta) * radius; const z = Math.cos(theta) * radius; const rotY = (theta * 180) / Math.PI; card.style.transform = `translate3d(${x}px, -20px, ${z + 100}px) rotateY(${rotY}deg) scale(1.1)`; } else { card.classList.remove('active'); // Reset non-active cards const theta = (2 * Math.PI / cardCount) * index; const radius = 300; const x = Math.sin(theta) * radius; const z = Math.cos(theta) * radius; const rotY = (theta * 180) / Math.PI; card.style.transform = `translate3d(${x}px, 0, ${z}px) rotateY(${rotY}deg)`; } }); dots.forEach((dot, index) => { if (index === activeIndex) { dot.classList.add('active'); } else { dot.classList.remove('active'); } }); } // Initialize carousel createProductCards(); // Simulate loading delay for dramatic effect setTimeout(() => { loadingOverlay.classList.add('hidden'); positionCards(); // Add "breathe" effect to the first card for initial attention const firstCard = document.querySelector('.product-card.active'); firstCard.classList.add('breathe'); setTimeout(() => { firstCard.classList.remove('breathe'); }, 3000); }, 1500); // Navigation button handlers prevBtn.addEventListener('click', () => { rotateCarousel((activeIndex - 1 + cardCount) % cardCount); }); nextBtn.addEventListener('click', () => { rotateCarousel((activeIndex + 1) % cardCount); }); // Add dot click handlers setTimeout(() => { const dots = document.querySelectorAll('.dot'); dots.forEach((dot, index) => { dot.addEventListener('click', () => { rotateCarousel(index); }); }); }, 1500); // Handle key navigation document.addEventListener('keydown', (e) => { if (e.key === 'ArrowLeft') { rotateCarousel((activeIndex - 1 + cardCount) % cardCount); } else if (e.key === 'ArrowRight') { rotateCarousel((activeIndex + 1) % cardCount); } }); // Handle "View Details" button clicks document.addEventListener('click', (e) => { if (e.target.classList.contains('view-btn')) { e.stopPropagation(); const card = e.target.closest('.product-card'); const index = Array.from(document.querySelectorAll('.product-card')).indexOf(card); // Make the card do a full 360 spin for fun card.style.transition = "transform 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275)"; card.style.transform = `${card.style.transform} rotateY(360deg)`; setTimeout(() => { card.style.transition = "all var(--transition-time) cubic-bezier(0.33, 1, 0.68, 1)"; // Reset to original position after animation if (card.classList.contains('active')) { const theta = (2 * Math.PI / cardCount) * index; const radius = 300; const x = Math.sin(theta) * radius; const z = Math.cos(theta) * radius; const rotY = (theta * 180) / Math.PI; card.style.transform = `translate3d(${x}px, -20px, ${z + 100}px) rotateY(${rotY}deg) scale(1.1)`; } }, 800); } }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Nexus Command // Gaming Dashboard</title> <style> :root { --primary: #0cf; --secondary: #f0c; --tertiary: #ff0; --background: #0a0e17; --panel: #12172a; --panel-dark: #0d1222; --text: #e1e6f0; --muted: #6f7a98; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Exo 2', sans-serif; } @font-face { font-family: 'Exo 2'; src: url('https://fonts.googleapis.com/css2?family=Exo+2:wght@400;600;800&display=swap'); } body { background-color: var(--background); color: var(--text); perspective: 1000px; overflow: hidden; width: 100%; height: 100vh; } .dashboard { width: 100%; height: 100vh; display: grid; grid-template-columns: 64px 1fr; grid-template-rows: 60px 1fr; grid-template-areas: "sidebar header" "sidebar main"; transform-style: preserve-3d; transform: rotateX(2deg); transition: transform 0.5s ease-out; } .dashboard:hover { transform: rotateX(0deg); } .header { grid-area: header; background-color: var(--panel-dark); padding: 0 20px; display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid rgba(255, 255, 255, 0.1); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); z-index: 10; } .search-bar { display: flex; align-items: center; background-color: rgba(255, 255, 255, 0.05); border-radius: 6px; padding: 6px 12px; width: 260px; } .search-bar input { background: transparent; border: none; color: var(--text); margin-left: 8px; width: 100%; outline: none; } .search-bar i { color: var(--muted); } .user-profile { display: flex; align-items: center; gap: 10px; } .avatar { width: 36px; height: 36px; border-radius: 50%; background: linear-gradient(45deg, var(--primary), var(--secondary)); display: flex; align-items: center; justify-content: center; box-shadow: 0 0 10px rgba(12, 204, 255, 0.6); } .sidebar { grid-area: sidebar; background-color: var(--panel-dark); padding: 20px 0; display: flex; flex-direction: column; align-items: center; gap: 30px; border-right: 1px solid rgba(255, 255, 255, 0.05); box-shadow: 4px 0 12px rgba(0, 0, 0, 0.2); z-index: 20; } .logo { width: 40px; height: 40px; background: linear-gradient(135deg, var(--primary), var(--secondary)); border-radius: 12px; display: flex; align-items: center; justify-content: center; font-weight: bold; font-size: 18px; transform: rotate(-5deg); box-shadow: 0 0 15px rgba(12, 204, 255, 0.4); margin-bottom: 20px; } .nav-item { width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; border-radius: 10px; color: var(--muted); font-size: 18px; transition: all 0.3s; position: relative; cursor: pointer; } .nav-item:hover, .nav-item.active { color: #fff; background-color: rgba(255, 255, 255, 0.1); transform: translateZ(20px); } .nav-item.active::before { content: ''; position: absolute; left: -10px; top: 50%; width: 4px; height: 20px; background: linear-gradient(to bottom, var(--primary), var(--secondary)); transform: translateY(-50%); border-radius: 0 2px 2px 0; } .main-content { grid-area: main; display: grid; grid-template-columns: 1fr 300px; grid-template-rows: 1fr; gap: 20px; padding: 20px; overflow: hidden; transform-style: preserve-3d; } .game-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); grid-template-rows: auto; gap: 20px; overflow-y: auto; padding-right: 10px; transform-style: preserve-3d; max-height: calc(100vh - 100px); } .game-grid::-webkit-scrollbar { width: 5px; } .game-grid::-webkit-scrollbar-track { background: rgba(255, 255, 255, 0.05); border-radius: 10px; } .game-grid::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.2); border-radius: 10px; } .game-card { background-color: var(--panel); border-radius: 12px; overflow: hidden; box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2); transition: all 0.4s ease; transform-style: preserve-3d; transform: translateZ(0px); position: relative; cursor: pointer; } .game-card:hover { transform: translateZ(20px) scale(1.03); box-shadow: 0 12px 24px rgba(0, 0, 0, 0.3), 0 0 20px rgba(12, 204, 255, 0.3); } .game-img { width: 100%; height: 120px; object-fit: cover; border-bottom: 2px solid rgba(255, 255, 255, 0.1); transition: all 0.5s ease; } .game-card:hover .game-img { filter: brightness(1.2); } .game-info { padding: 15px; } .game-title { font-size: 16px; font-weight: 600; margin-bottom: 5px; } .game-meta { display: flex; justify-content: space-between; font-size: 12px; color: var(--muted); } .game-stats { display: flex; align-items: center; gap: 8px; margin-top: 8px; } .stat { display: flex; align-items: center; gap: 4px; font-size: 11px; } .progress-bar { height: 3px; width: 100%; background-color: rgba(255, 255, 255, 0.1); margin-top: 12px; border-radius: 3px; overflow: hidden; } .progress-fill { height: 100%; background: linear-gradient(90deg, var(--primary), var(--secondary)); border-radius: 3px; width: 0; transition: width 1s ease; } .game-card:hover .progress-fill { width: 65%; } .side-panel { background-color: var(--panel); border-radius: 12px; padding: 20px; display: flex; flex-direction: column; gap: 20px; box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2); max-height: calc(100vh - 100px); transform-style: preserve-3d; transform: translateZ(10px); } .section-title { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; color: var(--text); font-weight: 600; } .viewall { color: var(--primary); font-size: 12px; cursor: pointer; text-decoration: none; } .achievements { display: flex; flex-direction: column; gap: 12px; } .achievement { display: flex; align-items: center; gap: 12px; background-color: rgba(255, 255, 255, 0.03); padding: 10px; border-radius: 8px; transition: all 0.3s; } .achievement:hover { background-color: rgba(255, 255, 255, 0.08); transform: translateZ(10px); } .achievement-icon { width: 40px; height: 40px; background: linear-gradient(135deg, #2a3a8c, #5a3a8c); border-radius: 8px; display: flex; align-items: center; justify-content: center; color: #fff; font-size: 16px; } .achievement-info { flex: 1; } .achievement-title { font-size: 14px; margin-bottom: 2px; } .achievement-game { font-size: 11px; color: var(--muted); } .playtime-chart { height: 160px; position: relative; margin-top: 10px; } .chart-bars { display: flex; justify-content: space-between; align-items: flex-end; height: 120px; } .chart-bar { width: 8px; background: linear-gradient(to top, var(--primary), var(--secondary)); border-radius: 4px; height: 0; transition: height.6s cubic-bezier(0.34, 1.56, 0.64, 1); } .chart-labels { display: flex; justify-content: space-between; margin-top: 8px; } .chart-label { font-size: 10px; color: var(--muted); width: 20px; text-align: center; } .notification-badge { position: absolute; top: -5px; right: -5px; background-color: var(--secondary); color: white; font-size: 10px; width: 16px; height: 16px; border-radius: 50%; display: flex; align-items: center; justify-content: center; } .rotating-preview { position: relative; height: 150px; width: 100%; perspective: 600px; margin-top: 15px; } .cube { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transform: translateZ(-100px); animation: rotate 20s infinite linear; } .cube-face { position: absolute; width: 100%; height: 100%; background-color: rgba(255, 255, 255, 0.05); border: 1px solid rgba(12, 204, 255, 0.3); display: flex; align-items: center; justify-content: center; font-size: 20px; color: var(--primary); border-radius: 8px; background-size: cover; background-position: center; } .front { transform: rotateY(0deg) translateZ(100px); background-image: url('https://images.unsplash.com/photo-1542751371-adc38448a05e?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80'); } .back { transform: rotateY(180deg) translateZ(100px); background-image: url('https://images.unsplash.com/photo-1593305841991-05c297ba4575?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80'); } .right { transform: rotateY(90deg) translateZ(100px); background-image: url('https://images.unsplash.com/photo-1550745165-9bc0b252726f?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80'); } .left { transform: rotateY(-90deg) translateZ(100px); background-image: url('https://images.unsplash.com/photo-1511512578047-dfb367046420?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80'); } @keyframes rotate { 0% { transform: translateZ(-100px) rotateY(0deg); } 100% { transform: translateZ(-100px) rotateY(360deg); } } .data-visualization { height: 160px; position: relative; transform-style: preserve-3d; perspective: 800px; } .data-point { position: absolute; width: 12px; height: 12px; border-radius: 50%; background: var(--primary); box-shadow: 0 0 8px rgba(12, 204, 255, 0.8); transform-style: preserve-3d; transition: all 0.5s ease; } .neon-glow { text-shadow: 0 0 10px var(--primary); } .secondary-glow { text-shadow: 0 0 10px var(--secondary); } .header-title { font-size: 18px; font-weight: 600; letter-spacing: 1px; } @media screen and (max-width: 768px) { .dashboard { grid-template-columns: 1fr; grid-template-rows: 60px 1fr; grid-template-areas: "header" "main"; } .sidebar { display: none; } .main-content { grid-template-columns: 1fr; padding: 10px; } .game-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); } .side-panel { display: none; } } /* Adds grid lines to the background for futuristic feel */ .main-content::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(rgba(12, 204, 255, 0.03) 1px, transparent 1px), linear-gradient(90deg, rgba(12, 204, 255, 0.03) 1px, transparent 1px); background-size: 20px 20px; z-index: -1; pointer-events: none; } </style> </head> <body> <div class="dashboard"> <header class="header"> <div class="header-title">NEXUS<span class="neon-glow">COMMAND</span></div> <div class="search-bar"> <i class="fas fa-search"></i> <input type="text" placeholder="Search games, achievements, stats..."> </div> <div class="user-profile"> <span class="level">LVL 42</span> <div class="avatar"> <i class="fas fa-user"></i> </div> </div> </header> <aside class="sidebar"> <div class="logo">NC</div> <div class="nav-item active"> <i class="fas fa-gamepad"></i> </div> <div class="nav-item"> <i class="fas fa-trophy"></i> </div> <div class="nav-item"> <i class="fas fa-users"></i> <div class="notification-badge">3</div> </div> <div class="nav-item"> <i class="fas fa-chart-bar"></i> </div> <div class="nav-item"> <i class="fas fa-store"></i> </div> <div class="nav-item"> <i class="fas fa-cog"></i> </div> </aside> <main class="main-content"> <div class="game-grid"> <div class="game-card"> <img class="game-img" src="https://images.unsplash.com/photo-1552820728-8b83bb6b773f?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80" alt="Stellar Odyssey"> <div class="game-info"> <div class="game-title">Stellar Odyssey</div> <div class="game-meta"> <span>Space RPG</span> <span>Last: 2h ago</span> </div> <div class="game-stats"> <div class="stat"> <i class="fas fa-clock"></i> <span>28h</span> </div> <div class="stat"> <i class="fas fa-trophy"></i> <span>16/24</span> </div> </div> <div class="progress-bar"> <div class="progress-fill"></div> </div> </div> </div> <div class="game-card"> <img class="game-img" src="https://images.unsplash.com/photo-1511882150382-421056c89033?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80" alt="Neon Drift"> <div class="game-info"> <div class="game-title">Neon Drift</div> <div class="game-meta"> <span>Racing</span> <span>Last: 5d ago</span> </div> <div class="game-stats"> <div class="stat"> <i class="fas fa-clock"></i> <span>42h</span> </div> <div class="stat"> <i class="fas fa-trophy"></i> <span>22/30</span> </div> </div> <div class="progress-bar"> <div class="progress-fill"></div> </div> </div> </div> <div class="game-card"> <img class="game-img" src="https://images.unsplash.com/photo-1542751371-adc38448a05e?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80" alt="Void Conqueror"> <div class="game-info"> <div class="game-title">Void Conqueror</div> <div class="game-meta"> <span>Strategy</span> <span>Last: 1d ago</span> </div> <div class="game-stats"> <div class="stat"> <i class="fas fa-clock"></i> <span>54h</span> </div> <div class="stat"> <i class="fas fa-trophy"></i> <span>18/35</span> </div> </div> <div class="progress-bar"> <div class="progress-fill"></div> </div> </div> </div> <div class="game-card"> <img class="game-img" src="https://images.unsplash.com/photo-1550745165-9bc0b252726f?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80" alt="Cyber Phantom"> <div class="game-info"> <div class="game-title">Cyber Phantom</div> <div class="game-meta"> <span>Action</span> <span>Last: 4h ago</span> </div> <div class="game-stats"> <div class="stat"> <i class="fas fa-clock"></i> <span>36h</span> </div> <div class="stat"> <i class="fas fa-trophy"></i> <span>12/20</span> </div> </div> <div class="progress-bar"> <div class="progress-fill"></div> </div> </div> </div> <div class="game-card"> <img class="game-img" src="https://images.unsplash.com/photo-1509198397868-475647b2a1e5?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80" alt="Aether Combat"> <div class="game-info"> <div class="game-title">Aether Combat</div> <div class="game-meta"> <span>FPS</span> <span>Last: 12h ago</span> </div> <div class="game-stats"> <div class="stat"> <i class="fas fa-clock"></i> <span>82h</span> </div> <div class="stat"> <i class="fas fa-trophy"></i> <span>26/40</span> </div> </div> <div class="progress-bar"> <div class="progress-fill"></div> </div> </div> </div> <div class="game-card"> <img class="game-img" src="https://images.unsplash.com/photo-1548484352-ea579e5233a8?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80" alt="Rogue Protocol"> <div class="game-info"> <div class="game-title">Rogue Protocol</div> <div class="game-meta"> <span>Stealth</span> <span>Last: 3d ago</span> </div> <div class="game-stats"> <div class="stat"> <i class="fas fa-clock"></i> <span>19h</span> </div> <div class="stat"> <i class="fas fa-trophy"></i> <span>9/15</span> </div> </div> <div class="progress-bar"> <div class="progress-fill"></div> </div> </div> </div> </div> <div class="side-panel"> <div> <div class="section-title"> <span>Game Preview</span> <a href="#" class="viewall">ROTATE</a> </div> <div class="rotating-preview"> <div class="cube"> <div class="cube-face front"></div> <div class="cube-face back"></div> <div class="cube-face right"></div> <div class="cube-face left"></div> </div> </div> </div> <div> <div class="section-title"> <span>Recent <span class="secondary-glow">Achievements</span></span> <a href="#" class="viewall">VIEW ALL</a> </div> <div class="achievements"> <div class="achievement"> <div class="achievement-icon"> <i class="fas fa-crown"></i> </div> <div class="achievement-info"> <div class="achievement-title">Master Tactician</div> <div class="achievement-game">Void Conqueror</div> </div> </div> <div class="achievement"> <div class="achievement-icon"> <i class="fas fa-rocket"></i> </div> <div class="achievement-info"> <div class="achievement-title">Speed Demon</div> <div class="achievement-game">Neon Drift</div> </div> </div> <div class="achievement"> <div class="achievement-icon"> <i class="fas fa-skull"></i> </div> <div class="achievement-info"> <div class="achievement-title">Phantom Assassin</div> <div class="achievement-game">Cyber Phantom</div> </div> </div> </div> </div> <div> <div class="section-title"> <span>Weekly <span class="neon-glow">Playtime</span></span> <a href="#" class="viewall">DETAILS</a> </div> <div class="playtime-chart"> <div class="chart-bars"> <div class="chart-bar" style="height: 40%;"></div> <div class="chart-bar" style="height: 70%;"></div> <div class="chart-bar" style="height: 50%;"></div> <div class="chart-bar" style="height: 30%;"></div> <div class="chart-bar" style="height: 90%;"></div> <div class="chart-bar" style="height: 80%;"></div> <div class="chart-bar" style="height: 60%;"></div> </div> <div class="chart-labels"> <div class="chart-label">MON</div> <div class="chart-label">TUE</div> <div class="chart-label">WED</div> <div class="chart-label">THU</div> <div class="chart-label">FRI</div> <div class="chart-label">SAT</div> <div class="chart-label">SUN</div> </div> </div> </div> <div> <div class="section-title"> <span>3D Data <span class="secondary-glow">Visualization</span></span> </div> <div class="data-visualization" id="dataViz"> <!-- Data points will be added via JS --> </div> </div> </div> </main> </div> <script src="https://kit.fontawesome.com/a076d05399.js" crossorigin="anonymous"></script> <script> document.addEventListener('DOMContentLoaded', function() { // Initialize chart bars animation const chartBars = document.querySelectorAll('.chart-bar'); setTimeout(() => { chartBars.forEach(bar => { const height = bar.style.height; bar.style.height = '0'; setTimeout(() => { bar.style.height = height; }, 100); }); }, 300); // Create 3D data visualization const dataViz = document.getElementById('dataViz'); const numPoints = 30; for (let i = 0; i < numPoints; i++) { const point = document.createElement('div'); point.className = 'data-point'; // Random position in 3D space const x = Math.random() * 100; const y = Math.random() * 100; const z = Math.random() * 50; point.style.left = `${x}%`; point.style.top = `${y}%`; point.style.transform = `translateZ(${z}px)`; // Alternate colors if (i % 3 === 0) { point.style.background = 'var(--secondary)'; point.style.boxShadow = '0 0 8px rgba(255, 0, 204, 0.8)'; } else if (i % 3 === 1) { point.style.background = 'var(--tertiary)'; point.style.boxShadow = '0 0 8px rgba(255, 255, 0, 0.8)'; } dataViz.appendChild(point); } // Add hover functionality to game cards for better 3D effect const gameCards = document.querySelectorAll('.game-card'); gameCards.forEach(card => { card.addEventListener('mousemove', function(e) { const rect = this.getBoundingClientRect(); const x = e.clientX - rect.left; // x position within the element const y = e.clientY - rect.top; // y position within the element // Calculate rotation based on mouse position const rotateY = ((x / rect.width) - 0.5) * 20; // -10 to 10 degrees const rotateX = ((y / rect.height) - 0.5) * -20; // 10 to -10 degrees this.style.transform = `translateZ(20px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`; }); card.addEventListener('mouseleave', function() { this.style.transform = 'translateZ(0px)'; }); }); // Add interaction to data visualization dataViz.addEventListener('mousemove', function(e) { const rect = this.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; const dataPoints = document.querySelectorAll('.data-point'); dataPoints.forEach(point => { const pointRect = point.getBoundingClientRect(); const pointX = pointRect.left + pointRect.width / 2 - rect.left; const pointY = pointRect.top + pointRect.height / 2 - rect.top; const distance = Math.sqrt(Math.pow(x - pointX, 2) + Math.pow(y - pointY, 2)); const scale = Math.max(1, 2 - distance / 50); const z = Math.max(0, 100 - distance) * 2; point.style.transform = `translateZ(${z}px) scale(${scale})`; }); }); dataViz.addEventListener('mouseleave', function() { const dataPoints = document.querySelectorAll('.data-point'); dataPoints.forEach((point, i) => { const z = Math.random() * 50; point.style.transform = `translateZ(${z}px) scale(1)`; }); }); // Make dashboard feel alive with subtle movement document.addEventListener('mousemove', function(e) { const dashboard = document.querySelector('.dashboard'); const x = e.clientX / window.innerWidth - 0.5; const y = e.clientY / window.innerHeight - 0.5; dashboard.style.transform = `rotateX(${2 - y * 2}deg) rotateY(${x * 2}deg)`; }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Creative Portfolio Showcase</title> <style> @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;500;700;900&family=Space+Grotesk:wght@400;700&display=swap'); :root { --primary: #fc3a6b; --secondary: #3a8bfc; --accent: #f9c22e; --dark: #111111; --light: #fafafa; --transition: all 0.4s cubic-bezier(0.165, 0.84, 0.44, 1); } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Space Grotesk', sans-serif; background-color: var(--dark); color: var(--light); overflow-x: hidden; position: relative; width: 100%; height: 100%; } .container { width: 100%; height: 100vh; max-width: 700px; max-height: 700px; margin: 0 auto; padding: 1rem; overflow: hidden; position: relative; } header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem; } .logo { font-weight: 900; font-size: 1.5rem; background: linear-gradient(90deg, var(--primary), var(--secondary)); -webkit-background-clip: text; color: transparent; text-transform: uppercase; letter-spacing: -1px; } .menu-toggle { background: none; border: none; color: var(--light); font-size: 1.25rem; cursor: pointer; z-index: 100; } .gallery-container { position: relative; height: calc(100% - 100px); perspective: 2000px; transform-style: preserve-3d; overflow: hidden; } .gallery-items { position: relative; width: 100%; height: 100%; display: grid; grid-template-columns: repeat(6, 1fr); grid-template-rows: repeat(6, 1fr); gap: 10px; transform-style: preserve-3d; } .gallery-item { position: relative; overflow: hidden; border-radius: 8px; box-shadow: 0 15px 35px rgba(0, 0, 0, 0.2); cursor: pointer; transition: var(--transition); transform-style: preserve-3d; filter: grayscale(60%); } .gallery-item:hover { filter: grayscale(0%); transform: translateZ(20px); } .gallery-item:nth-child(1) { grid-area: 1 / 1 / 4 / 4; background-color: var(--primary); } .gallery-item:nth-child(2) { grid-area: 1 / 4 / 3 / 7; background-color: var(--secondary); } .gallery-item:nth-child(3) { grid-area: 4 / 1 / 7 / 3; background-color: var(--accent); } .gallery-item:nth-child(4) { grid-area: 3 / 4 / 7 / 7; background-color: var(--primary); } .gallery-item:nth-child(5) { grid-area: 4 / 3 / 7 / 4; background-color: var(--secondary); } .gallery-item img { width: 100%; height: 100%; object-fit: cover; transition: var(--transition); } .gallery-item:hover img { transform: scale(1.05); } .item-content { position: absolute; bottom: 0; left: 0; width: 100%; padding: 1.5rem; background: linear-gradient(0deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0) 100%); transform: translateY(100%); transition: var(--transition); opacity: 0; } .gallery-item:hover .item-content { transform: translateY(0); opacity: 1; } .item-content h3 { font-family: 'Poppins', sans-serif; font-weight: 700; font-size: 1.2rem; margin-bottom: 0.5rem; color: var(--light); } .item-content p { font-size: 0.875rem; color: var(--light); opacity: 0.8; } .item-tags { display: flex; gap: 0.5rem; margin-top: 0.5rem; } .item-tag { font-size: 0.7rem; padding: 0.25rem 0.5rem; border-radius: 4px; background-color: rgba(255, 255, 255, 0.2); } .overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.9); display: flex; justify-content: center; align-items: center; z-index: 1000; opacity: 0; pointer-events: none; transition: var(--transition); } .overlay.active { opacity: 1; pointer-events: all; } .overlay-content { position: relative; max-width: 90%; max-height: 90%; } .overlay-content img { max-width: 100%; max-height: 80vh; border-radius: 8px; box-shadow: 0 25px 50px rgba(0, 0, 0, 0.5); } .overlay-details { margin-top: 1rem; max-width: 600px; } .overlay-details h2 { font-family: 'Poppins', sans-serif; font-weight: 900; font-size: 2rem; margin-bottom: 0.5rem; background: linear-gradient(90deg, var(--primary), var(--secondary)); -webkit-background-clip: text; color: transparent; } .overlay-details p { margin-bottom: 1rem; line-height: 1.6; } .close-overlay { position: absolute; top: -40px; right: 0; background: none; border: none; color: var(--light); font-size: 1.5rem; cursor: pointer; } .navigation { position: absolute; width: 100%; bottom: 1rem; display: flex; justify-content: center; gap: 0.5rem; } .nav-dot { width: 8px; height: 8px; border-radius: 50%; background-color: rgba(255, 255, 255, 0.3); transition: var(--transition); cursor: pointer; } .nav-dot.active { background-color: var(--primary); transform: scale(1.5); } .cursor { position: fixed; width: 40px; height: 40px; border-radius: 50%; border: 2px solid var(--primary); pointer-events: none; transform: translate(-50%, -50%); transition: transform 0.1s ease, width 0.3s ease, height 0.3s ease, border-color 0.3s ease; z-index: 9999; mix-blend-mode: difference; } .cursor-dot { position: fixed; width: 8px; height: 8px; background-color: var(--secondary); border-radius: 50%; pointer-events: none; transform: translate(-50%, -50%); transition: 0.1s ease; z-index: 10000; } .cursor.hover { width: 60px; height: 60px; border-color: var(--accent); } @media (max-width: 600px) { .gallery-items { grid-template-columns: repeat(2, 1fr); grid-template-rows: auto; gap: 10px; } .gallery-item:nth-child(1) { grid-area: auto; } .gallery-item:nth-child(2) { grid-area: auto; } .gallery-item:nth-child(3) { grid-area: auto; } .gallery-item:nth-child(4) { grid-area: auto; } .gallery-item:nth-child(5) { grid-area: auto; } .item-content h3 { font-size: 1rem; } .item-content p { font-size: 0.75rem; } } .pattern { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: radial-gradient(rgba(255, 255, 255, 0.05) 1px, transparent 1px); background-size: 20px 20px; pointer-events: none; opacity: 0.5; z-index: -1; } </style> </head> <body> <div class="container"> <header> <div class="logo">Prisma</div> <button class="menu-toggle">☰</button> </header> <div class="gallery-container"> <div class="gallery-items"> <div class="gallery-item" data-index="0"> <img src="https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80" alt="Abstract Digital Art"> <div class="item-content"> <h3>Neon Synthesis</h3> <p>Digital abstraction exploring color theory</p> <div class="item-tags"> <span class="item-tag">Digital Art</span> <span class="item-tag">3D</span> </div> </div> </div> <div class="gallery-item" data-index="1"> <img src="https://images.unsplash.com/photo-1617791160505-6f00504e3519?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80" alt="Product Design"> <div class="item-content"> <h3>Quantum Chair</h3> <p>Ergonomic furniture with fluid lines</p> <div class="item-tags"> <span class="item-tag">Product</span> <span class="item-tag">Industrial</span> </div> </div> </div> <div class="gallery-item" data-index="2"> <img src="https://images.unsplash.com/photo-1550895030-823330fc2551?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80" alt="Architecture Visualization"> <div class="item-content"> <h3>Vertical Gardens</h3> <p>Sustainable urban architecture concept</p> <div class="item-tags"> <span class="item-tag">Architecture</span> <span class="item-tag">3D</span> </div> </div> </div> <div class="gallery-item" data-index="3"> <img src="https://images.unsplash.com/photo-1604871000636-074fa5117945?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80" alt="Fashion Photography"> <div class="item-content"> <h3>Chromatic Vision</h3> <p>Fashion editorial with prismatic elements</p> <div class="item-tags"> <span class="item-tag">Fashion</span> <span class="item-tag">Photography</span> </div> </div> </div> <div class="gallery-item" data-index="4"> <img src="https://images.unsplash.com/photo-1547119957-637f8679db1e?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80" alt="Motion Graphics"> <div class="item-content"> <h3>Kinetic Type</h3> <p>Experimental motion typography</p> <div class="item-tags"> <span class="item-tag">Motion</span> <span class="item-tag">Typography</span> </div> </div> </div> </div> <div class="navigation"> <div class="nav-dot active" data-index="0"></div> <div class="nav-dot" data-index="1"></div> <div class="nav-dot" data-index="2"></div> <div class="nav-dot" data-index="3"></div> <div class="nav-dot" data-index="4"></div> </div> </div> <div class="pattern"></div> </div> <div class="overlay"> <div class="overlay-content"> <button class="close-overlay">✕</button> <img src="" alt=""> <div class="overlay-details"> <h2></h2> <p></p> </div> </div> </div> <div class="cursor"></div> <div class="cursor-dot"></div> <script> // Project details for the overlay const projectDetails = [ { title: "Neon Synthesis", description: "A deep exploration of color theory through digital abstraction. This piece combines parametric design with vibrant color harmonies to create an immersive visual experience that challenges perception and depth. Created using a combination of Cinema 4D and TouchDesigner." }, { title: "Quantum Chair", description: "A minimalist yet revolutionary furniture design that responds to body movements. The fluid lines and dynamic form provide ergonomic support while maintaining visual elegance. Constructed from sustainable composites with a focus on longevity and comfort." }, { title: "Vertical Gardens", description: "An architectural visualization for a proposed urban development incorporating extensive vertical gardens and sustainable water management systems. This concept aims to bring nature back into dense city environments while optimizing energy efficiency." }, { title: "Chromatic Vision", description: "Fashion editorial shot for Prism Magazine exploring the relationship between color theory and contemporary couture. The prismatic elements scattered throughout create dramatic light play on the textiles and model." }, { title: "Kinetic Type", description: "Experimental motion typography project exploring the boundaries between legibility and abstract form. This sequence demonstrates how letterforms can be deconstructed and reassembled while maintaining their communicative function." } ]; document.addEventListener('DOMContentLoaded', function() { const galleryContainer = document.querySelector('.gallery-container'); const galleryItems = document.querySelectorAll('.gallery-item'); const overlay = document.querySelector('.overlay'); const overlayImg = overlay.querySelector('img'); const overlayTitle = overlay.querySelector('h2'); const overlayDescription = overlay.querySelector('p'); const closeOverlay = document.querySelector('.close-overlay'); const navDots = document.querySelectorAll('.nav-dot'); const cursor = document.querySelector('.cursor'); const cursorDot = document.querySelector('.cursor-dot'); // Initialize 3D effect let mouseX = 0, mouseY = 0; let targetX = 0, targetY = 0; const windowWidth = window.innerWidth; const windowHeight = window.innerHeight; galleryContainer.addEventListener('mousemove', function(e) { mouseX = e.clientX; mouseY = e.clientY; targetX = (mouseX - windowWidth / 2) * 0.02; targetY = (mouseY - windowHeight / 2) * 0.02; // Apply tilt effect to gallery container galleryContainer.style.transform = `rotateY(${targetX}deg) rotateX(${-targetY}deg)`; }); galleryContainer.addEventListener('mouseleave', function() { // Reset tilt when mouse leaves galleryContainer.style.transform = 'rotateY(0deg) rotateX(0deg)'; }); // Gallery item click events galleryItems.forEach((item, index) => { item.addEventListener('click', function() { const imgSrc = item.querySelector('img').src; overlayImg.src = imgSrc; overlayTitle.textContent = projectDetails[index].title; overlayDescription.textContent = projectDetails[index].description; overlay.classList.add('active'); document.body.style.overflow = 'hidden'; }); // Add depth effect on hover item.addEventListener('mouseenter', function() { this.style.transform = `translateZ(40px) scale(1.02)`; cursor.classList.add('hover'); }); item.addEventListener('mouseleave', function() { this.style.transform = 'translateZ(0) scale(1)'; cursor.classList.remove('hover'); }); }); closeOverlay.addEventListener('click', function() { overlay.classList.remove('active'); document.body.style.overflow = 'auto'; }); // Navigation dots navDots.forEach((dot, index) => { dot.addEventListener('click', function() { navDots.forEach(d => d.classList.remove('active')); this.classList.add('active'); // Here you could add additional logic to focus on a specific gallery item galleryItems.forEach(item => { item.style.opacity = '0.5'; item.style.transform = 'scale(0.95)'; }); galleryItems[index].style.opacity = '1'; galleryItems[index].style.transform = 'scale(1.02) translateZ(20px)'; // Reset after animation setTimeout(() => { galleryItems.forEach(item => { item.style.opacity = '1'; item.style.transform = 'scale(1)'; }); }, 1000); }); }); // Custom cursor document.addEventListener('mousemove', function(e) { cursor.style.left = e.clientX + 'px'; cursor.style.top = e.clientY + 'px'; cursorDot.style.left = e.clientX + 'px'; cursorDot.style.top = e.clientY + 'px'; }); document.addEventListener('mousedown', function() { cursor.style.transform = 'translate(-50%, -50%) scale(0.9)'; cursorDot.style.transform = 'translate(-50%, -50%) scale(0.9)'; }); document.addEventListener('mouseup', function() { cursor.style.transform = 'translate(-50%, -50%) scale(1)'; cursorDot.style.transform = 'translate(-50%, -50%) scale(1)'; }); // Menu button interaction (just visual for this demo) const menuToggle = document.querySelector('.menu-toggle'); menuToggle.addEventListener('click', function() { this.classList.toggle('active'); // Here you could add a menu opening animation if (this.classList.contains('active')) { this.textContent = '✕'; } else { this.textContent = '☰'; } }); // Simple animation on load galleryItems.forEach((item, index) => { setTimeout(() => { item.style.opacity = '1'; item.style.transform = 'translateZ(0)'; }, 100 * index); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Virtual Storefront Experience</title> <style> :root { --primary-color: #f8c9b9; --secondary-color: #f5e6ca; --accent-color: #e88c7d; --dark-accent: #d16b5e; --text-color: #4a4a4a; --light-text: #767676; --white: #ffffff; --shadow-color: rgba(0, 0, 0, 0.1); --transition: all 0.4s cubic-bezier(0.25, 1, 0.5, 1); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Poppins', sans-serif; } body { background-color: var(--secondary-color); color: var(--text-color); overflow-x: hidden; height: 100vh; perspective: 1000px; } .store-container { max-width: 700px; height: 700px; margin: 0 auto; overflow: hidden; position: relative; display: flex; flex-direction: column; background: var(--white); box-shadow: 0 10px 30px var(--shadow-color); border-radius: 12px; } .store-header { padding: 20px; display: flex; justify-content: space-between; align-items: center; background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); border-bottom: 1px solid rgba(255, 255, 255, 0.3); position: relative; z-index: 10; } .store-logo { font-size: 1.5rem; font-weight: 700; color: var(--dark-accent); text-transform: uppercase; letter-spacing: 1px; } .store-nav { display: flex; gap: 20px; } .nav-item { cursor: pointer; position: relative; font-weight: 500; transition: var(--transition); } .nav-item:hover { color: var(--dark-accent); } .nav-item::after { content: ''; position: absolute; bottom: -5px; left: 0; height: 2px; width: 0; background: var(--accent-color); transition: var(--transition); } .nav-item:hover::after, .nav-item.active::after { width: 100%; } .nav-item.active { color: var(--dark-accent); } .store-view { flex: 1; position: relative; overflow: hidden; perspective: 1000px; transform-style: preserve-3d; transition: transform 0.8s cubic-bezier(0.25, 1, 0.5, 1); } .aisle { position: absolute; width: 100%; height: 100%; display: flex; flex-direction: column; transform-style: preserve-3d; transition: transform 0.8s cubic-bezier(0.25, 1, 0.5, 1); } .aisle-label { text-align: center; padding: 15px; font-size: 1.2rem; font-weight: 600; color: var(--text-color); background: rgba(255, 255, 255, 0.9); border-radius: 8px; margin: 15px; box-shadow: 0 5px 15px var(--shadow-color); transform: translateZ(30px); transition: var(--transition); } .products-row { display: flex; justify-content: center; align-items: center; flex-wrap: wrap; gap: 20px; padding: 0 20px; margin-bottom: 20px; transform-style: preserve-3d; } .product-card { width: 150px; height: 220px; background: var(--white); border-radius: 12px; padding: 15px; display: flex; flex-direction: column; align-items: center; box-shadow: 0 5px 20px var(--shadow-color); cursor: pointer; transition: var(--transition); transform-style: preserve-3d; transform: translateZ(20px); position: relative; overflow: hidden; } .product-card:hover { transform: translateZ(40px) scale(1.05); box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15); } .product-img { width: 120px; height: 120px; object-fit: contain; margin-bottom: 10px; transform-style: preserve-3d; transition: var(--transition); } .product-card:hover .product-img { transform: translateZ(20px) rotateY(15deg); } .product-title { font-size: 0.9rem; font-weight: 600; text-align: center; color: var(--text-color); margin-bottom: 5px; } .product-price { font-size: 1rem; font-weight: 700; color: var(--accent-color); } .product-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(135deg, rgba(248, 201, 185, 0.9), rgba(245, 230, 202, 0.9)); display: flex; flex-direction: column; justify-content: center; align-items: center; opacity: 0; transform: translateY(100%); transition: var(--transition); padding: 15px; } .product-card:hover .product-overlay { opacity: 1; transform: translateY(0); } .add-to-cart { background: var(--dark-accent); color: var(--white); border: none; padding: 8px 15px; border-radius: 25px; font-weight: 600; cursor: pointer; transition: var(--transition); margin-top: 10px; } .add-to-cart:hover { background: var(--accent-color); transform: scale(1.05); } .product-details { font-size: 0.8rem; text-align: center; color: var(--text-color); margin-bottom: 10px; } .navigation-controls { position: absolute; bottom: 20px; left: 0; width: 100%; display: flex; justify-content: center; gap: 20px; z-index: 10; } .nav-btn { background: var(--white); border: none; width: 40px; height: 40px; border-radius: 50%; display: flex; justify-content: center; align-items: center; box-shadow: 0 5px 15px var(--shadow-color); cursor: pointer; transition: var(--transition); } .nav-btn:hover { background: var(--primary-color); transform: translateY(-3px); } .nav-btn:active { transform: translateY(0); } .nav-btn svg { width: 20px; height: 20px; fill: var(--accent-color); } .floor { position: absolute; bottom: 0; left: 0; width: 100%; height: 50px; background: linear-gradient(to bottom, rgba(245, 230, 202, 0), rgba(245, 230, 202, 0.8)); transform: rotateX(90deg) translateZ(-25px); transform-origin: bottom; } .cart-indicator { position: absolute; top: 20px; right: 20px; background: var(--accent-color); color: var(--white); width: 24px; height: 24px; border-radius: 50%; display: flex; justify-content: center; align-items: center; font-size: 0.8rem; font-weight: bold; cursor: pointer; transition: var(--transition); z-index: 20; transform: scale(0); } .cart-indicator.active { transform: scale(1); } .cart-indicator:hover { background: var(--dark-accent); transform: scale(1.1); } .product-spotlight { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.97); z-index: 30; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 20px; opacity: 0; pointer-events: none; transition: var(--transition); transform: translateY(20px); } .product-spotlight.active { opacity: 1; pointer-events: all; transform: translateY(0); } .spotlight-close { position: absolute; top: 20px; right: 20px; background: none; border: none; font-size: 1.5rem; cursor: pointer; color: var(--accent-color); transition: var(--transition); } .spotlight-close:hover { color: var(--dark-accent); transform: rotate(90deg); } .spotlight-img-container { width: 250px; height: 250px; position: relative; perspective: 1000px; margin-bottom: 20px; } .spotlight-img { width: 100%; height: 100%; object-fit: contain; transform-style: preserve-3d; transition: transform 0.5s; } .spotlight-details { text-align: center; max-width: 400px; } .spotlight-title { font-size: 1.5rem; font-weight: 700; margin-bottom: 10px; color: var(--text-color); } .spotlight-price { font-size: 1.2rem; font-weight: 700; color: var(--accent-color); margin-bottom: 15px; } .spotlight-description { font-size: 0.9rem; color: var(--light-text); margin-bottom: 20px; line-height: 1.6; } .spotlight-actions { display: flex; gap: 15px; } .spotlight-btn { padding: 10px 20px; border: none; border-radius: 25px; font-weight: 600; cursor: pointer; transition: var(--transition); } .add-to-cart-btn { background: var(--accent-color); color: var(--white); } .add-to-cart-btn:hover { background: var(--dark-accent); } .view-details-btn { background: var(--white); color: var(--accent-color); border: 1px solid var(--accent-color); } .view-details-btn:hover { background: var(--secondary-color); } @media (max-width: 600px) { .store-header { flex-direction: column; gap: 10px; } .product-card { width: 130px; height: 200px; } .product-img { width: 100px; height: 100px; } .spotlight-img-container { width: 200px; height: 200px; } .spotlight-title { font-size: 1.2rem; } } /* Animated background pattern */ .pattern { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: -1; opacity: 0.4; } .pattern-dot { position: absolute; width: 6px; height: 6px; border-radius: 50%; background: var(--accent-color); animation: float 20s infinite linear; } @keyframes float { 0% { transform: translate(0, 0); } 25% { transform: translate(10px, 10px); } 50% { transform: translate(0, 20px); } 75% { transform: translate(-10px, 10px); } 100% { transform: translate(0, 0); } } /* Loading animation */ .loading { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: var(--white); display: flex; justify-content: center; align-items: center; z-index: 50; transition: opacity 0.5s, visibility 0.5s; } .loading.hidden { opacity: 0; visibility: hidden; } .loading-spinner { width: 60px; height: 60px; border: 4px solid rgba(232, 140, 125, 0.3); border-top: 4px solid var(--accent-color); border-radius: 50%; animation: spin 1s infinite linear; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } </style> </head> <body> <div class="store-container"> <!-- Loading screen --> <div class="loading"> <div class="loading-spinner"></div> </div> <!-- Store header --> <div class="store-header"> <div class="store-logo">Mélange</div> <div class="store-nav"> <div class="nav-item active" data-section="home">Home</div> <div class="nav-item" data-section="apparel">Apparel</div> <div class="nav-item" data-section="decor">Decor</div> </div> </div> <!-- Main store view --> <div class="store-view"> <!-- Pattern background --> <div class="pattern" id="pattern"></div> <!-- Aisle 1 - Featured Products --> <div class="aisle" data-aisle="home"> <div class="aisle-label">Featured Collection</div> <div class="products-row"> <div class="product-card" data-id="1"> <img src="https://images.unsplash.com/photo-1591047139829-d91aecb6caea?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" class="product-img" alt="Handcrafted Ceramic Vase"> <div class="product-title">Handcrafted Ceramic Vase</div> <div class="product-price">$68.00</div> <div class="product-overlay"> <div class="product-details">Artisan-made with natural clay and unique glazing techniques.</div> <button class="add-to-cart">Add to Cart</button> </div> </div> <div class="product-card" data-id="2"> <img src="https://images.unsplash.com/photo-1560060141-7b9018741ced?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" class="product-img" alt="Linen Throw Pillow"> <div class="product-title">Linen Throw Pillow</div> <div class="product-price">$45.00</div> <div class="product-overlay"> <div class="product-details">Organic linen with hand-embroidered details and feather filling.</div> <button class="add-to-cart">Add to Cart</button> </div> </div> <div class="product-card" data-id="3"> <img src="https://images.unsplash.com/photo-1593642634524-b40b5baae6bb?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" class="product-img" alt="Minimalist Desk Lamp"> <div class="product-title">Minimalist Desk Lamp</div> <div class="product-price">$129.00</div> <div class="product-overlay"> <div class="product-details">Brushed brass with matte finish and adjustable arm. Warm LED light included.</div> <button class="add-to-cart">Add to Cart</button> </div> </div> </div> <div class="products-row"> <div class="product-card" data-id="4"> <img src="https://images.unsplash.com/photo-1511401139252-f158d3209c17?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" class="product-img" alt="Woven Wall Hanging"> <div class="product-title">Woven Wall Hanging</div> <div class="product-price">$95.00</div> <div class="product-overlay"> <div class="product-details">Handwoven with organic cotton and reclaimed wood dowel. Each piece is unique.</div> <button class="add-to-cart">Add to Cart</button> </div> </div> <div class="product-card" data-id="5"> <img src="https://images.unsplash.com/photo-1519710164239-da123dc03ef4?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" class="product-img" alt="Botanical Print Set"> <div class="product-title">Botanical Print Set</div> <div class="product-price">$78.00</div> <div class="product-overlay"> <div class="product-details">Set of three archival quality prints on cotton paper. Frames not included.</div> <button class="add-to-cart">Add to Cart</button> </div> </div> <div class="product-card" data-id="6"> <img src="https://images.unsplash.com/photo-1580927752452-89d86da3fa0a?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" class="product-img" alt="Merino Wool Throw"> <div class="product-title">Merino Wool Throw</div> <div class="product-price">$149.00</div> <div class="product-overlay"> <div class="product-details">Sustainably sourced merino wool with hand-knotted fringe detail.</div> <button class="add-to-cart">Add to Cart</button> </div> </div> </div> <div class="floor"></div> </div> <!-- Aisle 2 - Apparel --> <div class="aisle" data-aisle="apparel" style="transform: translateX(100%); opacity: 0;"> <div class="aisle-label">Summer Apparel</div> <div class="products-row"> <div class="product-card" data-id="7"> <img src="https://images.unsplash.com/photo-1596755094514-f87e34085b2c?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" class="product-img" alt="Linen Shirt"> <div class="product-title">Linen Shirt</div> <div class="product-price">$89.00</div> <div class="product-overlay"> <div class="product-details">100% organic linen with natural mother-of-pearl buttons.</div> <button class="add-to-cart">Add to Cart</button> </div> </div> <div class="product-card" data-id="8"> <img src="https://images.unsplash.com/photo-1556121134-d3f7952e7777?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" class="product-img" alt="Cotton Sundress"> <div class="product-title">Cotton Sundress</div> <div class="product-price">$125.00</div> <div class="product-overlay"> <div class="product-details">Organic cotton with hand-embroidered details and pockets.</div> <button class="add-to-cart">Add to Cart</button> </div> </div> <div class="product-card" data-id="9"> <img src="https://images.unsplash.com/photo-1591047139829-d91aecb6caea?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" class="product-img" alt="Straw Hat"> <div class="product-title">Artisan Straw Hat</div> <div class="product-price">$58.00</div> <div class="product-overlay"> <div class="product-details">Hand-woven from sustainable palm leaves with adjustable fit.</div> <button class="add-to-cart">Add to Cart</button> </div> </div> </div> <div class="products-row"> <div class="product-card" data-id="10"> <img src="https://images.unsplash.com/photo-1618354691551-44de113f0164?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" class="product-img" alt="Canvas Tote"> <div class="product-title">Canvas Tote</div> <div class="product-price">$42.00</div> <div class="product-overlay"> <div class="product-details">Heavy-duty organic canvas with vegetable-tanned leather handles.</div> <button class="add-to-cart">Add to Cart</button> </div> </div> <div class="product-card" data-id="11"> <img src="https://images.unsplash.com/photo-1543163521-1bf539c55dd2?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" class="product-img" alt="Leather Sandals"> <div class="product-title">Leather Sandals</div> <div class="product-price">$110.00</div> <div class="product-overlay"> <div class="product-details">Ethically sourced leather with handcrafted soles. Made in small batches.</div> <button class="add-to-cart">Add to Cart</button> </div> </div> <div class="product-card" data-id="12"> <img src="https://images.unsplash.com/photo-1611591437281-460bfbe1220a?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" class="product-img" alt="Silk Scarf"> <div class="product-title">Hand-painted Silk Scarf</div> <div class="product-price">$75.00</div> <div class="product-overlay"> <div class="product-details">100% silk with hand-painted botanical design. Each piece is unique.</div> <button class="add-to-cart">Add to Cart</button> </div> </div> </div> <div class="floor"></div> </div> <!-- Aisle 3 - Home Decor --> <div class="aisle" data-aisle="decor" style="transform: translateX(100%); opacity: 0;"> <div class="aisle-label">Contemporary Home</div> <div class="products-row"> <div class="product-card" data-id="13"> <img src="https://images.unsplash.com/photo-1507473885765-e6ed057f782c?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" class="product-img" alt="Ceramic Planter"> <div class="product-title">Ceramic Planter</div> <div class="product-price">$48.00</div> <div class="product-overlay"> <div class="product-details">Handcrafted speckled ceramic with drainage hole and cork base.</div> <button class="add-to-cart">Add to Cart</button> </div> </div> <div class="product-card" data-id="14"> <img src="https://images.unsplash.com/photo-1583500178450-e59e4309b57a?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" class="product-img" alt="Wooden Serving Board"> <div class="product-title">Wooden Serving Board</div> <div class="product-price">$65.00</div> <div class="product-overlay"> <div class="product-details">Reclaimed walnut with natural live edge and mineral oil finish.</div> <button class="add-to-cart">Add to Cart</button> </div> </div> <div class="product-card" data-id="15"> <img src="https://images.unsplash.com/photo-1517705008128-361805f42e86?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" class="product-img" alt="Rattan Basket"> <div class="product-title">Rattan Storage Basket</div> <div class="product-price">$89.00</div> <div class="product-overlay"> <div class="product-details">Hand-woven rattan with natural variations. Perfect for blankets or plants.</div> <button class="add-to-cart">Add to Cart</button> </div> </div> </div> <div class="products-row"> <div class="product-card" data-id="16"> <img src="https://images.unsplash.com/photo-1519710164239-da123dc03ef4?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" class="product-img" alt="Copper Candleholders"> <div class="product-title">Copper Candleholders</div> <div class="product-price">$72.00</div> <div class="product-overlay"> <div class="product-details">Set of three handmade copper candleholders in graduated heights.</div> <button class="add-to-cart">Add to Cart</button> </div> </div> <div class="product-card" data-id="17"> <img src="https://images.unsplash.com/photo-1567225557594-88d73e55f2cb?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" class="product-img" alt="Linen Table Runner"> <div class="product-title">Linen Table Runner</div> <div class="product-price">$52.00</div> <div class="product-overlay"> <div class="product-details">Stone-washed linen with hand-stitched hems and natural texture.</div> <button class="add-to-cart">Add to Cart</button> </div> </div> <div class="product-card" data-id="18"> <img src="https://images.unsplash.com/photo-1596162954151-cdcb4c0f70a8?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" class="product-img" alt="Handblown Glassware"> <div class="product-title">Handblown Glassware</div> <div class="product-price">$98.00</div> <div class="product-overlay"> <div class="product-details">Set of four handblown glasses with subtle variations in color and texture.</div> <button class="add-to-cart">Add to Cart</button> </div> </div> </div> <div class="floor"></div> </div> <!-- Navigation controls --> <div class="navigation-controls"> <button class="nav-btn prev-btn"> <svg viewBox="0 0 24 24"> <path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/> </svg> </button> <button class="nav-btn next-btn"> <svg viewBox="0 0 24 24"> <path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/> </svg> </button> </div> <!-- Cart indicator --> <div class="cart-indicator">0</div> <!-- Product spotlight overlay --> <div class="product-spotlight"> <button class="spotlight-close">×</button> <div class="spotlight-img-container"> <img src="" class="spotlight-img" alt="Product"> </div> <div class="spotlight-details"> <h2 class="spotlight-title"></h2> <div class="spotlight-price"></div> <p class="spotlight-description"></p> <div class="spotlight-actions"> <button class="spotlight-btn add-to-cart-btn">Add to Cart</button> <button class="spotlight-btn view-details-btn">View Details</button> </div> </div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', () => { // Helper functions const select = selector => document.querySelector(selector); const selectAll = selector => document.querySelectorAll(selector); // Store elements const storeView = select('.store-view'); const aisles = selectAll('.aisle'); const navItems = selectAll('.nav-item'); const prevBtn = select('.prev-btn'); const nextBtn = select('.next-btn'); const cartIndicator = select('.cart-indicator'); const productCards = selectAll('.product-card'); const productSpotlight = select('.product-spotlight'); const spotlightClose = select('.spotlight-close'); const spotlightImg = select('.spotlight-img'); const spotlightTitle = select('.spotlight-title'); const spotlightPrice = select('.spotlight-price'); const spotlightDescription = select('.spotlight-description'); const addToCartBtn = select('.add-to-cart-btn'); const loadingScreen = select('.loading'); const pattern = select('#pattern'); // Store data let currentAisleIndex = 0; let cartCount = 0; const aisleNames = ['home', 'apparel', 'decor']; // Product data const products = { 1: { title: "Handcrafted Ceramic Vase", price: "$68.00", img: "https://images.unsplash.com/photo-1591047139829-d91aecb6caea?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80", description: "This unique ceramic vase is handcrafted by artisans using traditional techniques. Each piece features natural clay and unique glazing that makes it one-of-a-kind. Perfect for fresh or dried arrangements, or beautiful on its own as a sculptural accent." }, 2: { title: "Linen Throw Pillow", price: "$45.00", img: "https://images.unsplash.com/photo-1560060141-7b9018741ced?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80", description: "Made from 100% organic linen with hand-embroidered details, this pillow brings texture and warmth to any space. The feather filling provides luxurious comfort, while the natural linen cover is removable and washable." }, 3: { title: "Minimalist Desk Lamp", price: "$129.00", img: "https://images.unsplash.com/photo-1593642634524-b40b5baae6bb?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80", description: "Crafted with brushed brass and featuring a matte finish, this adjustable desk lamp combines form and function. The warm LED light creates a pleasant atmosphere for work or reading, while the minimalist design complements any decor style." }, 4: { title: "Woven Wall Hanging", price: "$95.00", img: "https://images.unsplash.com/photo-1511401139252-f158d3209c17?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80", description: "This handwoven wall piece is crafted with organic cotton and mounted on a reclaimed wood dowel. Each one is individually made by skilled artisans, ensuring a unique textile art piece that adds texture and warmth to your walls." }, 5: { title: "Botanical Print Set", price: "$78.00", img: "https://images.unsplash.com/photo-1519710164239-da123dc03ef4?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80", description: "A set of three archival quality botanical prints on 100% cotton paper. These detailed illustrations bring a touch of nature indoors and work beautifully grouped together or displayed separately. Frames not included." }, 6: { title: "Merino Wool Throw", price: "$149.00", img: "https://images.unsplash.com/photo-1580927752452-89d86da3fa0a?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80", description: "Made from ethically sourced merino wool, this luxurious throw features a hand-knotted fringe detail. Incredibly soft yet durable, it's perfect for cool evenings or as a beautiful accent draped over furniture." }, 7: { title: "Linen Shirt", price: "$89.00", img: "https://images.unsplash.com/photo-1596755094514-f87e34085b2c?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80", description: "This timeless linen shirt is crafted from 100% organic linen with natural mother-of-pearl buttons. The relaxed fit and breathable fabric make it perfect for warm days, while the quality construction ensures it will be a wardrobe staple for years." }, 8: { title: "Cotton Sundress", price: "$125.00", img: "https://images.unsplash.com/photo-1556121134-d3f7952e7777?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80", description: "
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Terrain Navigator Pro</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: #f0f2f5; width: 100%; height: 100vh; display: flex; justify-content: center; align-items: center; color: #2c3e50; overflow: hidden; } .map-container { width: 700px; height: 700px; position: relative; overflow: hidden; border-radius: 12px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15); background-color: #e6f4ff; } .map-wrapper { position: relative; width: 100%; height: 100%; perspective: 1000px; transform-style: preserve-3d; transition: all 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275); } .map { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transform: rotateX(45deg); transition: transform 0.8s cubic-bezier(0.34, 1.56, 0.64, 1); background: linear-gradient(135deg, #e6f1f8 0%, #cee3f8 50%, #b0d2f6 100%); } .map.zoomed { transform: rotateX(35deg) scale(1.2); } .terrain { position: absolute; width: 100%; height: 100%; transform-style: preserve-3d; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><rect width="100" height="100" fill="none" stroke="%23c0d6e8" stroke-width="0.5"/></svg>'); background-size: 50px 50px; } .elevation-layer { position: absolute; width: 100%; height: 100%; top: 0; left: 0; pointer-events: none; } .marker { position: absolute; transform-style: preserve-3d; transform: translateZ(var(--elevation)); transition: all 0.3s ease; cursor: pointer; display: flex; flex-direction: column; align-items: center; pointer-events: auto; } .marker-pin { width: 16px; height: 16px; border-radius: 50%; background: linear-gradient(to bottom, #4a89dc, #5b9bef); box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2); border: 2px solid white; position: relative; z-index: 2; transition: all 0.3s ease; } .marker-shadow { width: 12px; height: 4px; background: rgba(0, 0, 0, 0.2); border-radius: 50%; margin-top: 4px; filter: blur(2px); transform: scale(var(--elevation-scale)); opacity: 0.5; transition: all 0.3s ease; } .marker:hover .marker-pin { transform: scale(1.3); background: linear-gradient(to bottom, #5d9cef, #3679cf); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); } .marker-info { position: absolute; width: 180px; background: rgba(255, 255, 255, 0.97); padding: 15px; border-radius: 6px; box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1); top: -120px; left: -80px; opacity: 0; transform: translateY(10px); pointer-events: none; transition: all 0.3s ease; z-index: 100; } .marker:hover .marker-info { opacity: 1; transform: translateY(0); } .marker-info h3 { margin: 0 0 6px; color: #2c3e50; font-size: 14px; } .marker-info p { margin: 0; font-size: 12px; line-height: 1.4; color: #7f8c8d; } .marker-info .elevation-badge { position: absolute; top: -10px; right: -10px; background: #4a89dc; color: white; border-radius: 50%; width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: bold; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); } .control-panel { position: absolute; bottom: 20px; right: 20px; background: rgba(255, 255, 255, 0.9); border-radius: 8px; padding: 15px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); z-index: 10; display: flex; flex-direction: column; gap: 10px; } .control-btn { width: 40px; height: 40px; border-radius: 8px; border: none; background: linear-gradient(to bottom, #ffffff, #f2f6fa); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); cursor: pointer; display: flex; align-items: center; justify-content: center; color: #4a89dc; font-size: 18px; transition: all 0.2s ease; } .control-btn:hover { background: linear-gradient(to bottom, #f8faff, #e6f0fa); transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); } .control-btn:active { transform: translateY(0); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); } .rotate-control { position: absolute; top: 20px; right: 20px; background: rgba(255, 255, 255, 0.9); border-radius: 8px; padding: 15px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); z-index: 10; } .rotate-slider { width: 160px; -webkit-appearance: none; height: 6px; border-radius: 3px; background: #dfe6ee; outline: none; } .rotate-slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 18px; height: 18px; border-radius: 50%; background: #4a89dc; cursor: pointer; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); } .rotate-slider::-moz-range-thumb { width: 18px; height: 18px; border-radius: 50%; background: #4a89dc; cursor: pointer; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); border: none; } .rotate-label { color: #7f8c8d; font-size: 12px; margin-bottom: 6px; display: block; } .terrain-feature { position: absolute; background-color: #e0eaf5; border-radius: 50%; box-shadow: inset 0 -2px 8px rgba(0, 0, 0, 0.1); transform-style: preserve-3d; transition: transform 0.8s ease; } /* Glowing effect for highlighting features */ @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(74, 137, 220, 0.4); } 70% { box-shadow: 0 0 0 10px rgba(74, 137, 220, 0); } 100% { box-shadow: 0 0 0 0 rgba(74, 137, 220, 0); } } .layer-toggle { position: absolute; top: 20px; left: 20px; background: rgba(255, 255, 255, 0.9); border-radius: 8px; padding: 12px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); z-index: 10; } .layer-toggle-btn { background: transparent; border: none; padding: 8px 12px; margin: 0 4px; border-radius: 4px; font-size: 12px; color: #7f8c8d; cursor: pointer; transition: all 0.2s ease; } .layer-toggle-btn.active { background: #4a89dc; color: white; } .layer-toggle-btn:hover:not(.active) { background: #f0f4f8; } .terrain-label { position: absolute; font-size: 12px; color: #4a5568; font-weight: 500; pointer-events: none; transform-style: preserve-3d; text-shadow: 0 1px 2px rgba(255, 255, 255, 0.8); } /* Compass */ .compass { position: absolute; bottom: 20px; left: 20px; width: 60px; height: 60px; background: rgba(255, 255, 255, 0.9); border-radius: 50%; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); display: flex; align-items: center; justify-content: center; z-index: 10; transition: transform 0.5s ease; } .compass-inner { width: 45px; height: 45px; border-radius: 50%; background: linear-gradient(135deg, #e6f1f8 0%, #cee3f8 50%, #b0d2f6 100%); position: relative; display: flex; align-items: center; justify-content: center; } .compass-marker { position: absolute; width: 2px; height: 16px; background-color: #4a89dc; top: 6px; left: 50%; transform: translateX(-50%); } .compass-marker::after { content: ''; position: absolute; width: 0; height: 0; border-left: 5px solid transparent; border-right: 5px solid transparent; border-bottom: 8px solid #4a89dc; top: -8px; left: 50%; transform: translateX(-50%); } .compass-label { position: absolute; font-size: 10px; font-weight: bold; } .compass-n { top: 2px; left: 50%; transform: translateX(-50%); color: #e74c3c; } .compass-e { top: 50%; right: 2px; transform: translateY(-50%); } .compass-s { bottom: 2px; left: 50%; transform: translateX(-50%); } .compass-w { top: 50%; left: 2px; transform: translateY(-50%); } /* Loading animation */ .loading { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.9); display: flex; justify-content: center; align-items: center; z-index: 1000; opacity: 1; transition: opacity 0.5s ease, visibility 0.5s ease; } .loading.hidden { opacity: 0; visibility: hidden; } .loading-spinner { width: 50px; height: 50px; border: 5px solid #e0eaf5; border-top: 5px solid #4a89dc; border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .loading-text { position: absolute; top: 58%; text-align: center; color: #4a89dc; font-weight: 500; } /* Water animation */ .water { position: absolute; background: linear-gradient(to right, #a1c4fd, #c2e9fb); opacity: 0.7; transform-style: preserve-3d; transform: translateZ(5px); pointer-events: none; } @keyframes flow { 0% { background-position: 0 0; } 100% { background-position: 50px 0; } } .water::after { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="50" height="20" viewBox="0 0 50 20"><path d="M0,10 Q12.5,0 25,10 Q37.5,20 50,10" fill="none" stroke="%23ffffff" stroke-width="0.5" stroke-opacity="0.3"/></svg>'); animation: flow 3s linear infinite; } /* Scale indicator */ .scale-indicator { position: absolute; bottom: 20px; left: 100px; background: rgba(255, 255, 255, 0.9); border-radius: 4px; padding: 6px 10px; font-size: 11px; color: #4a5568; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); display: flex; align-items: center; gap: 6px; z-index: 10; } .scale-bar { height: 3px; width: 60px; background: linear-gradient(to right, #4a89dc 0%, #4a89dc 50%, #7f8c8d 50%, #7f8c8d 100%); border-radius: 2px; } </style> </head> <body> <div class="map-container"> <div class="loading"> <div class="loading-spinner"></div> <div class="loading-text">Loading terrain data...</div> </div> <div class="map-wrapper"> <div class="map"> <div class="terrain"></div> <div class="elevation-layer"></div> </div> </div> <div class="layer-toggle"> <button class="layer-toggle-btn active" data-layer="terrain">Terrain</button> <button class="layer-toggle-btn" data-layer="satellite">Satellite</button> </div> <div class="rotate-control"> <label class="rotate-label">Adjust Perspective</label> <input type="range" min="15" max="65" value="45" class="rotate-slider" id="perspective-control"> </div> <div class="control-panel"> <button class="control-btn" id="zoom-in">+</button> <button class="control-btn" id="zoom-out">-</button> <button class="control-btn" id="reset">⟲</button> </div> <div class="compass"> <div class="compass-inner"> <div class="compass-marker"></div> <div class="compass-label compass-n">N</div> <div class="compass-label compass-e">E</div> <div class="compass-label compass-s">S</div> <div class="compass-label compass-w">W</div> </div> </div> <div class="scale-indicator"> <div class="scale-bar"></div> <span>5 km</span> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const map = document.querySelector('.map'); const mapWrapper = document.querySelector('.map-wrapper'); const terrain = document.querySelector('.terrain'); const elevationLayer = document.querySelector('.elevation-layer'); const perspectiveControl = document.getElementById('perspective-control'); const zoomInBtn = document.getElementById('zoom-in'); const zoomOutBtn = document.getElementById('zoom-out'); const resetBtn = document.getElementById('reset'); const layerToggleBtns = document.querySelectorAll('.layer-toggle-btn'); const loading = document.querySelector('.loading'); // Set initial state let isZoomed = false; let currentZoom = 1; let isDragging = false; let currentX = 0; let currentY = 0; let initialX = 0; let initialY = 0; let xOffset = 0; let yOffset = 0; // Create terrain features createTerrainFeatures(); // Create markers const markers = [ { x: 25, y: 35, elevation: 320, name: "Mount Clearview", description: "Elevation 320m. Popular hiking destination with panoramic valley views.", type: "mountain" }, { x: 65, y: 55, elevation: 210, name: "Azure Lake", description: "Freshwater reservoir. Depth varies seasonally from 15-25m.", type: "water" }, { x: 38, y: 70, elevation: 180, name: "Evergreen Forest", description: "Protected woodland area with diverse eco-systems and wildlife corridors.", type: "forest" }, { x: 75, y: 25, elevation: 260, name: "Ridgeline Peak", description: "Dramatic cliff formations with historic geological significance.", type: "mountain" }, { x: 45, y: 45, elevation: 140, name: "Riverside Settlement", description: "Historic trading post dating back to 1845. Now a vibrant town center.", type: "settlement" } ]; // Add waters (decorative) const waters = [ { x: 62, y: 52, width: 20, height: 15 }, { x: 20, y: 75, width: 15, height: 10 } ]; // Add terrain labels const labels = [ { x: 25, y: 30, text: "Northern Highlands" }, { x: 70, y: 75, text: "Eastern Valley" }, { x: 20, y: 60, text: "Western Plateau" } ]; // Create water bodies waters.forEach(water => { const waterElement = document.createElement('div'); waterElement.className = 'water'; waterElement.style.width = `${water.width}%`; waterElement.style.height = `${water.height}%`; waterElement.style.left = `${water.x}%`; waterElement.style.top = `${water.y}%`; elevationLayer.appendChild(waterElement); }); // Create terrain labels labels.forEach(label => { const labelElement = document.createElement('div'); labelElement.className = 'terrain-label'; labelElement.textContent = label.text; labelElement.style.left = `${label.x}%`; labelElement.style.top = `${label.y}%`; labelElement.style.transform = 'translateZ(30px)'; elevationLayer.appendChild(labelElement); }); // Create markers markers.forEach(marker => { createMarker(marker); }); // Event listeners perspectiveControl.addEventListener('input', function() { const angle = parseInt(this.value); map.style.transform = `rotateX(${angle}deg)`; }); zoomInBtn.addEventListener('click', function() { if (currentZoom < 1.6) { currentZoom += 0.2; updateZoom(); } }); zoomOutBtn.addEventListener('click', function() { if (currentZoom > 0.8) { currentZoom -= 0.2; updateZoom(); } }); resetBtn.addEventListener('click', function() { resetMapPosition(); }); layerToggleBtns.forEach(btn => { btn.addEventListener('click', function() { layerToggleBtns.forEach(b => b.classList.remove('active')); this.classList.add('active'); const layer = this.getAttribute('data-layer'); if (layer === 'satellite') { map.style.background = 'linear-gradient(135deg, #2c3e50 0%, #34495e 50%, #2c3e50 100%)'; terrain.style.backgroundImage = 'url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><rect width="100" height="100" fill="none" stroke="%234a5568" stroke-width="0.5"/></svg>\')'; } else { map.style.background = 'linear-gradient(135deg, #e6f1f8 0%, #cee3f8 50%, #b0d2f6 100%)'; terrain.style.backgroundImage = 'url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><rect width="100" height="100" fill="none" stroke="%23c0d6e8" stroke-width="0.5"/></svg>\')'; } }); }); // Map dragging map.addEventListener('mousedown', dragStart); map.addEventListener('mouseup', dragEnd); map.addEventListener('mousemove', drag); // Touch events map.addEventListener('touchstart', dragStart); map.addEventListener('touchend', dragEnd); map.addEventListener('touchmove', drag); function dragStart(e) { if (e.type === 'touchstart') { initialX = e.touches[0].clientX - xOffset; initialY = e.touches[0].clientY - yOffset; } else { initialX = e.clientX - xOffset; initialY = e.clientY - yOffset; } isDragging = true; map.style.cursor = 'grabbing'; } function dragEnd() { initialX = currentX; initialY = currentY; isDragging = false; map.style.cursor = 'grab'; } function drag(e) { if (isDragging) { e.preventDefault(); if (e.type === 'touchmove') { currentX = e.touches[0].clientX - initialX; currentY = e.touches[0].clientY - initialY; } else { currentX = e.clientX - initialX; currentY = e.clientY - initialY; } // Limit dragging currentX = Math.max(Math.min(currentX, 150), -150); currentY = Math.max(Math.min(currentY, 150), -150); xOffset = currentX; yOffset = currentY; updateMapPosition(); } } function updateMapPosition() { mapWrapper.style.transform = `translate(${currentX}px, ${currentY}px)`; } function resetMapPosition() { currentZoom = 1; currentX = 0; currentY = 0; xOffset = 0; yOffset = 0; mapWrapper.style.transform = 'translate(0, 0)'; map.style.transform = 'rotateX(45deg)'; perspectiveControl.value = 45; isZoomed = false; map.classList.remove('zoomed'); // Reset all active states layerToggleBtns.forEach((btn, index) => { btn.classList.toggle('active', index === 0); }); // Reset map style map.style.background = 'linear-gradient(135deg, #e6f1f8 0%, #cee3f8 50%, #b0d2f6 100%)'; terrain.style.backgroundImage = 'url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><rect width="100" height="100" fill="none" stroke="%23c0d6e8" stroke-width="0.5"/></svg>\')'; } function updateZoom() { isZoomed = currentZoom > 1; map.classList.toggle('zoomed', isZoomed); // Apply zoom mapWrapper.style.transform = `translate(${currentX}px, ${currentY}px) scale(${currentZoom})`; // Adjust perspective based on zoom if (isZoomed) { const newAngle = Math.max(15, 45 - (currentZoom - 1) * 20); perspectiveControl.value = newAngle; map.style.transform = `rotateX(${newAngle}deg)`; } } function createMarker(markerData) { const marker = document.createElement('div'); marker.className = 'marker'; marker.style.left = `${markerData.x}%`; marker.style.top = `${markerData.y}%`; marker.style.setProperty('--elevation', `${markerData.elevation / 10}px`); marker.style.setProperty('--elevation-scale', `${1 + markerData.elevation / 500}`); const pin = document.createElement('div'); pin.className = 'marker-pin'; marker.appendChild(pin); const shadow = document.createElement('div'); shadow.className = 'marker-shadow'; marker.appendChild(shadow); const info = document.createElement('div'); info.className = 'marker-info'; const title = document.createElement('h3'); title.textContent = markerData.name; info.appendChild(title); const description = document.createElement('p'); description.textContent = markerData.description; info.appendChild(description); const elevBadge = document.createElement('div'); elevBadge.className = 'elevation-badge'; elevBadge.textContent = `${markerData.elevation}m`; info.appendChild(elevBadge); marker.appendChild(info); elevationLayer.appendChild(marker); } function createTerrainFeatures() { // Create random terrain features like hills and mountains const featureCount = 15; for (let i = 0; i < featureCount; i++) { const size = Math.random() * 20 + 10; const x = Math.random() * 90; const y = Math.random() * 90; const height = Math.random() * 40 + 10; const feature = document.createElement('div'); feature.className = 'terrain-feature'; feature.style.width = `${size}%`; feature.style.height = `${size}%`; feature.style.left = `${x}%`; feature.style.top = `${y}%`; feature.style.transform = `translateZ(${height}px)`; terrain.appendChild(feature); } } // Simulate loading setTimeout(() => { loading.classList.add('hidden'); }, 1500); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Dashboard Notifications Panel</title> <style> :root { --primary-color: #f5f7fa; --accent-color: #6c5ce7; --text-primary: #2d3436; --text-secondary: #636e72; --card-1: #e3f2fd; --card-2: #f3e5f5; --card-3: #e8f5e9; --card-4: #fff8e1; --shadow-color: rgba(0, 0, 0, 0.08); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; } body { display: flex; justify-content: center; align-items: center; min-height: 100vh; background-color: #f9fafc; overflow: hidden; } .container { width: 100%; max-width: 700px; height: 700px; display: flex; position: relative; } .dashboard { width: 100%; height: 100%; background-color: var(--primary-color); border-radius: 16px; box-shadow: 0 10px 30px var(--shadow-color); overflow: hidden; position: relative; display: flex; flex-direction: column; } .dashboard-header { padding: 24px 30px; display: flex; justify-content: space-between; align-items: center; background-color: white; border-bottom: 1px solid rgba(0,0,0,0.05); } .header-title { font-size: 20px; font-weight: 600; color: var(--text-primary); } .notification-icon { width: 42px; height: 42px; border-radius: 50%; background-color: var(--primary-color); display: flex; justify-content: center; align-items: center; cursor: pointer; position: relative; transition: transform 0.2s ease; } .notification-icon:hover { transform: scale(1.05); } .notification-icon svg { width: 22px; height: 22px; fill: var(--accent-color); } .notification-badge { position: absolute; top: -2px; right: -2px; width: 18px; height: 18px; background-color: #ff7675; border-radius: 50%; color: white; font-size: 10px; font-weight: 600; display: flex; justify-content: center; align-items: center; } .dashboard-content { flex: 1; padding: 30px; overflow: hidden; position: relative; } .notifications-panel { position: absolute; top: 0; right: -350px; width: 320px; height: 100%; background-color: white; box-shadow: -5px 0 25px rgba(0, 0, 0, 0.1); transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); overflow-y: auto; overflow-x: hidden; padding: 24px 0; z-index: 100; } .notifications-panel.open { transform: translateX(-350px); } .panel-header { padding: 0 24px 24px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid rgba(0,0,0,0.05); margin-bottom: 16px; } .panel-title { font-size: 18px; font-weight: 600; color: var(--text-primary); } .close-panel { width: 32px; height: 32px; border-radius: 50%; display: flex; justify-content: center; align-items: center; cursor: pointer; transition: background-color 0.2s; } .close-panel:hover { background-color: var(--primary-color); } .notification-cards { padding: 0 24px; } .notification-card { padding: 20px; border-radius: 12px; margin-bottom: 16px; box-shadow: 0 4px 15px var(--shadow-color); transform: perspective(1000px) rotateY(5deg) translateZ(0); transition: all 0.3s ease; position: relative; overflow: hidden; cursor: pointer; } .notification-card:hover { transform: perspective(1000px) rotateY(0deg) translateZ(10px); } .notification-card.unread::before { content: ''; position: absolute; top: 0; left: 0; width: 5px; height: 100%; background-color: var(--accent-color); } .notification-card:nth-child(1) { background-color: var(--card-1); } .notification-card:nth-child(2) { background-color: var(--card-2); } .notification-card:nth-child(3) { background-color: var(--card-3); } .notification-card:nth-child(4) { background-color: var(--card-4); } .card-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; } .card-title { font-size: 14px; font-weight: 600; color: var(--text-primary); } .card-time { font-size: 12px; color: var(--text-secondary); } .card-content { font-size: 13px; line-height: 1.5; color: var(--text-secondary); margin-bottom: 16px; } .card-actions { display: flex; gap: 10px; } .card-action-btn { padding: 6px 12px; border-radius: 6px; font-size: 12px; font-weight: 500; cursor: pointer; transition: all 0.2s; } .primary-action { background-color: var(--accent-color); color: white; } .primary-action:hover { background-color: #5649cc; } .secondary-action { background-color: rgba(0,0,0,0.05); color: var(--text-secondary); } .secondary-action:hover { background-color: rgba(0,0,0,0.1); } .overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.3); opacity: 0; visibility: hidden; transition: opacity 0.3s, visibility 0.3s; z-index: 99; } .overlay.active { opacity: 1; visibility: visible; } .card-icon { width: 36px; height: 36px; border-radius: 8px; display: flex; justify-content: center; align-items: center; margin-right: 12px; } .card-top { display: flex; align-items: center; margin-bottom: 12px; } .no-notifications { padding: 30px; text-align: center; color: var(--text-secondary); } .empty-state { width: 100px; height: 100px; margin: 0 auto 20px; opacity: 0.5; } @media (max-width: 600px) { .dashboard-header { padding: 20px; } .dashboard-content { padding: 20px; } .notifications-panel { width: 280px; right: -280px; } .notifications-panel.open { transform: translateX(-280px); } .panel-header { padding: 0 20px 20px; } .notification-cards { padding: 0 20px; } } /* Animation for new notifications */ @keyframes pushNotification { 0% { transform: perspective(1000px) rotateY(5deg) translateZ(0) scale(0.95); } 50% { transform: perspective(1000px) rotateY(5deg) translateZ(0) scale(1.03); } 100% { transform: perspective(1000px) rotateY(5deg) translateZ(0) scale(1); } } .notification-card.new-notification { animation: pushNotification 0.5s forwards; } /* Empty dashboard placeholder */ .dashboard-placeholder { text-align: center; padding: 100px 40px; color: var(--text-secondary); } .dashboard-placeholder svg { width: 80px; height: 80px; margin-bottom: 24px; fill: #dfe6e9; } .placeholder-title { font-size: 20px; font-weight: 600; margin-bottom: 12px; color: var(--text-primary); } .placeholder-subtitle { font-size: 14px; line-height: 1.6; max-width: 400px; margin: 0 auto; } </style> </head> <body> <div class="container"> <div class="dashboard"> <div class="dashboard-header"> <h1 class="header-title">Project Analytics</h1> <div class="notification-icon" id="notificationToggle"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M12 22c1.1 0 2-.9 2-2h-4c0 1.1.9 2 2 2zm6-6v-5c0-3.07-1.63-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.64 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2zm-2 1H8v-6c0-2.48 1.51-4.5 4-4.5s4 2.02 4 4.5v6z"/> </svg> <div class="notification-badge">4</div> </div> </div> <div class="dashboard-content"> <div class="dashboard-placeholder"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V5h14v14zM7 10h2v7H7zm4-3h2v10h-2zm4 6h2v4h-2z"/> </svg> <h2 class="placeholder-title">Your analytics dashboard</h2> <p class="placeholder-subtitle">Check the notification panel to see updates on your recent data reports and system alerts.</p> </div> </div> <div class="notifications-panel" id="notificationsPanel"> <div class="panel-header"> <div class="panel-title">Notifications</div> <div class="close-panel" id="closePanel"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <line x1="18" y1="6" x2="6" y2="18"></line> <line x1="6" y1="6" x2="18" y2="18"></line> </svg> </div> </div> <div class="notification-cards" id="notificationCards"> <div class="notification-card unread new-notification"> <div class="card-top"> <div class="card-icon" style="background-color: rgba(108, 92, 231, 0.1);"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="#6c5ce7"> <path d="M21.21 15.89A10 10 0 1 1 8 2.83M22 12A10 10 0 0 0 12 2v10z"></path> </svg> </div> <div> <div class="card-title">Q4 Report Generated</div> <div class="card-time">Just now</div> </div> </div> <div class="card-content"> Your Q4 marketing analytics report has been generated. The data shows a 23% increase in campaign performance compared to Q3. </div> <div class="card-actions"> <div class="card-action-btn primary-action">View Report</div> <div class="card-action-btn secondary-action">Dismiss</div> </div> </div> <div class="notification-card unread"> <div class="card-top"> <div class="card-icon" style="background-color: rgba(255, 118, 117, 0.1);"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="#ff7675"> <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path> </svg> </div> <div> <div class="card-title">Security Alert</div> <div class="card-time">10 minutes ago</div> </div> </div> <div class="card-content"> We detected a login attempt from an unrecognized device in Singapore. If this wasn't you, secure your account immediately. </div> <div class="card-actions"> <div class="card-action-btn primary-action">Secure Account</div> <div class="card-action-btn secondary-action">It was me</div> </div> </div> <div class="notification-card"> <div class="card-top"> <div class="card-icon" style="background-color: rgba(0, 184, 148, 0.1);"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="#00b894"> <path d="M20 7h-4V4c0-1.1-.9-2-2-2h-4c-1.1 0-2 .9-2 2v3H4c-1.1 0-2 .9-2 2v11c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V9c0-1.1-.9-2-2-2zM10 4h4v3h-4V4zm10 16H4V9h16v11z"></path> </svg> </div> <div> <div class="card-title">Project Status Update</div> <div class="card-time">Today, 2:45 PM</div> </div> </div> <div class="card-content"> "Sirius" project milestones have been updated. 16/20 tasks complete with 3 awaiting review. Current progress is at 87%, ahead of schedule. </div> <div class="card-actions"> <div class="card-action-btn primary-action">View Project</div> <div class="card-action-btn secondary-action">Mark as Read</div> </div> </div> <div class="notification-card unread"> <div class="card-top"> <div class="card-icon" style="background-color: rgba(253, 203, 110, 0.1);"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="#fdcb6e"> <path d="M22 12h-4l-3 9L9 3l-3 9H2"></path> </svg> </div> <div> <div class="card-title">System Maintenance</div> <div class="card-time">Tomorrow, 2:00 AM</div> </div> </div> <div class="card-content"> Scheduled maintenance will occur tomorrow at 2:00 AM UTC. Expected downtime: 15 minutes. Analytics dashboard will be temporarily unavailable. </div> <div class="card-actions"> <div class="card-action-btn primary-action">Set Reminder</div> <div class="card-action-btn secondary-action">Dismiss</div> </div> </div> </div> </div> </div> <div class="overlay" id="overlay"></div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const notificationToggle = document.getElementById('notificationToggle'); const notificationsPanel = document.getElementById('notificationsPanel'); const closePanel = document.getElementById('closePanel'); const overlay = document.getElementById('overlay'); const notificationCards = document.querySelectorAll('.notification-card'); const notificationBadge = document.querySelector('.notification-badge'); // Toggle notification panel notificationToggle.addEventListener('click', function() { notificationsPanel.classList.toggle('open'); overlay.classList.toggle('active'); // Apply push effect to unread notifications document.querySelectorAll('.notification-card.unread').forEach(card => { card.classList.add('new-notification'); // Remove the animation class after animation completes setTimeout(() => { card.classList.remove('new-notification'); }, 500); }); }); // Close panel on click closePanel.addEventListener('click', function() { notificationsPanel.classList.remove('open'); overlay.classList.remove('active'); }); // Close panel when clicking overlay overlay.addEventListener('click', function() { notificationsPanel.classList.remove('open'); overlay.classList.remove('active'); }); // Add click events to notification cards notificationCards.forEach(card => { // Add tilt effect on hover card.addEventListener('mousemove', function(e) { const rect = card.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; const centerX = rect.width / 2; const centerY = rect.height / 2; const rotateX = (y - centerY) / 20; const rotateY = (centerX - x) / 20; card.style.transform = `perspective(1000px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) translateZ(5px)`; }); // Reset transform on mouse leave card.addEventListener('mouseleave', function() { card.style.transform = `perspective(1000px) rotateY(5deg) translateZ(0)`; }); // Handle card clicks card.addEventListener('click', function(e) { if (e.target.classList.contains('card-action-btn')) { const action = e.target.textContent.trim(); // Simple feedback animation e.target.style.transform = 'scale(0.95)'; setTimeout(() => { e.target.style.transform = 'scale(1)'; }, 100); // If it's dismiss or mark as read, remove the unread marker if (action === 'Dismiss' || action === 'Mark as Read' || action === 'It was me') { card.classList.remove('unread'); // Update the notification badge count const unreadCount = document.querySelectorAll('.notification-card.unread').length; notificationBadge.textContent = unreadCount; if (unreadCount === 0) { notificationBadge.style.display = 'none'; } } } }); }); // Add random notification function function addRandomNotification() { const notificationTypes = [ { title: 'User Feedback Received', content: 'New user feedback on the analytics dashboard has been submitted with a rating of 4.7/5. Suggestions include adding export functionality.', icon: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="#00cec9"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"></path></svg>', bgColor: 'rgba(0, 206, 201, 0.1)', actions: ['Review Feedback', 'Dismiss'] }, { title: 'Data Integration Complete', content: 'The integration with Salesforce has been completed successfully. 2,453 records were synchronized without errors.', icon: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="#6c5ce7"><path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"></path></svg>', bgColor: 'rgba(108, 92, 231, 0.1)', actions: ['View Data', 'Dismiss'] } ]; // Select a random notification type const randomType = notificationTypes[Math.floor(Math.random() * notificationTypes.length)]; // Create new notification card const newCard = document.createElement('div'); newCard.className = 'notification-card unread new-notification'; newCard.innerHTML = ` <div class="card-top"> <div class="card-icon" style="background-color: ${randomType.bgColor};"> ${randomType.icon} </div> <div> <div class="card-title">${randomType.title}</div> <div class="card-time">Just now</div> </div> </div> <div class="card-content"> ${randomType.content} </div> <div class="card-actions"> <div class="card-action-btn primary-action">${randomType.actions[0]}</div> <div class="card-action-btn secondary-action">${randomType.actions[1]}</div> </div> `; // Add the new card to the top of the notifications const notificationCards = document.getElementById('notificationCards'); notificationCards.insertBefore(newCard, notificationCards.firstChild); // Update the notification badge count const unreadCount = document.querySelectorAll('.notification-card.unread').length; notificationBadge.textContent = unreadCount; notificationBadge.style.display = 'flex'; // Add event listeners to the new card addCardEventListeners(newCard); // Remove the animation class after animation completes setTimeout(() => { newCard.classList.remove('new-notification'); }, 500); } function addCardEventListeners(card) { // Add tilt effect on hover card.addEventListener('mousemove', function(e) { const rect = card.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; const centerX = rect.width / 2; const centerY = rect.height / 2; const rotateX = (y - centerY) / 20; const rotateY = (centerX - x) / 20; card.style.transform = `perspective(1000px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) translateZ(5px)`; }); // Reset transform on mouse leave card.addEventListener('mouseleave', function() { card.style.transform = `perspective(1000px) rotateY(5deg) translateZ(0)`; }); // Handle card clicks card.addEventListener('click', function(e) { if (e.target.classList.contains('card-action-btn')) { const action = e.target.textContent.trim(); // Simple feedback animation e.target.style.transform = 'scale(0.95)'; setTimeout(() => { e.target.style.transform = 'scale(1)'; }, 100); // If it's dismiss or mark as read, remove the unread marker if (action === 'Dismiss' || action === 'Mark as Read' || action === 'It was me') { card.classList.remove('unread'); // Update the notification badge count const unreadCount = document.querySelectorAll('.notification-card.unread').length; notificationBadge.textContent = unreadCount; if (unreadCount === 0) { notificationBadge.style.display = 'none'; } } } }); } // Simulate new notification after some time setTimeout(addRandomNotification, 8000); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Educational Course Navigator</title> <style> :root { --primary: #ff7043; --primary-light: #ffad8b; --secondary: #4a6572; --tertiary: #f9a826; --background: #f8f9fa; --text-dark: #37474f; --text-light: #f8f9fa; --shadow: rgba(0, 0, 0, 0.08); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Nunito', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; } body { background-color: var(--background); color: var(--text-dark); min-height: 100vh; display: flex; justify-content: center; align-items: center; padding: 20px; overflow-x: hidden; perspective: 1000px; } .course-container { width: 100%; max-width: 650px; min-height: 600px; position: relative; transform-style: preserve-3d; } .course-header { text-align: center; margin-bottom: 30px; transform: translateZ(30px); opacity: 0; animation: fadeIn 0.8s ease forwards 0.3s; } .course-header h1 { font-size: 28px; font-weight: 800; color: var(--primary); margin-bottom: 8px; letter-spacing: -0.5px; } .course-header p { font-size: 16px; color: var(--secondary); max-width: 500px; margin: 0 auto; } .progress-container { position: relative; margin: 25px auto; height: 8px; width: 90%; background: #e0e0e0; border-radius: 10px; overflow: hidden; transform: translateZ(20px); box-shadow: 0 2px 8px var(--shadow); } .progress-bar { position: absolute; height: 100%; background: linear-gradient(90deg, var(--primary-light), var(--primary)); border-radius: 10px; width: 0; transition: width 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55); } .module-container { perspective: 1200px; margin: 0 auto; position: relative; height: 380px; width: 100%; transform-style: preserve-3d; } .module-card { position: absolute; width: 95%; max-width: 600px; height: 200px; left: 50%; top: 50%; background: white; border-radius: 16px; overflow: hidden; transition: all 0.7s cubic-bezier(0.175, 0.885, 0.32, 1.275); transform-origin: center; box-shadow: 0 8px 30px var(--shadow); display: flex; flex-direction: column; cursor: pointer; transform: translate(-50%, -50%) translateZ(0) rotateY(0) scale(0.95); opacity: 0; visibility: hidden; } .module-card.active { transform: translate(-50%, -50%) translateZ(70px) rotateY(0) scale(1); z-index: 5; opacity: 1; visibility: visible; } .module-card.prev { transform: translate(-50%, -50%) translateZ(30px) rotateY(-10deg) scale(0.9); z-index: 4; opacity: 0.7; visibility: visible; } .module-card.next { transform: translate(-50%, -50%) translateZ(30px) rotateY(10deg) scale(0.9); z-index: 3; opacity: 0.7; visibility: visible; } .module-card.far-prev { transform: translate(-50%, -50%) translateZ(10px) rotateY(-20deg) scale(0.85); z-index: 2; opacity: 0.4; visibility: visible; } .module-card.far-next { transform: translate(-50%, -50%) translateZ(10px) rotateY(20deg) scale(0.85); z-index: 1; opacity: 0.4; visibility: visible; } .module-header { background: linear-gradient(135deg, var(--primary) 0%, var(--tertiary) 100%); color: var(--text-light); padding: 20px 25px; position: relative; overflow: hidden; } .module-header h2 { font-size: 22px; font-weight: 700; margin-bottom: 6px; position: relative; z-index: 2; } .module-header p { font-size: 14px; opacity: 0.9; position: relative; z-index: 2; } .module-pattern { position: absolute; top: 0; right: 0; height: 100%; width: 180px; opacity: 0.15; background-image: radial-gradient(circle, white 2px, transparent 2px); background-size: 15px 15px; } .module-content { padding: 20px 25px; flex-grow: 1; background: white; display: flex; flex-direction: column; justify-content: space-between; } .module-topics { margin-bottom: 12px; } .module-topics li { margin-bottom: 8px; display: flex; align-items: center; font-size: 14.5px; } .module-topics li:before { content: ""; display: block; width: 8px; height: 8px; border-radius: 50%; background-color: var(--primary); margin-right: 10px; flex-shrink: 0; } .module-footer { display: flex; align-items: center; justify-content: space-between; border-top: 1px solid rgba(0, 0, 0, 0.05); padding-top: 12px; margin-top: auto; } .module-duration { display: flex; align-items: center; font-size: 14px; color: var(--secondary); } .module-duration svg { margin-right: 6px; } .module-status { font-size: 13px; font-weight: 600; padding: 5px 12px; border-radius: 50px; background: #e3f2fd; color: #1976d2; } .module-status.completed { background: #e8f5e9; color: #2e7d32; } .module-status.in-progress { background: #fff8e1; color: #ff8f00; } .navigation-controls { display: flex; justify-content: center; margin-top: 30px; gap: 15px; transform: translateZ(30px); opacity: 0; animation: fadeIn 0.8s ease forwards 0.6s; } .nav-btn { background: white; border: none; width: 45px; height: 45px; border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; box-shadow: 0 4px 12px var(--shadow); transition: all 0.3s ease; color: var(--secondary); } .nav-btn:hover { background: var(--primary); color: white; transform: translateY(-3px); box-shadow: 0 6px 15px rgba(255, 112, 67, 0.25); } .nav-btn:active { transform: translateY(0); } .nav-btn.disabled { opacity: 0.5; pointer-events: none; } .module-indicator { display: flex; justify-content: center; gap: 8px; margin-top: 15px; opacity: 0; animation: fadeIn 0.8s ease forwards 0.9s; } .indicator-dot { width: 8px; height: 8px; border-radius: 50%; background: #ddd; transition: all 0.3s ease; } .indicator-dot.active { background: var(--primary); transform: scale(1.3); } @keyframes fadeIn { from { opacity: 0; transform: translateY(20px) translateZ(30px); } to { opacity: 1; transform: translateY(0) translateZ(30px); } } @keyframes floatAnimation { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-10px); } } .floating-elements { position: absolute; width: 100%; height: 100%; pointer-events: none; z-index: -1; } .floating-element { position: absolute; border-radius: 50%; opacity: 0.1; animation: floatAnimation 6s infinite ease-in-out; } .element-1 { width: 80px; height: 80px; background-color: var(--primary); top: 10%; left: 10%; animation-delay: 0s; } .element-2 { width: 50px; height: 50px; background-color: var(--tertiary); bottom: 15%; right: 15%; animation-delay: 2s; } .element-3 { width: 40px; height: 40px; background-color: var(--secondary); top: 20%; right: 20%; animation-delay: 4s; } @media (max-width: 600px) { .course-header h1 { font-size: 24px; } .course-header p { font-size: 14px; } .module-card { width: 90%; height: 230px; } .module-header h2 { font-size: 18px; } .module-header p { font-size: 13px; } .module-topics li { font-size: 13px; } } </style> </head> <body> <div class="floating-elements"> <div class="floating-element element-1"></div> <div class="floating-element element-2"></div> <div class="floating-element element-3"></div> </div> <div class="course-container"> <div class="course-header"> <h1>UX Design Fundamentals</h1> <p>Master the principles of user experience design through interactive lessons, practical exercises, and expert guidance.</p> </div> <div class="progress-container"> <div class="progress-bar" id="progress-bar"></div> </div> <div class="module-container" id="module-container"> <!-- Modules will be added dynamically --> </div> <div class="navigation-controls"> <button class="nav-btn" id="prev-btn"> <svg width="20" height="20" fill="currentColor" viewBox="0 0 16 16"> <path fill-rule="evenodd" d="M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z"/> </svg> </button> <button class="nav-btn" id="next-btn"> <svg width="20" height="20" fill="currentColor" viewBox="0 0 16 16"> <path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"/> </svg> </button> </div> <div class="module-indicator" id="module-indicator"> <!-- Indicator dots will be added dynamically --> </div> </div> <script> document.addEventListener('DOMContentLoaded', () => { // Course modules data const modules = [ { title: "Introduction to UX Design", description: "Discover the fundamental concepts and principles of UX design", topics: [ "What is User Experience Design?", "The UX Design Process", "History and Evolution of UX Design" ], duration: "45 min", status: "completed" }, { title: "User Research Methods", description: "Learn effective techniques to understand user needs and behaviors", topics: [ "Qualitative vs. Quantitative Research", "User Interviews and Surveys", "Creating User Personas", "Journey Mapping Techniques" ], duration: "1h 15min", status: "in-progress" }, { title: "Information Architecture", description: "Organize and structure content to enhance usability and findability", topics: [ "Content Strategy Basics", "Site Mapping and Navigation Design", "Card Sorting and Tree Testing", ], duration: "1h 30min", status: "locked" }, { title: "Wireframing & Prototyping", description: "Create visual representations of your design ideas", topics: [ "Low vs. High-Fidelity Wireframes", "Interactive Prototyping Techniques", "Effective Use of UI Patterns", "Tools for Modern Prototyping" ], duration: "2h", status: "locked" }, { title: "Usability Testing", description: "Evaluate your designs with real users to improve the experience", topics: [ "Planning Usability Studies", "Moderated vs. Unmoderated Testing", "Analyzing and Reporting User Feedback", "Iterative Design Process" ], duration: "1h 45min", status: "locked" } ]; // Initial setup let currentModuleIndex = 0; const moduleContainer = document.getElementById('module-container'); const progressBar = document.getElementById('progress-bar'); const prevBtn = document.getElementById('prev-btn'); const nextBtn = document.getElementById('next-btn'); const moduleIndicator = document.getElementById('module-indicator'); // Create module cards function createModuleCards() { modules.forEach((module, index) => { const moduleCard = document.createElement('div'); moduleCard.className = 'module-card'; const statusText = module.status === 'completed' ? 'Completed' : module.status === 'in-progress' ? 'In Progress' : 'Locked'; const statusClass = module.status === 'completed' ? 'completed' : module.status === 'in-progress' ? 'in-progress' : ''; moduleCard.innerHTML = ` <div class="module-header"> <h2>Module ${index + 1}: ${module.title}</h2> <p>${module.description}</p> <div class="module-pattern"></div> </div> <div class="module-content"> <ul class="module-topics"> ${module.topics.map(topic => `<li>${topic}</li>`).join('')} </ul> <div class="module-footer"> <div class="module-duration"> <svg width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path d="M8 3.5a.5.5 0 0 0-1 0V9a.5.5 0 0 0 .252.434l3.5 2a.5.5 0 0 0 .496-.868L8 8.71V3.5z"/> <path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm7-8A7 7 0 1 1 1 8a7 7 0 0 1 14 0z"/> </svg> ${module.duration} </div> <div class="module-status ${statusClass}">${statusText}</div> </div> </div> `; moduleContainer.appendChild(moduleCard); // Create indicator dot const dot = document.createElement('div'); dot.className = 'indicator-dot'; if (index === 0) dot.classList.add('active'); moduleIndicator.appendChild(dot); }); } // Update cards position based on current index function updateModuleCards() { const moduleCards = document.querySelectorAll('.module-card'); const indicatorDots = document.querySelectorAll('.indicator-dot'); moduleCards.forEach((card, index) => { card.className = 'module-card'; if (index === currentModuleIndex) { card.classList.add('active'); } else if (index === currentModuleIndex - 1) { card.classList.add('prev'); } else if (index === currentModuleIndex - 2) { card.classList.add('far-prev'); } else if (index === currentModuleIndex + 1) { card.classList.add('next'); } else if (index === currentModuleIndex + 2) { card.classList.add('far-next'); } }); // Update indicator dots indicatorDots.forEach((dot, index) => { dot.classList.toggle('active', index === currentModuleIndex); }); // Update progress bar const progressPercentage = ((currentModuleIndex) / (modules.length - 1)) * 100; progressBar.style.width = `${progressPercentage}%`; // Update navigation buttons prevBtn.classList.toggle('disabled', currentModuleIndex === 0); nextBtn.classList.toggle('disabled', currentModuleIndex === modules.length - 1); } // Navigation event handlers prevBtn.addEventListener('click', () => { if (currentModuleIndex > 0) { currentModuleIndex--; updateModuleCards(); } }); nextBtn.addEventListener('click', () => { if (currentModuleIndex < modules.length - 1) { currentModuleIndex++; updateModuleCards(); } }); // Add click event to indicator dots function setupIndicatorDots() { const dots = document.querySelectorAll('.indicator-dot'); dots.forEach((dot, index) => { dot.addEventListener('click', () => { currentModuleIndex = index; updateModuleCards(); }); }); } // Add click event to module cards function setupModuleCards() { const cards = document.querySelectorAll('.module-card'); cards.forEach((card, index) => { card.addEventListener('click', (e) => { // Only navigate to card if it's adjacent to current if (Math.abs(index - currentModuleIndex) <= 2) { currentModuleIndex = index; updateModuleCards(); } }); }); } // Initialize createModuleCards(); updateModuleCards(); setupIndicatorDots(); setupModuleCards(); // Add keyboard navigation document.addEventListener('keydown', (e) => { if (e.key === 'ArrowLeft' && currentModuleIndex > 0) { currentModuleIndex--; updateModuleCards(); } else if (e.key === 'ArrowRight' && currentModuleIndex < modules.length - 1) { currentModuleIndex++; updateModuleCards(); } }); // Add a subtle hover effect to active card const moduleCards = document.querySelectorAll('.module-card'); moduleCards.forEach(card => { card.addEventListener('mousemove', (e) => { if (card.classList.contains('active')) { const rect = card.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; const centerX = rect.width / 2; const centerY = rect.height / 2; const deltaX = (x - centerX) / 20; const deltaY = (y - centerY) / 20; card.style.transform = `translate(-50%, -50%) translateZ(70px) rotateX(${-deltaY}deg) rotateY(${deltaX}deg) scale(1)`; } }); card.addEventListener('mouseleave', () => { if (card.classList.contains('active')) { card.style.transform = 'translate(-50%, -50%) translateZ(70px) rotateY(0) rotateX(0) scale(1)'; } }); }); }); </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: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { width: 100%; height: 100vh; background: #0a0a15; color: #fff; overflow: hidden; perspective: 1000px; } .vr-container { width: 100%; height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; position: relative; } .focal-point { position: absolute; width: 20px; height: 20px; background: rgba(0, 255, 255, 0.5); border-radius: 50%; box-shadow: 0 0 15px 5px rgba(0, 255, 255, 0.3); transform: translateZ(0); opacity: 0.7; pointer-events: none; mix-blend-mode: screen; z-index: 1000; transition: transform 0.3s ease-out; } .vr-menu { position: relative; transform-style: preserve-3d; width: 600px; height: 500px; display: flex; align-items: center; justify-content: center; transition: transform 0.5s cubic-bezier(0.23, 1, 0.32, 1); } .menu-item { position: absolute; width: 180px; height: 180px; background: rgba(15, 20, 40, 0.6); border: 1px solid rgba(0, 220, 255, 0.2); border-radius: 10px; display: flex; flex-direction: column; align-items: center; justify-content: center; transition: all 0.5s cubic-bezier(0.19, 1, 0.22, 1); text-align: center; cursor: pointer; backdrop-filter: blur(5px); transform-style: preserve-3d; box-shadow: 0 0 20px rgba(0, 200, 255, 0.1); padding: 15px; } .menu-item:hover { background: rgba(20, 30, 70, 0.9); border-color: rgba(0, 255, 255, 0.8); box-shadow: 0 0 25px rgba(0, 255, 255, 0.3), 0 0 8px rgba(0, 255, 255, 0.5) inset; transform: translateZ(30px) scale(1.1); z-index: 100; } .menu-item.focused { background: rgba(25, 40, 100, 0.9); border-color: rgba(0, 255, 255, 1); box-shadow: 0 0 35px rgba(0, 255, 255, 0.5), 0 0 15px rgba(0, 255, 255, 0.5) inset; transform: translateZ(50px) scale(1.15); z-index: 200; } .item-icon { width: 60px; height: 60px; margin-bottom: 15px; display: flex; align-items: center; justify-content: center; position: relative; } .item-icon svg { width: 100%; height: 100%; } .item-icon:after { content: ''; position: absolute; width: 70px; height: 70px; border-radius: 50%; background: radial-gradient(rgba(0, 255, 255, 0.15), transparent 70%); z-index: -1; } .item-title { font-size: 16px; font-weight: 600; color: #00ffff; margin-bottom: 8px; text-shadow: 0 0 10px rgba(0, 255, 255, 0.5); transform: translateZ(5px); } .item-description { font-size: 11px; color: rgba(255, 255, 255, 0.7); transform: translateZ(2px); max-width: 150px; } .user-guidance { position: absolute; bottom: 20px; left: 0; width: 100%; text-align: center; color: rgba(0, 255, 255, 0.8); font-size: 14px; padding: 10px; animation: pulse 2s infinite; } @keyframes pulse { 0% { opacity: 0.5; } 50% { opacity: 1; } 100% { opacity: 0.5; } } .grid-lines { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: -1; opacity: 0.15; } .grid-horizontal, .grid-vertical { position: absolute; background: linear-gradient(90deg, transparent, rgba(0, 255, 255, 0.3), transparent); } .grid-horizontal { width: 100%; height: 1px; } .grid-vertical { height: 100%; width: 1px; background: linear-gradient(0deg, transparent, rgba(0, 255, 255, 0.3), transparent); } .vr-title { position: absolute; top: 40px; font-size: 24px; font-weight: 700; color: #00ffff; text-transform: uppercase; letter-spacing: 2px; text-shadow: 0 0 15px rgba(0, 255, 255, 0.5); opacity: 0.9; } .vr-subtitle { position: absolute; top: 80px; font-size: 14px; opacity: 0.6; max-width: 400px; text-align: center; } .loading-indicator { position: absolute; top: 20px; right: 20px; width: 40px; height: 40px; border: 2px solid rgba(0, 255, 255, 0.3); border-top: 2px solid rgba(0, 255, 255, 1); border-radius: 50%; animation: rotate 2s linear infinite; } @keyframes rotate { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .ring-effect { position: absolute; border-radius: 50%; border: 1px solid rgba(0, 255, 255, 0.2); pointer-events: none; z-index: -1; } @media (max-width: 700px) { .vr-menu { width: 90%; height: 400px; } .menu-item { width: 130px; height: 130px; } .item-icon { width: 40px; height: 40px; } .item-title { font-size: 14px; } .item-description { font-size: 10px; max-width: 110px; } } </style> </head> <body> <div class="vr-container"> <div class="focal-point"></div> <h1 class="vr-title">NeuroSphere VR</h1> <p class="vr-subtitle">Navigate with your gaze. Depth adapts to your focus.</p> <div class="vr-menu"> <div class="menu-item" data-depth="-300"> <div class="item-icon"> <svg viewBox="0 0 24 24" fill="none" stroke="#00ffff" stroke-width="1.5"> <path d="M12 15a3 3 0 100-6 3 3 0 000 6z"></path> <path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-2 2 2 2 0 01-2-2v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83 0 2 2 0 010-2.83l.06-.06a1.65 1.65 0 00.33-1.82 1.65 1.65 0 00-1.51-1H3a2 2 0 01-2-2 2 2 0 012-2h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 010-2.83 2 2 0 012.83 0l.06.06a1.65 1.65 0 001.82.33H9a1.65 1.65 0 001-1.51V3a2 2 0 012-2 2 2 0 012 2v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 0 2 2 0 010 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9a1.65 1.65 0 001.51 1H21a2 2 0 012 2 2 2 0 01-2 2h-.09a1.65 1.65 0 00-1.51 1z"></path> </svg> </div> <h3 class="item-title">System Config</h3> <p class="item-description">Calibrate your NeuroLink settings for optimal neural response</p> </div> <div class="menu-item" data-depth="-100"> <div class="item-icon"> <svg viewBox="0 0 24 24" fill="none" stroke="#00ffff" stroke-width="1.5"> <path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"></path> </svg> </div> <h3 class="item-title">Environment</h3> <p class="item-description">Adjust spatial behavior and physics parameters</p> </div> <div class="menu-item" data-depth="100"> <div class="item-icon"> <svg viewBox="0 0 24 24" fill="none" stroke="#00ffff" stroke-width="1.5"> <circle cx="12" cy="12" r="10"></circle> <line x1="2" y1="12" x2="22" y2="12"></line> <path d="M12 2a15.3 15.3 0 014 10 15.3 15.3 0 01-4 10 15.3 15.3 0 01-4-10 15.3 15.3 0 014-10z"></path> </svg> </div> <h3 class="item-title">Worlds</h3> <p class="item-description">Explore procedurally generated dimensional spaces</p> </div> <div class="menu-item" data-depth="300"> <div class="item-icon"> <svg viewBox="0 0 24 24" fill="none" stroke="#00ffff" stroke-width="1.5"> <path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2"></path> <circle cx="9" cy="7" r="4"></circle> <path d="M23 21v-2a4 4 0 00-3-3.87"></path> <path d="M16 3.13a4 4 0 010 7.75"></path> </svg> </div> <h3 class="item-title">Neural Link</h3> <p class="item-description">Connect with other users across quantum networks</p> </div> <div class="menu-item" data-depth="0"> <div class="item-icon"> <svg viewBox="0 0 24 24" fill="none" stroke="#00ffff" stroke-width="1.5"> <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"></polygon> </svg> </div> <h3 class="item-title">Power Systems</h3> <p class="item-description">Manage neural processing allocation and quantum rendering</p> </div> </div> <div class="loading-indicator"></div> <p class="user-guidance">Move your cursor to navigate the depth space</p> <div class="grid-lines"></div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const container = document.querySelector('.vr-container'); const menu = document.querySelector('.vr-menu'); const menuItems = document.querySelectorAll('.menu-item'); const focalPoint = document.querySelector('.focal-point'); const gridLines = document.querySelector('.grid-lines'); // Create grid lines for (let i = 1; i < 10; i++) { const horizontalLine = document.createElement('div'); horizontalLine.classList.add('grid-horizontal'); horizontalLine.style.top = `${i * 10}%`; const verticalLine = document.createElement('div'); verticalLine.classList.add('grid-vertical'); verticalLine.style.left = `${i * 10}%`; gridLines.appendChild(horizontalLine); gridLines.appendChild(verticalLine); } // Create ring effects for (let i = 1; i <= 3; i++) { const ring = document.createElement('div'); ring.classList.add('ring-effect'); ring.style.width = `${i * 200}px`; ring.style.height = `${i * 200}px`; container.appendChild(ring); } // Position menu items in 3D space function positionMenuItems() { const angleStep = (2 * Math.PI) / menuItems.length; const radius = Math.min(container.offsetWidth, container.offsetHeight) * 0.25; menuItems.forEach((item, index) => { const angle = angleStep * index; const x = radius * Math.cos(angle); const y = radius * Math.sin(angle) * 0.5; // Flatten the circle a bit const z = parseFloat(item.getAttribute('data-depth')); item.style.transform = `translate3d(${x}px, ${y}px, ${z}px)`; }); } positionMenuItems(); // Handle mouse movement for gaze simulation document.addEventListener('mousemove', function(e) { const { clientX, clientY } = e; const rect = container.getBoundingClientRect(); const x = clientX - rect.left; const y = clientY - rect.top; // Center coordinates (between -1 and 1) const centerX = (x / rect.width) * 2 - 1; const centerY = (y / rect.height) * 2 - 1; // Move the focal point focalPoint.style.left = `${x}px`; focalPoint.style.top = `${y}px`; // Rotate menu based on mouse position menu.style.transform = `rotateY(${centerX * 15}deg) rotateX(${-centerY * 15}deg)`; // Update ring positions const rings = document.querySelectorAll('.ring-effect'); rings.forEach((ring, i) => { ring.style.left = `${x}px`; ring.style.top = `${y}px`; ring.style.transform = `translate(-50%, -50%) scale(${1 + (Math.sin(Date.now() / 1000 + i) + 1) * 0.1})`; }); // Check item focus based on proximity menuItems.forEach(item => { const itemRect = item.getBoundingClientRect(); const itemCenterX = itemRect.left + itemRect.width / 2; const itemCenterY = itemRect.top + itemRect.height / 2; const distance = Math.sqrt( Math.pow(clientX - itemCenterX, 2) + Math.pow(clientY - itemCenterY, 2) ); if (distance < 100) { item.classList.add('focused'); // Dynamic depth adjustment when focused const currentZ = parseFloat(item.getAttribute('data-depth')); const newZ = currentZ * 1.2; item.style.transform = `translate3d(${item.style.transform.split('(')[1].split(',')[0]}, ${item.style.transform.split(',')[1]}, ${newZ}px)`; } else { item.classList.remove('focused'); // Reset to original depth const originalZ = parseFloat(item.getAttribute('data-depth')); item.style.transform = `translate3d(${item.style.transform.split('(')[1].split(',')[0]}, ${item.style.transform.split(',')[1]}, ${originalZ}px)`; } }); }); // Handle clicks on menu items menuItems.forEach(item => { item.addEventListener('click', function() { // Flash effect this.style.boxShadow = '0 0 50px rgba(0, 255, 255, 0.8), 0 0 20px rgba(0, 255, 255, 0.8) inset'; // Menu selection animation menuItems.forEach(otherItem => { if (otherItem !== this) { otherItem.style.opacity = '0.3'; otherItem.style.transform = `${otherItem.style.transform.split('translate')[0]} translate3d(${Math.random() * 500 - 250}px, ${Math.random() * 500 - 250}px, ${-500}px)`; } }); this.style.transform = `translate3d(0, 0, 200px) scale(1.5)`; // Reset after animation setTimeout(() => { positionMenuItems(); menuItems.forEach(item => { item.style.opacity = '1'; item.style.boxShadow = ''; }); }, 1200); }); }); // Handle resize events window.addEventListener('resize', positionMenuItems); // Add some dynamic effects function animateBackground() { const now = Date.now() / 1000; document.body.style.background = `radial-gradient(ellipse at ${Math.sin(now * 0.2) * 50 + 50}% ${Math.cos(now * 0.2) * 50 + 50}%, rgba(10, 20, 50, 0.8), #0a0a15)`; requestAnimationFrame(animateBackground); } animateBackground(); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Woodland Tales - Interactive Storybook</title> <style> :root { --color-parchment: #f5ecd8; --color-forest: #2c5e4c; --color-moss: #8b9e70; --color-bark: #6e4530; --color-autumn: #d47f46; --color-midnight: #1d2c3b; --shadow-soft: 0 10px 30px rgba(0, 0, 0, 0.15); --shadow-page: 0 5px 15px rgba(0, 0, 0, 0.1); --transition-flip: all 0.7s cubic-bezier(0.645, 0.045, 0.355, 1); } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Garamond', serif; background-color: var(--color-midnight); height: 100vh; display: flex; justify-content: center; align-items: center; overflow: hidden; perspective: 1500px; } .storybook-container { width: 100%; max-width: 700px; height: 700px; position: relative; perspective: 1500px; transform-style: preserve-3d; } .book { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transform: rotateX(10deg); transition: transform 0.5s ease; } .book:hover { transform: rotateX(5deg); } .book-cover { position: absolute; width: 100%; height: 100%; transform-style: preserve-3d; background: var(--color-bark); border-radius: 5px 15px 15px 5px; box-shadow: var(--shadow-soft); display: flex; justify-content: center; align-items: center; overflow: hidden; z-index: 1; } .book-title { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: var(--color-parchment); font-size: 3rem; text-align: center; letter-spacing: 2px; text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); z-index: 3; width: 80%; } .book-subtitle { position: absolute; top: 65%; left: 50%; transform: translate(-50%, -50%); color: var(--color-parchment); font-size: 1.2rem; text-align: center; font-style: italic; z-index: 3; width: 80%; } .cover-illustration { position: absolute; width: 90%; height: 90%; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 100 100'%3E%3Cpath d='M50,10 C70,10 80,40 80,50 C80,70 70,90 50,90 C30,90 20,70 20,50 C20,40 30,10 50,10z' fill='%238b9e70' stroke='%232c5e4c' stroke-width='2'/%3E%3Cpath d='M50,20 C60,20 70,35 70,50 C70,65 60,80 50,80 C40,80 30,65 30,50 C30,35 40,20 50,20z' fill='%23f5ecd8' opacity='0.3'/%3E%3C/svg%3E"); background-size: cover; opacity: 0.3; z-index: 2; } .page { position: absolute; width: 96%; height: 96%; top: 2%; left: 2%; background: var(--color-parchment); border-radius: 2px 10px 10px 2px; box-shadow: var(--shadow-page); transform-origin: left center; transform-style: preserve-3d; transition: var(--transition-flip); cursor: pointer; padding: 30px; overflow: hidden; display: flex; flex-direction: column; justify-content: space-between; } .page-content { position: relative; z-index: 1; height: 100%; display: flex; flex-direction: column; justify-content: space-between; } .page-number { align-self: flex-end; font-style: italic; color: var(--color-forest); opacity: 0.7; } .page-title { font-size: 1.8rem; color: var(--color-forest); margin-bottom: 20px; position: relative; } .page-title::after { content: ''; position: absolute; bottom: -10px; left: 0; width: 60px; height: 2px; background-color: var(--color-autumn); } .page-text { font-size: 1.1rem; line-height: 1.6; color: var(--color-bark); margin-bottom: 20px; } .page-illustration { width: 100%; height: 200px; margin: 20px 0; position: relative; overflow: hidden; border-radius: 8px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); } .page-illustration-bg { position: absolute; width: 100%; height: 100%; background-color: var(--color-moss); opacity: 0.2; } .page-illustration-element { position: absolute; transition: transform 0.5s ease; } .illustration-tree { width: 100px; height: 150px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 150'%3E%3Cpath d='M50,10 L35,50 L45,50 L30,90 L45,90 L40,130 L60,130 L55,90 L70,90 L55,50 L65,50 z' fill='%236e4530'/%3E%3Ccircle cx='50' cy='35' r='25' fill='%232c5e4c'/%3E%3C/svg%3E"); background-repeat: no-repeat; top: 20px; left: 20px; } .illustration-bird { width: 30px; height: 20px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 20'%3E%3Cpath d='M5,10 Q15,0 25,10 L27,8 L28,10 L30,9 L28,12 Q15,20 2,12 L0,9 L2,10 L3,8 L5,10' fill='%23d47f46'/%3E%3C/svg%3E"); background-repeat: no-repeat; top: 50px; right: 60px; } .illustration-fox { width: 60px; height: 40px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 40'%3E%3Cpath d='M10,30 Q20,15 30,30 Q40,15 50,30 L55,25 L58,30 L50,35 L30,35 L10,35 L2,30 L5,25 z' fill='%23d47f46'/%3E%3Ccircle cx='20' cy='25' r='2' fill='%23000'/%3E%3Ccircle cx='40' cy='25' r='2' fill='%23000'/%3E%3C/svg%3E"); background-repeat: no-repeat; bottom: 20px; right: 30px; } .page-decoration { position: absolute; width: 40px; height: 40px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 40'%3E%3Cpath d='M20,0 Q40,20 20,40 Q0,20 20,0' fill='none' stroke='%238b9e70' stroke-width='1'/%3E%3C/svg%3E"); opacity: 0.3; } .decoration-1 { top: 20px; right: 20px; } .decoration-2 { bottom: 20px; left: 20px; transform: rotate(90deg); } .page.flipped { transform: rotateY(-180deg); } .page-front { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; -webkit-backface-visibility: hidden; } .page-back { position: absolute; width: 100%; height: 100%; transform: rotateY(180deg); backface-visibility: hidden; -webkit-backface-visibility: hidden; } .navigation { position: absolute; bottom: 30px; display: flex; justify-content: space-between; width: 120px; left: 50%; transform: translateX(-50%); z-index: 100; } .nav-btn { background: none; border: none; width: 50px; height: 50px; border-radius: 50%; background-color: var(--color-forest); color: var(--color-parchment); font-size: 1.5rem; cursor: pointer; display: flex; justify-content: center; align-items: center; box-shadow: var(--shadow-soft); transition: all 0.3s ease; } .nav-btn:hover { background-color: var(--color-autumn); transform: translateY(-3px); } .nav-btn:disabled { background-color: var(--color-moss); opacity: 0.5; cursor: not-allowed; transform: none; } .page-fold { position: absolute; right: 0; top: 0; width: 30px; height: 30px; background: linear-gradient(135deg, transparent 50%, rgba(0,0,0,0.05) 50%); border-radius: 0 0 0 5px; z-index: 2; } @keyframes floatBird { 0% { transform: translate(0, 0); } 50% { transform: translate(10px, -5px); } 100% { transform: translate(0, 0); } } @keyframes breathe { 0% { transform: scale(1); } 50% { transform: scale(1.03); } 100% { transform: scale(1); } } @media (max-width: 700px) { .book { transform: rotateX(5deg) scale(0.9); } .page-title { font-size: 1.5rem; } .page-text { font-size: 1rem; } .book-title { font-size: 2.5rem; } } @media (max-width: 500px) { .book { transform: rotateX(3deg) scale(0.8); } .page-illustration { height: 150px; } .page-title { font-size: 1.3rem; } .book-title { font-size: 2rem; } .book-subtitle { font-size: 1rem; } } .shadow-element { position: absolute; width: 100%; height: 30px; background: linear-gradient(to bottom, rgba(0,0,0,0.2) 0%, rgba(0,0,0,0) 100%); bottom: -30px; transform: rotateX(90deg); transform-origin: top; opacity: 0.5; } </style> </head> <body> <div class="storybook-container"> <div class="book"> <div class="shadow-element"></div> <div class="book-cover"> <div class="cover-illustration"></div> <h1 class="book-title">Woodland Tales</h1> <h2 class="book-subtitle">A journey through the whispering forest</h2> </div> <!-- Page 1 --> <div class="page" id="page1"> <div class="page-fold"></div> <div class="page-front"> <div class="page-content"> <div> <h2 class="page-title">The Secret Path</h2> <p class="page-text">At the edge of the old village, where cobblestone streets surrender to wild ferns and tangled roots, stands an ancient oak with bark etched by centuries of wind and rain. The villagers speak of it in hushed tones, for this is no ordinary tree—it's the guardian of the forest's secret path.</p> <div class="page-illustration"> <div class="page-illustration-bg"></div> <div class="page-illustration-element illustration-tree"></div> <div class="page-illustration-element illustration-bird"></div> </div> <p class="page-text">Only those with the gentlest hearts can see the faint glow of moss that marks the beginning of the hidden trail. And only the most patient souls can hear the soft whispers of leaves that guide wanderers deeper into the woodland realm.</p> </div> <span class="page-number">1</span> </div> <div class="page-decoration decoration-1"></div> <div class="page-decoration decoration-2"></div> </div> <div class="page-back"> <div class="page-content"> <div> <h2 class="page-title">First Encounters</h2> <p class="page-text">Clara discovered the path on a misty autumn morning. The air tasted of damp earth and pine as she followed the luminescent moss between twisted roots and hanging vines. Each step felt like crossing an invisible threshold into a different world.</p> <div class="page-illustration"> <div class="page-illustration-bg"></div> <div class="page-illustration-element illustration-fox"></div> </div> <p class="page-text">The first creature to greet her was a fox with russet fur that seemed to shimmer with amber light. Its eyes held ancient wisdom, and when it turned to lead her deeper into the woods, Clara knew this was no ordinary forest dweller. This was a keeper of secrets.</p> </div> <span class="page-number">2</span> </div> <div class="page-decoration decoration-1"></div> <div class="page-decoration decoration-2"></div> </div> </div> <!-- Page 2 --> <div class="page" id="page2"> <div class="page-fold"></div> <div class="page-front"> <div class="page-content"> <div> <h2 class="page-title">The Whispering Trees</h2> <p class="page-text">As Clara ventured deeper, the trees grew taller, their canopies weaving together to form a cathedral of leaves. Sunlight filtered through in dancing patterns, creating pools of gold on the forest floor. The air itself seemed to thicken with magic.</p> <div class="page-illustration"> <div class="page-illustration-bg"></div> <div class="page-illustration-element illustration-tree" style="left: 60px;"></div> <div class="page-illustration-element illustration-tree" style="left: 200px; top: 30px;"></div> </div> <p class="page-text">"Listen carefully," her fox guide seemed to say without words. Clara held her breath and heard it—the trees were conversing in a language of rustling leaves and creaking branches. They spoke of seasons long past, of storms weathered, and of the ancient pact between forest and mankind.</p> </div> <span class="page-number">3</span> </div> <div class="page-decoration decoration-1"></div> <div class="page-decoration decoration-2"></div> </div> <div class="page-back"> <div class="page-content"> <div> <h2 class="page-title">The Heart of the Forest</h2> <p class="page-text">By midday, Clara reached a clearing unlike any other. At its center stood a circle of seven standing stones, their surfaces etched with spirals and symbols that seemed to shift when observed from the corner of one's eye. The fox sat beside the tallest stone, waiting.</p> <div class="page-illustration"> <div class="page-illustration-bg"></div> <div class="page-illustration-element illustration-fox" style="bottom: 50px; right: 100px;"></div> <div class="page-illustration-element illustration-bird" style="top: 30px; right: 40px;"></div> </div> <p class="page-text">Here, at the heart of the forest, the boundary between worlds grew thin. Clara could feel the pulse of the earth beneath her feet, the rhythm of life that connected every creature, every plant, every stone. The forest was alive, and it had chosen her to hear its story.</p> </div> <span class="page-number">4</span> </div> <div class="page-decoration decoration-1"></div> <div class="page-decoration decoration-2"></div> </div> </div> <!-- Page 3 --> <div class="page" id="page3"> <div class="page-fold"></div> <div class="page-front"> <div class="page-content"> <div> <h2 class="page-title">The Keeper's Tale</h2> <p class="page-text">As dusk approached, the clearing transformed. Fireflies emerged, their gentle glow illuminating the space between the ancient stones. The fox, now seated at Clara's feet, began to share the forest's most treasured legend—not with words, but with visions that bloomed in Clara's mind.</p> <div class="page-illustration"> <div class="page-illustration-bg"></div> <div class="page-illustration-element illustration-fox" style="bottom: 30px; left: 50px;"></div> <div class="page-illustration-element illustration-bird" style="top: 40px; right: 100px;"></div> </div> <p class="page-text">Long ago, the forest and humans lived in harmony. The villagers were keepers of the woodland, and in return, the trees shared their magic—healing remedies, protection from harsh weather, and wisdom passed through generations. But as time wore on, people forgot the old ways.</p> </div> <span class="page-number">5</span> </div> <div class="page-decoration decoration-1"></div> <div class="page-decoration decoration-2"></div> </div> <div class="page-back"> <div class="page-content"> <div> <h2 class="page-title">A Promise Renewed</h2> <p class="page-text">The stars emerged overhead as the fox's tale concluded. Clara understood now why she had been drawn to the ancient oak, why the path had revealed itself to her. The forest was seeking a new keeper, someone to renew the forgotten promise between worlds.</p> <div class="page-illustration"> <div class="page-illustration-bg"></div> <div class="page-illustration-element illustration-tree" style="left: 150px;"></div> <div class="page-illustration-element illustration-bird" style="top: 70px; left: 40px;"></div> </div> <p class="page-text">With a heart full of wonder and responsibility, Clara placed her palm against the tallest standing stone. A warm energy flowed through her fingertips, sealing her commitment. The fox gave a nod of approval before disappearing into the twilight shadows. Clara wasn't alone anymore—she was part of something ancient and alive.</p> </div> <span class="page-number">6</span> </div> <div class="page-decoration decoration-1"></div> <div class="page-decoration decoration-2"></div> </div> </div> </div> <div class="navigation"> <button class="nav-btn" id="prev-btn" disabled>←</button> <button class="nav-btn" id="next-btn">→</button> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const book = document.querySelector('.book'); const bookCover = document.querySelector('.book-cover'); const pages = document.querySelectorAll('.page'); const prevBtn = document.getElementById('prev-btn'); const nextBtn = document.getElementById('next-btn'); const birds = document.querySelectorAll('.illustration-bird'); const foxes = document.querySelectorAll('.illustration-fox'); const trees = document.querySelectorAll('.illustration-tree'); let currentPage = 0; const totalPages = pages.length; // Initial setup - hide all pages except the cover pages.forEach((page, index) => { page.style.zIndex = 10 - index; if (index > 0) { page.style.transform = 'rotateY(-180deg)'; } }); // Apply animations to illustration elements birds.forEach(bird => { bird.style.animation = 'floatBird 4s ease-in-out infinite'; }); foxes.forEach(fox => { fox.style.animation = 'breathe 6s ease-in-out infinite'; }); trees.forEach(tree => { tree.style.animation = 'breathe 10s ease-in-out infinite'; }); // Parallax effect for illustrations const illustrations = document.querySelectorAll('.page-illustration'); illustrations.forEach(illustration => { illustration.addEventListener('mousemove', function(e) { const rect = illustration.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; const xPercent = x / rect.width; const yPercent = y / rect.height; const elements = illustration.querySelectorAll('.page-illustration-element'); elements.forEach((element, index) => { const depth = (index + 1) * 10; const moveX = (xPercent - 0.5) * depth; const moveY = (yPercent - 0.5) * depth; element.style.transform = `translate(${moveX}px, ${moveY}px)`; }); }); illustration.addEventListener('mouseleave', function() { const elements = illustration.querySelectorAll('.page-illustration-element'); elements.forEach(element => { element.style.transform = 'translate(0, 0)'; }); }); }); // Book open effect bookCover.addEventListener('click', function() { if (currentPage === 0) { bookCover.style.transform = 'rotateY(-180deg)'; bookCover.style.zIndex = '0'; currentPage++; updateButtons(); } }); // Page turn functionality function turnPage(direction) { if (direction === 'next' && currentPage < totalPages) { if (currentPage === 0) { // Open the book cover bookCover.style.transform = 'rotateY(-180deg)'; bookCover.style.zIndex = '0'; } else { // Flip to next page pages[currentPage - 1].classList.add('flipped'); } currentPage++; } else if (direction === 'prev' && currentPage > 0) { currentPage--; if (currentPage === 0) { // Close the book cover bookCover.style.transform = ''; bookCover.style.zIndex = '10'; } else { // Flip back to previous page pages[currentPage - 1].classList.remove('flipped'); } } updateButtons(); } function updateButtons() { prevBtn.disabled = currentPage === 0; nextBtn.disabled = currentPage === totalPages; } // Event listeners for buttons nextBtn.addEventListener('click', () => turnPage('next')); prevBtn.addEventListener('click', () => turnPage('prev')); // Page click to turn pages.forEach((page, index) => { page.addEventListener('click', function(e) { // Only flip if clicking near the edge const rect = page.getBoundingClientRect(); const clickX = e.clientX - rect.left; if (clickX > rect.width * 0.7) { if (index === currentPage - 1) { turnPage('next'); } } else if (clickX < rect.width * 0.3) { if (index === currentPage - 2) { turnPage('prev'); } } }); }); // 3D book tilt effect document.addEventListener('mousemove', function(e) { const xAxis = (window.innerWidth / 2 - e.pageX) / 25; const yAxis = (window.innerHeight / 2 - e.pageY) / 25; book.style.transform = `rotateX(${yAxis + 10}deg) rotateY(${-xAxis}deg)`; }); // Touch events for mobile let touchStartX = 0; document.addEventListener('touchstart', function(e) { touchStartX = e.touches[0].clientX; }); document.addEventListener('touchend', function(e) { const touchEndX = e.changedTouches[0].clientX; const diff = touchStartX - touchEndX; if (diff > 50) { // Swipe left turnPage('next'); } else if (diff < -50) { // Swipe right turnPage('prev'); } }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>BluePrint Visualizer Pro</title> <style> @import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@300;400;500&family=JetBrains+Mono:wght@300;400;500&display=swap'); :root { --primary-blue: #1e4d78; --light-blue: #5f99cc; --accent-blue: #0a84ff; --pale-blue: #e4f0ff; --dark-gray: #2c3e50; --medium-gray: #607d8b; --light-gray: #eceff1; --ultra-light-gray: #f5f7fa; --grid-color: rgba(30, 77, 120, 0.15); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'JetBrains Mono', 'IBM Plex Mono', monospace; } body { width: 100%; height: 100vh; overflow: hidden; background-color: var(--ultra-light-gray); display: flex; justify-content: center; align-items: center; } .app-container { width: 700px; height: 700px; display: flex; flex-direction: column; background-color: white; border-radius: 8px; box-shadow: 0 10px 30px rgba(44, 62, 80, 0.1); overflow: hidden; position: relative; } .header { padding: 16px 24px; background-color: var(--primary-blue); color: white; display: flex; justify-content: space-between; align-items: center; border-bottom: 2px solid var(--medium-gray); } .header h1 { font-size: 18px; font-weight: 500; letter-spacing: -0.5px; } .project-info { font-size: 12px; opacity: 0.8; } .toolbar { display: flex; justify-content: space-between; align-items: center; padding: 12px 24px; background-color: var(--light-gray); border-bottom: 1px solid rgba(96, 125, 139, 0.3); } .view-options { display: flex; gap: 12px; } .view-btn { background-color: transparent; border: 1px solid var(--medium-gray); color: var(--dark-gray); padding: 6px 12px; border-radius: 4px; font-size: 12px; cursor: pointer; transition: all 0.2s ease; } .view-btn:hover { background-color: rgba(30, 77, 120, 0.1); } .view-btn.active { background-color: var(--primary-blue); color: white; border-color: var(--primary-blue); } .zoom-controls { display: flex; gap: 8px; align-items: center; } .zoom-btn { width: 28px; height: 28px; display: flex; align-items: center; justify-content: center; background-color: white; border: 1px solid var(--medium-gray); border-radius: 4px; cursor: pointer; font-size: 16px; transition: all 0.2s ease; } .zoom-btn:hover { background-color: var(--pale-blue); } .zoom-value { font-size: 12px; color: var(--dark-gray); width: 40px; text-align: center; } .main-container { display: flex; flex: 1; overflow: hidden; position: relative; } .layers-panel { width: 180px; background-color: var(--ultra-light-gray); border-right: 1px solid rgba(96, 125, 139, 0.3); padding: 16px; overflow-y: auto; } .layer-title { font-size: 12px; color: var(--dark-gray); margin-bottom: 12px; font-weight: 500; display: flex; justify-content: space-between; align-items: center; } .eye-all { cursor: pointer; opacity: 0.7; transition: opacity 0.2s; } .eye-all:hover { opacity: 1; } .layer-item { display: flex; align-items: center; margin-bottom: 8px; padding: 8px; border-radius: 4px; transition: background-color 0.2s; } .layer-item:hover { background-color: rgba(30, 77, 120, 0.05); } .layer-icon { width: 16px; height: 16px; margin-right: 8px; display: flex; align-items: center; justify-content: center; } .layer-icon svg { width: 16px; height: 16px; } .layer-checkbox { margin-right: 8px; appearance: none; width: 16px; height: 16px; border: 1px solid var(--medium-gray); border-radius: 3px; cursor: pointer; position: relative; } .layer-checkbox:checked { background-color: var(--primary-blue); border-color: var(--primary-blue); } .layer-checkbox:checked::after { content: "✓"; position: absolute; color: white; font-size: 12px; top: 50%; left: 50%; transform: translate(-50%, -50%); } .layer-name { font-size: 12px; color: var(--dark-gray); flex: 1; } .floor-plan-container { flex: 1; position: relative; overflow: hidden; display: flex; justify-content: center; align-items: center; background-color: var(--ultra-light-gray); background-image: linear-gradient(var(--grid-color) 1px, transparent 1px), linear-gradient(90deg, var(--grid-color) 1px, transparent 1px); background-size: 20px 20px; transition: background-size 0.3s ease; } .floor-plan { position: relative; width: 400px; height: 300px; transform-style: preserve-3d; transition: transform 0.8s cubic-bezier(0.34, 1.56, 0.64, 1); transform: rotateX(45deg) rotateZ(45deg) scale(0.8); } .floor-plan.flat { transform: rotateX(0deg) rotateZ(0deg) scale(1); } .floor-plan.isometric { transform: rotateX(45deg) rotateZ(45deg) scale(0.8); } .floor-plan-layer { position: absolute; top: 0; left: 0; width: 100%; height: 100%; transition: opacity 0.3s, transform 0.5s; } .wall-layer { background-color: var(--light-blue); opacity: 0.9; mask: url("data:image/svg+xml,%3Csvg width='400' height='300' viewBox='0 0 400 300' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M20 20H380V280H20V20ZM120 120H220V180H120V120ZM140 70H170V100H140V70ZM240 70H270V100H240V70ZM240 200H270V230H240V200ZM140 200H170V230H140V200Z' fill='black'/%3E%3C/svg%3E"); -webkit-mask: url("data:image/svg+xml,%3Csvg width='400' height='300' viewBox='0 0 400 300' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M20 20H380V280H20V20ZM120 120H220V180H120V120ZM140 70H170V100H140V70ZM240 70H270V100H240V70ZM240 200H270V230H240V200ZM140 200H170V230H140V200Z' fill='black'/%3E%3C/svg%3E"); } .furniture-layer { background-color: transparent; background-image: url("data:image/svg+xml,%3Csvg width='400' height='300' viewBox='0 0 400 300' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Crect x='75' y='160' width='30' height='50' rx='2' fill='%232c3e50' fill-opacity='0.6'/%3E%3Crect x='290' y='160' width='30' height='50' rx='2' fill='%232c3e50' fill-opacity='0.6'/%3E%3Crect x='270' y='50' width='60' height='30' rx='2' fill='%232c3e50' fill-opacity='0.6'/%3E%3Crect x='70' y='50' width='60' height='30' rx='2' fill='%232c3e50' fill-opacity='0.6'/%3E%3Ccircle cx='170' cy='150' r='20' fill='%232c3e50' fill-opacity='0.6'/%3E%3C/svg%3E"); } .electrical-layer { background-color: transparent; background-image: url("data:image/svg+xml,%3Csvg width='400' height='300' viewBox='0 0 400 300' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='50' cy='50' r='5' fill='%23e74c3c'/%3E%3Ccircle cx='200' cy='50' r='5' fill='%23e74c3c'/%3E%3Ccircle cx='350' cy='50' r='5' fill='%23e74c3c'/%3E%3Ccircle cx='50' cy='250' r='5' fill='%23e74c3c'/%3E%3Ccircle cx='200' cy='250' r='5' fill='%23e74c3c'/%3E%3Ccircle cx='350' cy='250' r='5' fill='%23e74c3c'/%3E%3Ccircle cx='50' cy='150' r='5' fill='%23e74c3c'/%3E%3Ccircle cx='350' cy='150' r='5' fill='%23e74c3c'/%3E%3C/svg%3E"); } .plumbing-layer { background-color: transparent; background-image: url("data:image/svg+xml,%3Csvg width='400' height='300' viewBox='0 0 400 300' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='75' cy='240' r='10' stroke='%230984e3' stroke-width='2' fill='none'/%3E%3Ccircle cx='325' cy='240' r='10' stroke='%230984e3' stroke-width='2' fill='none'/%3E%3Cpath d='M75 230 L75 180 L325 180 L325 230' stroke='%230984e3' stroke-width='2' fill='none'/%3E%3C/svg%3E"); } .hvac-layer { background-color: transparent; background-image: url("data:image/svg+xml,%3Csvg width='400' height='300' viewBox='0 0 400 300' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M40 40 L80 40 L80 80 L40 80 Z' stroke='%2327ae60' stroke-width='2' fill='none'/%3E%3Cpath d='M320 40 L360 40 L360 80 L320 80 Z' stroke='%2327ae60' stroke-width='2' fill='none'/%3E%3Cpath d='M40 220 L80 220 L80 260 L40 260 Z' stroke='%2327ae60' stroke-width='2' fill='none'/%3E%3Cpath d='M320 220 L360 220 L360 260 L320 260 Z' stroke='%2327ae60' stroke-width='2' fill='none'/%3E%3Cpath d='M80 60 L320 60' stroke='%2327ae60' stroke-width='2' stroke-dasharray='5 3'/%3E%3Cpath d='M80 240 L320 240' stroke='%2327ae60' stroke-width='2' stroke-dasharray='5 3'/%3E%3Cpath d='M60 80 L60 220' stroke='%2327ae60' stroke-width='2' stroke-dasharray='5 3'/%3E%3Cpath d='M340 80 L340 220' stroke='%2327ae60' stroke-width='2' stroke-dasharray='5 3'/%3E%3C/svg%3E"); } .floor-plan-layer.hidden { opacity: 0; pointer-events: none; } .annotations-layer { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; } .annotation { position: absolute; font-size: 12px; color: var(--primary-blue); font-weight: 500; opacity: 0; transform: translateY(10px); transition: opacity 0.3s, transform 0.3s; } .annotation.visible { opacity: 1; transform: translateY(0); } .annotation::before { content: ''; position: absolute; width: 5px; height: 5px; border-radius: 50%; background-color: var(--accent-blue); top: 6px; left: -12px; } .floor-selector { position: absolute; right: 16px; top: 50%; transform: translateY(-50%); background-color: white; border-radius: 8px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); overflow: hidden; display: flex; flex-direction: column; } .floor-option { padding: 10px 16px; font-size: 12px; cursor: pointer; transition: all 0.2s; border-bottom: 1px solid var(--light-gray); } .floor-option:last-child { border-bottom: none; } .floor-option:hover { background-color: var(--pale-blue); } .floor-option.active { background-color: var(--primary-blue); color: white; } .status-bar { display: flex; justify-content: space-between; align-items: center; padding: 8px 24px; background-color: var(--light-gray); border-top: 1px solid rgba(96, 125, 139, 0.3); font-size: 11px; color: var(--medium-gray); } .coordinates { display: flex; gap: 12px; } .coordinate { display: flex; align-items: center; gap: 4px; } .coordinate-label { opacity: 0.7; } .coordinate-value { font-weight: 500; } .scale-indicator { display: flex; align-items: center; gap: 8px; } .scale-line { width: 60px; height: 2px; background-color: var(--dark-gray); position: relative; } .scale-line::before, .scale-line::after { content: ''; position: absolute; width: 1px; height: 6px; background-color: var(--dark-gray); top: -2px; } .scale-line::before { left: 0; } .scale-line::after { right: 0; } .scale-text { font-weight: 500; } .element-tooltip { position: absolute; background-color: var(--dark-gray); color: white; padding: 8px 12px; border-radius: 4px; font-size: 11px; pointer-events: none; opacity: 0; transform: translateY(-10px); transition: opacity 0.2s, transform 0.2s; z-index: 100; white-space: nowrap; } .element-tooltip::after { content: ''; position: absolute; bottom: -5px; left: 50%; transform: translateX(-50%); width: 0; height: 0; border-left: 5px solid transparent; border-right: 5px solid transparent; border-top: 5px solid var(--dark-gray); } .element-tooltip.visible { opacity: 1; transform: translateY(0); } .hotspot { position: absolute; width: 12px; height: 12px; border-radius: 50%; background-color: var(--accent-blue); cursor: pointer; transition: transform 0.2s, box-shadow 0.2s; z-index: 10; transform: scale(1) translate(-50%, -50%); } .hotspot:hover { transform: scale(1.3) translate(-40%, -40%); box-shadow: 0 0 0 4px rgba(10, 132, 255, 0.3); } .hotspot::after { content: ''; position: absolute; width: 100%; height: 100%; border-radius: 50%; background-color: var(--accent-blue); opacity: 0.5; animation: pulse 2s infinite; } @keyframes pulse { 0% { transform: scale(1); opacity: 0.5; } 70% { transform: scale(2); opacity: 0; } 100% { transform: scale(1); opacity: 0; } } /* Responsive adjustments */ @media (max-width: 700px) { .header h1 { font-size: 16px; } .layers-panel { width: 150px; } .view-btn { padding: 4px 8px; font-size: 11px; } .floor-plan { width: 300px; height: 220px; } .annotation { font-size: 10px; } } @media (max-width: 500px) { .header { padding: 12px 16px; } .toolbar { padding: 8px 16px; flex-direction: column; gap: 8px; align-items: flex-start; } .layers-panel { width: 120px; } .status-bar { padding: 6px 16px; font-size: 10px; } .floor-plan { width: 250px; height: 180px; } } </style> </head> <body> <div class="app-container"> <header class="header"> <div> <h1>BluePrint Visualizer Pro</h1> <div class="project-info">Project ID: ARV-2301 • Modern Office Complex</div> </div> </header> <div class="toolbar"> <div class="view-options"> <button class="view-btn active" id="isometric-view">Isometric</button> <button class="view-btn" id="flat-view">Flat (2D)</button> </div> <div class="zoom-controls"> <button class="zoom-btn" id="zoom-out">−</button> <div class="zoom-value" id="zoom-value">100%</div> <button class="zoom-btn" id="zoom-in">+</button> </div> </div> <div class="main-container"> <div class="layers-panel"> <div class="layer-title"> <span>Layers</span> <span class="eye-all" id="toggle-all-layers" title="Toggle all layers">👁️</span> </div> <div class="layer-item"> <input type="checkbox" class="layer-checkbox" id="walls-checkbox" checked> <div class="layer-icon"> <svg viewBox="0 0 24 24" fill="none" stroke="#2c3e50" stroke-width="2"> <rect x="3" y="3" width="18" height="18" rx="2"></rect> </svg> </div> <span class="layer-name">Walls & Rooms</span> </div> <div class="layer-item"> <input type="checkbox" class="layer-checkbox" id="furniture-checkbox" checked> <div class="layer-icon"> <svg viewBox="0 0 24 24" fill="none" stroke="#2c3e50" stroke-width="2"> <rect x="4" y="8" width="16" height="12" rx="1"></rect> <path d="M6 8V6C6 4.89543 6.89543 4 8 4H16C17.1046 4 18 4.89543 18 6V8"></path> </svg> </div> <span class="layer-name">Furniture</span> </div> <div class="layer-item"> <input type="checkbox" class="layer-checkbox" id="electrical-checkbox" checked> <div class="layer-icon"> <svg viewBox="0 0 24 24" fill="none" stroke="#e74c3c" stroke-width="2"> <circle cx="12" cy="12" r="4"></circle> <path d="M16 8L18 6"></path> <path d="M8 16L6 18"></path> <path d="M16 16L18 18"></path> <path d="M8 8L6 6"></path> </svg> </div> <span class="layer-name">Electrical</span> </div> <div class="layer-item"> <input type="checkbox" class="layer-checkbox" id="plumbing-checkbox" checked> <div class="layer-icon"> <svg viewBox="0 0 24 24" fill="none" stroke="#0984e3" stroke-width="2"> <circle cx="12" cy="8" r="3"></circle> <path d="M12 11L12 20"></path> <path d="M9 20L15 20"></path> </svg> </div> <span class="layer-name">Plumbing</span> </div> <div class="layer-item"> <input type="checkbox" class="layer-checkbox" id="hvac-checkbox" checked> <div class="layer-icon"> <svg viewBox="0 0 24 24" fill="none" stroke="#27ae60" stroke-width="2"> <path d="M3 12H6"></path> <path d="M18 12H21"></path> <path d="M12 3V6"></path> <path d="M12 18V21"></path> <circle cx="12" cy="12" r="6"></circle> </svg> </div> <span class="layer-name">HVAC</span> </div> </div> <div class="floor-plan-container" id="floor-plan-container"> <div class="floor-plan isometric" id="floor-plan"> <div class="floor-plan-layer wall-layer" id="walls-layer"></div> <div class="floor-plan-layer furniture-layer" id="furniture-layer"></div> <div class="floor-plan-layer electrical-layer" id="electrical-layer"></div> <div class="floor-plan-layer plumbing-layer" id="plumbing-layer"></div> <div class="floor-plan-layer hvac-layer" id="hvac-layer"></div> <div class="annotations-layer" id="annotations-layer"> <div class="annotation" style="top: 30px; left: 40px;">North Wall (7.2m)</div> <div class="annotation" style="top: 140px; left: 160px;">Conference Room</div> <div class="annotation" style="top: 80px; left: 60px;">Office A</div> <div class="annotation" style="top: 80px; left: 260px;">Office B</div> <div class="annotation" style="top: 210px; left: 60px;">Office C</div> <div class="annotation" style="top: 210px; left: 260px;">Office D</div> </div> <div class="hotspot" style="top: 50%; left: 50%;" data-tooltip="Conference room with seating for 8 people"></div> <div class="hotspot" style="top: 25%; left: 25%;" data-tooltip="Private office with window view"></div> <div class="hotspot" style="top: 25%; left: 75%;" data-tooltip="Executive office with private bathroom"></div> <div class="hotspot" style="top: 75%; left: 25%;" data-tooltip="Standard office with built-in storage"></div> <div class="hotspot" style="top: 75%; left: 75%;" data-tooltip="Guest office with multimedia equipment"></div> </div> <div class="floor-selector"> <div class="floor-option active" data-floor="1">Floor 1</div> <div class="floor-option" data-floor="2">Floor 2</div> <div class="floor-option" data-floor="3">Floor 3</div> </div> <div class="element-tooltip" id="element-tooltip"></div> </div> </div> <div class="status-bar"> <div class="coordinates"> <div class="coordinate"> <span class="coordinate-label">X:</span> <span class="coordinate-value" id="coord-x">0.00</span> </div> <div class="coordinate"> <span class="coordinate-label">Y:</span> <span class="coordinate-value" id="coord-y">0.00</span> </div> <div class="coordinate"> <span class="coordinate-label">Floor:</span> <span class="coordinate-value" id="current-floor">1</span> </div> </div> <div class="scale-indicator"> <div class="scale-line"></div> <div class="scale-text">10m</div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Elements const floorPlan = document.getElementById('floor-plan'); const floorPlanContainer = document.getElementById('floor-plan-container'); const isometricViewBtn = document.getElementById('isometric-view'); const flatViewBtn = document.getElementById('flat-view'); const zoomInBtn = document.getElementById('zoom-in'); const zoomOutBtn = document.getElementById('zoom-out'); const zoomValueEl = document.getElementById('zoom-value'); const toggleAllLayers = document.getElementById('toggle-all-layers'); const coordX = document.getElementById('coord-x'); const coordY = document.getElementById('coord-y'); const currentFloorEl = document.getElementById('current-floor'); const annotationsLayer = document.getElementById('annotations-layer'); const tooltip = document.getElementById('element-tooltip'); const floorOptions = document.querySelectorAll('.floor-option'); const hotspots = document.querySelectorAll('.hotspot'); // Layer elements const wallsCheckbox = document.getElementById('walls-checkbox'); const furnitureCheckbox = document.getElementById('furniture-checkbox'); const electricalCheckbox = document.getElementById('electrical-checkbox'); const plumbingCheckbox = document.getElementById('plumbing-checkbox'); const hvacCheckbox = document.getElementById('hvac-checkbox'); const wallsLayer = document.getElementById('walls-layer'); const furnitureLayer = document.getElementById('furniture-layer'); const electricalLayer = document.getElementById('electrical-layer'); const plumbingLayer = document.getElementById('plumbing-layer'); const hvacLayer = document.getElementById('hvac-layer'); // State let zoomLevel = 100; let isDragging = false; let startX, startY, scrollLeft, scrollTop; let allLayersVisible = true; let currentFloor = 1; // Initialize showAnnotations(); updateLayerVisibility(); // View type (isometric/flat) buttons isometricViewBtn.addEventListener('click', function() { isometricViewBtn.classList.add('active'); flatViewBtn.classList.remove('active'); floorPlan.classList.remove('flat'); floorPlan.classList.add('isometric'); }); flatViewBtn.addEventListener('click', function() { flatViewBtn.classList.add('active'); isometricViewBtn.classList.remove('active'); floorPlan.classList.remove('isometric'); floorPlan.classList.add('flat'); }); // Zoom controls zoomInBtn.addEventListener('click', function() { if (zoomLevel < 200) { zoomLevel += 20; updateZoom(); } }); zoomOutBtn.addEventListener('click', function() { if (zoomLevel > 60) { zoomLevel -= 20; updateZoom(); } }); function updateZoom() { zoomValueEl.textContent = zoomLevel + '%'; floorPlan.style.transform = floorPlan.classList.contains('isometric') ? `rotateX(45deg) rotateZ(45deg) scale(${zoomLevel / 100 * 0.8})` : `rotateX(0deg) rotateZ(0deg) scale(${zoomLevel / 100})`; // Update grid size based on zoom const gridSize = 20 * (100 / zoomLevel); floorPlanContainer.style.backgroundSize = `${gridSize}px ${gridSize}px`; } // Pan functionality (drag to move around) floorPlanContainer.addEventListener('mousedown', function(e) { isDragging = true; startX = e.pageX - floorPlanContainer.offsetLeft; startY = e.pageY - floorPlanContainer.offsetTop; scrollLeft = floorPlanContainer.scrollLeft; scrollTop = floorPlanContainer.scrollTop; floorPlanContainer.style.cursor = 'grabbing'; }); window.addEventListener('mouseup', function() { if (isDragging) { isDragging = false; floorPlanContainer.style.cursor = 'default'; } }); window.addEventListener('mousemove', function(e) { if (!isDragging) return; e.preventDefault(); const x = e.pageX - floorPlanContainer.offsetLeft; const y = e.pageY - floorPlanContainer.offsetTop; const moveX = (x - startX) * 1.5; const moveY = (y - startY) * 1.5; floorPlanContainer.scrollLeft = scrollLeft - moveX; floorPlanContainer.scrollTop = scrollTop - moveY; updateCoordinates(x, y); }); floorPlanContainer.addEventListener('mousemove', function(e) { if (!isDragging) { const rect = floorPlanContainer.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; updateCoordinates(x, y); } }); // Update coordinates display function updateCoordinates(x, y) { // Convert pixel coordinates to virtual meters (just for demonstration) const virtualX = (x / floorPlanContainer.clientWidth * 20).toFixed(2); const virtualY = (y / floorPlanContainer.clientHeight * 15).toFixed(2); coordX.textContent = virtualX; coordY.textContent = virtualY; } // Layer visibility toggle wallsCheckbox.addEventListener('change', updateLayerVisibility); furnitureCheckbox.addEventListener('change', updateLayerVisibility); electricalCheckbox.addEventListener('change', updateLayerVisibility); plumbingCheckbox.addEventListener('change', updateLayerVisibility); hvacCheckbox.addEventListener('change', updateLayerVisibility); function updateLayerVisibility() { wallsLayer.classList.toggle('hidden', !wallsCheckbox.checked); furnitureLayer.classList.toggle('hidden', !furnitureCheckbox.checked); electricalLayer.classList.toggle('hidden', !electricalCheckbox.checked); plumbingLayer.classList.toggle('hidden', !plumbingCheckbox.checked); hvacLayer.classList.toggle('hidden', !hvacCheckbox.checked); } // Toggle all layers toggleAllLayers.addEventListener('click', function() { allLayersVisible = !allLayersVisible; wallsCheckbox.checked = allLayersVisible; furnitureCheckbox.checked = allLayersVisible; electricalCheckbox.checked = allLayersVisible; plumbingCheckbox.checked = allLayersVisible; hvacCheckbox.checked = allLayersVisible; updateLayerVisibility(); }); // Floor selector floorOptions.forEach(option => { option.addEventListener('click', function() { floorOptions.forEach(o => o.classList.remove('active')); this.classList.add('active'); currentFloor = this.getAttribute('data-floor'); currentFloorEl.textContent = currentFloor; // Animate floor change floorPlan.style.opacity = 0; setTimeout(() => { // Here you would change the floor data // For demo we'll just show a transition floorPlan.style.opacity = 1; }, 300); }); }); // Annotations display function showAnnotations() { const annotations = document.querySelectorAll('.annotation'); annotations.forEach((annotation, index) => { setTimeout(() => { annotation.classList.add('visible'); }, 500 + (index * 150)); }); } // Hotspot tooltips hotspots.forEach(hotspot => { hotspot.addEventListener('mouseenter', function(e) { const tooltipText = this.getAttribute('data-tooltip'); tooltip.textContent = tooltipText; tooltip.style.left = `${e.pageX - floorPlanContainer.getBoundingClientRect().left}px`; tooltip.style.top = `${e.pageY