Creating visually appealing backdrops can significantly enhance the user experience of any application. In this article, we will explore 10 stunning backdrop examples that can elevate your design projects.
From minimalist designs to intricate patterns, these examples showcase the versatility and creativity that backdrops can bring to your UI. Let's dive in and get inspired.
CODE1
Here's the code:
CODETEXT1
CODE2
Here's the code:
CODETEXT2
CODE3
Here's the code:
CODETEXT3
CODE4
Here's the code:
CODETEXT4
CODE5
Here's the code:
CODETEXT5
Subframe's drag-and-drop interface and intuitive, responsive canvas make it easy for designers and developers to create pixel-perfect UI every time. Loved by professionals across the industry, Subframe ensures your backdrops are both stunning and functional.
Start for free and elevate your design projects 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 transform your design process? With Subframe, you can create pixel-perfect UIs, including stunning backdrops, in minutes. Experience unparalleled efficiency and creativity.
Don't wait—start for free and begin designing immediately. Elevate your projects with Subframe today!
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>FinSecure Banking App</title> <style> :root { --primary: #1a2c42; --secondary: #395980; --accent: #4f8ec9; --light: #e8f0f9; --text: #2c3e50; --success: #2ecc71; --error: #e74c3c; --neutral: #f7f9fc; --shadow: rgba(9, 30, 66, 0.15); --shadow-strong: rgba(9, 30, 66, 0.25); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; } body { background-color: var(--light); color: var(--text); height: 100vh; display: flex; justify-content: center; align-items: center; overflow: hidden; } .app-container { width: 100%; max-width: 700px; height: 700px; background-color: white; border-radius: 16px; box-shadow: 0 12px 24px var(--shadow); overflow: hidden; position: relative; } .app-header { padding: 20px; background: linear-gradient(135deg, var(--primary), var(--secondary)); color: white; display: flex; justify-content: space-between; align-items: center; } .logo { font-weight: 600; font-size: 1.3rem; letter-spacing: -0.5px; display: flex; align-items: center; } .logo-icon { margin-right: 8px; background: white; color: var(--primary); width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 15px; } .user-profile { display: flex; align-items: center; font-size: 0.9rem; } .user-avatar { width: 32px; height: 32px; border-radius: 50%; margin-left: 10px; background: var(--light); display: flex; align-items: center; justify-content: center; color: var(--primary); font-weight: 600; } .app-content { padding: 20px; height: calc(100% - 76px); overflow-y: auto; } .balance-section { background: linear-gradient(to right, var(--primary), var(--secondary)); color: white; padding: 24px; border-radius: 12px; margin-bottom: 24px; position: relative; overflow: hidden; } .balance-title { font-size: 0.85rem; font-weight: 500; opacity: 0.9; margin-bottom: 4px; } .balance-amount { font-size: 2.2rem; font-weight: 600; margin-bottom: 5px; letter-spacing: -0.5px; } .balance-change { font-size: 0.85rem; display: flex; align-items: center; opacity: 0.9; } .balance-change i { margin-right: 4px; } .balance-pattern { position: absolute; right: 0; top: 0; height: 100%; width: 40%; opacity: 0.1; background-image: radial-gradient(circle at 50% 50%, white 1px, transparent 1px); background-size: 12px 12px; } .section-title { font-size: 1.1rem; font-weight: 600; margin-bottom: 16px; color: var(--primary); } .transaction-list { margin-bottom: 30px; } .transaction-item { display: flex; align-items: center; padding: 14px 0; border-bottom: 1px solid rgba(0, 0, 0, 0.06); transition: transform 0.2s ease; cursor: pointer; } .transaction-item:hover { transform: translateX(4px); } .transaction-icon { width: 40px; height: 40px; border-radius: 10px; background-color: var(--light); display: flex; align-items: center; justify-content: center; margin-right: 14px; color: var(--primary); flex-shrink: 0; } .transaction-details { flex-grow: 1; } .transaction-title { font-weight: 500; margin-bottom: 3px; } .transaction-date { font-size: 0.8rem; color: #7c8a97; } .transaction-amount { font-weight: 600; } .amount-negative { color: var(--error); } .amount-positive { color: var(--success); } .quick-actions { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-top: 30px; } .action-button { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 16px 10px; background-color: var(--neutral); border-radius: 12px; transition: all 0.3s ease; cursor: pointer; border: none; color: var(--text); } .action-button:hover { background-color: var(--light); transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.05); } .action-icon { width: 34px; height: 34px; border-radius: 50%; background-color: white; display: flex; align-items: center; justify-content: center; margin-bottom: 8px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); color: var(--primary); } .action-title { font-size: 0.75rem; font-weight: 500; } .modal-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.3); display: flex; align-items: center; justify-content: center; opacity: 0; visibility: hidden; transition: all 0.3s ease; } .modal-overlay.active { opacity: 1; visibility: visible; } .modal-content { width: 90%; max-width: 360px; background-color: white; border-radius: 16px; transform: translateY(20px) scale(0.95); transition: all 0.4s cubic-bezier(0.165, 0.84, 0.44, 1); padding: 24px; box-shadow: 0 15px 30px var(--shadow-strong); opacity: 0; } .modal-overlay.active .modal-content { transform: translateY(0) scale(1); opacity: 1; } .modal-header { margin-bottom: 20px; text-align: center; } .modal-title { font-size: 1.3rem; font-weight: 600; color: var(--primary); margin-bottom: 5px; } .modal-subtitle { font-size: 0.9rem; color: #7c8a97; } .input-group { margin-bottom: 18px; } .input-label { display: block; font-size: 0.85rem; margin-bottom: 6px; font-weight: 500; color: var(--text); } .form-input { width: 100%; padding: 12px 16px; border: 1px solid rgba(0, 0, 0, 0.1); border-radius: 8px; font-size: 0.95rem; transition: all 0.2s ease; background-color: var(--neutral); } .form-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(79, 142, 201, 0.1); } .amount-input-wrapper { position: relative; } .amount-input-wrapper::before { content: '$'; position: absolute; left: 16px; top: 50%; transform: translateY(-50%); color: var(--text); font-weight: 500; } .amount-input { padding-left: 28px; } .transfer-button { width: 100%; padding: 14px; background: linear-gradient(135deg, var(--primary), var(--secondary)); color: white; border: none; border-radius: 8px; font-weight: 600; font-size: 1rem; cursor: pointer; transition: all 0.3s ease; display: flex; justify-content: center; align-items: center; margin-top: 6px; } .transfer-button:hover { box-shadow: 0 4px 12px rgba(26, 44, 66, 0.3); transform: translateY(-2px); } .cancel-button { background: none; border: none; color: #7c8a97; font-size: 0.95rem; margin-top: 12px; cursor: pointer; transition: color 0.2s ease; padding: 8px; width: 100%; } .cancel-button:hover { color: var(--primary); } .success-animation { width: 70px; height: 70px; margin: 0 auto 20px; border-radius: 50%; background-color: var(--success); display: flex; align-items: center; justify-content: center; color: white; font-size: 2rem; transform: scale(0); } .success-modal .success-animation { animation: scaleIn 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards; } .backdrop-blur-active { backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); background-color: rgba(255, 255, 255, 0.1); transition: backdrop-filter 0.4s ease, background-color 0.4s ease; } .button-loading { position: relative; color: transparent; } .button-loading::after { content: ""; position: absolute; width: 20px; height: 20px; border: 2px solid rgba(255, 255, 255, 0.3); border-radius: 50%; border-top-color: white; animation: spin 0.8s linear infinite; } @keyframes scaleIn { 0% { transform: scale(0); } 70% { transform: scale(1.1); } 100% { transform: scale(1); } } @keyframes spin { to { transform: rotate(360deg); } } .success-details { text-align: center; margin-bottom: 20px; } .success-amount { font-size: 2rem; font-weight: 600; color: var(--primary); margin-bottom: 5px; } .success-recipient { color: #7c8a97; font-size: 0.95rem; } .success-reference { font-size: 0.85rem; color: #7c8a97; background-color: var(--neutral); border-radius: 4px; padding: 3px 8px; display: inline-block; margin-top: 5px; } /* Responsive adjustments */ @media (max-width: 480px) { .quick-actions { grid-template-columns: repeat(2, 1fr); } .balance-amount { font-size: 1.8rem; } .modal-content { width: 95%; } } </style> </head> <body> <div class="app-container"> <header class="app-header"> <div class="logo"> <div class="logo-icon">FS</div> FinSecure </div> <div class="user-profile"> <span>Alex Morgan</span> <div class="user-avatar">AM</div> </div> </header> <div class="app-content"> <div class="balance-section"> <div class="balance-title">Available Balance</div> <div class="balance-amount">$24,562.84</div> <div class="balance-change"> <i>↑</i> +$1,240.55 this month </div> <div class="balance-pattern"></div> </div> <div class="section-title">Recent Transactions</div> <div class="transaction-list"> <div class="transaction-item"> <div class="transaction-icon"> <i>↑</i> </div> <div class="transaction-details"> <div class="transaction-title">Salary Deposit</div> <div class="transaction-date">Aug 2 • TechCorp Inc</div> </div> <div class="transaction-amount amount-positive">+$5,240.00</div> </div> <div class="transaction-item"> <div class="transaction-icon"> <i>↓</i> </div> <div class="transaction-details"> <div class="transaction-title">Home Mortgage</div> <div class="transaction-date">Aug 1 • First City Bank</div> </div> <div class="transaction-amount amount-negative">-$1,850.50</div> </div> <div class="transaction-item"> <div class="transaction-icon"> <i>↓</i> </div> <div class="transaction-details"> <div class="transaction-title">Grocery Shopping</div> <div class="transaction-date">Jul 28 • Whole Foods</div> </div> <div class="transaction-amount amount-negative">-$147.32</div> </div> <div class="transaction-item"> <div class="transaction-icon"> <i>↓</i> </div> <div class="transaction-details"> <div class="transaction-title">Streaming Service</div> <div class="transaction-date">Jul 26 • NetFlix</div> </div> <div class="transaction-amount amount-negative">-$14.99</div> </div> </div> <div class="section-title">Quick Actions</div> <div class="quick-actions"> <button class="action-button" id="transferBtn"> <div class="action-icon">↗</div> <div class="action-title">Transfer</div> </button> <button class="action-button"> <div class="action-icon">↘</div> <div class="action-title">Request</div> </button> <button class="action-button"> <div class="action-icon">☰</div> <div class="action-title">Bills</div> </button> <button class="action-button"> <div class="action-icon">⋮</div> <div class="action-title">More</div> </button> </div> </div> </div> <div class="modal-overlay" id="transferModal"> <div class="modal-content"> <div class="modal-header"> <div class="modal-title">Transfer Money</div> <div class="modal-subtitle">Send funds to another account</div> </div> <form id="transferForm"> <div class="input-group"> <label class="input-label" for="recipient">Recipient</label> <input type="text" id="recipient" class="form-input" placeholder="Enter name or account number"> </div> <div class="input-group"> <label class="input-label" for="amount">Amount</label> <div class="amount-input-wrapper"> <input type="text" id="amount" class="form-input amount-input" placeholder="0.00"> </div> </div> <div class="input-group"> <label class="input-label" for="note">Note (optional)</label> <input type="text" id="note" class="form-input" placeholder="What's this for?"> </div> <button type="submit" class="transfer-button" id="submitTransfer">Send Transfer</button> <button type="button" class="cancel-button" id="cancelTransfer">Cancel</button> </form> </div> </div> <div class="modal-overlay" id="successModal"> <div class="modal-content success-modal"> <div class="success-animation">✓</div> <div class="success-details"> <div class="success-amount">$250.00</div> <div class="success-recipient">To: Sarah Johnson</div> <div class="success-reference">Ref: TRX-8571294</div> </div> <div class="modal-header"> <div class="modal-title">Transfer Successful</div> <div class="modal-subtitle">Your money is on its way</div> </div> <button type="button" class="transfer-button" id="doneBtn">Done</button> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const transferBtn = document.getElementById('transferBtn'); const transferModal = document.getElementById('transferModal'); const successModal = document.getElementById('successModal'); const cancelTransfer = document.getElementById('cancelTransfer'); const transferForm = document.getElementById('transferForm'); const submitTransfer = document.getElementById('submitTransfer'); const doneBtn = document.getElementById('doneBtn'); // Format amount input with commas const amountInput = document.getElementById('amount'); amountInput.addEventListener('input', function(e) { // Remove non-digits and format let value = e.target.value.replace(/[^0-9.]/g, ''); // Split decimal part const parts = value.split('.'); // Format integer part with commas if (parts[0]) { parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); } // Reconstruct with at most 2 decimal places if (parts.length > 1) { parts[1] = parts[1].slice(0, 2); e.target.value = parts.join('.'); } else { e.target.value = parts[0]; } }); function openModal(modal) { modal.classList.add('active'); modal.classList.add('backdrop-blur-active'); } function closeModal(modal) { modal.classList.remove('active'); setTimeout(() => { modal.classList.remove('backdrop-blur-active'); }, 300); } transferBtn.addEventListener('click', function() { openModal(transferModal); }); cancelTransfer.addEventListener('click', function() { closeModal(transferModal); }); transferForm.addEventListener('submit', function(e) { e.preventDefault(); // Show loading submitTransfer.classList.add('button-loading'); // Simulate API call setTimeout(() => { closeModal(transferModal); // Reset form transferForm.reset(); submitTransfer.classList.remove('button-loading'); // Show success after a short delay setTimeout(() => { openModal(successModal); }, 300); }, 1500); }); doneBtn.addEventListener('click', function() { closeModal(successModal); }); // Close modal when clicking outside window.addEventListener('click', function(e) { if (e.target === transferModal) { closeModal(transferModal); } if (e.target === successModal) { closeModal(successModal); } }); // Add hover effects to transaction items const transactionItems = document.querySelectorAll('.transaction-item'); transactionItems.forEach(item => { item.addEventListener('mouseenter', function() { this.style.backgroundColor = 'rgba(232, 240, 249, 0.5)'; }); item.addEventListener('mouseleave', function() { this.style.backgroundColor = 'transparent'; }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Lumina Stream Player</title> <style> :root { --primary: #ff2a6d; --secondary: #05d9e8; --tertiary: #d1f7ff; --dark: #01012b; --darker: #000116; --font-main: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: var(--font-main); background-color: var(--darker); color: white; height: 100vh; display: flex; align-items: center; justify-content: center; overflow: hidden; } .player-container { width: 100%; max-width: 400px; height: 650px; display: flex; flex-direction: column; position: relative; border-radius: 20px; overflow: hidden; box-shadow: 0 20px 40px rgba(0, 0, 0, 0.6); background: var(--dark); } .now-playing { padding: 20px; display: flex; align-items: center; justify-content: space-between; position: relative; z-index: 2; background: rgba(1, 1, 43, 0.6); backdrop-filter: blur(6px); } .now-playing h3 { font-size: 16px; font-weight: 600; color: var(--tertiary); letter-spacing: 1px; } .options-btn { background: none; border: none; color: white; cursor: pointer; transition: transform 0.3s ease; } .options-btn:hover { transform: rotate(90deg); } .album-art-container { position: relative; flex: 1; overflow: hidden; } .album-art { width: 100%; height: 100%; object-fit: cover; transition: transform 0.5s cubic-bezier(0.215, 0.610, 0.355, 1); } .controls-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(1, 1, 43, 0.3); backdrop-filter: blur(0px); display: flex; flex-direction: column; justify-content: flex-end; padding: 30px; transition: all 0.4s cubic-bezier(0.215, 0.610, 0.355, 1); opacity: 0; } .album-art-container:hover .controls-overlay { backdrop-filter: blur(20px); opacity: 1; } .album-art-container:hover .album-art { transform: scale(1.05); } .track-info { margin-bottom: 30px; transform: translateY(20px); opacity: 0; transition: all 0.4s cubic-bezier(0.215, 0.610, 0.355, 1); transition-delay: 0.1s; } .album-art-container:hover .track-info { transform: translateY(0); opacity: 1; } .track-title { font-size: 28px; font-weight: 700; margin-bottom: 5px; color: white; text-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); } .artist { font-size: 16px; color: var(--tertiary); font-weight: 500; text-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); } .progress-container { width: 100%; margin-bottom: 20px; transform: translateY(20px); opacity: 0; transition: all 0.4s cubic-bezier(0.215, 0.610, 0.355, 1); transition-delay: 0.2s; } .album-art-container:hover .progress-container { transform: translateY(0); opacity: 1; } .progress-bar { width: 100%; height: 4px; background: rgba(255, 255, 255, 0.2); border-radius: 2px; position: relative; cursor: pointer; overflow: hidden; } .progress { position: absolute; height: 100%; width: 35%; background: linear-gradient(90deg, var(--primary), var(--secondary)); border-radius: 2px; transition: width 0.1s ease; } .progress::after { content: ''; position: absolute; right: 0; top: 50%; transform: translateY(-50%); width: 10px; height: 10px; background: white; border-radius: 50%; box-shadow: 0 0 10px rgba(255, 42, 109, 0.8); } .time-info { display: flex; justify-content: space-between; margin-top: 8px; font-size: 12px; color: rgba(255, 255, 255, 0.7); } .control-buttons { display: flex; align-items: center; justify-content: space-between; transform: translateY(20px); opacity: 0; transition: all 0.4s cubic-bezier(0.215, 0.610, 0.355, 1); transition-delay: 0.3s; } .album-art-container:hover .control-buttons { transform: translateY(0); opacity: 1; } .btn { background: none; border: none; color: white; cursor: pointer; transition: all 0.3s ease; display: flex; align-items: center; justify-content: center; } .btn:hover { transform: translateY(-3px); text-shadow: 0 0 10px var(--primary); } .btn.play-pause { width: 60px; height: 60px; background: linear-gradient(135deg, var(--primary), var(--secondary)); border-radius: 50%; box-shadow: 0 0 20px rgba(255, 42, 109, 0.4); } .btn.play-pause:hover { box-shadow: 0 0 30px rgba(255, 42, 109, 0.6); transform: translateY(-3px) scale(1.05); } .btn.play-pause i { font-size: 24px; } .btn i { font-size: 20px; } .playlist { background: var(--dark); padding: 20px; border-top: 1px solid rgba(255, 255, 255, 0.1); } .playlist-title { font-size: 14px; font-weight: 600; color: var(--tertiary); margin-bottom: 15px; display: flex; align-items: center; justify-content: space-between; } .view-all { font-size: 12px; color: var(--secondary); cursor: pointer; transition: color 0.3s ease; } .view-all:hover { color: var(--primary); } .playlist-songs { display: flex; gap: 12px; overflow-x: auto; padding-bottom: 10px; scroll-behavior: smooth; scrollbar-width: none; } .playlist-songs::-webkit-scrollbar { display: none; } .playlist-song { min-width: 60px; width: 60px; text-align: center; cursor: pointer; transition: transform 0.3s ease; } .playlist-song:hover { transform: translateY(-5px); } .playlist-song img { width: 60px; height: 60px; border-radius: 6px; object-fit: cover; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3); transition: all 0.3s ease; } .playlist-song:hover img { box-shadow: 0 8px 20px rgba(255, 42, 109, 0.3); } .playlist-song p { font-size: 10px; margin-top: 6px; color: rgba(255, 255, 255, 0.7); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 60px; } .active-song img { border: 2px solid var(--primary); box-shadow: 0 0 15px rgba(255, 42, 109, 0.5); } .equalizer { display: none; height: 15px; width: 20px; margin: 0 auto; position: relative; margin-top: -25px; } .active-song .equalizer { display: flex; } .bar { background: var(--primary); bottom: 0; height: 3px; width: 3px; margin: 0 1px; border-radius: 5px; animation: sound 0ms -800ms linear infinite alternate; } @keyframes sound { 0% { height: 3px; } 100% { height: 15px; } } .bar:nth-child(1) { animation-duration: 474ms; } .bar:nth-child(2) { animation-duration: 433ms; } .bar:nth-child(3) { animation-duration: 407ms; } .bar:nth-child(4) { animation-duration: 458ms; } .glow-effect { position: absolute; width: 100%; height: 100%; background: radial-gradient(circle at 50% 50%, rgba(255, 42, 109, 0.2) 0%, transparent 70%); mix-blend-mode: overlay; pointer-events: none; opacity: 0; transition: opacity 0.5s ease; } .album-art-container:hover .glow-effect { opacity: 1; } .volume-container { position: absolute; top: 20px; right: 20px; display: flex; align-items: center; gap: 8px; background: rgba(1, 1, 43, 0.7); backdrop-filter: blur(10px); padding: 8px 12px; border-radius: 20px; opacity: 0; transform: translateY(-10px); transition: all 0.3s ease; z-index: 10; } .album-art-container:hover .volume-container { opacity: 1; transform: translateY(0); } .volume-slider { width: 80px; height: 4px; -webkit-appearance: none; background: rgba(255, 255, 255, 0.2); outline: none; border-radius: 2px; transition: all 0.3s ease; } .volume-slider::-webkit-slider-thumb { -webkit-appearance: none; width: 8px; height: 8px; background: white; border-radius: 50%; cursor: pointer; transition: all 0.3s ease; } .volume-slider:hover::-webkit-slider-thumb { width: 10px; height: 10px; box-shadow: 0 0 8px var(--primary); } .volume-icon { color: white; font-size: 14px; } /* Responsive Adjustments */ @media (max-width: 400px) { .player-container { height: 600px; border-radius: 15px; } .track-title { font-size: 24px; } .artist { font-size: 14px; } .btn.play-pause { width: 50px; height: 50px; } } /* Pulse Animation for Play Button */ @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(255, 42, 109, 0.7); } 70% { box-shadow: 0 0 0 10px rgba(255, 42, 109, 0); } 100% { box-shadow: 0 0 0 0 rgba(255, 42, 109, 0); } } .btn.play-pause { animation: pulse 2s infinite; } </style> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css"> </head> <body> <div class="player-container"> <div class="now-playing"> <h3>NOW PLAYING</h3> <button class="options-btn"> <i class="fas fa-ellipsis-v"></i> </button> </div> <div class="album-art-container"> <img src="https://images.unsplash.com/photo-1614613535308-eb5fbd3d2c17?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80" alt="Album Art" class="album-art"> <div class="controls-overlay"> <div class="volume-container"> <i class="fas fa-volume-up volume-icon"></i> <input type="range" min="0" max="100" value="80" class="volume-slider"> </div> <div class="track-info"> <h2 class="track-title">Midnight Echoes</h2> <p class="artist">The Neon Collective</p> </div> <div class="progress-container"> <div class="progress-bar"> <div class="progress"></div> </div> <div class="time-info"> <span>1:47</span> <span>4:32</span> </div> </div> <div class="control-buttons"> <button class="btn"> <i class="fas fa-backward"></i> </button> <button class="btn"> <i class="fas fa-step-backward"></i> </button> <button class="btn play-pause"> <i class="fas fa-pause"></i> </button> <button class="btn"> <i class="fas fa-step-forward"></i> </button> <button class="btn"> <i class="fas fa-random"></i> </button> </div> </div> <div class="glow-effect"></div> </div> <div class="playlist"> <div class="playlist-title"> <span>UP NEXT</span> <span class="view-all">View All</span> </div> <div class="playlist-songs"> <div class="playlist-song active-song"> <img src="https://images.unsplash.com/photo-1614613535308-eb5fbd3d2c17?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80" alt="Song"> <div class="equalizer"> <span class="bar"></span> <span class="bar"></span> <span class="bar"></span> <span class="bar"></span> </div> <p>Midnight Echoes</p> </div> <div class="playlist-song"> <img src="https://images.unsplash.com/photo-1594623930572-300a3011d9ae?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80" alt="Song"> <p>Digital Dreams</p> </div> <div class="playlist-song"> <img src="https://images.unsplash.com/photo-1508700115892-45ecd05ae2ad?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1469&q=80" alt="Song"> <p>Synthwave Love</p> </div> <div class="playlist-song"> <img src="https://images.unsplash.com/photo-1631488077842-41507eb173d3?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1074&q=80" alt="Song"> <p>Urban Pulse</p> </div> <div class="playlist-song"> <img src="https://images.unsplash.com/photo-1557672172-298e090bd0f1?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=687&q=80" alt="Song"> <p>Electric Dreams</p> </div> <div class="playlist-song"> <img src="https://images.unsplash.com/photo-1530026405186-ed1f139313f8?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=687&q=80" alt="Song"> <p>Neon Nights</p> </div> </div> </div> </div> <script> // Progress bar interaction const progressBar = document.querySelector('.progress-bar'); const progress = document.querySelector('.progress'); progressBar.addEventListener('click', (e) => { const width = progressBar.clientWidth; const clickX = e.offsetX; const percentage = (clickX / width) * 100; progress.style.width = `${percentage}%`; // Update time display based on percentage updateTimeDisplay(percentage); }); function updateTimeDisplay(percentage) { // Total time in seconds (4:32 = 272 seconds) const totalSeconds = 272; const currentSeconds = Math.floor((percentage / 100) * totalSeconds); const minutes = Math.floor(currentSeconds / 60); const seconds = currentSeconds % 60; const timeDisplay = document.querySelector('.time-info span:first-child'); timeDisplay.textContent = `${minutes}:${seconds < 10 ? '0' + seconds : seconds}`; } // Play/Pause button toggle const playPauseBtn = document.querySelector('.btn.play-pause'); const playPauseIcon = playPauseBtn.querySelector('i'); let isPlaying = true; playPauseBtn.addEventListener('click', () => { isPlaying = !isPlaying; if (isPlaying) { playPauseIcon.classList.remove('fa-play'); playPauseIcon.classList.add('fa-pause'); document.querySelector('.equalizer').style.display = 'flex'; } else { playPauseIcon.classList.remove('fa-pause'); playPauseIcon.classList.add('fa-play'); document.querySelector('.equalizer').style.display = 'none'; } }); // Playlist song selection const playlistSongs = document.querySelectorAll('.playlist-song'); playlistSongs.forEach(song => { song.addEventListener('click', () => { // Remove active class from all songs playlistSongs.forEach(s => s.classList.remove('active-song')); // Add active class to clicked song song.classList.add('active-song'); // Update main player with the selected song info const songImg = song.querySelector('img').src; const songTitle = song.querySelector('p').textContent; document.querySelector('.album-art').src = songImg; document.querySelector('.track-title').textContent = songTitle; // Reset progress and make sure playing state is active progress.style.width = '0%'; updateTimeDisplay(0); if (!isPlaying) { isPlaying = true; playPauseIcon.classList.remove('fa-play'); playPauseIcon.classList.add('fa-pause'); } // Create a new equalizer for the active song const allEqualizers = document.querySelectorAll('.equalizer'); allEqualizers.forEach(eq => eq.remove()); const newEqualizer = document.createElement('div'); newEqualizer.className = 'equalizer'; for (let i = 0; i < 4; i++) { const bar = document.createElement('span'); bar.className = 'bar'; newEqualizer.appendChild(bar); } song.appendChild(newEqualizer); }); }); // Volume slider const volumeSlider = document.querySelector('.volume-slider'); const volumeIcon = document.querySelector('.volume-icon'); volumeSlider.addEventListener('input', () => { const volume = volumeSlider.value; // Update volume icon based on level if (volume == 0) { volumeIcon.className = 'fas fa-volume-mute volume-icon'; } else if (volume < 50) { volumeIcon.className = 'fas fa-volume-down volume-icon'; } else { volumeIcon.className = 'fas fa-volume-up volume-icon'; } }); // Mouse position effect on glow const albumContainer = document.querySelector('.album-art-container'); const glowEffect = document.querySelector('.glow-effect'); albumContainer.addEventListener('mousemove', (e) => { const rect = albumContainer.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; const centerX = rect.width / 2; const centerY = rect.height / 2; // Calculate distance from center (0-1) const distX = (x - centerX) / centerX; const distY = (y - centerY) / centerY; // Update glow position glowEffect.style.background = `radial-gradient(circle at ${x}px ${y}px, rgba(255, 42, 109, 0.3) 0%, transparent 70%)`; }); // Simulate progress over time when playing let progressInterval; function startProgress() { let currentWidth = parseFloat(progress.style.width) || 0; progressInterval = setInterval(() => { if (isPlaying) { currentWidth += 0.1; if (currentWidth >= 100) { currentWidth = 0; // Auto-play next song const activeSong = document.querySelector('.active-song'); const nextSong = activeSong.nextElementSibling || document.querySelector('.playlist-song'); if (nextSong) nextSong.click(); } progress.style.width = `${currentWidth}%`; updateTimeDisplay(currentWidth); } }, 100); } startProgress(); // Initialize bars with random heights for equalizer document.querySelectorAll('.bar').forEach((bar, index) => { bar.style.animationDelay = `${index * 200}ms`; }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Data Dashboard Sidebar</title> <style> :root { --primary-color: #2c3e50; --accent-color: #3498db; --accent-light: #5dade2; --text-color: #ecf0f1; --light-text: #bdc3c7; --bg-color: #1a1f25; --sidebar-width: 280px; --sidebar-collapsed-width: 80px; --animation-time: 0.3s; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: var(--bg-color); color: var(--text-color); overflow-x: hidden; height: 100vh; width: 100%; display: flex; position: relative; } .dashboard { display: flex; width: 100%; height: 100%; position: relative; } .sidebar { width: var(--sidebar-width); height: 100%; background-color: rgba(25, 34, 49, 0.5); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); box-shadow: 0 0 20px rgba(0, 0, 0, 0.2); transition: all var(--animation-time) ease-in-out; position: absolute; top: 0; left: 0; z-index: 100; overflow-y: auto; transform: translateX(0); } .sidebar.collapsed { width: var(--sidebar-collapsed-width); } .sidebar-header { display: flex; align-items: center; justify-content: space-between; padding: 1.5rem 1.2rem; border-bottom: 1px solid rgba(255, 255, 255, 0.05); } .logo { display: flex; align-items: center; gap: 0.8rem; opacity: 1; transition: opacity var(--animation-time) ease; } .logo-icon { color: var(--accent-color); font-size: 1.5rem; display: flex; align-items: center; justify-content: center; width: 2.5rem; height: 2.5rem; background: rgba(52, 152, 219, 0.1); border-radius: 10px; } .logo-text { font-weight: 600; font-size: 1.2rem; white-space: nowrap; transition: opacity var(--animation-time) ease; } .collapsed .logo-text { opacity: 0; visibility: hidden; width: 0; } .toggle-btn { background: none; border: none; cursor: pointer; color: var(--light-text); font-size: 1.2rem; width: 2rem; height: 2rem; display: flex; align-items: center; justify-content: center; border-radius: 50%; transition: background 0.2s, color 0.2s; } .toggle-btn:hover { background: rgba(255, 255, 255, 0.05); color: var(--text-color); } .avatar { width: 2.5rem; height: 2.5rem; border-radius: 50%; object-fit: cover; border: 2px solid var(--accent-color); } .sidebar-user { padding: 1rem 1.2rem; display: flex; align-items: center; gap: 0.8rem; position: relative; cursor: pointer; border-bottom: 1px solid rgba(255, 255, 255, 0.05); } .user-info { flex: 1; transition: opacity var(--animation-time) ease, width var(--animation-time) ease; white-space: nowrap; } .collapsed .user-info { opacity: 0; visibility: hidden; width: 0; } .user-name { font-size: 0.9rem; font-weight: 500; margin-bottom: 0.2rem; } .user-role { font-size: 0.75rem; color: var(--light-text); } .user-status { width: 10px; height: 10px; background-color: #2ecc71; border-radius: 50%; position: absolute; bottom: 1rem; left: 3.1rem; border: 1.5px solid var(--bg-color); } .nav-list { list-style: none; padding: 1rem 0; } .nav-item { position: relative; } .nav-link { display: flex; align-items: center; padding: 0.9rem 1.2rem; color: var(--light-text); text-decoration: none; transition: all 0.2s ease; position: relative; gap: 0.8rem; } .nav-link:hover, .nav-link.active { color: var(--text-color); background: rgba(52, 152, 219, 0.08); } .nav-link.active::before { content: ''; position: absolute; left: 0; top: 0; height: 100%; width: 4px; background-color: var(--accent-color); } .nav-icon { font-size: 1.2rem; min-width: 1.5rem; display: flex; align-items: center; justify-content: center; } .nav-text { flex: 1; transition: opacity var(--animation-time) ease; white-space: nowrap; } .collapsed .nav-text { opacity: 0; visibility: hidden; width: 0; } .badge { background-color: var(--accent-color); color: white; padding: 0.1rem 0.5rem; border-radius: 10px; font-size: 0.7rem; transition: opacity var(--animation-time) ease; } .collapsed .badge { opacity: 0; visibility: hidden; width: 0; } .nav-section-title { padding: 1.2rem 1.2rem 0.5rem; color: var(--light-text); font-size: 0.75rem; font-weight: 500; text-transform: uppercase; letter-spacing: 1px; transition: opacity var(--animation-time) ease; } .collapsed .nav-section-title { opacity: 0; visibility: hidden; height: 0.5rem; padding: 0; } .main-content { flex: 1; margin-left: var(--sidebar-width); padding: 1.5rem; transition: margin-left var(--animation-time) ease; position: relative; overflow-y: auto; } .main-content.expanded { margin-left: var(--sidebar-collapsed-width); } .data-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1.5rem; margin-bottom: 1.5rem; } .data-card { background: rgba(44, 62, 80, 0.4); border-radius: 12px; padding: 1.5rem; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); height: 200px; position: relative; overflow: hidden; transition: transform 0.3s ease, box-shadow 0.3s ease; } .data-card:hover { transform: translateY(-5px); box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15); } .card-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 1rem; } .card-title { font-size: 1rem; font-weight: 500; margin-bottom: 0.25rem; color: var(--light-text); } .card-value { font-size: 1.8rem; font-weight: 600; margin-bottom: 0.5rem; } .card-change { font-size: 0.85rem; } .positive { color: #2ecc71; } .negative { color: #e74c3c; } .sparkline { height: 60px; width: 100%; position: absolute; bottom: 0; left: 0; } .large-chart { background: rgba(44, 62, 80, 0.4); border-radius: 12px; padding: 1.5rem; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); height: 350px; display: flex; flex-direction: column; } .chart-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem; } .chart-tabs { display: flex; gap: 1rem; } .chart-tab { background: none; border: none; color: var(--light-text); cursor: pointer; padding: 0.5rem 0; font-size: 0.9rem; position: relative; transition: color 0.2s; } .chart-tab:hover { color: var(--text-color); } .chart-tab.active { color: var(--accent-color); } .chart-tab.active::after { content: ''; position: absolute; bottom: 0; left: 0; width: 100%; height: 2px; background-color: var(--accent-color); } .chart-container { flex: 1; position: relative; } .tooltip { position: absolute; display: none; background-color: rgba(25, 34, 49, 0.9); backdrop-filter: blur(5px); -webkit-backdrop-filter: blur(5px); color: var(--text-color); padding: 0.75rem; border-radius: 6px; font-size: 0.85rem; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); z-index: 10; pointer-events: none; transition: opacity 0.2s; width: auto; max-width: 200px; } .tooltip-title { font-weight: 500; margin-bottom: 0.3rem; } .tooltip-value { color: var(--accent-color); font-weight: 600; } .chart-legend { display: flex; gap: 1rem; margin-top: 0.5rem; } .legend-item { display: flex; align-items: center; gap: 0.5rem; font-size: 0.8rem; color: var(--light-text); } .legend-color { width: 10px; height: 10px; border-radius: 50%; } /* Responsive adjustments */ @media (max-width: 1200px) { .data-grid { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); } } @media (max-width: 700px) { .sidebar { transform: translateX(-100%); } .sidebar.open { transform: translateX(0); } .main-content { margin-left: 0; } .main-content.expanded { margin-left: 0; } .mobile-menu-btn { display: block; position: fixed; top: 1rem; left: 1rem; z-index: 200; background: var(--primary-color); border: none; color: var(--text-color); width: 40px; height: 40px; border-radius: 8px; display: flex; align-items: center; justify-content: center; cursor: pointer; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); } } /* Custom scrollbar */ ::-webkit-scrollbar { width: 6px; height: 6px; } ::-webkit-scrollbar-track { background: rgba(255, 255, 255, 0.05); } ::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.1); border-radius: 3px; } ::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.2); } /* Animations */ @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .data-card { animation: fadeIn 0.5s ease forwards; } .data-card:nth-child(1) { animation-delay: 0.1s; } .data-card:nth-child(2) { animation-delay: 0.2s; } .data-card:nth-child(3) { animation-delay: 0.3s; } .data-card:nth-child(4) { animation-delay: 0.4s; } .notification-dot { position: absolute; top: 10px; right: 18px; width: 8px; height: 8px; background-color: #e74c3c; border-radius: 50%; animation: pulse 2s infinite; } </style> </head> <body> <div class="dashboard"> <button class="mobile-menu-btn" id="mobile-menu"> <i class="fas fa-bars"></i> </button> <div class="sidebar" id="sidebar"> <div class="sidebar-header"> <div class="logo"> <div class="logo-icon"> <i class="fas fa-chart-network"></i> </div> <span class="logo-text">DataVision</span> </div> <button class="toggle-btn" id="toggle-sidebar"> <i class="fas fa-chevron-left"></i> </button> </div> <div class="sidebar-user"> <img src="https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-1.2.1&auto=format&fit=crop&w=128&q=80" alt="User avatar" class="avatar"> <div class="user-info"> <div class="user-name">Sarah Chen</div> <div class="user-role">Data Analyst</div> </div> <div class="user-status"></div> </div> <div class="nav-section-title">Main</div> <ul class="nav-list"> <li class="nav-item"> <a href="#" class="nav-link active"> <span class="nav-icon"><i class="fas fa-home"></i></span> <span class="nav-text">Dashboard</span> </a> </li> <li class="nav-item"> <a href="#" class="nav-link"> <span class="nav-icon"><i class="fas fa-chart-bar"></i></span> <span class="nav-text">Analytics</span> <span class="badge">New</span> </a> </li> <li class="nav-item"> <a href="#" class="nav-link"> <span class="nav-icon"><i class="fas fa-table"></i></span> <span class="nav-text">Reports</span> </a> </li> </ul> <div class="nav-section-title">Insights</div> <ul class="nav-list"> <li class="nav-item"> <a href="#" class="nav-link"> <span class="nav-icon"><i class="fas fa-dollar-sign"></i></span> <span class="nav-text">Revenue</span> </a> </li> <li class="nav-item"> <a href="#" class="nav-link"> <span class="nav-icon"><i class="fas fa-users"></i></span> <span class="nav-text">Customers</span> </a> </li> <li class="nav-item"> <a href="#" class="nav-link"> <span class="nav-icon"><i class="fas fa-shopping-cart"></i></span> <span class="nav-text">Products</span> </a> </li> <li class="nav-item"> <a href="#" class="nav-link"> <span class="nav-icon"><i class="fas fa-bullseye"></i></span> <span class="nav-text">Marketing</span> <div class="notification-dot"></div> </a> </li> </ul> <div class="nav-section-title">System</div> <ul class="nav-list"> <li class="nav-item"> <a href="#" class="nav-link"> <span class="nav-icon"><i class="fas fa-cog"></i></span> <span class="nav-text">Settings</span> </a> </li> <li class="nav-item"> <a href="#" class="nav-link"> <span class="nav-icon"><i class="fas fa-bell"></i></span> <span class="nav-text">Notifications</span> <span class="badge">5</span> </a> </li> <li class="nav-item"> <a href="#" class="nav-link"> <span class="nav-icon"><i class="fas fa-question-circle"></i></span> <span class="nav-text">Help & Support</span> </a> </li> </ul> </div> <div class="main-content" id="main-content"> <div class="data-grid"> <div class="data-card"> <div class="card-header"> <div> <div class="card-title">Monthly Revenue</div> <div class="card-value">$178,432</div> <div class="card-change positive"> <i class="fas fa-arrow-up"></i> 12.4% vs last month </div> </div> <div class="card-icon"> <i class="fas fa-chart-line"></i> </div> </div> <svg class="sparkline" id="revenue-spark" viewBox="0 0 100 30"></svg> </div> <div class="data-card"> <div class="card-header"> <div> <div class="card-title">Active Users</div> <div class="card-value">8,942</div> <div class="card-change positive"> <i class="fas fa-arrow-up"></i> 7.6% vs yesterday </div> </div> <div class="card-icon"> <i class="fas fa-users"></i> </div> </div> <svg class="sparkline" id="users-spark" viewBox="0 0 100 30"></svg> </div> <div class="data-card"> <div class="card-header"> <div> <div class="card-title">Conversion Rate</div> <div class="card-value">3.8%</div> <div class="card-change negative"> <i class="fas fa-arrow-down"></i> 0.6% vs 7-day avg </div> </div> <div class="card-icon"> <i class="fas fa-exchange-alt"></i> </div> </div> <svg class="sparkline" id="conversion-spark" viewBox="0 0 100 30"></svg> </div> <div class="data-card"> <div class="card-header"> <div> <div class="card-title">Avg. Session Time</div> <div class="card-value">4m 36s</div> <div class="card-change positive"> <i class="fas fa-arrow-up"></i> 18s vs last week </div> </div> <div class="card-icon"> <i class="fas fa-clock"></i> </div> </div> <svg class="sparkline" id="session-spark" viewBox="0 0 100 30"></svg> </div> </div> <div class="large-chart"> <div class="chart-header"> <h2>Revenue Breakdown</h2> <div class="chart-tabs"> <button class="chart-tab active">3 Months</button> <button class="chart-tab">6 Months</button> <button class="chart-tab">1 Year</button> </div> </div> <div class="chart-container" id="revenue-chart"> <svg width="100%" height="100%" id="main-chart"></svg> <div class="tooltip" id="chart-tooltip"> <div class="tooltip-title">September 2023</div> <div class="tooltip-value">$34,789</div> <div class="tooltip-change positive">+8.9% vs August</div> </div> </div> <div class="chart-legend"> <div class="legend-item"> <div class="legend-color" style="background-color: #3498db;"></div> <span>Direct Sales</span> </div> <div class="legend-item"> <div class="legend-color" style="background-color: #2ecc71;"></div> <span>Partner Revenue</span> </div> <div class="legend-item"> <div class="legend-color" style="background-color: #9b59b6;"></div> <span>Subscription</span> </div> </div> </div> </div> </div> <script> // Wait for DOM to be fully loaded document.addEventListener('DOMContentLoaded', function() { // Toggle sidebar between collapsed and expanded states const toggleBtn = document.getElementById('toggle-sidebar'); const sidebar = document.getElementById('sidebar'); const mainContent = document.getElementById('main-content'); const mobileMenuBtn = document.getElementById('mobile-menu'); toggleBtn.addEventListener('click', function() { sidebar.classList.toggle('collapsed'); mainContent.classList.toggle('expanded'); // Change icon based on current state const icon = toggleBtn.querySelector('i'); if (sidebar.classList.contains('collapsed')) { icon.classList.remove('fa-chevron-left'); icon.classList.add('fa-chevron-right'); } else { icon.classList.remove('fa-chevron-right'); icon.classList.add('fa-chevron-left'); } }); // Mobile menu toggle if (mobileMenuBtn) { mobileMenuBtn.addEventListener('click', function() { sidebar.classList.toggle('open'); }); } // Chart tabs const chartTabs = document.querySelectorAll('.chart-tab'); chartTabs.forEach(tab => { tab.addEventListener('click', function() { chartTabs.forEach(t => t.classList.remove('active')); this.classList.add('active'); // In a real scenario, we would update the chart data here updateMainChart(this.textContent.trim()); }); }); // Draw sparklines drawSparkline('revenue-spark', generateData(20, 15, 25, 1), '#3498db'); drawSparkline('users-spark', generateData(20, 10, 30, 0.5), '#2ecc71'); drawSparkline('conversion-spark', generateData(20, 10, 30, 0.5, true), '#e74c3c'); drawSparkline('session-spark', generateData(20, 10, 30, 0.5), '#9b59b6'); // Draw main chart drawMainChart(); // Tooltip functionality for the main chart const chartContainer = document.getElementById('revenue-chart'); const tooltip = document.getElementById('chart-tooltip'); chartContainer.addEventListener('mousemove', function(e) { // In a real app, we would get the actual data point // For now, just position the tooltip near the cursor const rect = chartContainer.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; // Only show tooltip when hovering over the chart area (avoid edges) if (x > 50 && x < rect.width - 50 && y > 50 && y < rect.height - 50) { tooltip.style.display = 'block'; tooltip.style.left = (x + 10) + 'px'; tooltip.style.top = (y - 10) + 'px'; } else { tooltip.style.display = 'none'; } }); chartContainer.addEventListener('mouseleave', function() { tooltip.style.display = 'none'; }); }); // Helper function to generate random data for charts function generateData(points, min, max, volatility, downtrend = false) { let data = []; let value = Math.random() * (max - min) + min; for (let i = 0; i < points; i++) { value += (Math.random() * 2 - (downtrend ? 1.2 : 1)) * volatility; value = Math.max(min, Math.min(max, value)); data.push(value); } return data; } // Draw a simple sparkline function drawSparkline(id, data, color) { const svg = document.getElementById(id); if (!svg) return; const width = 100; const height = 30; const max = Math.max(...data); const min = Math.min(...data); const range = max - min; // Create path let path = `M 0 ${height - ((data[0] - min) / range) * height}`; for (let i = 1; i < data.length; i++) { const x = (i / (data.length - 1)) * width; const y = height - ((data[i] - min) / range) * height; path += ` L ${x} ${y}`; } // Create SVG path element const pathElement = document.createElementNS('http://www.w3.org/2000/svg', 'path'); pathElement.setAttribute('d', path); pathElement.setAttribute('fill', 'none'); pathElement.setAttribute('stroke', color); pathElement.setAttribute('stroke-width', '1.5'); pathElement.setAttribute('opacity', '0.6'); svg.appendChild(pathElement); // Add area fill const areaPath = path + ` L ${width} ${height} L 0 ${height} Z`; const areaElement = document.createElementNS('http://www.w3.org/2000/svg', 'path'); areaElement.setAttribute('d', areaPath); areaElement.setAttribute('fill', color); areaElement.setAttribute('opacity', '0.1'); svg.insertBefore(areaElement, pathElement); } // Draw the main revenue chart function drawMainChart() { const svg = document.getElementById('main-chart'); if (!svg) return; const width = svg.clientWidth || 600; const height = svg.clientHeight || 250; // Clear existing content svg.innerHTML = ''; // Add grid lines for (let i = 1; i < 5; i++) { const y = (i / 5) * height; const line = document.createElementNS('http://www.w3.org/2000/svg', 'line'); line.setAttribute('x1', '0'); line.setAttribute('y1', y); line.setAttribute('x2', width); line.setAttribute('y2', y); line.setAttribute('stroke', 'rgba(255, 255, 255, 0.1)'); line.setAttribute('stroke-width', '1'); svg.appendChild(line); // Add labels const text = document.createElementNS('http://www.w3.org/2000/svg', 'text'); text.setAttribute('x', '10'); text.setAttribute('y', y - 5); text.setAttribute('fill', '#bdc3c7'); text.setAttribute('font-size', '10'); text.textContent = `$${(100 - (i / 5) * 100).toFixed(0)}k`; svg.appendChild(text); } // Generate three data series const seriesA = generateData(12, 40, 90, 5); const seriesB = generateData(12, 30, 60, 4); const seriesC = generateData(12, 20, 40, 3); // Draw each series drawSeries(svg, seriesA, '#3498db', width, height); drawSeries(svg, seriesB, '#2ecc71', width, height); drawSeries(svg, seriesC, '#9b59b6', width, height); // Add month labels on x-axis const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; for (let i = 0; i < 12; i++) { const x = (i / 11) * width; const text = document.createElementNS('http://www.w3.org/2000/svg', 'text'); text.setAttribute('x', x); text.setAttribute('y', height + 15); text.setAttribute('fill', '#bdc3c7'); text.setAttribute('font-size', '10'); text.setAttribute('text-anchor', 'middle'); text.textContent = months[i]; svg.appendChild(text); } // Add interactive points addInteractivePoints(svg, seriesA, '#3498db', width, height); } // Draw a data series on the chart function drawSeries(svg, data, color, width, height) { const max = 100; // Fixed max for better visualization const min = 0; // Fixed min const range = max - min; // Create path let path = `M 0 ${height - ((data[0] - min) / range) * height}`; for (let i = 1; i < data.length; i++) { const x = (i / (data.length - 1)) * width; const y = height - ((data[i] - min) / range) * height; // Use a curve instead of straight lines const prevX = ((i - 1) / (data.length - 1)) * width; const prevY = height - ((data[i - 1] - min) / range) * height; const cpx1 = prevX + (x - prevX) / 3; const cpy1 = prevY; const cpx2 = x - (x - prevX) / 3; const cpy2 = y; path += ` C ${cpx1} ${cpy1}, ${cpx2} ${cpy2}, ${x} ${y}`; } // Create SVG path element const pathElement = document.createElementNS('http://www.w3.org/2000/svg', 'path'); pathElement.setAttribute('d', path); pathElement.setAttribute('fill', 'none'); pathElement.setAttribute('stroke', color); pathElement.setAttribute('stroke-width', '2'); pathElement.setAttribute('opacity', '0.8'); svg.appendChild(pathElement); // Add subtle gradient area fill const areaPath = path + ` L ${width} ${height} L 0 ${height} Z`; const areaElement = document.createElementNS('http://www.w3.org/2000/svg', 'path'); areaElement.setAttribute('d', areaPath); areaElement.setAttribute('fill', `url(#gradient-${color.substring(1)})`); areaElement.setAttribute('opacity', '0.2'); svg.insertBefore(areaElement, pathElement); // Add gradient definition const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs'); const gradient = document.createElementNS('http://www.w3.org/2000/svg', 'linearGradient'); gradient.setAttribute('id', `gradient-${color.substring(1)}`); gradient.setAttribute('x1', '0%'); gradient.setAttribute('y1', '0%'); gradient.setAttribute('x2', '0%'); gradient.setAttribute('y2', '100%'); const stop1 = document.createElementNS('http://www.w3.org/2000/svg', 'stop'); stop1.setAttribute('offset', '0%'); stop1.setAttribute('stop-color', color); stop1.setAttribute('stop-opacity', '0.5'); const stop2 = document.createElementNS('http://www.w3.org/2000/svg', 'stop'); stop2.setAttribute('offset', '100%'); stop2.setAttribute('stop-color', color); stop2.setAttribute('stop-opacity', '0.1'); gradient.appendChild(stop1); gradient.appendChild(stop2); defs.appendChild(gradient); svg.insertBefore(defs, svg.firstChild); } // Add interactive points to the chart function addInteractivePoints(svg, data, color, width, height) { const max = 100; const min = 0; const range = max - min; for (let i = 0; i < data.length; i++) { const x = (i / (data.length - 1)) * width; const y = height - ((data[i] - min) / range) * height; // Create an invisible interactive point const point = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); point.setAttribute('cx', x); point.setAttribute('cy', y); point.setAttribute('r', '8'); point.setAttribute('fill', 'transparent'); point.setAttribute('stroke', 'transparent'); point.setAttribute('stroke-width', '2'); point.setAttribute('class', 'interactive-point'); point.setAttribute('data-value', `$${Math.round(data[i] * 1000)}`); point.setAttribute('data-month', getMonthName(i)); // Add hover effects
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Luxury Product Quick View</title> <style> :root { --primary: #e8d5c4; --secondary: #937d64; --text: #38302a; --background: #f9f4f0; --accent: #c8a987; --white: #ffffff; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', 'Segoe UI', Roboto, sans-serif; } body { background-color: var(--background); color: var(--text); height: 100vh; width: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 20px; } .product-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 20px; max-width: 660px; width: 100%; } .product-card { background-color: var(--white); border-radius: 12px; overflow: hidden; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05); transition: transform 0.3s ease, box-shadow 0.3s ease; position: relative; cursor: pointer; } .product-card:hover { transform: translateY(-5px); box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1); } .product-image { width: 100%; height: 180px; object-fit: cover; display: block; } .product-info { padding: 15px; } .product-name { font-size: 16px; font-weight: 600; margin-bottom: 5px; color: var(--text); } .product-price { font-size: 15px; color: var(--secondary); font-weight: 500; } .product-tag { position: absolute; top: 10px; right: 10px; background-color: var(--accent); color: var(--white); padding: 4px 8px; border-radius: 4px; font-size: 12px; font-weight: 500; opacity: 0.9; } .quick-view-button { position: absolute; bottom: 15px; right: 15px; background-color: var(--primary); color: var(--text); border: none; border-radius: 50%; width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; cursor: pointer; opacity: 0; transform: translateY(10px); transition: opacity 0.3s ease, transform 0.3s ease, background-color 0.2s ease; } .product-card:hover .quick-view-button { opacity: 1; transform: translateY(0); } .quick-view-button:hover { background-color: var(--accent); color: var(--white); } /* Modal Styles */ .modal-backdrop { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(56, 48, 42, 0.3); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); display: flex; align-items: center; justify-content: center; opacity: 0; pointer-events: none; transition: opacity 0.4s ease; z-index: 1000; } .modal-backdrop.active { opacity: 1; pointer-events: all; } .modal-content { display: flex; flex-direction: column; max-width: 90%; width: 620px; max-height: 90vh; background-color: var(--white); border-radius: 16px; overflow: hidden; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15); transform: translateY(30px) scale(0.95); opacity: 0; transition: transform 0.5s cubic-bezier(0.19, 1, 0.22, 1), opacity 0.5s cubic-bezier(0.19, 1, 0.22, 1); } .modal-backdrop.active .modal-content { transform: translateY(0) scale(1); opacity: 1; } @media (min-width: 640px) { .modal-content { flex-direction: row; height: 450px; } } .modal-image-container { flex: 1; position: relative; max-height: 300px; overflow: hidden; } @media (min-width: 640px) { .modal-image-container { max-height: none; } } .modal-image { width: 100%; height: 100%; object-fit: cover; } .modal-details { flex: 1; padding: 30px; display: flex; flex-direction: column; overflow-y: auto; } .modal-header { position: relative; margin-bottom: 20px; } .modal-title { font-size: 24px; font-weight: 600; margin-right: 30px; } .modal-price { font-size: 20px; font-weight: 600; color: var(--secondary); margin: 10px 0 20px; } .modal-close { position: absolute; top: 0; right: 0; background: transparent; border: none; font-size: 24px; color: var(--text); cursor: pointer; width: 32px; height: 32px; display: flex; align-items: center; justify-content: center; transition: transform 0.3s ease; } .modal-close:hover { transform: rotate(90deg); } .modal-description { line-height: 1.6; color: #5a5a5a; margin-bottom: 25px; } .color-options { margin-bottom: 25px; } .options-title { font-size: 14px; font-weight: 600; margin-bottom: 10px; color: var(--text); } .colors { display: flex; gap: 12px; } .color-option { width: 24px; height: 24px; border-radius: 50%; cursor: pointer; position: relative; transition: transform 0.2s ease; } .color-option:hover { transform: scale(1.15); } .color-option.selected::after { content: ''; position: absolute; top: -4px; left: -4px; right: -4px; bottom: -4px; border: 2px solid var(--accent); border-radius: 50%; } .size-options { margin-bottom: 25px; } .sizes { display: flex; gap: 10px; } .size-option { padding: 8px 12px; border: 1px solid #ddd; border-radius: 6px; font-size: 14px; cursor: pointer; transition: all 0.2s ease; } .size-option:hover { border-color: var(--accent); background-color: rgba(200, 169, 135, 0.1); } .size-option.selected { background-color: var(--accent); color: white; border-color: var(--accent); } .modal-actions { margin-top: auto; display: flex; gap: 15px; } .btn { padding: 12px 20px; border-radius: 8px; font-weight: 600; font-size: 15px; cursor: pointer; transition: all 0.2s ease; border: none; } .btn-primary { background-color: var(--accent); color: white; flex: 2; } .btn-primary:hover { background-color: #b99974; transform: translateY(-2px); box-shadow: 0 4px 12px rgba(200, 169, 135, 0.3); } .btn-outline { background-color: transparent; border: 1px solid var(--accent); color: var(--accent); flex: 1; } .btn-outline:hover { background-color: rgba(200, 169, 135, 0.1); } .product-badge { position: absolute; top: 15px; left: 15px; background-color: var(--white); color: var(--accent); padding: 5px 10px; border-radius: 20px; font-size: 12px; font-weight: 600; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); } .image-controls { position: absolute; bottom: 15px; left: 0; right: 0; display: flex; justify-content: center; gap: 8px; } .image-dot { width: 10px; height: 10px; border-radius: 50%; background-color: rgba(255, 255, 255, 0.5); cursor: pointer; transition: all 0.2s ease; } .image-dot.active { background-color: white; transform: scale(1.2); } .page-title { margin-bottom: 30px; font-size: 24px; font-weight: 600; color: var(--text); text-align: center; } .product-count { font-size: 15px; color: var(--secondary); margin-bottom: 20px; text-align: center; } /* Shimmer effect */ .product-card::before { content: ''; position: absolute; top: 0; left: -100%; width: 50%; height: 100%; background: linear-gradient( to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.3) 50%, rgba(255, 255, 255, 0) 100% ); transform: skewX(-25deg); z-index: 1; transition: left 0.8s ease; } .product-card:hover::before { left: 150%; } </style> </head> <body> <h1 class="page-title">Artisanal Ceramics Collection</h1> <p class="product-count">Showing 6 handcrafted pieces</p> <div class="product-grid"> <!-- Product 1 --> <div class="product-card" data-id="1"> <img src="https://images.unsplash.com/photo-1565193566173-7a0af3ac2d98?ixlib=rb-4.0.3&auto=format&fit=crop&w=500&q=80" alt="Terracotta Vase" class="product-image"> <div class="product-tag">New</div> <div class="product-info"> <h3 class="product-name">Terracotta Vase</h3> <p class="product-price">$89.00</p> </div> <button class="quick-view-button" aria-label="Quick view"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path d="M10.5 8a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0z"/> <path d="M0 8s3-5.5 8-5.5S16 8 16 8s-3 5.5-8 5.5S0 8 0 8zm8 3.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7z"/> </svg> </button> </div> <!-- Product 2 --> <div class="product-card" data-id="2"> <img src="https://images.unsplash.com/photo-1610701596061-2ecf227e85b2?ixlib=rb-4.0.3&auto=format&fit=crop&w=500&q=80" alt="Sand Mug Set" class="product-image"> <div class="product-info"> <h3 class="product-name">Sand Mug Set</h3> <p class="product-price">$65.00</p> </div> <button class="quick-view-button" aria-label="Quick view"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path d="M10.5 8a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0z"/> <path d="M0 8s3-5.5 8-5.5S16 8 16 8s-3 5.5-8 5.5S0 8 0 8zm8 3.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7z"/> </svg> </button> </div> <!-- Product 3 --> <div class="product-card" data-id="3"> <img src="https://images.unsplash.com/photo-1578749471545-8c3f8d5f0b8b?ixlib=rb-4.0.3&auto=format&fit=crop&w=500&q=80" alt="Ivory Platter" class="product-image"> <div class="product-tag">Limited</div> <div class="product-info"> <h3 class="product-name">Ivory Platter</h3> <p class="product-price">$78.50</p> </div> <button class="quick-view-button" aria-label="Quick view"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path d="M10.5 8a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0z"/> <path d="M0 8s3-5.5 8-5.5S16 8 16 8s-3 5.5-8 5.5S0 8 0 8zm8 3.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7z"/> </svg> </button> </div> <!-- Product 4 --> <div class="product-card" data-id="4"> <img src="https://images.unsplash.com/photo-1612197527762-8c6a2d8147ce?ixlib=rb-4.0.3&auto=format&fit=crop&w=500&q=80" alt="Clay Bowl Trio" class="product-image"> <div class="product-info"> <h3 class="product-name">Clay Bowl Trio</h3> <p class="product-price">$54.00</p> </div> <button class="quick-view-button" aria-label="Quick view"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path d="M10.5 8a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0z"/> <path d="M0 8s3-5.5 8-5.5S16 8 16 8s-3 5.5-8 5.5S0 8 0 8zm8 3.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7z"/> </svg> </button> </div> <!-- Product 5 --> <div class="product-card" data-id="5"> <img src="https://images.unsplash.com/photo-1606760562172-9226793bf2b8?ixlib=rb-4.0.3&auto=format&fit=crop&w=500&q=80" alt="Speckled Pitcher" class="product-image"> <div class="product-info"> <h3 class="product-name">Speckled Pitcher</h3> <p class="product-price">$72.00</p> </div> <button class="quick-view-button" aria-label="Quick view"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path d="M10.5 8a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0z"/> <path d="M0 8s3-5.5 8-5.5S16 8 16 8s-3 5.5-8 5.5S0 8 0 8zm8 3.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7z"/> </svg> </button> </div> <!-- Product 6 --> <div class="product-card" data-id="6"> <img src="https://images.unsplash.com/photo-1605883705077-8d3d856fe3c7?ixlib=rb-4.0.3&auto=format&fit=crop&w=500&q=80" alt="Ceramic Teapot" class="product-image"> <div class="product-tag">Best Seller</div> <div class="product-info"> <h3 class="product-name">Ceramic Teapot</h3> <p class="product-price">$95.00</p> </div> <button class="quick-view-button" aria-label="Quick view"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path d="M10.5 8a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0z"/> <path d="M0 8s3-5.5 8-5.5S16 8 16 8s-3 5.5-8 5.5S0 8 0 8zm8 3.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7z"/> </svg> </button> </div> </div> <!-- Modal Backdrop --> <div class="modal-backdrop"> <div class="modal-content"> <div class="modal-image-container"> <div class="product-badge">Artisan Crafted</div> <img src="" alt="" class="modal-image"> <div class="image-controls"> <div class="image-dot active"></div> <div class="image-dot"></div> <div class="image-dot"></div> </div> </div> <div class="modal-details"> <div class="modal-header"> <h2 class="modal-title"></h2> <button class="modal-close" aria-label="Close modal">✕</button> </div> <div class="modal-price"></div> <p class="modal-description"></p> <div class="color-options"> <h4 class="options-title">Color</h4> <div class="colors"> <div class="color-option selected" style="background-color: #d2b48c;"></div> <div class="color-option" style="background-color: #8b4513;"></div> <div class="color-option" style="background-color: #dcdcdc;"></div> </div> </div> <div class="size-options"> <h4 class="options-title">Size</h4> <div class="sizes"> <div class="size-option">S</div> <div class="size-option selected">M</div> <div class="size-option">L</div> </div> </div> <div class="modal-actions"> <button class="btn btn-primary">Add to Cart</button> <button class="btn btn-outline">Save</button> </div> </div> </div> </div> <script> // Product data const products = { 1: { name: "Terracotta Vase", price: "$89.00", image: "https://images.unsplash.com/photo-1565193566173-7a0af3ac2d98?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80", description: "Hand-thrown terracotta vase with a unique organic shape, perfect for minimalist floral arrangements. Each piece has subtle variations that showcase the artisan's craftsmanship and the beauty of natural clay." }, 2: { name: "Sand Mug Set", price: "$65.00", image: "https://images.unsplash.com/photo-1610701596061-2ecf227e85b2?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80", description: "Set of four handcrafted ceramic mugs in a warm sand finish. These stackable mugs feature comfortable handles and a glazed interior, while maintaining the raw texture on the outside for a natural tactile experience." }, 3: { name: "Ivory Platter", price: "$78.50", image: "https://images.unsplash.com/photo-1578749471545-8c3f8d5f0b8b?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80", description: "Elegant oval serving platter in an ivory glaze with a subtle speckled finish. The raised edges prevent spills while the generous surface provides ample room for serving appetizers or displaying decorative items." }, 4: { name: "Clay Bowl Trio", price: "$54.00", image: "https://images.unsplash.com/photo-1612197527762-8c6a2d8147ce?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80", description: "Set of three nesting bowls with a textured matte exterior and smooth glazed interior. Perfect for serving snacks, side dishes, or using as catchalls around your home. Each piece shows the maker's fingerprints for authenticity." }, 5: { name: "Speckled Pitcher", price: "$72.00", image: "https://images.unsplash.com/photo-1606760562172-9226793bf2b8?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80", description: "Beautifully shaped pouring vessel with a comfortable handle and precise spout. The speckled finish adds character to this versatile pitcher, ideal for serving beverages or displaying fresh-cut flowers." }, 6: { name: "Ceramic Teapot", price: "$95.00", image: "https://images.unsplash.com/photo-1605883705077-8d3d856fe3c7?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80", description: "Traditional ceramic teapot with a contemporary silhouette, featuring an integrated strainer and balanced handle. The natural clay body retains heat beautifully while the tight-fitting lid preserves your tea's aroma." } }; // DOM elements const productCards = document.querySelectorAll('.product-card'); const modalBackdrop = document.querySelector('.modal-backdrop'); const modalContent = document.querySelector('.modal-content'); const modalImage = document.querySelector('.modal-image'); const modalTitle = document.querySelector('.modal-title'); const modalPrice = document.querySelector('.modal-price'); const modalDescription = document.querySelector('.modal-description'); const modalClose = document.querySelector('.modal-close'); const colorOptions = document.querySelectorAll('.color-option'); const sizeOptions = document.querySelectorAll('.size-option'); const imageDots = document.querySelectorAll('.image-dot'); const addToCartBtn = document.querySelector('.btn-primary'); const saveBtn = document.querySelector('.btn-outline'); // Open modal with product data function openModal(productId) { const product = products[productId]; if (!product) return; modalImage.src = product.image; modalImage.alt = product.name; modalTitle.textContent = product.name; modalPrice.textContent = product.price; modalDescription.textContent = product.description; modalBackdrop.classList.add('active'); document.body.style.overflow = 'hidden'; } // Close modal function closeModal() { modalBackdrop.classList.remove('active'); document.body.style.overflow = ''; } // Event listeners productCards.forEach(card => { card.addEventListener('click', (e) => { if (!e.target.closest('.quick-view-button')) return; e.preventDefault(); e.stopPropagation(); openModal(card.dataset.id); }); }); modalClose.addEventListener('click', closeModal); modalBackdrop.addEventListener('click', (e) => { if (e.target === modalBackdrop) { closeModal(); } }); // Color selection colorOptions.forEach(option => { option.addEventListener('click', () => { colorOptions.forEach(opt => opt.classList.remove('selected')); option.classList.add('selected'); }); }); // Size selection sizeOptions.forEach(option => { option.addEventListener('click', () => { sizeOptions.forEach(opt => opt.classList.remove('selected')); option.classList.add('selected'); }); }); // Image pagination imageDots.forEach((dot, index) => { dot.addEventListener('click', () => { imageDots.forEach(d => d.classList.remove('active')); dot.classList.add('active'); // Would normally switch the image here // For demo purposes we'll just pretend console.log(`Switching to image ${index + 1}`); }); }); // Add to cart button animation addToCartBtn.addEventListener('click', (e) => { e.preventDefault(); addToCartBtn.textContent = "Added!"; setTimeout(() => { addToCartBtn.textContent = "Add to Cart"; closeModal(); }, 1500); }); // Save button saveBtn.addEventListener('click', (e) => { e.preventDefault(); saveBtn.textContent = "Saved"; saveBtn.style.backgroundColor = "var(--accent)"; saveBtn.style.color = "white"; setTimeout(() => { saveBtn.textContent = "Save"; saveBtn.style.backgroundColor = ""; saveBtn.style.color = ""; }, 1500); }); // Keyboard accessibility document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && modalBackdrop.classList.contains('active')) { closeModal(); } }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Blume - Social Feed</title> <style> :root { --pastel-pink: #ffb6c1; --pastel-blue: #add8e6; --pastel-green: #98fb98; --pastel-yellow: #ffffe0; --pastel-purple: #d8bfd8; --muted-gray: #9a9a9a; --muted-blue: #9aa9c9; --muted-pink: #d9b3b3; --light-bg: #f5f5f7; --dark-text: #333; --overlay-bg: rgba(255, 255, 255, 0.5); --card-shadow: 0 10px 20px rgba(0, 0, 0, 0.05); --transition-standard: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: var(--light-bg); color: var(--dark-text); height: 100vh; display: flex; justify-content: center; align-items: center; overflow: hidden; } .app-container { width: 100%; max-width: 700px; height: 700px; position: relative; overflow: hidden; border-radius: 20px; box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1); background-color: white; } .header { padding: 20px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid rgba(0,0,0,0.05); background: linear-gradient(135deg, var(--pastel-blue), var(--pastel-purple)); color: white; position: relative; z-index: 10; } .logo { font-weight: 700; font-size: 24px; background: linear-gradient(45deg, #fff, rgba(255,255,255,0.8)); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; letter-spacing: 1px; } .action-buttons { display: flex; gap: 15px; } .btn { background: none; border: none; cursor: pointer; border-radius: 50%; width: 40px; height: 40px; display: flex; justify-content: center; align-items: center; transition: var(--transition-standard); background-color: rgba(255, 255, 255, 0.2); color: white; } .btn:hover { background-color: rgba(255, 255, 255, 0.4); transform: translateY(-2px); } .feed-container { height: calc(100% - 80px); overflow-y: auto; padding: 20px; position: relative; scroll-behavior: smooth; } .feed-container::-webkit-scrollbar { width: 6px; } .feed-container::-webkit-scrollbar-track { background: rgba(0, 0, 0, 0.03); } .feed-container::-webkit-scrollbar-thumb { background: var(--muted-blue); border-radius: 3px; } .post { background-color: white; border-radius: 12px; margin-bottom: 20px; box-shadow: var(--card-shadow); overflow: hidden; transition: var(--transition-standard); transform-origin: center; position: relative; } .post:hover { transform: translateY(-3px); box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1); } .post-header { padding: 15px; display: flex; align-items: center; gap: 12px; } .avatar { width: 40px; height: 40px; border-radius: 50%; object-fit: cover; border: 2px solid white; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); } .user-info { flex: 1; } .username { font-weight: 600; color: var(--dark-text); font-size: 14px; } .time { font-size: 12px; color: var(--muted-gray); } .post-content { padding: 0 15px 15px; } .post-text { margin-bottom: 15px; line-height: 1.5; font-size: 15px; color: var(--dark-text); } .post-image { width: 100%; border-radius: 8px; margin-bottom: 15px; max-height: 300px; object-fit: cover; } .post-footer { display: flex; justify-content: space-between; padding: 10px 15px; border-top: 1px solid rgba(0, 0, 0, 0.05); color: var(--muted-gray); } .post-action { display: flex; align-items: center; gap: 5px; cursor: pointer; font-size: 13px; transition: var(--transition-standard); padding: 5px 10px; border-radius: 20px; } .post-action:hover { color: var(--pastel-purple); background-color: rgba(216, 191, 216, 0.1); } .post-action.active { color: var(--pastel-purple); } .overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: var(--overlay-bg); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); display: flex; justify-content: center; align-items: center; z-index: 1000; opacity: 0; pointer-events: none; transition: opacity 0.3s ease; } .overlay.active { opacity: 1; pointer-events: all; } .modal { background-color: white; border-radius: 16px; padding: 25px; width: 90%; max-width: 400px; box-shadow: 0 15px 40px rgba(0, 0, 0, 0.15); transform: translateY(20px); transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); position: relative; } .overlay.active .modal { transform: translateY(0); } .modal-header { margin-bottom: 20px; display: flex; justify-content: space-between; align-items: center; } .modal-title { font-size: 18px; font-weight: 600; color: var(--dark-text); } .close-btn { background: none; border: none; font-size: 22px; cursor: pointer; color: var(--muted-gray); transition: var(--transition-standard); } .close-btn:hover { color: var(--dark-text); transform: rotate(90deg); } .comment-box { display: flex; gap: 12px; margin-top: 20px; } .comment-input { flex: 1; padding: 12px 15px; border: 1px solid rgba(0, 0, 0, 0.1); border-radius: 25px; font-size: 14px; transition: var(--transition-standard); outline: none; } .comment-input:focus { border-color: var(--pastel-purple); box-shadow: 0 0 0 3px rgba(216, 191, 216, 0.3); } .send-btn { background-color: var(--pastel-purple); color: white; border: none; border-radius: 25px; padding: 0 20px; cursor: pointer; transition: var(--transition-standard); font-weight: 600; font-size: 14px; } .send-btn:hover { background-color: #c9a6c9; transform: translateY(-2px); } .comments-container { margin-top: 20px; max-height: 300px; overflow-y: auto; } .comment { display: flex; gap: 10px; margin-bottom: 15px; } .comment-content { flex: 1; background-color: var(--light-bg); padding: 12px 15px; border-radius: 12px; font-size: 14px; line-height: 1.4; } .comment-user { font-weight: 600; margin-bottom: 4px; color: var(--dark-text); } .comment-text { color: var(--muted-gray); } .floating-button { position: absolute; bottom: 20px; right: 20px; width: 60px; height: 60px; border-radius: 50%; background: linear-gradient(135deg, var(--pastel-blue), var(--pastel-purple)); color: white; display: flex; justify-content: center; align-items: center; font-size: 24px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.15); cursor: pointer; transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); z-index: 10; border: none; outline: none; } .floating-button:hover { transform: translateY(-5px) rotate(90deg); box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2); } .blurred-content { filter: blur(0px); transition: filter 0.4s ease; } .blurred-content.active { filter: blur(5px); } .badge { position: absolute; top: 10px; right: 10px; background: linear-gradient(135deg, var(--pastel-pink), var(--pastel-purple)); color: white; font-size: 11px; padding: 3px 8px; border-radius: 12px; font-weight: 600; opacity: 0; transform: scale(0.8); transition: all 0.3s ease; } .post:hover .badge { opacity: 1; transform: scale(1); } .quick-action { position: absolute; top: -40px; left: 0; right: 0; display: flex; justify-content: center; gap: 15px; transition: top 0.3s ease; } .post:hover .quick-action { top: 10px; } .quick-btn { width: 36px; height: 36px; border-radius: 50%; display: flex; justify-content: center; align-items: center; background-color: white; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); color: var(--muted-gray); cursor: pointer; transition: all 0.3s ease; border: none; } .quick-btn:hover { transform: scale(1.1); color: var(--pastel-purple); } .post-type { position: absolute; bottom: 10px; left: 10px; font-size: 11px; padding: 3px 8px; border-radius: 12px; background-color: rgba(255, 255, 255, 0.9); font-weight: 600; color: var(--pastel-purple); box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05); } .shimmer { background: linear-gradient( 90deg, transparent, rgba(255, 255, 255, 0.8), transparent ); background-size: 200% 100%; animation: shimmer 1.5s infinite; position: absolute; top: 0; left: 0; right: 0; bottom: 0; opacity: 0; transition: opacity 0.3s ease; pointer-events: none; } .post:hover .shimmer { opacity: 1; } @keyframes shimmer { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } } @media (max-width: 700px) { .app-container { border-radius: 0; height: 100vh; } .post-image { max-height: 200px; } .modal { width: 95%; } } </style> </head> <body> <div class="app-container"> <div class="blurred-content"> <header class="header"> <div class="logo">blume</div> <div class="action-buttons"> <button class="btn"> <svg width="20" height="20" fill="currentColor" viewBox="0 0 24 24"> <path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/> </svg> </button> <button class="btn"> <svg width="20" height="20" fill="currentColor" viewBox="0 0 24 24"> <path d="M12 22c1.1 0 2-.9 2-2h-4c0 1.1.89 2 2 2zm6-6v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2z"/> </svg> </button> </div> </header> <div class="feed-container"> <div class="post"> <div class="quick-action"> <button class="quick-btn"> <svg width="16" height="16" fill="currentColor" viewBox="0 0 24 24"> <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/> </svg> </button> <button class="quick-btn"> <svg width="16" height="16" fill="currentColor" viewBox="0 0 24 24"> <path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81 1.66 0 3-1.34 3-3s-1.34-3-3-3-3 1.34-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9c-1.66 0-3 1.34-3 3s1.34 3 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.16c-.05.21-.08.43-.08.65 0 1.61 1.31 2.92 2.92 2.92 1.61 0 2.92-1.31 2.92-2.92s-1.31-2.92-2.92-2.92z"/> </svg> </button> </div> <div class="shimmer"></div> <div class="badge">Trending</div> <div class="post-header"> <img src="https://randomuser.me/api/portraits/women/22.jpg" alt="User Avatar" class="avatar"> <div class="user-info"> <div class="username">Emma Walker</div> <div class="time">2 hours ago</div> </div> </div> <div class="post-content"> <div class="post-text">Just discovered the best coffee shop in town! Their lavender latte is a game-changer for my morning routine. Anyone else finding hidden gems in their neighborhood? ✨</div> <img src="https://images.unsplash.com/photo-1507133750040-4a8f57021571" alt="Coffee shop" class="post-image"> </div> <div class="post-footer"> <div class="post-action like-action"> <svg width="16" height="16" fill="currentColor" viewBox="0 0 24 24"> <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/> </svg> <span>143</span> </div> <div class="post-action comment-action"> <svg width="16" height="16" fill="currentColor" viewBox="0 0 24 24"> <path d="M21 6h-2v9H6v2c0 .55.45 1 1 1h11l4 4V7c0-.55-.45-1-1-1zm-4 6V3c0-.55-.45-1-1-1H3c-.55 0-1 .45-1 1v14l4-4h10c.55 0 1-.45 1-1z"/> </svg> <span>28</span> </div> <div class="post-action"> <svg width="16" height="16" fill="currentColor" viewBox="0 0 24 24"> <path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81 1.66 0 3-1.34 3-3s-1.34-3-3-3-3 1.34-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9c-1.66 0-3 1.34-3 3s1.34 3 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.16c-.05.21-.08.43-.08.65 0 1.61 1.31 2.92 2.92 2.92 1.61 0 2.92-1.31 2.92-2.92s-1.31-2.92-2.92-2.92z"/> </svg> <span>Share</span> </div> </div> <div class="post-type">Lifestyle</div> </div> <div class="post"> <div class="quick-action"> <button class="quick-btn"> <svg width="16" height="16" fill="currentColor" viewBox="0 0 24 24"> <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/> </svg> </button> <button class="quick-btn"> <svg width="16" height="16" fill="currentColor" viewBox="0 0 24 24"> <path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81 1.66 0 3-1.34 3-3s-1.34-3-3-3-3 1.34-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9c-1.66 0-3 1.34-3 3s1.34 3 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.16c-.05.21-.08.43-.08.65 0 1.61 1.31 2.92 2.92 2.92 1.61 0 2.92-1.31 2.92-2.92s-1.31-2.92-2.92-2.92z"/> </svg> </button> </div> <div class="shimmer"></div> <div class="post-header"> <img src="https://randomuser.me/api/portraits/men/32.jpg" alt="User Avatar" class="avatar"> <div class="user-info"> <div class="username">Alex Chen</div> <div class="time">5 hours ago</div> </div> </div> <div class="post-content"> <div class="post-text">Finally finished my latest digital illustration project. This one took me 3 weeks to complete! Learning how to blend traditional techniques with digital workflows has been challenging but so rewarding.</div> <img src="https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe" alt="Digital Illustration" class="post-image"> </div> <div class="post-footer"> <div class="post-action like-action active"> <svg width="16" height="16" fill="currentColor" viewBox="0 0 24 24"> <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/> </svg> <span>289</span> </div> <div class="post-action comment-action"> <svg width="16" height="16" fill="currentColor" viewBox="0 0 24 24"> <path d="M21 6h-2v9H6v2c0 .55.45 1 1 1h11l4 4V7c0-.55-.45-1-1-1zm-4 6V3c0-.55-.45-1-1-1H3c-.55 0-1 .45-1 1v14l4-4h10c.55 0 1-.45 1-1z"/> </svg> <span>47</span> </div> <div class="post-action"> <svg width="16" height="16" fill="currentColor" viewBox="0 0 24 24"> <path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81 1.66 0 3-1.34 3-3s-1.34-3-3-3-3 1.34-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9c-1.66 0-3 1.34-3 3s1.34 3 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.16c-.05.21-.08.43-.08.65 0 1.61 1.31 2.92 2.92 2.92 1.61 0 2.92-1.31 2.92-2.92s-1.31-2.92-2.92-2.92z"/> </svg> <span>Share</span> </div> </div> <div class="post-type">Creative</div> </div> <div class="post"> <div class="quick-action"> <button class="quick-btn"> <svg width="16" height="16" fill="currentColor" viewBox="0 0 24 24"> <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/> </svg> </button> <button class="quick-btn"> <svg width="16" height="16" fill="currentColor" viewBox="0 0 24 24"> <path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81 1.66 0 3-1.34 3-3s-1.34-3-3-3-3 1.34-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9c-1.66 0-3 1.34-3 3s1.34 3 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.16c-.05.21-.08.43-.08.65 0 1.61 1.31 2.92 2.92 2.92 1.61 0 2.92-1.31 2.92-2.92s-1.31-2.92-2.92-2.92z"/> </svg> </button> </div> <div class="shimmer"></div> <div class="badge">Popular</div> <div class="post-header"> <img src="https://randomuser.me/api/portraits/women/65.jpg" alt="User Avatar" class="avatar"> <div class="user-info"> <div class="username">Jamie Lee</div> <div class="time">Yesterday</div> </div> </div> <div class="post-content"> <div class="post-text">My urban garden is finally thriving after months of trial and error! Found that these container plants are particularly good for small balconies in the city. Any fellow urban gardeners have tips for maximizing limited space?</div> <img src="https://images.unsplash.com/photo-1590594012599-948b4be71b3f" alt="Urban Garden" class="post-image"> </div> <div class="post-footer"> <div class="post-action like-action"> <svg width="16" height="16" fill="currentColor" viewBox="0 0 24 24"> <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/> </svg> <span>176</span> </div> <div class="post-action comment-action"> <svg width="16" height="16" fill="currentColor" viewBox="0 0 24 24"> <path d="M21 6h-2v9H6v2c0 .55.45 1 1 1h11l4 4V7c0-.55-.45-1-1-1zm-4 6V3c0-.55-.45-1-1-1H3c-.55 0-1 .45-1 1v14l4-4h10c.55 0 1-.45 1-1z"/> </svg> <span>36</span> </div> <div class="post-action"> <svg width="16" height="16" fill="currentColor" viewBox="0 0 24 24"> <path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81 1.66 0 3-1.34 3-3s-1.34-3-3-3-3 1.34-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9c-1.66 0-3 1.34-3 3s1.34 3 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.16c-.05.21-.08.43-.08.65 0 1.61 1.31 2.92 2.92 2.92 1.61 0 2.92-1.31 2.92-2.92s-1.31-2.92-2.92-2.92z"/> </svg> <span>Share</span> </div> </div> <div class="post-type">Green Living</div> </div> </div> <button class="floating-button"> <svg width="24" height="24" fill="currentColor" viewBox="0 0 24 24"> <path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/> </svg> </button> </div> <div class="overlay"> <div class="modal"> <div class="modal-header"> <div class="modal-title">Comments</div> <button class="close-btn">×</button> </div> <div class="comments-container"> <div class="comment"> <img src="https://randomuser.me/api/portraits/women/44.jpg" alt="User Avatar" class="avatar"> <div class="comment-content"> <div class="comment-user">Sophia Kim</div> <div class="comment-text">That coffee shop is amazing! I love their seasonal specialties too. Have you tried their matcha croissant?</div> </div> </div> <div class="comment"> <img src="https://randomuser.me/api/portraits/men/75.jpg" alt="User Avatar" class="avatar"> <div class="comment-content"> <div class="comment-user">Michael Torres</div> <div class="comment-text">Which coffee shop is this? I need to try that lavender latte immediately!</div> </div> </div> <div class="comment"> <img src="https://randomuser.me/api/portraits/women/22.jpg" alt="User Avatar" class="avatar"> <div class="comment-content"> <div class="comment-user">Emma Walker</div> <div class="comment-text">@Michael It's Daydream Coffee on Maple Street. They open at 6am on weekdays!</div> </div> </div> <div class="comment"> <img src="https://randomuser.me/api/portraits/men/26.jpg" alt="User Avatar" class="avatar"> <div class="comment-content"> <div class="comment-user">James Wilson</div> <div class="comment-text">Thanks for sharing! I'm always looking for cozy spots to work remotely. Does this place have good wifi?</div> </div> </div> </div> <div class="comment-box"> <img src="https://randomuser.me/api/portraits/lego/1.jpg" alt="Your Avatar" class="avatar"> <input type="text" class="comment-input" placeholder="Add a comment..."> <button class="send-btn">Send</button> </div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const overlay = document.querySelector('.overlay'); const closeBtn = document.querySelector('.close-btn'); const commentActions = document.querySelectorAll('.comment-action'); const likeActions = document.querySelectorAll('.like-action'); const floating
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Design Portfolio Lightbox</title> <style> :root { --primary-color: #f0f0f0; --secondary-color: #e0e0e0; --text-color: #333; --accent-color: #989898; --overlay-bg: rgba(255, 255, 255, 0.3); --transition-speed: 0.4s; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; } body { background-color: var(--primary-color); color: var(--text-color); overflow-x: hidden; line-height: 1.6; height: 100vh; width: 100%; display: flex; flex-direction: column; } header { padding: 20px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid var(--secondary-color); } .logo { font-weight: 700; font-size: 1.2rem; letter-spacing: 1px; position: relative; } .logo::after { content: ""; position: absolute; bottom: -2px; left: 0; width: 0; height: 2px; background-color: var(--text-color); transition: width var(--transition-speed) ease; } .logo:hover::after { width: 100%; } nav ul { display: flex; list-style: none; gap: 20px; } nav a { text-decoration: none; color: var(--text-color); font-size: 0.9rem; position: relative; padding: 2px 0; opacity: 0.7; transition: opacity var(--transition-speed) ease; } nav a:hover { opacity: 1; } nav a::after { content: ""; position: absolute; bottom: 0; left: 0; width: 0; height: 1px; background-color: var(--text-color); transition: width var(--transition-speed) ease; } nav a:hover::after { width: 100%; } main { flex: 1; padding: 20px; display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 20px; max-width: 1200px; margin: 0 auto; width: 100%; } .intro { grid-column: 1 / -1; margin-bottom: 10px; } .intro h1 { font-size: 1.8rem; font-weight: 700; margin-bottom: 10px; letter-spacing: -0.5px; } .intro p { max-width: 600px; color: #666; font-size: 0.95rem; } .portfolio-item { aspect-ratio: 1 / 1; overflow: hidden; position: relative; border-radius: 4px; cursor: pointer; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05); transition: transform var(--transition-speed) ease, box-shadow var(--transition-speed) ease; } .portfolio-item:hover { transform: translateY(-5px); box-shadow: 0 10px 20px rgba(0, 0, 0, 0.08); } .portfolio-item img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--transition-speed) ease; } .portfolio-item:hover img { transform: scale(1.05); } .item-overlay { position: absolute; bottom: 0; left: 0; width: 100%; padding: 15px; background: linear-gradient(to top, rgba(0, 0, 0, 0.7), transparent); color: white; opacity: 0; transform: translateY(10px); transition: opacity var(--transition-speed) ease, transform var(--transition-speed) ease; } .portfolio-item:hover .item-overlay { opacity: 1; transform: translateY(0); } .item-overlay h3 { font-size: 0.9rem; margin-bottom: 5px; } .item-overlay p { font-size: 0.75rem; opacity: 0.9; } /* Lightbox Styling */ .lightbox { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 1000; display: flex; align-items: center; justify-content: center; opacity: 0; visibility: hidden; transition: opacity var(--transition-speed) ease, visibility var(--transition-speed) ease; backdrop-filter: blur(0px); -webkit-backdrop-filter: blur(0px); } .lightbox.active { opacity: 1; visibility: visible; backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); } .lightbox-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: var(--overlay-bg); cursor: pointer; } .lightbox-content { position: relative; z-index: 1001; background-color: white; padding: 20px; border-radius: 8px; box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15); width: 90%; max-width: 600px; max-height: 90vh; overflow-y: auto; transform: translateY(20px); opacity: 0; transition: transform var(--transition-speed) ease, opacity var(--transition-speed) ease; } .lightbox.active .lightbox-content { transform: translateY(0); opacity: 1; } .lightbox-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 20px; } .lightbox-title { font-size: 1.4rem; font-weight: 700; letter-spacing: -0.5px; } .lightbox-close { background: none; border: none; cursor: pointer; color: var(--text-color); font-size: 1.5rem; line-height: 1; padding: 5px; transition: transform var(--transition-speed) ease; } .lightbox-close:hover { transform: rotate(90deg); } .lightbox-image { width: 100%; border-radius: 4px; margin-bottom: 20px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05); } .lightbox-description { margin-bottom: 20px; } .lightbox-description h3 { font-size: 1rem; margin-bottom: 8px; color: #555; } .lightbox-description p { font-size: 0.9rem; line-height: 1.7; color: #666; } .lightbox-meta { display: flex; gap: 20px; font-size: 0.8rem; color: #888; padding-top: 20px; border-top: 1px solid var(--secondary-color); } .meta-item span { color: var(--text-color); font-weight: 600; } .lightbox-nav { display: flex; justify-content: space-between; margin-top: 20px; } .nav-button { background: none; border: 1px solid var(--secondary-color); padding: 8px 15px; border-radius: 20px; cursor: pointer; font-size: 0.8rem; transition: background-color var(--transition-speed) ease, color var(--transition-speed) ease; display: flex; align-items: center; gap: 8px; } .nav-button:hover { background-color: var(--text-color); color: white; } .nav-prev::before { content: "←"; } .nav-next::after { content: "→"; } @media (max-width: 768px) { main { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 15px; padding: 15px; } .intro h1 { font-size: 1.5rem; } .lightbox-content { padding: 15px; } .lightbox-title { font-size: 1.2rem; } nav ul { gap: 15px; } } @media (max-width: 500px) { header { flex-direction: column; gap: 15px; align-items: flex-start; } nav ul { width: 100%; justify-content: space-between; } .intro p { font-size: 0.85rem; } } /* Unique cursors feature */ .custom-cursor { position: fixed; width: 20px; height: 20px; border-radius: 50%; pointer-events: none; z-index: 9999; mix-blend-mode: difference; transform: translate(-50%, -50%); transition: transform 0.1s ease; background-color: white; opacity: 0.6; } .cursor-follower { position: fixed; width: 40px; height: 40px; border: 1px solid rgba(255, 255, 255, 0.3); border-radius: 50%; pointer-events: none; z-index: 9998; mix-blend-mode: difference; transform: translate(-50%, -50%); transition: transform 0.3s ease, width 0.3s ease, height 0.3s ease; } .portfolio-item:hover ~ .custom-cursor { transform: translate(-50%, -50%) scale(1.5); background-color: white; } .portfolio-item:hover ~ .cursor-follower { transform: translate(-50%, -50%) scale(0.5); border-color: rgba(255, 255, 255, 0.5); } </style> </head> <body> <div class="custom-cursor"></div> <div class="cursor-follower"></div> <header> <div class="logo">ATELIER</div> <nav> <ul> <li><a href="#">Work</a></li> <li><a href="#">About</a></li> <li><a href="#">Process</a></li> <li><a href="#">Contact</a></li> </ul> </nav> </header> <main> <div class="intro"> <h1>Curated Design Portfolio</h1> <p>A collection of thoughtfully crafted visual experiences that balance form and function. Each project represents a unique challenge in composition, color theory, and communication.</p> </div> <div class="portfolio-item" data-id="1"> <img src="https://images.unsplash.com/photo-1585184394271-4c0a47dc59c9?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=500&q=80" alt="Mono Magazine"> <div class="item-overlay"> <h3>Mono Magazine</h3> <p>Editorial Design</p> </div> </div> <div class="portfolio-item" data-id="2"> <img src="https://images.unsplash.com/photo-1634986666676-ec8fd927c23d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=500&q=80" alt="Pastel Structures"> <div class="item-overlay"> <h3>Pastel Structures</h3> <p>Brand Identity</p> </div> </div> <div class="portfolio-item" data-id="3"> <img src="https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=500&q=80" alt="Minimalist Space"> <div class="item-overlay"> <h3>Minimalist Space</h3> <p>Interior Concept</p> </div> </div> <div class="portfolio-item" data-id="4"> <img src="https://images.unsplash.com/photo-1567016376408-0226e4d0c1ea?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=500&q=80" alt="Soft Curves"> <div class="item-overlay"> <h3>Soft Curves</h3> <p>Product Design</p> </div> </div> <div class="portfolio-item" data-id="5"> <img src="https://images.unsplash.com/photo-1611464908623-07f19927264e?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=500&q=80" alt="Tonal Balance"> <div class="item-overlay"> <h3>Tonal Balance</h3> <p>Photography Series</p> </div> </div> <div class="portfolio-item" data-id="6"> <img src="https://images.unsplash.com/photo-1602849087467-35675f4959c2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=500&q=80" alt="Neutrals Collection"> <div class="item-overlay"> <h3>Neutrals Collection</h3> <p>Digital Art</p> </div> </div> </main> <div class="lightbox"> <div class="lightbox-overlay"></div> <div class="lightbox-content"> <div class="lightbox-header"> <h2 class="lightbox-title">Project Title</h2> <button class="lightbox-close">×</button> </div> <img class="lightbox-image" src="" alt="Project Image"> <div class="lightbox-description"> <h3>About this project</h3> <p>Project description goes here.</p> </div> <div class="lightbox-meta"> <div class="meta-item">Client: <span class="meta-client">Client Name</span></div> <div class="meta-item">Year: <span class="meta-year">2023</span></div> <div class="meta-item">Role: <span class="meta-role">Design</span></div> </div> <div class="lightbox-nav"> <button class="nav-button nav-prev">Previous</button> <button class="nav-button nav-next">Next</button> </div> </div> </div> <script> // Project data const projects = [ { id: 1, title: "Mono Magazine", image: "https://images.unsplash.com/photo-1585184394271-4c0a47dc59c9?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80", description: "A minimalist editorial design focusing on typography and whitespace. Mono Magazine is a quarterly publication that explores the intersection of design, architecture, and monochromatic aesthetics. The layout employs negative space as a design element, creating rhythm and breathing room for content.", client: "Mono Publishing", year: "2023", role: "Editorial Design" }, { id: 2, title: "Pastel Structures", image: "https://images.unsplash.com/photo-1634986666676-ec8fd927c23d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80", description: "Brand identity for an architectural visualization studio that specializes in soft, muted renderings. The visual language draws from geometric forms contrasted with gentle color gradients, creating a distinctive signature that's both professional and approachable.", client: "Artchitect Studio", year: "2022", role: "Brand Identity" }, { id: 3, title: "Minimalist Space", image: "https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80", description: "A conceptual interior design project focusing on the harmonious balance between functionality and aesthetic simplicity. Using a refined palette of materials and considerate spatial planning, this concept creates environments that feel both expansive and intimate.", client: "Essence Living", year: "2023", role: "Interior Concept" }, { id: 4, title: "Soft Curves", image: "https://images.unsplash.com/photo-1567016376408-0226e4d0c1ea?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80", description: "A product design collection that challenges the conventional sharp edges of household objects. Each piece in the collection is designed with ergonomics in mind, featuring organically rounded forms that feel natural to the touch and visually harmonious in any space.", client: "Form & Function", year: "2022", role: "Product Design" }, { id: 5, title: "Tonal Balance", image: "https://images.unsplash.com/photo-1611464908623-07f19927264e?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80", description: "A photographic exploration of light, shadow, and monochromatic compositions. This series examines how subtle variations in tone can create depth and dimension within a restrained color palette, inviting viewers to appreciate the quieter details within each frame.", client: "Personal Project", year: "2023", role: "Photography" }, { id: 6, title: "Neutrals Collection", image: "https://images.unsplash.com/photo-1602849087467-35675f4959c2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80", description: "A series of digital artworks that celebrate the subtlety of neutral colors and organic textures. These compositions explore the relationship between form, texture, and muted color to create pieces that feel both contemporary and timeless, with a focus on creating visual serenity.", client: "Gallery Monochrome", year: "2023", role: "Digital Art" } ]; // DOM elements const lightbox = document.querySelector('.lightbox'); const lightboxOverlay = document.querySelector('.lightbox-overlay'); const lightboxClose = document.querySelector('.lightbox-close'); const portfolioItems = document.querySelectorAll('.portfolio-item'); const navPrev = document.querySelector('.nav-prev'); const navNext = document.querySelector('.nav-next'); let currentProjectId = null; // Open lightbox function openLightbox(projectId) { currentProjectId = projectId; const project = projects.find(p => p.id === projectId); if (project) { // Populate lightbox content document.querySelector('.lightbox-title').textContent = project.title; document.querySelector('.lightbox-image').src = project.image; document.querySelector('.lightbox-image').alt = project.title; document.querySelector('.lightbox-description p').textContent = project.description; document.querySelector('.meta-client').textContent = project.client; document.querySelector('.meta-year').textContent = project.year; document.querySelector('.meta-role').textContent = project.role; // Show lightbox with animation lightbox.classList.add('active'); document.body.style.overflow = 'hidden'; } } // Close lightbox function closeLightbox() { lightbox.classList.remove('active'); document.body.style.overflow = ''; // Reset after animation completes setTimeout(() => { currentProjectId = null; }, 400); } // Navigate to previous project function navigateToPrev() { if (currentProjectId === null) return; let prevId = currentProjectId - 1; if (prevId < 1) { prevId = projects.length; } openLightbox(prevId); } // Navigate to next project function navigateToNext() { if (currentProjectId === null) return; let nextId = currentProjectId + 1; if (nextId > projects.length) { nextId = 1; } openLightbox(nextId); } // Event listeners portfolioItems.forEach(item => { item.addEventListener('click', () => { const projectId = parseInt(item.dataset.id); openLightbox(projectId); }); }); lightboxOverlay.addEventListener('click', closeLightbox); lightboxClose.addEventListener('click', closeLightbox); navPrev.addEventListener('click', navigateToPrev); navNext.addEventListener('click', navigateToNext); // Keyboard navigation document.addEventListener('keydown', (e) => { if (!lightbox.classList.contains('active')) return; if (e.key === 'Escape') { closeLightbox(); } else if (e.key === 'ArrowLeft') { navigateToPrev(); } else if (e.key === 'ArrowRight') { navigateToNext(); } }); // Custom cursor const cursor = document.querySelector('.custom-cursor'); const cursorFollower = document.querySelector('.cursor-follower'); document.addEventListener('mousemove', (e) => { cursor.style.left = e.clientX + 'px'; cursor.style.top = e.clientY + 'px'; // Delayed follower for smooth effect setTimeout(() => { cursorFollower.style.left = e.clientX + 'px'; cursorFollower.style.top = e.clientY + 'px'; }, 100); }); // Change cursor size on clickable elements const clickables = document.querySelectorAll('a, button, .portfolio-item'); clickables.forEach(element => { element.addEventListener('mouseenter', () => { cursor.style.transform = 'translate(-50%, -50%) scale(1.5)'; cursorFollower.style.transform = 'translate(-50%, -50%) scale(0.5)'; }); element.addEventListener('mouseleave', () => { cursor.style.transform = 'translate(-50%, -50%) scale(1)'; cursorFollower.style.transform = 'translate(-50%, -50%) scale(1)'; }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Virtual Collaboration Modal</title> <style> :root { --primary-blue: #4285f4; --accent-blue: #00b8ff; --light-blue: #e8f0fe; --dark-blue: #1a73e8; --glass-blue: rgba(66, 133, 244, 0.15); --glass-highlight: rgba(255, 255, 255, 0.25); --glass-border: rgba(255, 255, 255, 0.18); --text-primary: #202124; --text-secondary: #5f6368; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; } body { 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 x="0" y="0" width="100" height="100" fill="%23f8f9fa"/><circle cx="10" cy="10" r="2" fill="%234285f41a"/><circle cx="30" cy="10" r="2" fill="%234285f41a"/><circle cx="50" cy="10" r="2" fill="%234285f41a"/><circle cx="70" cy="10" r="2" fill="%234285f41a"/><circle cx="90" cy="10" r="2" fill="%234285f41a"/><circle cx="10" cy="30" r="2" fill="%234285f41a"/><circle cx="30" cy="30" r="2" fill="%234285f41a"/><circle cx="50" cy="30" r="2" fill="%234285f41a"/><circle cx="70" cy="30" r="2" fill="%234285f41a"/><circle cx="90" cy="30" r="2" fill="%234285f41a"/><circle cx="10" cy="50" r="2" fill="%234285f41a"/><circle cx="30" cy="50" r="2" fill="%234285f41a"/><circle cx="50" cy="50" r="2" fill="%234285f41a"/><circle cx="70" cy="50" r="2" fill="%234285f41a"/><circle cx="90" cy="50" r="2" fill="%234285f41a"/><circle cx="10" cy="70" r="2" fill="%234285f41a"/><circle cx="30" cy="70" r="2" fill="%234285f41a"/><circle cx="50" cy="70" r="2" fill="%234285f41a"/><circle cx="70" cy="70" r="2" fill="%234285f41a"/><circle cx="90" cy="70" r="2" fill="%234285f41a"/><circle cx="10" cy="90" r="2" fill="%234285f41a"/><circle cx="30" cy="90" r="2" fill="%234285f41a"/><circle cx="50" cy="90" r="2" fill="%234285f41a"/><circle cx="70" cy="90" r="2" fill="%234285f41a"/><circle cx="90" cy="90" r="2" fill="%234285f41a"/></svg>'); display: flex; justify-content: center; align-items: center; min-height: 100vh; color: var(--text-primary); overflow: hidden; position: relative; padding: 20px; } .container { width: 100%; max-width: 700px; height: 680px; display: flex; flex-direction: column; overflow: hidden; position: relative; } .collaboration-app { width: 100%; height: 100%; background-color: white; border-radius: 12px; box-shadow: 0 8px 30px rgba(0, 0, 0, 0.08); overflow: hidden; display: flex; flex-direction: column; } .app-header { display: flex; align-items: center; padding: 16px 24px; background-color: white; border-bottom: 1px solid rgba(0, 0, 0, 0.06); } .app-logo { display: flex; align-items: center; gap: 10px; } .logo-icon { width: 28px; height: 28px; background: linear-gradient(135deg, var(--primary-blue), var(--accent-blue)); border-radius: 8px; position: relative; display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; } .logo-icon::before, .logo-icon::after { content: ''; position: absolute; background-color: white; } .logo-icon::before { width: 4px; height: 10px; border-radius: 2px; left: 8px; } .logo-icon::after { width: 10px; height: 4px; border-radius: 2px; top: 8px; } .logo-text { font-weight: 600; font-size: 16px; } .app-actions { margin-left: auto; display: flex; gap: 12px; } .action-btn { background: none; border: none; cursor: pointer; width: 32px; height: 32px; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: var(--text-secondary); transition: background-color 0.2s, color 0.2s; } .action-btn:hover { background-color: var(--light-blue); color: var(--primary-blue); } .collaboration-content { flex: 1; padding: 20px; display: flex; gap: 16px; overflow: auto; position: relative; } .document-preview { flex: 1; background-color: white; border-radius: 8px; border: 1px solid rgba(0, 0, 0, 0.08); height: 100%; overflow: hidden; position: relative; } .document-header { padding: 12px 16px; border-bottom: 1px solid rgba(0, 0, 0, 0.06); display: flex; align-items: center; justify-content: space-between; } .document-title { font-weight: 500; font-size: 16px; } .document-content { padding: 16px; height: calc(100% - 49px); overflow: auto; } .paragraph { margin-bottom: 16px; line-height: 1.6; color: var(--text-primary); } .heading { font-size: 20px; font-weight: 600; margin: 24px 0 16px; color: var(--text-primary); } .heading:first-child { margin-top: 0; } .participant-list { width: 70px; display: flex; flex-direction: column; gap: 16px; align-items: center; } .participant { width: 48px; height: 48px; border-radius: 50%; background-color: #f1f3f4; display: flex; align-items: center; justify-content: center; color: var(--text-primary); font-weight: 500; font-size: 18px; position: relative; cursor: pointer; transition: transform 0.2s, box-shadow 0.2s; } .participant:hover { transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); } .participant.online::after { content: ''; position: absolute; width: 12px; height: 12px; background-color: #34a853; border-radius: 50%; bottom: 0; right: 0; border: 2px solid white; } .participant:nth-child(1) { background-color: #e8f0fe; color: var(--primary-blue); } .participant:nth-child(2) { background-color: #fce8e6; color: #ea4335; } .participant:nth-child(3) { background-color: #e6f4ea; color: #34a853; } .participant:nth-child(4) { background-color: #fef6e0; color: #fbbc04; } /* Modal Styling */ .modal-backdrop { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.3); backdrop-filter: blur(8px); display: flex; justify-content: center; align-items: center; z-index: 1000; opacity: 0; pointer-events: none; transition: opacity 0.3s ease; } .modal-backdrop.active { opacity: 1; pointer-events: all; } .collaboration-modal { width: 90%; max-width: 600px; background: rgba(255, 255, 255, 0.8); backdrop-filter: blur(20px) saturate(180%); -webkit-backdrop-filter: blur(20px) saturate(180%); border-radius: 16px; border: 1px solid var(--glass-border); box-shadow: 0 15px 50px rgba(0, 0, 0, 0.12); padding: 0; transform: translateY(20px) scale(0.95); opacity: 0; transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.3s ease; overflow: hidden; position: relative; } .modal-backdrop.active .collaboration-modal { transform: translateY(0) scale(1); opacity: 1; } .modal-header { padding: 20px 24px; display: flex; align-items: center; justify-content: space-between; background: linear-gradient(135deg, rgba(66, 133, 244, 0.08), rgba(0, 184, 255, 0.08)); border-bottom: 1px solid rgba(66, 133, 244, 0.15); } .modal-title { font-size: 18px; font-weight: 600; color: var(--dark-blue); } .close-modal { background: none; border: none; width: 32px; height: 32px; border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; color: var(--text-secondary); transition: background-color 0.2s, color 0.2s; } .close-modal:hover { background-color: rgba(0, 0, 0, 0.06); color: var(--text-primary); } .modal-content { padding: 24px; } .edit-field { margin-bottom: 20px; } .field-label { display: block; margin-bottom: 8px; font-weight: 500; font-size: 14px; color: var(--text-secondary); } .edit-input, .edit-textarea { width: 100%; padding: 12px 16px; border: 1px solid rgba(0, 0, 0, 0.15); border-radius: 8px; font-size: 15px; transition: border-color 0.2s, box-shadow 0.2s; background-color: rgba(255, 255, 255, 0.9); } .edit-input:focus, .edit-textarea:focus { outline: none; border-color: var(--primary-blue); box-shadow: 0 0 0 3px rgba(66, 133, 244, 0.2); } .edit-textarea { min-height: 160px; resize: vertical; } .modal-footer { padding: 16px 24px; display: flex; justify-content: flex-end; gap: 12px; border-top: 1px solid rgba(0, 0, 0, 0.06); background-color: rgba(248, 249, 250, 0.7); } .modal-btn { padding: 10px 20px; border-radius: 8px; font-size: 14px; font-weight: 500; cursor: pointer; transition: background-color 0.2s, transform 0.1s; } .btn-secondary { background-color: transparent; border: 1px solid rgba(0, 0, 0, 0.15); color: var(--text-secondary); } .btn-secondary:hover { background-color: rgba(0, 0, 0, 0.04); } .btn-primary { background-color: var(--primary-blue); color: white; border: none; box-shadow: 0 2px 6px rgba(66, 133, 244, 0.3); } .btn-primary:hover { background-color: var(--dark-blue); box-shadow: 0 4px 12px rgba(66, 133, 244, 0.4); } .modal-btn:active { transform: translateY(1px); } /* Real-time indicator styles */ .real-time-indicator { position: absolute; bottom: 20px; left: 20px; display: flex; align-items: center; gap: 8px; padding: 6px 12px; background-color: rgba(255, 255, 255, 0.8); backdrop-filter: blur(10px); border-radius: 20px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); font-size: 13px; color: var(--text-secondary); opacity: 0; transform: translateY(10px); transition: opacity 0.3s ease, transform 0.3s ease; } .real-time-indicator.active { opacity: 1; transform: translateY(0); } .pulse { width: 10px; height: 10px; background-color: var(--accent-blue); border-radius: 50%; position: relative; } .pulse::after { content: ''; position: absolute; width: 100%; height: 100%; background-color: var(--accent-blue); border-radius: 50%; animation: pulse 1.5s infinite; opacity: 0.6; transform: scale(1); top: 0; left: 0; } @keyframes pulse { 0% { transform: scale(1); opacity: 0.6; } 70% { transform: scale(2.5); opacity: 0; } 100% { transform: scale(1); opacity: 0; } } /* Glass effect overlay for active editing */ .glass-overlay { position: absolute; width: 40px; height: 40px; border-radius: 50%; background: radial-gradient( circle, rgba(66, 133, 244, 0.15) 0%, rgba(255, 255, 255, 0) 70% ); pointer-events: none; z-index: 10; opacity: 0; transition: opacity 0.3s ease; } /* Users typing indicator */ .users-typing { position: absolute; bottom: 20px; right: 20px; padding: 8px 16px; background-color: rgba(255, 255, 255, 0.9); backdrop-filter: blur(10px); border-radius: 20px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); font-size: 13px; color: var(--text-secondary); display: flex; align-items: center; gap: 8px; opacity: 0; transform: translateY(10px); transition: opacity 0.3s ease, transform 0.3s ease; } .users-typing.active { opacity: 1; transform: translateY(0); } .typing-dots { display: flex; gap: 4px; } .typing-dot { width: 6px; height: 6px; background-color: var(--accent-blue); border-radius: 50%; opacity: 0.6; } .typing-dot:nth-child(1) { animation: dot-fade 1.4s 0s infinite; } .typing-dot:nth-child(2) { animation: dot-fade 1.4s 0.2s infinite; } .typing-dot:nth-child(3) { animation: dot-fade 1.4s 0.4s infinite; } @keyframes dot-fade { 0%, 60%, 100% { opacity: 0.6; transform: scale(1); } 30% { opacity: 1; transform: scale(1.2); } } .grid-bg { position: absolute; width: 100%; height: 100%; top: 0; left: 0; opacity: 0; transition: opacity 0.5s ease; pointer-events: none; background-size: 30px 30px; background-image: linear-gradient(to right, rgba(66, 133, 244, 0.05) 1px, transparent 1px), linear-gradient(to bottom, rgba(66, 133, 244, 0.05) 1px, transparent 1px); } .modal-backdrop.active .grid-bg { opacity: 0.3; } .edit-btn { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; background-color: transparent; border: none; border-radius: 50%; cursor: pointer; color: var(--text-secondary); transition: background-color 0.2s, color 0.2s; } .edit-btn:hover { background-color: var(--light-blue); color: var(--primary-blue); } /* Tooltip styling */ .tooltip { position: absolute; background-color: rgba(0, 0, 0, 0.8); color: white; padding: 6px 10px; border-radius: 6px; font-size: 12px; pointer-events: none; opacity: 0; transform: translateY(5px); transition: opacity 0.2s, transform 0.2s; z-index: 100; white-space: nowrap; } .tooltip.visible { opacity: 1; transform: translateY(0); } .collaboration-tools { display: flex; align-items: center; gap: 8px; } /* Responsive adjustments */ @media (max-width: 600px) { .participant-list { width: 60px; } .participant { width: 40px; height: 40px; font-size: 16px; } .collaboration-modal { width: 95%; } .modal-header { padding: 16px 20px; } .modal-content { padding: 16px; } .modal-footer { padding: 12px 16px; } .edit-input, .edit-textarea { padding: 10px 12px; } .real-time-indicator, .users-typing { bottom: 10px; font-size: 12px; padding: 4px 10px; } } /* Animation for the modal */ @keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-6px); } } .floating-element { position: absolute; width: 80px; height: 80px; border-radius: 40px; background: linear-gradient(135deg, rgba(66, 133, 244, 0.1), rgba(0, 184, 255, 0.05)); filter: blur(3px); pointer-events: none; z-index: -1; } .floating-element:nth-child(1) { top: -20px; right: 30px; animation: float 8s ease-in-out infinite; } .floating-element:nth-child(2) { bottom: 40px; left: -20px; width: 100px; height: 100px; animation: float 7s ease-in-out infinite; animation-delay: 1s; } .floating-element:nth-child(3) { bottom: -30px; right: 80px; width: 70px; height: 70px; animation: float 6s ease-in-out infinite; animation-delay: 2s; } /* Edit history thread */ .edit-history { position: absolute; top: 100px; right: -280px; width: 260px; height: calc(100% - 160px); background-color: white; border-radius: 8px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); display: flex; flex-direction: column; transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1); z-index: 100; overflow: hidden; } .edit-history.active { transform: translateX(-300px); } .history-header { padding: 12px 16px; border-bottom: 1px solid rgba(0, 0, 0, 0.06); display: flex; align-items: center; justify-content: space-between; } .history-title { font-weight: 500; font-size: 14px; } .history-list { padding: 12px; overflow: auto; flex: 1; } .history-item { padding: 10px; border-radius: 8px; background-color: var(--light-blue); margin-bottom: 8px; font-size: 13px; border-left: 3px solid var(--primary-blue); } .history-item:last-child { margin-bottom: 0; } .history-user { font-weight: 500; color: var(--primary-blue); } .history-action { color: var(--text-secondary); margin-top: 4px; font-size: 12px; } .history-time { font-size: 11px; color: var(--text-secondary); margin-top: 4px; } .edit-context { color: var(--text-primary); margin-top: 6px; padding: 6px; background-color: rgba(255, 255, 255, 0.7); border-radius: 4px; font-family: 'Roboto Mono', monospace; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .toggle-history { background: none; border: none; cursor: pointer; color: var(--primary-blue); font-size: 14px; font-weight: 500; padding: 4px 8px; border-radius: 4px; transition: background-color 0.2s; } .toggle-history:hover { background-color: var(--light-blue); } /* Cursor animation */ .custom-cursor { position: absolute; width: 30px; height: 30px; pointer-events: none; z-index: 9999; opacity: 0; transition: transform 0.05s linear; } .cursor-dot { position: absolute; width: 10px; height: 10px; background-color: var(--primary-blue); border-radius: 50%; opacity: 0.8; top: 0; left: 0; } .cursor-user { position: absolute; top: -20px; left: 10px; background-color: var(--primary-blue); color: white; padding: 2px 8px; border-radius: 10px; font-size: 11px; white-space: nowrap; } .ai-suggestion { position: absolute; bottom: 80px; left: 50%; transform: translateX(-50%) translateY(100%); background: rgba(255, 255, 255, 0.95); box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); backdrop-filter: blur(10px); border-radius: 12px; padding: 14px 20px; width: 90%; max-width: 500px; font-size: 14px; color: var(--text-primary); border: 1px solid var(--glass-border); transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.3s ease; opacity: 0; z-index: 200; } .ai-suggestion.active { transform: translateX(-50%) translateY(0); opacity: 1; } .ai-header { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; } .ai-icon { width: 20px; height: 20px; background: linear-gradient(135deg, var(--primary-blue), var(--accent-blue)); border-radius: 50%; display: flex; align-items: center; justify-content: center; color: white; font-size: 12px; font-weight: bold; } .ai-title { font-weight: 500; font-size: 14px; color: var(--dark-blue); } .ai-text { line-height: 1.5; } .ai-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 12px; } .ai-btn { background: none; border: none; font-size: 13px; padding: 4px 12px; border-radius: 4px; cursor: pointer; transition: background-color 0.2s; } .ai-btn-primary { background-color: var(--primary-blue); color: white; } .ai-btn-secondary { color: var(--text-secondary); } .ai-btn:hover { background-color: var(--dark-blue); } .ai-btn-secondary:hover { background-color: rgba(0, 0, 0, 0.06); } </style> </head> <body> <div class="container"> <div class="collaboration-app"> <div class="app-header"> <div class="app-logo"> <div class="logo-icon">C</div> <div class="logo-text">Collabspace</div> </div> <div class="app-actions"> <button class="action-btn"> <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"> <circle cx="11" cy="11" r="8"></circle> <line x1="21" y1="21" x2="16.65" y2="16.65"></line> </svg> </button> <button class="action-btn"> <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"> <path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"></path> <path d="M13.73 21a2 2 0 0 1-3.46 0"></path> </svg> </button> <button class="action-btn"> <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"> <circle cx="12" cy="12" r="3"></circle> <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path> </svg> </button> </div> </div> <div class="collaboration-content"> <div class="document-preview"> <div class="document-header"> <div class="document-title">Product Vision Document</div> <button class="edit-btn open-modal" id="editDocumentBtn"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path> <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path> </svg> </button> </div> <div class="document-content"> <div class="heading">Executive Summary</div> <p class="paragraph">Our next-generation collaboration platform will redefine remote teamwork by providing seamless, real-time document editing with an immersive user experience. The glass-inspired interface creates a focused environment while maintaining awareness of the underlying workspace.</p> <div class="heading">Key Design Principles</div> <p class="paragraph">1. <strong>Focus-driven UI:</strong> Semi-transparent modal interfaces that maintain context without distraction</p> <p class="paragraph">2. <strong>Real-time presence:</strong> Visualize collaborators' actions with subtle animation cues</p> <p class="paragraph">3. <strong>Futuristic aesthetics:</strong> Icy blue gradients, glass effects, and minimal visual noise</p> <p class="paragraph">4. <strong>Intuitive interactions:</strong> Gesture-based editing with predictive assistance</p> <div class="heading">Implementation Timeline</div> <p class="paragraph">• Phase 1: Core editing functionality with basic collaboration features (Q2 2023)</p> <p class="paragraph">• Phase 2: Enhanced real-time visualization and advanced modals (Q3 2023)</p> <p class="paragraph">• Phase 3: AI-assisted collaborative editing and analytics (Q4 2023)</p> </div> </div> <div class="participant-list"> <div class="participant online">AK</div> <div class="participant online">JD</div> <div class="participant">MS</div> <div class="participant online">RL</div> </div> </div> </div> <div class="modal-backdrop" id="modalBackdrop"> <div class="grid-bg"></div> <div class="floating-element"></div> <div class="floating-element"></div> <div class="floating-element"></div> <div class="collaboration-modal"> <div class="modal-header"> <div class="modal-title">Edit Document</div> <div class="collaboration-tools"> <button class="toggle-history" id="toggleHistory"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>URBANE - Urban Magazine</title> <style> :root { --primary: #ff4d5a; --secondary: #2a2a38; --accent: #ffb84d; --light: #f5f5f7; --dark: #121220; --header-height: 80px; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; } body { background-color: var(--dark); color: var(--light); overflow-x: hidden; max-width: 700px; margin: 0 auto; position: relative; height: 100vh; } .magazine-container { height: 100%; overflow-y: auto; scroll-behavior: smooth; position: relative; } .header { position: sticky; top: 0; z-index: 100; backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); background-color: rgba(18, 18, 32, 0.5); height: var(--header-height); display: flex; justify-content: space-between; align-items: center; padding: 0 1.5rem; transition: all 0.3s ease; border-bottom: 1px solid rgba(255, 255, 255, 0.1); } .header.scrolled { height: 60px; background-color: rgba(18, 18, 32, 0.85); } .logo { display: flex; align-items: center; gap: 0.5rem; } .logo-text { font-size: 1.5rem; font-weight: 800; letter-spacing: 1px; color: var(--light); position: relative; } .logo-text::after { content: ''; position: absolute; bottom: -4px; left: 0; width: 60%; height: 3px; background-color: var(--primary); } .nav-toggle { background: none; border: none; color: var(--light); font-size: 1.5rem; cursor: pointer; display: flex; align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: 50%; transition: all 0.2s ease; } .nav-toggle:hover { background-color: rgba(255, 255, 255, 0.1); } .nav { position: fixed; top: var(--header-height); right: -300px; width: 300px; height: calc(100vh - var(--header-height)); background-color: var(--secondary); padding: 2rem; transition: right 0.3s ease; z-index: 99; backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); background-color: rgba(42, 42, 56, 0.95); border-left: 1px solid rgba(255, 255, 255, 0.1); } .nav.open { right: 0; } .nav-list { list-style: none; display: flex; flex-direction: column; gap: 1.5rem; } .nav-item a { color: var(--light); text-decoration: none; font-size: 1.2rem; font-weight: 500; letter-spacing: 0.5px; position: relative; padding-bottom: 5px; transition: all 0.2s ease; display: block; } .nav-item a::after { content: ''; position: absolute; left: 0; bottom: 0; width: 0; height: 2px; background-color: var(--primary); transition: width 0.3s ease; } .nav-item a:hover { color: var(--primary); } .nav-item a:hover::after { width: 30%; } .hero { height: calc(100vh - var(--header-height)); min-height: 500px; position: relative; display: flex; align-items: flex-end; overflow: hidden; } .hero-image { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; z-index: -1; } .hero-content { padding: 2rem; position: relative; z-index: 1; width: 100%; transform: translateY(20px); opacity: 0; animation: fadeUp 0.8s forwards 0.2s; } .tag { display: inline-block; padding: 0.3rem 0.8rem; background-color: var(--primary); color: white; font-size: 0.8rem; font-weight: 600; letter-spacing: 1px; text-transform: uppercase; margin-bottom: 1rem; border-radius: 3px; } .hero-title { font-size: 2.5rem; font-weight: 800; line-height: 1.2; margin-bottom: 1rem; color: var(--light); transition: all 0.3s ease; } .hero-subtitle { font-size: 1.1rem; font-weight: 400; line-height: 1.5; margin-bottom: 1.5rem; color: rgba(255, 255, 255, 0.8); max-width: 90%; } .hero-cta { display: inline-block; padding: 0.8rem 1.5rem; background-color: var(--accent); color: var(--dark); text-decoration: none; font-weight: 600; border-radius: 3px; transition: all 0.2s ease; transform: translateZ(0); position: relative; overflow: hidden; } .hero-cta::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(255, 255, 255, 0.2); transform: translateX(-100%); transition: transform 0.3s ease; z-index: -1; } .hero-cta:hover::before { transform: translateX(0); } .content-section { padding: 4rem 2rem; } .section-title { font-size: 1.8rem; font-weight: 700; margin-bottom: 2rem; color: var(--light); position: relative; display: inline-block; } .section-title::after { content: ''; position: absolute; bottom: -10px; left: 0; width: 60px; height: 3px; background-color: var(--primary); } .articles { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 2rem; } .article-card { background-color: rgba(42, 42, 56, 0.5); border-radius: 8px; overflow: hidden; transition: all 0.3s ease; transform: translateY(0); position: relative; } .article-card:hover { transform: translateY(-5px); box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2); } .article-image { width: 100%; height: 180px; object-fit: cover; } .article-content { padding: 1.5rem; } .article-tag { display: inline-block; padding: 0.2rem 0.6rem; background-color: var(--primary); color: white; font-size: 0.7rem; font-weight: 600; letter-spacing: 1px; text-transform: uppercase; margin-bottom: 0.8rem; border-radius: 3px; } .article-title { font-size: 1.2rem; font-weight: 700; margin-bottom: 0.5rem; color: var(--light); line-height: 1.3; } .article-excerpt { font-size: 0.9rem; color: rgba(255, 255, 255, 0.7); line-height: 1.5; margin-bottom: 1rem; } .article-meta { display: flex; align-items: center; gap: 1rem; font-size: 0.8rem; color: rgba(255, 255, 255, 0.5); } .article-author { display: flex; align-items: center; gap: 0.5rem; } .author-avatar { width: 24px; height: 24px; border-radius: 50%; object-fit: cover; } /* Animations */ @keyframes fadeUp { to { opacity: 1; transform: translateY(0); } } .nav-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); opacity: 0; visibility: hidden; transition: all 0.3s ease; backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); z-index: 98; } .nav-overlay.active { opacity: 1; visibility: visible; } .newsletter { background-color: rgba(42, 42, 56, 0.7); padding: 2rem; border-radius: 8px; margin-top: 4rem; border: 1px solid rgba(255, 255, 255, 0.1); } .newsletter-title { font-size: 1.5rem; font-weight: 700; margin-bottom: 1rem; color: var(--light); } .newsletter-description { font-size: 1rem; color: rgba(255, 255, 255, 0.7); line-height: 1.5; margin-bottom: 1.5rem; } .newsletter-form { display: flex; gap: 0.5rem; } .newsletter-input { flex: 1; padding: 0.8rem 1rem; background-color: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 4px; color: var(--light); font-size: 1rem; transition: all 0.2s ease; } .newsletter-input:focus { outline: none; border-color: var(--primary); background-color: rgba(255, 255, 255, 0.15); } .newsletter-button { padding: 0.8rem 1.5rem; background-color: var(--primary); color: white; border: none; border-radius: 4px; font-weight: 600; cursor: pointer; transition: all 0.2s ease; } .newsletter-button:hover { background-color: #e6404a; } .scroll-indicator { position: absolute; bottom: 2rem; left: 50%; transform: translateX(-50%); display: flex; flex-direction: column; align-items: center; gap: 0.5rem; z-index: 2; opacity: 0.8; transition: all 0.2s ease; } .scroll-text { font-size: 0.8rem; font-weight: 500; text-transform: uppercase; letter-spacing: 1px; color: var(--light); } .scroll-icon { width: 30px; height: 50px; border: 2px solid var(--light); border-radius: 15px; position: relative; display: flex; justify-content: center; } .scroll-dot { width: 6px; height: 6px; background-color: var(--light); border-radius: 50%; position: absolute; top: 10px; animation: scrollDown 2s infinite; } @keyframes scrollDown { 0% { transform: translateY(0); opacity: 1; } 80% { opacity: 0; } 100% { transform: translateY(25px); opacity: 0; } } .gradient-overlay { position: absolute; bottom: 0; left: 0; width: 100%; height: 60%; background: linear-gradient(to top, rgba(18, 18, 32, 0.9), transparent); z-index: 0; } @media (max-width: 600px) { .hero-title { font-size: 2rem; } .hero-subtitle { font-size: 1rem; max-width: 100%; } .content-section { padding: 3rem 1.5rem; } .articles { grid-template-columns: 1fr; } .newsletter-form { flex-direction: column; } .newsletter-button { width: 100%; } } </style> </head> <body> <div class="magazine-container"> <header class="header"> <div class="logo"> <span class="logo-text">URBANE</span> </div> <button class="nav-toggle" id="navToggle"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M3 12H21" stroke="currentColor" stroke-width="2" stroke-linecap="round"/> <path d="M3 6H21" stroke="currentColor" stroke-width="2" stroke-linecap="round"/> <path d="M3 18H21" stroke="currentColor" stroke-width="2" stroke-linecap="round"/> </svg> </button> </header> <nav class="nav" id="nav"> <ul class="nav-list"> <li class="nav-item"><a href="#features">Features</a></li> <li class="nav-item"><a href="#architecture">Architecture</a></li> <li class="nav-item"><a href="#street-culture">Street Culture</a></li> <li class="nav-item"><a href="#photography">Photography</a></li> <li class="nav-item"><a href="#city-guides">City Guides</a></li> <li class="nav-item"><a href="#about">About</a></li> </ul> </nav> <div class="nav-overlay" id="navOverlay"></div> <section class="hero"> <img src="https://images.unsplash.com/photo-1558469050-62a34bb35b29?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80" alt="Urban cityscape at sunset" class="hero-image"> <div class="gradient-overlay"></div> <div class="hero-content"> <span class="tag">Featured Story</span> <h1 class="hero-title">The Architecture of Sound in Urban Spaces</h1> <p class="hero-subtitle">How designers are reimagining city acoustics to create more harmonious urban environments through innovative sound mapping.</p> <a href="#" class="hero-cta">Read Feature</a> </div> <div class="scroll-indicator"> <span class="scroll-text">Scroll</span> <div class="scroll-icon"> <span class="scroll-dot"></span> </div> </div> </section> <section class="content-section" id="features"> <h2 class="section-title">Latest Features</h2> <div class="articles"> <article class="article-card"> <img src="https://images.unsplash.com/photo-1542145748-72b437c63878?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80" alt="Brutalist architecture" class="article-image"> <div class="article-content"> <span class="article-tag">Architecture</span> <h3 class="article-title">Brutalism's Urban Renaissance in Modern City Centers</h3> <p class="article-excerpt">How concrete giants from the 60s and 70s are finding new life through thoughtful restoration and adaptive reuse.</p> <div class="article-meta"> <div class="article-author"> <img src="https://randomuser.me/api/portraits/women/44.jpg" alt="Author avatar" class="author-avatar"> <span>Elisa Chen</span> </div> <span>6 min read</span> </div> </div> </article> <article class="article-card"> <img src="https://images.unsplash.com/photo-1516450360452-9312f5463ebb?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80" alt="Urban street art" class="article-image"> <div class="article-content"> <span class="article-tag">Street Culture</span> <h3 class="article-title">The Political Canvas: Street Art as Urban Dialogue</h3> <p class="article-excerpt">Exploring how muralists are transforming public discourse through large-scale visual commentary in city spaces.</p> <div class="article-meta"> <div class="article-author"> <img src="https://randomuser.me/api/portraits/men/32.jpg" alt="Author avatar" class="author-avatar"> <span>Marcus Rivera</span> </div> <span>8 min read</span> </div> </div> </article> </div> <div class="newsletter"> <h3 class="newsletter-title">Stay Connected to the Urban Pulse</h3> <p class="newsletter-description">Join our community of urban enthusiasts. Get weekly insights on architecture, design, city culture, and innovation delivered to your inbox.</p> <form class="newsletter-form" id="newsletter-form"> <input type="email" placeholder="Your email address" class="newsletter-input" required> <button type="button" class="newsletter-button" id="newsletter-button">Subscribe</button> </form> </div> </section> </div> <script> // Header scroll effect const header = document.querySelector('.header'); const magazineContainer = document.querySelector('.magazine-container'); magazineContainer.addEventListener('scroll', () => { if (magazineContainer.scrollTop > 50) { header.classList.add('scrolled'); } else { header.classList.remove('scrolled'); } }); // Mobile navigation const navToggle = document.getElementById('navToggle'); const nav = document.getElementById('nav'); const navOverlay = document.getElementById('navOverlay'); navToggle.addEventListener('click', () => { nav.classList.toggle('open'); navOverlay.classList.toggle('active'); document.body.style.overflow = nav.classList.contains('open') ? 'hidden' : 'auto'; }); navOverlay.addEventListener('click', () => { nav.classList.remove('open'); navOverlay.classList.remove('active'); document.body.style.overflow = 'auto'; }); // Scroll indicator click const scrollIndicator = document.querySelector('.scroll-indicator'); scrollIndicator.addEventListener('click', () => { const featuresSection = document.getElementById('features'); featuresSection.scrollIntoView({ behavior: 'smooth' }); }); // Newsletter form handling const newsletterForm = document.getElementById('newsletter-form'); const newsletterButton = document.getElementById('newsletter-button'); const newsletterInput = document.querySelector('.newsletter-input'); newsletterButton.addEventListener('click', (e) => { e.preventDefault(); if (newsletterInput.value.trim() === '') { newsletterInput.style.borderColor = '#ff4d5a'; newsletterInput.focus(); return; } // Simulate successful subscription newsletterButton.textContent = 'Subscribed!'; newsletterButton.style.backgroundColor = '#4CAF50'; newsletterInput.value = ''; setTimeout(() => { newsletterButton.textContent = 'Subscribe'; newsletterButton.style.backgroundColor = ''; }, 3000); }); // Intersection Observer for scroll animations const observerOptions = { threshold: 0.1, rootMargin: '0px 0px -50px 0px' }; const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.style.opacity = '1'; entry.target.style.transform = 'translateY(0)'; } }); }, observerOptions); const articleCards = document.querySelectorAll('.article-card'); articleCards.forEach(card => { card.style.opacity = '0'; card.style.transform = 'translateY(20px)'; card.style.transition = 'opacity 0.6s ease, transform 0.6s ease'; observer.observe(card); }); // Prevent actual form submission document.addEventListener('submit', (e) => { e.preventDefault(); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Wanderlux Travel Booking</title> <style> :root { --primary: #e3d5ca; --secondary: #d5bdaf; --accent: #a08c7e; --text: #3d3d3d; --light: #f5ebe0; --white: #ffffff; --shadow: rgba(0, 0, 0, 0.1); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Montserrat', sans-serif; } body { background-color: var(--light); color: var(--text); height: 100vh; width: 100%; overflow-x: hidden; max-width: 700px; margin: 0 auto; } .container { max-width: 700px; height: 700px; margin: 0 auto; padding: 0; position: relative; overflow: hidden; } .background-images { position: absolute; width: 100%; height: 100%; z-index: -1; transition: all 0.8s cubic-bezier(0.25, 1, 0.5, 1); } .bg-image { position: absolute; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity 1.5s ease; } .bg-image.active { opacity: 1; } .booking-container { padding: 2rem; height: 100%; display: flex; flex-direction: column; justify-content: flex-start; position: relative; z-index: 1; } .header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; } .logo { font-size: 1.5rem; font-weight: 700; color: var(--white); letter-spacing: 1px; text-shadow: 1px 1px 2px rgba(0,0,0,0.2); } .nav { display: flex; gap: 15px; } .nav-item { cursor: pointer; color: var(--white); font-weight: 500; font-size: 0.9rem; transition: all 0.3s ease; text-shadow: 1px 1px 2px rgba(0,0,0,0.2); } .nav-item:hover { color: var(--primary); } .booking-interface { backdrop-filter: blur(8px); background-color: rgba(255, 255, 255, 0.15); border-radius: 16px; box-shadow: 0 8px 32px var(--shadow); border: 1px solid rgba(255, 255, 255, 0.18); padding: 2rem; margin-top: 1rem; margin-bottom: 1rem; max-width: 500px; transition: backdrop-filter 0.5s ease, transform 0.5s ease; } .booking-interface:hover { backdrop-filter: blur(12px); transform: translateY(-5px); } .booking-tabs { display: flex; gap: 10px; margin-bottom: 1.5rem; } .tab { padding: 8px 16px; border-radius: 20px; font-size: 0.9rem; font-weight: 600; cursor: pointer; transition: all 0.3s ease; background-color: rgba(255, 255, 255, 0.25); color: var(--white); border: none; } .tab.active { background-color: rgba(255, 255, 255, 0.6); color: var(--text); } .form-group { margin-bottom: 1.2rem; } .form-label { display: block; margin-bottom: 0.5rem; font-weight: 500; color: var(--white); font-size: 0.9rem; text-shadow: 1px 1px 1px rgba(0,0,0,0.1); } .form-input { width: 100%; padding: 0.8rem; border-radius: 8px; border: 1px solid rgba(255, 255, 255, 0.3); background-color: rgba(255, 255, 255, 0.2); color: var(--text); font-size: 0.9rem; transition: all 0.3s ease; } .form-input:focus { outline: none; background-color: rgba(255, 255, 255, 0.3); border-color: var(--primary); } .form-input::placeholder { color: rgba(255, 255, 255, 0.7); } .date-inputs { display: flex; gap: 10px; } .date-inputs .form-group { flex: 1; } .search-btn { background: linear-gradient(135deg, var(--secondary) 0%, var(--accent) 100%); color: var(--white); border: none; padding: 0.8rem 1.5rem; border-radius: 8px; font-weight: 600; cursor: pointer; transition: all 0.3s ease; width: 100%; margin-top: 0.5rem; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); } .search-btn:hover { transform: translateY(-3px); box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15); } .destination-cards { display: none; gap: 15px; overflow-x: auto; margin-top: 2rem; padding-bottom: 1rem; scrollbar-width: none; scroll-behavior: smooth; max-width: 100%; } .destination-cards::-webkit-scrollbar { display: none; } .destination-card { flex: 0 0 auto; width: 180px; height: 220px; border-radius: 12px; overflow: hidden; position: relative; box-shadow: 0 6px 15px rgba(0, 0, 0, 0.1); cursor: pointer; transition: transform 0.4s ease, box-shadow 0.4s ease; } .destination-card:hover { transform: translateY(-5px) scale(1.02); box-shadow: 0 12px 25px rgba(0, 0, 0, 0.15); } .destination-img { width: 100%; height: 100%; object-fit: cover; } .destination-overlay { position: absolute; bottom: 0; left: 0; right: 0; padding: 15px; background: linear-gradient(to top, rgba(0, 0, 0, 0.7), transparent); color: var(--white); } .destination-name { font-weight: 600; font-size: 1rem; margin-bottom: 5px; } .destination-price { font-size: 0.8rem; opacity: 0.9; } .tab-content { display: none; } .tab-content.active { display: block; } .scroll-indicator { display: flex; justify-content: center; gap: 8px; margin-top: 1rem; } .scroll-dot { width: 8px; height: 8px; border-radius: 50%; background-color: rgba(255, 255, 255, 0.3); transition: all 0.3s ease; } .scroll-dot.active { background-color: var(--white); transform: scale(1.2); } @media (max-width: 600px) { .booking-container { padding: 1rem; } .booking-interface { padding: 1.5rem; } .tab { padding: 6px 12px; font-size: 0.8rem; } .date-inputs { flex-direction: column; gap: 5px; } } .floating-bubbles { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 0; } .bubble { position: absolute; border-radius: 50%; background: rgba(255, 255, 255, 0.1); backdrop-filter: blur(1px); box-shadow: 0 8px 32px rgba(255, 255, 255, 0.05); animation: float 8s infinite ease-in-out; opacity: 0.7; } @keyframes float { 0%, 100% { transform: translateY(0) rotate(0deg); } 50% { transform: translateY(-20px) rotate(180deg); } } .spinner { width: 24px; height: 24px; border: 3px solid rgba(255, 255, 255, 0.3); border-radius: 50%; border-top-color: var(--white); animation: spin 1s linear infinite; display: none; margin: 0 auto; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .success-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.6); backdrop-filter: blur(5px); display: flex; justify-content: center; align-items: center; z-index: 100; opacity: 0; pointer-events: none; transition: opacity 0.5s ease; } .success-modal { background-color: var(--white); padding: 2rem; border-radius: 12px; text-align: center; max-width: 400px; transform: translateY(20px); transition: transform 0.5s ease; } .success-overlay.active { opacity: 1; pointer-events: auto; } .success-overlay.active .success-modal { transform: translateY(0); } .success-title { font-size: 1.4rem; margin-bottom: 1rem; color: var(--accent); } .success-message { margin-bottom: 1.5rem; line-height: 1.6; color: var(--text); } .close-btn { background-color: var(--accent); color: var(--white); border: none; padding: 0.8rem 1.5rem; border-radius: 8px; font-weight: 600; cursor: pointer; transition: all 0.3s ease; } .close-btn:hover { background-color: var(--secondary); } .check-icon { color: var(--accent); font-size: 3rem; margin-bottom: 1rem; } </style> </head> <body> <div class="container"> <div class="background-images"> <img src="https://images.unsplash.com/photo-1530789253388-582c481c54b0?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8Mnx8c2FudG9yaW5pfGVufDB8fDB8fHww&auto=format&fit=crop&w=1200&q=80" alt="Santorini, Greece" class="bg-image active"> <img src="https://images.unsplash.com/photo-1516483638261-f4dbaf036963?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8M3x8aXRhbHl8ZW58MHx8MHx8fDA%3D&auto=format&fit=crop&w=1200&q=80" alt="Amalfi Coast, Italy" class="bg-image"> <img src="https://images.unsplash.com/photo-1596422846543-75c6fc197f11?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8NXx8bWFsZGl2ZXN8ZW58MHx8MHx8fDA%3D&auto=format&fit=crop&w=1200&q=80" alt="Maldives" class="bg-image"> <img src="https://images.unsplash.com/photo-1502602898657-3e91760cbb34?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8Mnx8cGFyaXN8ZW58MHx8MHx8fDA%3D&auto=format&fit=crop&w=1200&q=80" alt="Paris, France" class="bg-image"> </div> <div class="floating-bubbles"> <div class="bubble" style="width: 80px; height: 80px; left: 10%; top: 20%; animation-delay: 0s;"></div> <div class="bubble" style="width: 50px; height: 50px; left: 80%; top: 60%; animation-delay: 1s;"></div> <div class="bubble" style="width: 65px; height: 65px; left: 60%; top: 30%; animation-delay: 2s;"></div> <div class="bubble" style="width: 40px; height: 40px; left: 30%; top: 70%; animation-delay: 3s;"></div> <div class="bubble" style="width: 100px; height: 100px; left: 70%; top: 15%; animation-delay: 4s;"></div> </div> <div class="booking-container"> <div class="header"> <div class="logo">WanderLux</div> <div class="nav"> <div class="nav-item">Home</div> <div class="nav-item">Destinations</div> <div class="nav-item">About</div> </div> </div> <div class="booking-interface"> <div class="booking-tabs"> <button class="tab active" data-tab="flights">Flights</button> <button class="tab" data-tab="hotels">Hotels</button> <button class="tab" data-tab="experiences">Experiences</button> </div> <div class="tab-content active" id="flights"> <div class="form-group"> <label class="form-label">Departure City</label> <input type="text" class="form-input" placeholder="Where are you leaving from?" id="departure-input"> </div> <div class="form-group"> <label class="form-label">Destination</label> <input type="text" class="form-input" placeholder="Where do you want to go?" id="destination-input"> </div> <div class="date-inputs"> <div class="form-group"> <label class="form-label">Departing</label> <input type="date" class="form-input" id="depart-date"> </div> <div class="form-group"> <label class="form-label">Returning</label> <input type="date" class="form-input" id="return-date"> </div> </div> <div class="form-group"> <label class="form-label">Travelers</label> <input type="number" class="form-input" min="1" value="1" id="travelers-input"> </div> <button class="search-btn" id="search-btn"> <span>Find Your Adventure</span> <div class="spinner"></div> </button> </div> <div class="tab-content" id="hotels"> <div class="form-group"> <label class="form-label">Destination</label> <input type="text" class="form-input" placeholder="Where do you want to stay?"> </div> <div class="date-inputs"> <div class="form-group"> <label class="form-label">Check-in</label> <input type="date" class="form-input"> </div> <div class="form-group"> <label class="form-label">Check-out</label> <input type="date" class="form-input"> </div> </div> <div class="form-group"> <label class="form-label">Guests & Rooms</label> <input type="text" class="form-input" placeholder="2 guests, 1 room"> </div> <button class="search-btn">Find Perfect Stay</button> </div> <div class="tab-content" id="experiences"> <div class="form-group"> <label class="form-label">Location</label> <input type="text" class="form-input" placeholder="Where do you want to explore?"> </div> <div class="form-group"> <label class="form-label">Dates</label> <input type="date" class="form-input"> </div> <div class="form-group"> <label class="form-label">Experience Type</label> <select class="form-input"> <option>All Experiences</option> <option>Adventure</option> <option>Cultural</option> <option>Culinary</option> <option>Relaxation</option> </select> </div> <button class="search-btn">Discover Experiences</button> </div> </div> <div class="destination-cards"> <div class="destination-card"> <img src="https://images.unsplash.com/photo-1530789253388-582c481c54b0?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8Mnx8c2FudG9yaW5pfGVufDB8fDB8fHww&auto=format&fit=crop&w=500&q=60" alt="Santorini" class="destination-img"> <div class="destination-overlay"> <div class="destination-name">Santorini, Greece</div> <div class="destination-price">From $799</div> </div> </div> <div class="destination-card"> <img src="https://images.unsplash.com/photo-1516483638261-f4dbaf036963?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8M3x8aXRhbHl8ZW58MHx8MHx8fDA%3D&auto=format&fit=crop&w=500&q=60" alt="Amalfi Coast" class="destination-img"> <div class="destination-overlay"> <div class="destination-name">Amalfi Coast, Italy</div> <div class="destination-price">From $749</div> </div> </div> <div class="destination-card"> <img src="https://images.unsplash.com/photo-1596422846543-75c6fc197f11?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8NXx8bWFsZGl2ZXN8ZW58MHx8MHx8fDA%3D&auto=format&fit=crop&w=500&q=60" alt="Maldives" class="destination-img"> <div class="destination-overlay"> <div class="destination-name">Maldives</div> <div class="destination-price">From $1,299</div> </div> </div> <div class="destination-card"> <img src="https://images.unsplash.com/photo-1502602898657-3e91760cbb34?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8Mnx8cGFyaXN8ZW58MHx8MHx8fDA%3D&auto=format&fit=crop&w=500&q=60" alt="Paris" class="destination-img"> <div class="destination-overlay"> <div class="destination-name">Paris, France</div> <div class="destination-price">From $649</div> </div> </div> <div class="destination-card"> <img src="https://images.unsplash.com/photo-1542051841857-5f90071e7989?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8Mnx8amFwYW58ZW58MHx8MHx8fDA%3D&auto=format&fit=crop&w=500&q=60" alt="Tokyo" class="destination-img"> <div class="destination-overlay"> <div class="destination-name">Tokyo, Japan</div> <div class="destination-price">From $899</div> </div> </div> </div> <div class="scroll-indicator"> <div class="scroll-dot active"></div> <div class="scroll-dot"></div> <div class="scroll-dot"></div> <div class="scroll-dot"></div> </div> </div> </div> <div class="success-overlay" id="success-overlay"> <div class="success-modal"> <div class="check-icon">✓</div> <h3 class="success-title">Your journey awaits!</h3> <p class="success-message"> We've received your travel details and are searching for the best options. You'll receive personalized recommendations via email shortly. </p> <button class="close-btn" id="close-btn">Continue exploring</button> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Tab switching const tabs = document.querySelectorAll('.tab'); const tabContents = document.querySelectorAll('.tab-content'); tabs.forEach(tab => { tab.addEventListener('click', () => { const tabId = tab.getAttribute('data-tab'); // Remove active class from all tabs and contents tabs.forEach(t => t.classList.remove('active')); tabContents.forEach(content => content.classList.remove('active')); // Add active class to current tab and content tab.classList.add('active'); document.getElementById(tabId).classList.add('active'); // Change background image based on tab const bgImages = document.querySelectorAll('.bg-image'); bgImages.forEach(img => img.classList.remove('active')); let index = 0; if (tabId === 'flights') index = 0; if (tabId === 'hotels') index = 1; if (tabId === 'experiences') index = 2; bgImages[index].classList.add('active'); }); }); // Background image rotation const bgImages = document.querySelectorAll('.bg-image'); let currentBgIndex = 0; function rotateBgImages() { bgImages.forEach(img => img.classList.remove('active')); currentBgIndex = (currentBgIndex + 1) % bgImages.length; bgImages[currentBgIndex].classList.add('active'); // Update scroll dots document.querySelectorAll('.scroll-dot').forEach((dot, index) => { dot.classList.toggle('active', index === currentBgIndex); }); } // Rotate background every 6 seconds setInterval(rotateBgImages, 6000); // Interactive destination cards const destinationCards = document.querySelector('.destination-cards'); // Show destination cards when there's some interaction const searchBtn = document.getElementById('search-btn'); searchBtn.addEventListener('click', function() { const departureInput = document.getElementById('departure-input').value; const destinationInput = document.getElementById('destination-input').value; const departDate = document.getElementById('depart-date').value; const returnDate = document.getElementById('return-date').value; if (departureInput && destinationInput && departDate && returnDate) { // Show loading spinner searchBtn.querySelector('span').style.display = 'none'; searchBtn.querySelector('.spinner').style.display = 'block'; // Simulate loading setTimeout(() => { // Hide spinner searchBtn.querySelector('span').style.display = 'inline'; searchBtn.querySelector('.spinner').style.display = 'none'; // Show success message document.getElementById('success-overlay').classList.add('active'); // Animate destination cards into view destinationCards.style.display = 'flex'; // Animate each card with delay const cards = document.querySelectorAll('.destination-card'); cards.forEach((card, index) => { card.style.opacity = '0'; card.style.transform = 'translateY(20px)'; setTimeout(() => { card.style.transition = 'opacity 0.5s ease, transform 0.5s ease'; card.style.opacity = '1'; card.style.transform = 'translateY(0)'; }, 100 * index); }); }, 1500); } }); // Close success modal document.getElementById('close-btn').addEventListener('click', function() { document.getElementById('success-overlay').classList.remove('active'); }); // Dynamic backdrop-filter effect on scroll/hover const bookingInterface = document.querySelector('.booking-interface'); bookingInterface.addEventListener('mouseenter', () => { bookingInterface.style.backdropFilter = 'blur(12px)'; }); bookingInterface.addEventListener('mouseleave', () => { bookingInterface.style.backdropFilter = 'blur(8px)'; }); // Set minimum dates for date inputs const today = new Date(); const tomorrow = new Date(today); tomorrow.setDate(tomorrow.getDate() + 1); const formatDate = (date) => { const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); return `${year}-${month}-${day}`; }; const departDate = document.getElementById('depart-date'); const returnDate = document.getElementById('return-date'); departDate.min = formatDate(today); returnDate.min = formatDate(tomorrow); departDate.addEventListener('change', () => { const selectedDate = new Date(departDate.value); const nextDay = new Date(selectedDate); nextDay.setDate(nextDay.getDate() + 1); returnDate.min = formatDate(nextDay); if (new Date(returnDate.value) <= selectedDate) { returnDate.value = formatDate(nextDay); } }); // Add dynamic hover effects to navigation items const navItems = document.querySelectorAll('.nav-item'); navItems.forEach(item => { item.addEventListener('mouseenter', () => { item.style.transform = 'translateY(-3px)'; item.style.textShadow = '0 4px 8px rgba(0,0,0,0.3)'; }); item.addEventListener('mouseleave', () => { item.style.transform = 'translateY(0)'; item.style.textShadow = '1px 1px 2px rgba(0,0,0,0.2)'; }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> :root { --color-primary: #8B4513; --color-secondary: #A57C52; --color-accent: #DAA06D; --color-background: #2B1D13; --color-text: #F9EEE2; --color-text-muted: #C9B9A8; --font-primary: 'Playfair Display', serif; --font-secondary: 'Lato', sans-serif; --transition-speed: 0.4s; } * { margin: 0; padding: 0; box-sizing: border-box; } @import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,500;0,600;0,700;1,400&family=Lato:wght@300;400;700&display=swap'); body { font-family: var(--font-secondary); background-image: url('https://images.unsplash.com/photo-1517248135467-4c7edcad34c4?ixlib=rb-4.0.3&auto=format&fit=crop&w=1350&q=80'); background-size: cover; background-position: center; color: var(--color-text); min-height: 100vh; display: flex; justify-content: center; align-items: center; padding: 10px; overflow-x: hidden; } .container { width: 100%; max-width: 700px; height: 680px; position: relative; display: flex; flex-direction: column; overflow: hidden; border-radius: 12px; box-shadow: 0 30px 60px rgba(0, 0, 0, 0.3); } .menu-background { position: absolute; width: 100%; height: 100%; top: 0; left: 0; background: rgba(43, 29, 19, 0.8); z-index: -1; backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); } .header { padding: 24px; text-align: center; border-bottom: 1px solid rgba(218, 160, 109, 0.3); } .header h1 { font-family: var(--font-primary); font-size: 2.5rem; margin-bottom: 8px; color: var(--color-accent); font-weight: 600; letter-spacing: 0.5px; position: relative; display: inline-block; } .header h1::after { content: ''; position: absolute; bottom: -10px; left: 50%; transform: translateX(-50%); width: 70px; height: 2px; background-color: var(--color-accent); } .header p { font-size: 1rem; color: var(--color-text-muted); font-style: italic; margin-top: 16px; } .nav { display: flex; justify-content: center; padding: 15px 0; background-color: rgba(43, 29, 19, 0.7); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); position: sticky; top: 0; z-index: 100; } .nav-item { padding: 8px 16px; margin: 0 8px; font-family: var(--font-secondary); font-weight: 600; font-size: 0.9rem; color: var(--color-text-muted); letter-spacing: 1px; text-transform: uppercase; cursor: pointer; transition: color var(--transition-speed), transform var(--transition-speed); position: relative; } .nav-item:hover, .nav-item.active { color: var(--color-accent); transform: translateY(-3px); } .nav-item::after { content: ''; position: absolute; bottom: 0; left: 50%; transform: translateX(-50%) scaleX(0); width: 60%; height: 2px; background-color: var(--color-accent); transition: transform var(--transition-speed); } .nav-item:hover::after, .nav-item.active::after { transform: translateX(-50%) scaleX(1); } .menu-content { flex: 1; overflow-y: auto; padding: 20px; scroll-behavior: smooth; } .menu-content::-webkit-scrollbar { width: 6px; } .menu-content::-webkit-scrollbar-track { background: rgba(0, 0, 0, 0.1); border-radius: 10px; } .menu-content::-webkit-scrollbar-thumb { background: var(--color-secondary); border-radius: 10px; } .menu-section { margin-bottom: 30px; opacity: 0; transform: translateY(20px); transition: opacity 0.6s, transform 0.6s; display: none; } .menu-section.active { display: block; opacity: 1; transform: translateY(0); } .section-title { font-family: var(--font-primary); color: var(--color-accent); font-size: 1.8rem; margin-bottom: 15px; padding-bottom: 10px; border-bottom: 1px solid rgba(218, 160, 109, 0.3); position: relative; } .section-title::before { content: ''; position: absolute; left: 0; bottom: -1px; width: 80px; height: 3px; background-color: var(--color-accent); } .menu-item { margin-bottom: 25px; background: rgba(0, 0, 0, 0.2); border-radius: 10px; padding: 16px; transition: transform var(--transition-speed), box-shadow var(--transition-speed); position: relative; overflow: hidden; cursor: pointer; } .menu-item::before { content: ''; position: absolute; top: 0; left: 0; width: 4px; height: 100%; background-color: var(--color-accent); transform: scaleY(0); transition: transform var(--transition-speed); transform-origin: top; } .menu-item:hover { transform: translateY(-5px); box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2); } .menu-item:hover::before { transform: scaleY(1); } .item-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; } .item-name { font-family: var(--font-primary); font-weight: 600; font-size: 1.2rem; color: var(--color-text); } .item-price { font-family: var(--font-secondary); font-weight: 700; font-size: 1.1rem; color: var(--color-accent); background: rgba(139, 69, 19, 0.3); padding: 4px 12px; border-radius: 20px; } .item-description { font-size: 0.9rem; line-height: 1.5; color: var(--color-text-muted); } .item-tags { display: flex; flex-wrap: wrap; margin-top: 10px; gap: 6px; } .tag { font-size: 0.7rem; padding: 3px 8px; border-radius: 4px; background: rgba(165, 124, 82, 0.3); color: var(--color-text-muted); } .order-button { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); background: var(--color-primary); color: var(--color-text); border: none; border-radius: 30px; padding: 12px 35px; font-family: var(--font-secondary); font-weight: 700; font-size: 1rem; cursor: pointer; transition: background-color var(--transition-speed), transform var(--transition-speed); outline: none; box-shadow: 0 8px 15px rgba(0, 0, 0, 0.3); z-index: 200; } .order-button:hover { background: var(--color-secondary); transform: translateX(-50%) translateY(-3px); } .order-button:active { transform: translateX(-50%) translateY(0); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); } .order-modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; background: rgba(0, 0, 0, 0.7); z-index: 300; opacity: 0; visibility: hidden; transition: opacity var(--transition-speed), visibility var(--transition-speed); backdrop-filter: blur(5px); -webkit-backdrop-filter: blur(5px); } .order-modal.active { opacity: 1; visibility: visible; } .modal-content { width: 90%; max-width: 450px; background: var(--color-background); border-radius: 12px; padding: 30px; box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4); transform: translateY(50px); opacity: 0; transition: transform var(--transition-speed), opacity var(--transition-speed); position: relative; } .order-modal.active .modal-content { transform: translateY(0); opacity: 1; } .modal-title { font-family: var(--font-primary); font-size: 1.8rem; margin-bottom: 20px; color: var(--color-accent); text-align: center; } .modal-close { position: absolute; top: 15px; right: 15px; font-size: 1.5rem; background: transparent; border: none; color: var(--color-text-muted); cursor: pointer; transition: color var(--transition-speed); } .modal-close:hover { color: var(--color-accent); } .modal-message { text-align: center; margin-bottom: 20px; line-height: 1.6; color: var(--color-text-muted); } .modal-buttons { display: flex; justify-content: center; gap: 15px; } .modal-btn { padding: 10px 20px; border-radius: 6px; font-family: var(--font-secondary); font-weight: 600; cursor: pointer; transition: background-color var(--transition-speed), transform var(--transition-speed); } .modal-btn-primary { background: var(--color-accent); color: var(--color-background); border: none; } .modal-btn-secondary { background: transparent; color: var(--color-text); border: 1px solid var(--color-accent); } .modal-btn:hover { transform: translateY(-3px); } .modal-btn-primary:hover { background: #C48E5D; } .modal-btn-secondary:hover { background: rgba(218, 160, 109, 0.1); } .highlight-card { position: relative; overflow: hidden; border-radius: 8px; margin-bottom: 25px; background: linear-gradient(to right, rgba(139, 69, 19, 0.7), rgba(43, 29, 19, 0.9)); box-shadow: 0 15px 25px rgba(0, 0, 0, 0.2); } .highlight-content { display: flex; align-items: center; padding: 15px; } .highlight-img { width: 80px; height: 80px; border-radius: 50%; object-fit: cover; border: 3px solid var(--color-accent); box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3); transform: translateZ(0); transition: transform var(--transition-speed); } .highlight-card:hover .highlight-img { transform: scale(1.1) translateZ(0); } .highlight-details { margin-left: 15px; flex: 1; } .highlight-title { font-family: var(--font-primary); font-size: 1.2rem; color: var(--color-accent); margin-bottom: 5px; } .highlight-description { font-size: 0.9rem; color: var(--color-text-muted); margin-bottom: 8px; } .highlight-price { display: inline-block; padding: 3px 10px; background: rgba(218, 160, 109, 0.3); border-radius: 20px; font-weight: 600; font-size: 0.9rem; color: var(--color-text); } .leaf-animation { position: absolute; width: 40px; height: 40px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23DAA06D' opacity='0.2'%3E%3Cpath d='M17,8C8,10,5.9,16.17,3.82,21.34L5.71,22l1-2.3A4.49,4.49,0,0,0,8,20c6,0,10-5,10-12V4h-1L17,8z'/%3E%3C/svg%3E"); background-size: contain; background-repeat: no-repeat; pointer-events: none; z-index: -1; opacity: 0; } @keyframes floatLeaf { 0% { transform: translateY(0) rotate(0deg); opacity: 0; } 10% { opacity: 0.7; } 90% { opacity: 0.3; } 100% { transform: translateY(200px) rotate(360deg); opacity: 0; } } @media (max-width: 480px) { .header h1 { font-size: 2rem; } .nav { padding: 10px 0; } .nav-item { padding: 6px 10px; margin: 0 5px; font-size: 0.8rem; } .section-title { font-size: 1.5rem; } .item-name { font-size: 1.1rem; } .item-price { font-size: 1rem; } .highlight-img { width: 60px; height: 60px; } .highlight-title { font-size: 1.1rem; } } </style> </head> <body> <div class="container"> <div class="menu-background"></div> <div class="header"> <h1>Hearth & Table</h1> <p>Farm-to-table comfort in every bite</p> </div> <div class="nav"> <div class="nav-item active" data-target="starters">Starters</div> <div class="nav-item" data-target="mains">Mains</div> <div class="nav-item" data-target="desserts">Desserts</div> <div class="nav-item" data-target="drinks">Drinks</div> </div> <div class="menu-content"> <div id="starters" class="menu-section active"> <h2 class="section-title">Starters</h2> <div class="highlight-card"> <div class="highlight-content"> <img src="https://images.unsplash.com/photo-1626082655103-0cd2b0d5a0e1?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=800&q=80" alt="Chef's Special" class="highlight-img"> <div class="highlight-details"> <h3 class="highlight-title">Chef's Special: Wild Mushroom Bruschetta</h3> <p class="highlight-description">Seasonal foraged mushrooms on freshly baked sourdough with thyme-infused ricotta</p> <span class="highlight-price">$12</span> </div> </div> </div> <div class="menu-item"> <div class="item-header"> <h3 class="item-name">Truffle Arancini</h3> <span class="item-price">$11</span> </div> <p class="item-description">Crispy risotto balls with truffle, aged parmesan, and wild mushroom, served with aioli.</p> <div class="item-tags"> <span class="tag">Vegetarian</span> <span class="tag">House Favorite</span> </div> </div> <div class="menu-item"> <div class="item-header"> <h3 class="item-name">Butternut & Sage Croquettes</h3> <span class="item-price">$9</span> </div> <p class="item-description">Roasted butternut squash and crispy sage, hand-formed and lightly fried, with maple aioli.</p> <div class="item-tags"> <span class="tag">Vegetarian</span> <span class="tag">Seasonal</span> </div> </div> <div class="menu-item"> <div class="item-header"> <h3 class="item-name">Wood-Fired Sourdough</h3> <span class="item-price">$8</span> </div> <p class="item-description">House-made 48-hour fermented sourdough, served with cultured butter and sea salt.</p> <div class="item-tags"> <span class="tag">Vegetarian</span> </div> </div> </div> <div id="mains" class="menu-section"> <h2 class="section-title">Mains</h2> <div class="highlight-card"> <div class="highlight-content"> <img src="https://images.unsplash.com/photo-1518779578993-ec3579fee39f?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=800&q=80" alt="Chef's Special" class="highlight-img"> <div class="highlight-details"> <h3 class="highlight-title">Chef's Special: Heritage Pork Chop</h3> <p class="highlight-description">Brined for 24 hours, seared & slow-roasted with autumn root vegetables and cider reduction</p> <span class="highlight-price">$32</span> </div> </div> </div> <div class="menu-item"> <div class="item-header"> <h3 class="item-name">Root Vegetable Wellington</h3> <span class="item-price">$24</span> </div> <p class="item-description">Caramelized beets, carrots and parsnips with herbed duxelles, wrapped in flaky pastry with red wine jus.</p> <div class="item-tags"> <span class="tag">Vegetarian</span> <span class="tag">Seasonal</span> </div> </div> <div class="menu-item"> <div class="item-header"> <h3 class="item-name">Cast Iron Chicken</h3> <span class="item-price">$26</span> </div> <p class="item-description">Half chicken from Willow Creek Farm, pan-roasted with garlic confit, thyme, and lemon, served with smashed potatoes.</p> <div class="item-tags"> <span class="tag">Gluten-Free</span> <span class="tag">Free-Range</span> </div> </div> <div class="menu-item"> <div class="item-header"> <h3 class="item-name">Cedar-Plank Salmon</h3> <span class="item-price">$28</span> </div> <p class="item-description">Wild-caught salmon roasted on cedar with maple glaze, served with charred brussels sprouts and pearl onions.</p> <div class="item-tags"> <span class="tag">Gluten-Free</span> <span class="tag">Omega-Rich</span> </div> </div> </div> <div id="desserts" class="menu-section"> <h2 class="section-title">Desserts</h2> <div class="highlight-card"> <div class="highlight-content"> <img src="https://images.unsplash.com/photo-1551024506-0bccd828d307?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=800&q=80" alt="Chef's Special" class="highlight-img"> <div class="highlight-details"> <h3 class="highlight-title">Chef's Special: Brown Butter Apple Tarte Tatin</h3> <p class="highlight-description">Baked with local heirloom apples and served with vanilla bean ice cream</p> <span class="highlight-price">$11</span> </div> </div> </div> <div class="menu-item"> <div class="item-header"> <h3 class="item-name">Dark Chocolate Bread Pudding</h3> <span class="item-price">$10</span> </div> <p class="item-description">Made with our day-old sourdough, dark chocolate, and hazelnuts, topped with salted caramel and crème fraîche.</p> <div class="item-tags"> <span class="tag">Vegetarian</span> <span class="tag">Contains Nuts</span> </div> </div> <div class="menu-item"> <div class="item-header"> <h3 class="item-name">Maple Crème Brûlée</h3> <span class="item-price">$9</span> </div> <p class="item-description">Local maple-infused custard with a perfectly caramelized sugar crust, served with shortbread cookies.</p> <div class="item-tags"> <span class="tag">Vegetarian</span> <span class="tag">Gluten-Free Option</span> </div> </div> <div class="menu-item"> <div class="item-header"> <h3 class="item-name">Seasonal Fruit Cobbler</h3> <span class="item-price">$10</span> </div> <p class="item-description">Warm local fruit baked with brown butter streusel topping, served with house-made vanilla ice cream.</p> <div class="item-tags"> <span class="tag">Vegetarian</span> <span class="tag">Seasonal</span> </div> </div> </div> <div id="drinks" class="menu-section"> <h2 class="section-title">Drinks</h2> <div class="highlight-card"> <div class="highlight-content"> <img src="https://images.unsplash.com/photo-1536935338788-846bb9981813?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=800&q=80" alt="Chef's Special" class="highlight-img"> <div class="highlight-details"> <h3 class="highlight-title">Signature: Smoked Cedar Old Fashioned</h3> <p class="highlight-description">Rye whiskey, maple, bitters, and orange zest with cedar smoke</p> <span class="highlight-price">$14</span> </div> </div> </div> <div class="menu-item"> <div class="item-header"> <h3 class="item-name">Orchard Spritz</h3> <span class="item-price">$12</span> </div> <p class="item-description">House-pressed apple, elderflower, prosecco, and soda water with a sprig of thyme.</p> <div class="item-tags"> <span class="tag">Seasonal</span> <span class="tag">Staff Pick</span> </div> </div> <div class="menu-item"> <div class="item-header"> <h3 class="item-name">Mulled Wine</h3> <span class="item-price">$11</span> </div> <p class="item-description">Red wine simmered with cinnamon, star anise, cloves, and orange peel, served warm.</p> <div class="item-tags"> <span class="tag">Seasonal</span> <span class="tag">Warming</span> </div> </div> <div class="menu-item"> <div class="item-header"> <h3 class="item-name">Rosemary Honey Lemonade</h3> <span class="item-price">$6</span> </div> <p class="item-description">House-made lemonade infused with rosemary and sweetened with local wildflower honey.</p> <div class="item-tags"> <span class="tag">Non-Alcoholic</span> <span class="tag">Refreshing</span> </div> </div> </div> </div> <button class="order-button">Place an Order</button> <div class="order-modal"> <div class="modal-content"> <button class="modal-close">×</button> <h2 class="modal-title">Ready to Order?</h2> <p class="modal-message">Your server will be with you shortly to take your order. Would you like to review our daily specials while you wait?</p> <div class="modal-buttons"> <button class="modal-btn modal-btn-primary">See Specials</button> <button class="modal-btn modal-btn-secondary">Close</button> </div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Navigation functionality const navItems = document.querySelectorAll('.nav-item'); const menuSections = document.querySelectorAll('.menu-section'); navItems.forEach(item => { item.addEventListener('click', function() { // Update active nav item navItems.forEach(nav => nav.classList.remove('active')); this.classList.add('active'); // Show corresponding section const targetId = this.getAttribute('data-target'); menuSections.forEach(section => { section.classList.remove('active'); if (section.id === targetId) { section.classList.add('active'); } }); }); }); // Modal functionality const orderButton = document.querySelector('.order-button'); const orderModal = document.querySelector('.order-modal'); const modalClose = document.querySelector('.modal-close'); const modalBtnSecondary = document.querySelector('.modal-btn-secondary'); const modalBtnPrimary = document.querySelector('.modal-btn-primary'); orderButton.addEventListener('click', function() { orderModal.classList.add('active'); }); function closeModal() { orderModal.classList.remove('active'); } modalClose.addEventListener('click', closeModal); modalBtnSecondary.addEventListener('click', closeModal); modalBtnPrimary.addEventListener('click', function() { // Show starters section when "See Specials" is clicked navItems.forEach(nav => nav.classList.remove('active')); navItems[0].classList.add('active'); menuSections.forEach(section => section.classList.remove('active')); document.getElementById('starters').classList.add('active'); closeModal(); }); // Close modal when clicking outside of it orderModal.addEventListener('click', function(e) { if (e.target === orderModal) { closeModal(); } }); // Leaf animation function createLeaf() { const leaf = document.createElement('div'); leaf.classList.add('leaf-animation'); // Random position across the container width const container = document.querySelector('.container'); const containerWidth = container.offsetWidth; const randomX = Math.random() * containerWidth; leaf.style.left = `${randomX}px`; leaf.style.top = '0'; leaf.style.animation = `floatLeaf ${5 + Math.random() * 5}s linear forwards`; container.appendChild(leaf); // Remove leaf after animation setTimeout(() => { leaf.remove(); }, 10000); } // Create leaves occasionally setInterval(createLeaf, 3000); // Menu item hover effect with subtle animation const menuItems = document.querySelectorAll('.menu-item'); menuItems.forEach(item => { item.addEventListener('mouseenter', function() { this.style.transition = 'transform 0.4s, box-shadow 0.4s'; }); }); }); </script> </body> </html>