The ripple effect is a fascinating phenomenon where a single action can set off a chain of events, influencing outcomes far beyond the initial impact. Understanding these examples can provide valuable insights into how interconnected our world truly is.
From environmental changes to social dynamics, the ripple effect manifests in various ways, often with surprising consequences. Here are ten compelling examples that illustrate the far-reaching impact of seemingly small actions.
CODE1
Here's the code:
CODETEXT1
CODE2
Here's the code:
CODETEXT2
CODE3
Here's the code:
CODETEXT3
CODE4
Here's the code:
CODETEXT4
CODE5
Here's the code:
CODETEXT5
Designers and developers, elevate your projects with Subframe's drag-and-drop interface and intuitive, responsive canvas. Create pixel-perfect UI effortlessly, every time. Loved by professionals, Subframe makes designing ripple effects a breeze.
Start for free and experience the magic of Subframe today!
CODE6
Here's the code:
CODETEXT6
CODE7
Here's the code:
CODETEXT7
CODE8
Here's the code:
CODETEXT8
CODE9
Here's the code:
CODETEXT9
CODE10
Here's the code:
CODETEXT10
Unlock the power of Subframe and design stunning UIs with ease. From ripple effects to pixel-perfect interfaces, Subframe's drag-and-drop editor makes it all possible.
Experience unparalleled efficiency and start creating immediately. Start for free and elevate your design game today!
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>SwiftBank Mobile App</title> <style> :root { --primary-blue: #1e88e5; --dark-blue: #0d47a1; --light-blue: #bbdefb; --extra-light-blue: #e3f2fd; --white: #ffffff; --gray: #f5f5f5; --dark-gray: #757575; --black: #212121; --shadow: 0 4px 6px rgba(0, 0, 0, 0.1); --border-radius: 12px; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; } body { background-color: var(--extra-light-blue); display: flex; justify-content: center; align-items: center; min-height: 700px; padding: 20px; overflow-x: hidden; } .app-container { width: 100%; max-width: 360px; height: 650px; background-color: var(--white); border-radius: 24px; overflow: hidden; position: relative; box-shadow: var(--shadow); display: flex; flex-direction: column; } .status-bar { height: 24px; background-color: var(--primary-blue); display: flex; justify-content: space-between; align-items: center; padding: 0 15px; color: var(--white); font-size: 12px; } .status-bar-icons { display: flex; gap: 5px; } .header { background-color: var(--primary-blue); color: var(--white); padding: 15px 20px; display: flex; justify-content: space-between; align-items: center; } .logo { display: flex; align-items: center; gap: 8px; font-weight: 600; font-size: 18px; } .logo-icon { width: 24px; height: 24px; background-color: var(--white); border-radius: 50%; display: flex; justify-content: center; align-items: center; color: var(--primary-blue); font-weight: 700; } .profile { width: 32px; height: 32px; background-color: var(--light-blue); border-radius: 50%; display: flex; justify-content: center; align-items: center; color: var(--primary-blue); font-weight: 600; cursor: pointer; transition: transform 0.2s; } .profile:hover { transform: scale(1.1); } .balance-card { background: linear-gradient(135deg, var(--primary-blue), var(--dark-blue)); color: var(--white); margin: 15px 20px; padding: 20px; border-radius: var(--border-radius); box-shadow: var(--shadow); } .balance-label { font-size: 14px; opacity: 0.8; margin-bottom: 5px; } .balance-amount { font-size: 28px; font-weight: 600; margin-bottom: 15px; } .card-details { display: flex; justify-content: space-between; font-size: 12px; opacity: 0.9; } .quick-actions { display: flex; justify-content: space-around; margin: 15px 10px; } .action-btn { display: flex; flex-direction: column; align-items: center; gap: 8px; } .action-icon { width: 48px; height: 48px; background-color: var(--extra-light-blue); border-radius: 50%; display: flex; justify-content: center; align-items: center; color: var(--primary-blue); font-size: 20px; transition: background-color 0.2s; cursor: pointer; overflow: hidden; position: relative; } .action-icon:hover { background-color: var(--light-blue); } .action-label { font-size: 12px; color: var(--dark-gray); } .recent-transactions { flex: 1; padding: 0 20px; overflow-y: auto; } .section-title { font-size: 16px; font-weight: 600; color: var(--black); margin-bottom: 15px; margin-top: 10px; } .transaction { display: flex; align-items: center; padding: 12px 0; border-bottom: 1px solid var(--gray); } .transaction-icon { width: 40px; height: 40px; background-color: var(--light-blue); border-radius: 50%; display: flex; justify-content: center; align-items: center; color: var(--primary-blue); margin-right: 12px; } .transaction-info { flex: 1; } .transaction-name { font-size: 14px; font-weight: 500; color: var(--black); margin-bottom: 2px; } .transaction-date { font-size: 12px; color: var(--dark-gray); } .transaction-amount { font-weight: 600; font-size: 15px; } .amount-negative { color: #e53935; } .amount-positive { color: #43a047; } .bottom-nav { height: 60px; display: flex; justify-content: space-around; align-items: center; background-color: var(--white); border-top: 1px solid var(--gray); } .nav-item { display: flex; flex-direction: column; align-items: center; color: var(--dark-gray); font-size: 10px; cursor: pointer; transition: color 0.2s; } .nav-item.active { color: var(--primary-blue); } .nav-icon { font-size: 20px; margin-bottom: 2px; } .ripple { position: absolute; background-color: rgba(255, 255, 255, 0.3); border-radius: 50%; transform: scale(0); animation: ripple 0.6s linear; } @keyframes ripple { to { transform: scale(2.5); opacity: 0; } } .btn { position: relative; background-color: var(--primary-blue); color: var(--white); border: none; padding: 12px 20px; border-radius: 25px; font-weight: 500; cursor: pointer; overflow: hidden; transition: background-color 0.2s; letter-spacing: 0.5px; } .btn:hover { background-color: var(--dark-blue); } .btn-outline { background-color: transparent; border: 1px solid var(--white); } .btn-outline:hover { background-color: rgba(255, 255, 255, 0.1); } .card-actions { display: flex; justify-content: space-between; margin-top: 15px; } .notification-badge { position: absolute; top: -2px; right: -2px; background-color: #f44336; color: white; font-size: 8px; width: 12px; height: 12px; border-radius: 50%; display: flex; justify-content: center; align-items: center; } .send-money-container { padding: 20px; background-color: var(--white); border-radius: var(--border-radius); box-shadow: var(--shadow); position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%) scale(0.9); width: 90%; max-width: 320px; opacity: 0; visibility: hidden; transition: all 0.3s ease; z-index: 10; } .send-money-container.active { opacity: 1; visibility: visible; transform: translate(-50%, -50%) scale(1); } .modal-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; } .modal-title { font-size: 18px; font-weight: 600; color: var(--black); } .close-btn { background: none; border: none; cursor: pointer; font-size: 20px; color: var(--dark-gray); } .input-group { margin-bottom: 15px; } .input-label { display: block; font-size: 14px; color: var(--dark-gray); margin-bottom: 5px; } .input-field { width: 100%; padding: 12px; border: 1px solid var(--light-blue); border-radius: 8px; font-size: 14px; transition: border-color 0.2s; } .input-field:focus { outline: none; border-color: var(--primary-blue); } .recent-contacts { display: flex; gap: 10px; overflow-x: auto; margin: 15px 0; padding-bottom: 5px; } .contact { display: flex; flex-direction: column; align-items: center; min-width: 60px; } .contact-avatar { width: 40px; height: 40px; border-radius: 50%; background-color: var(--light-blue); display: flex; justify-content: center; align-items: center; color: var(--primary-blue); font-weight: 600; margin-bottom: 5px; cursor: pointer; } .contact-name { font-size: 12px; color: var(--dark-gray); text-align: center; } .overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.5); opacity: 0; visibility: hidden; transition: all 0.3s ease; z-index: 5; } .overlay.active { opacity: 1; visibility: visible; } /* Pulse animation for the CTA button */ @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(30, 136, 229, 0.4); } 70% { box-shadow: 0 0 0 10px rgba(30, 136, 229, 0); } 100% { box-shadow: 0 0 0 0 rgba(30, 136, 229, 0); } } .pulse-btn { animation: pulse 2s infinite; } /* Custom scrollbar */ ::-webkit-scrollbar { width: 6px; height: 6px; } ::-webkit-scrollbar-track { background: var(--gray); border-radius: 10px; } ::-webkit-scrollbar-thumb { background: var(--light-blue); border-radius: 10px; } ::-webkit-scrollbar-thumb:hover { background: var(--primary-blue); } /* Media query for smaller screens */ @media (max-width: 370px) { .app-container { height: 600px; } .balance-amount { font-size: 24px; } .action-icon { width: 40px; height: 40px; } } </style> </head> <body> <div class="app-container"> <div class="status-bar"> <span>9:41</span> <div class="status-bar-icons"> <span>5G</span> <span>100%</span> </div> </div> <div class="header"> <div class="logo"> <div class="logo-icon">S</div> <span>SwiftBank</span> </div> <div class="profile">JD</div> </div> <div class="balance-card"> <div class="balance-label">Available Balance</div> <div class="balance-amount">$3,547.82</div> <div class="card-actions"> <button class="btn btn-outline ripple-btn">Add Money</button> <button class="btn pulse-btn ripple-btn">Send Money</button> </div> <div class="card-details"> <span>**** 4582</span> <span>Exp: 09/25</span> </div> </div> <div class="quick-actions"> <div class="action-btn"> <div class="action-icon ripple-btn"> <i>↑</i> </div> <span class="action-label">Pay</span> </div> <div class="action-btn"> <div class="action-icon ripple-btn"> <i>↓</i> </div> <span class="action-label">Request</span> </div> <div class="action-btn"> <div class="action-icon ripple-btn" style="position: relative;"> <i>✉</i> <span class="notification-badge">2</span> </div> <span class="action-label">Bills</span> </div> <div class="action-btn"> <div class="action-icon ripple-btn"> <i>≡</i> </div> <span class="action-label">More</span> </div> </div> <div class="recent-transactions"> <div class="section-title">Recent Transactions</div> <div class="transaction"> <div class="transaction-icon">☕</div> <div class="transaction-info"> <div class="transaction-name">Morning Brew Café</div> <div class="transaction-date">Today, 8:32 AM</div> </div> <div class="transaction-amount amount-negative">-$4.75</div> </div> <div class="transaction"> <div class="transaction-icon">🛒</div> <div class="transaction-info"> <div class="transaction-name">Fresh Market</div> <div class="transaction-date">Yesterday, 2:14 PM</div> </div> <div class="transaction-amount amount-negative">-$32.41</div> </div> <div class="transaction"> <div class="transaction-icon">👤</div> <div class="transaction-info"> <div class="transaction-name">Sarah Johnson</div> <div class="transaction-date">May 15, 5:30 PM</div> </div> <div class="transaction-amount amount-positive">+$125.00</div> </div> <div class="transaction"> <div class="transaction-icon">🏙️</div> <div class="transaction-info"> <div class="transaction-name">Urban Apartments</div> <div class="transaction-date">May 1, 9:00 AM</div> </div> <div class="transaction-amount amount-negative">-$1,200.00</div> </div> <div class="transaction"> <div class="transaction-icon">💼</div> <div class="transaction-info"> <div class="transaction-name">Payroll - TechCorp</div> <div class="transaction-date">April 30, 10:05 AM</div> </div> <div class="transaction-amount amount-positive">+$3,250.00</div> </div> </div> <div class="bottom-nav"> <div class="nav-item active"> <div class="nav-icon">🏠</div> <span>Home</span> </div> <div class="nav-item"> <div class="nav-icon">📊</div> <span>Statistics</span> </div> <div class="nav-item"> <div class="nav-icon">💳</div> <span>Cards</span> </div> <div class="nav-item"> <div class="nav-icon">⚙️</div> <span>Settings</span> </div> </div> </div> <div class="overlay" id="overlay"></div> <div class="send-money-container" id="sendMoneyModal"> <div class="modal-header"> <div class="modal-title">Send Money</div> <button class="close-btn" id="closeModal">×</button> </div> <div class="input-group"> <label class="input-label">Recent Contacts</label> <div class="recent-contacts"> <div class="contact"> <div class="contact-avatar ripple-btn">SJ</div> <div class="contact-name">Sarah</div> </div> <div class="contact"> <div class="contact-avatar ripple-btn">TK</div> <div class="contact-name">Tom</div> </div> <div class="contact"> <div class="contact-avatar ripple-btn">MR</div> <div class="contact-name">Mike</div> </div> <div class="contact"> <div class="contact-avatar ripple-btn">LW</div> <div class="contact-name">Lisa</div> </div> <div class="contact"> <div class="contact-avatar ripple-btn">+</div> <div class="contact-name">Add New</div> </div> </div> </div> <div class="input-group"> <label class="input-label" for="recipient">Recipient Email or Phone</label> <input type="text" id="recipient" class="input-field" placeholder="[email protected]"> </div> <div class="input-group"> <label class="input-label" for="amount">Amount</label> <input type="text" id="amount" class="input-field" placeholder="$0.00"> </div> <div class="input-group"> <label class="input-label" for="note">Note (Optional)</label> <input type="text" id="note" class="input-field" placeholder="Add a note..."> </div> <button class="btn ripple-btn" style="width: 100%;">Send Payment</button> </div> <script> // Ripple effect for all buttons with ripple-btn class document.addEventListener('DOMContentLoaded', function() { const rippleElements = document.querySelectorAll('.ripple-btn, .action-icon, .nav-item'); rippleElements.forEach(element => { element.addEventListener('click', function(e) { const rect = this.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; const ripple = document.createElement('span'); ripple.classList.add('ripple'); ripple.style.left = x + 'px'; ripple.style.top = y + 'px'; this.appendChild(ripple); setTimeout(() => { ripple.remove(); }, 600); }); }); // Handle send money modal const sendMoneyBtn = document.querySelector('.pulse-btn'); const overlay = document.getElementById('overlay'); const sendMoneyModal = document.getElementById('sendMoneyModal'); const closeModalBtn = document.getElementById('closeModal'); sendMoneyBtn.addEventListener('click', function() { overlay.classList.add('active'); sendMoneyModal.classList.add('active'); }); closeModalBtn.addEventListener('click', function() { overlay.classList.remove('active'); sendMoneyModal.classList.remove('active'); }); overlay.addEventListener('click', function() { overlay.classList.remove('active'); sendMoneyModal.classList.remove('active'); }); // Nav item click handler const navItems = document.querySelectorAll('.nav-item'); navItems.forEach(item => { item.addEventListener('click', function() { navItems.forEach(navItem => navItem.classList.remove('active')); this.classList.add('active'); }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Terrain Explorer: Interactive Travel Map</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', 'Segoe UI', Roboto, sans-serif; } :root { --desert: #e9c46a; --forest: #588157; --mountain: #6d6875; --coast: #219ebc; --city: #f94144; --primary: #264653; --light: #f8f9fa; --dark: #1d3557; --transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); } body { background-color: #f7f7f7; height: 700px; width: 700px; overflow: hidden; position: relative; } .container { max-width: 700px; height: 700px; margin: 0 auto; display: flex; flex-direction: column; position: relative; } .map-container { flex: 1; position: relative; overflow: hidden; border-radius: 16px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); background-color: var(--light); height: 75%; } .map { width: 100%; height: 100%; background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48ZGVmcz48bGluZWFyR3JhZGllbnQgaWQ9ImEiIHgxPSIwJSIgeTE9IjAlIiB4Mj0iMTAwJSIgeTI9IjEwMCUiPjxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiNmNWY1ZjUiLz48c3RvcCBvZmZzZXQ9IjI1JSIgc3RvcC1jb2xvcj0iI2YwZjBmMCIvPjxzdG9wIG9mZnNldD0iNTAlIiBzdG9wLWNvbG9yPSIjZWJlYmViIi8+PHN0b3Agb2Zmc2V0PSI3NSUiIHN0b3AtY29sb3I9IiNlNWU1ZTUiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNlMGUwZTAiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cGF0aCBmaWxsPSJ1cmwoI2EpIiBkPSJNMCAwaDEwMHYxMDBIMHoiLz48cGF0aCBmaWxsPSIjZWJlYmViIiBkPSJNMTAgMTBoNXY1aC01em0xNSAwaDV2NWgtNXptMTUgMGg1djVoLTV6bTE1IDBoNXY1aC01em0xNSAwaDV2NWgtNXptMTUgMGg1djVoLTV6TTEwIDI1aDV2NWgtNXptMTUgMGg1djVoLTV6bTE1IDBoNXY1aC01em0xNSAwaDV2NWgtNXptMTUgMGg1djVoLTV6bTE1IDBoNXY1aC01ek0xMCA0MGg1djVoLTV6bTE1IDBoNXY1aC01em0xNSAwaDV2NWgtNXptMTUgMGg1djVoLTV6bTE1IDBoNXY1aC01em0xNSAwaDV2NWgtNXpNMTAgNTVoNXY1aC01em0xNSAwaDV2NWgtNXptMTUgMGg1djVoLTV6bTE1IDBoNXY1aC01em0xNSAwaDV2NWgtNXptMTUgMGg1djVoLTV6TTEwIDcwaDV2NWgtNXptMTUgMGg1djVoLTV6bTE1IDBoNXY1aC01em0xNSAwaDV2NWgtNXptMTUgMGg1djVoLTV6bTE1IDBoNXY1aC01ek0xMCA4NWg1djVoLTV6bTE1IDBoNXY1aC01em0xNSAwaDV2NWgtNXptMTUgMGg1djVoLTV6bTE1IDBoNXY1aC01em0xNSAwaDV2NWgtNXoiLz48L3N2Zz4='); background-repeat: repeat; background-size: 100px; position: relative; } .location-marker { position: absolute; width: 24px; height: 24px; border-radius: 50%; transform: translate(-50%, -50%); cursor: pointer; z-index: 10; transition: var(--transition); display: flex; align-items: center; justify-content: center; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); } .location-marker::before { content: ''; position: absolute; width: 40px; height: 40px; border-radius: 50%; opacity: 0; transition: var(--transition); z-index: -1; } .location-marker:hover { transform: translate(-50%, -50%) scale(1.2); } .location-marker:hover::before { animation: ripple 1.5s cubic-bezier(0.25, 0.8, 0.25, 1) infinite; } .marker-desert { background-color: var(--desert); } .marker-desert::before { background-color: var(--desert); } .marker-forest { background-color: var(--forest); } .marker-forest::before { background-color: var(--forest); } .marker-mountain { background-color: var(--mountain); } .marker-mountain::before { background-color: var(--mountain); } .marker-coast { background-color: var(--coast); } .marker-coast::before { background-color: var(--coast); } .marker-city { background-color: var(--city); } .marker-city::before { background-color: var(--city); } .marker-icon { font-size: 14px; color: white; } .location-info { position: absolute; width: 100%; bottom: 0; left: 0; padding: 20px; background: linear-gradient(to bottom, transparent, rgba(38, 70, 83, 0.9)); color: white; opacity: 0; transform: translateY(20px); transition: var(--transition); z-index: 5; border-radius: 0 0 16px 16px; pointer-events: none; } .location-info.active { opacity: 1; transform: translateY(0); } .location-title { font-size: 1.5rem; font-weight: 700; margin-bottom: 8px; display: flex; align-items: center; gap: 8px; } .location-type { font-size: 0.875rem; font-weight: 500; padding: 4px 8px; border-radius: 4px; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 8px; display: inline-block; } .location-description { font-size: 0.875rem; line-height: 1.4; margin-bottom: 12px; } .highlights { display: flex; gap: 8px; margin-top: 10px; } .highlight { background-color: rgba(255, 255, 255, 0.15); padding: 4px 10px; border-radius: 20px; font-size: 0.75rem; backdrop-filter: blur(4px); } .type-desert { background-color: var(--desert); color: var(--dark); } .type-forest { background-color: var(--forest); color: white; } .type-mountain { background-color: var(--mountain); color: white; } .type-coast { background-color: var(--coast); color: white; } .type-city { background-color: var(--city); color: white; } .header { padding: 20px; display: flex; justify-content: space-between; align-items: center; } .title { font-size: 1.5rem; font-weight: 700; color: var(--dark); display: flex; align-items: center; gap: 10px; } .title .icon { font-size: 1.5rem; color: var(--primary); } .filters { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; padding: 0 20px; } .filter-button { background-color: #f0f0f0; border: none; padding: 6px 12px; border-radius: 20px; font-size: 0.75rem; font-weight: 500; cursor: pointer; transition: var(--transition); display: flex; align-items: center; gap: 4px; } .filter-button.active { color: white; } .filter-button:hover { transform: translateY(-2px); box-shadow: 0 3px 6px rgba(0, 0, 0, 0.1); } .filter-desert { color: var(--dark); } .filter-desert.active { background-color: var(--desert); } .filter-forest { color: var(--dark); } .filter-forest.active { background-color: var(--forest); } .filter-mountain { color: var(--dark); } .filter-mountain.active { background-color: var(--mountain); } .filter-coast { color: var(--dark); } .filter-coast.active { background-color: var(--coast); } .filter-city { color: var(--dark); } .filter-city.active { background-color: var(--city); } .logo { background-color: var(--primary); color: white; width: 32px; height: 32px; display: flex; align-items: center; justify-content: center; border-radius: 8px; font-weight: 700; } .zoom-controls { position: absolute; right: 16px; top: 50%; transform: translateY(-50%); display: flex; flex-direction: column; gap: 8px; z-index: 20; } .zoom-button { width: 36px; height: 36px; border-radius: 50%; background-color: white; border: none; box-shadow: 0 3px 6px rgba(0, 0, 0, 0.1); display: flex; align-items: center; justify-content: center; cursor: pointer; transition: var(--transition); font-size: 1rem; color: var(--dark); } .zoom-button:hover { background-color: var(--primary); color: white; } .attribution { position: absolute; bottom: 8px; right: 8px; font-size: 0.625rem; color: rgba(0, 0, 0, 0.5); background-color: rgba(255, 255, 255, 0.7); padding: 2px 6px; border-radius: 4px; z-index: 5; } @keyframes ripple { 0% { transform: scale(0.8); opacity: 0.8; } 50% { transform: scale(1.5); opacity: 0.4; } 100% { transform: scale(2.2); opacity: 0; } } /* Responsive adjustments */ @media (max-width: 600px) { .header { flex-direction: column; align-items: flex-start; gap: 10px; } .map-container { height: 65%; } .location-title { font-size: 1.25rem; } .location-description { font-size: 0.75rem; } .zoom-controls { top: auto; bottom: 16px; transform: none; } } </style> </head> <body> <div class="container"> <div class="header"> <div class="title"> <div class="logo">TE</div> <span>Terrain Explorer</span> </div> </div> <div class="filters"> <button class="filter-button filter-desert active" data-type="desert"> <span>🏜️ Desert</span> </button> <button class="filter-button filter-forest active" data-type="forest"> <span>🌲 Forest</span> </button> <button class="filter-button filter-mountain active" data-type="mountain"> <span>⛰️ Mountain</span> </button> <button class="filter-button filter-coast active" data-type="coast"> <span>🌊 Coast</span> </button> <button class="filter-button filter-city active" data-type="city"> <span>🏙️ City</span> </button> </div> <div class="map-container"> <div class="map" id="map"> <!-- Markers will be injected by JavaScript --> <div class="location-info" id="location-info"> <div class="location-title"></div> <span class="location-type"></span> <p class="location-description"></p> <div class="highlights"></div> </div> <div class="zoom-controls"> <button class="zoom-button" id="zoom-in">+</button> <button class="zoom-button" id="zoom-out">−</button> </div> <div class="attribution">Map data © Terrain Explorer 2023</div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Location data with coordinates and details const locations = [ { id: 1, name: "Sahara Desert", type: "desert", coordinates: { x: 30, y: 25 }, description: "A vast expanse of golden dunes and rugged landscapes. The Sahara offers unparalleled stargazing opportunities and ancient camel caravan routes.", highlights: ["Sand dunes", "Stargazing", "Camel treks"] }, { id: 2, name: "Amazon Rainforest", type: "forest", coordinates: { x: 60, y: 65 }, description: "The world's largest tropical rainforest with unmatched biodiversity. Visit indigenous communities and spot rare wildlife in this green paradise.", highlights: ["Wildlife spotting", "River cruises", "Canopy walks"] }, { id: 3, name: "Swiss Alps", type: "mountain", coordinates: { x: 75, y: 30 }, description: "Dramatic alpine peaks offering world-class skiing in winter and spectacular hiking trails during summer months.", highlights: ["Skiing", "Alpine villages", "Mountain lakes"] }, { id: 4, name: "Amalfi Coast", type: "coast", coordinates: { x: 80, y: 60 }, description: "Crystal clear waters meet dramatic cliffs topped with colorful villages. Explore hidden coves and sample authentic Italian cuisine.", highlights: ["Coastal drives", "Cliffside villages", "Seafood cuisine"] }, { id: 5, name: "Kyoto", type: "city", coordinates: { x: 20, y: 55 }, description: "Ancient temples and beautiful gardens blend with modern urban life in this former imperial capital of Japan.", highlights: ["Historic temples", "Cherry blossoms", "Tea ceremonies"] }, { id: 6, name: "Atacama Desert", type: "desert", coordinates: { x: 40, y: 80 }, description: "The driest non-polar desert on Earth, with otherworldly landscapes that resemble Mars. Perfect for astronomy enthusiasts.", highlights: ["Salt flats", "Geysers", "Moon Valley"] }, { id: 7, name: "Pacific Northwest Forests", type: "forest", coordinates: { x: 20, y: 15 }, description: "Misty coastal forests with towering redwoods and lush fern undergrowth. Experience the temperate rainforest ecosystem.", highlights: ["Redwood trees", "Moss-covered trails", "Coastal views"] }, { id: 8, name: "Santorini", type: "coast", coordinates: { x: 65, y: 40 }, description: "White-washed buildings perched on volcanic cliffs overlooking the deep blue Aegean Sea. Famous for stunning sunsets.", highlights: ["Sunset views", "Volcanic beaches", "Aegean cuisine"] } ]; // Map element and current state const map = document.getElementById('map'); const locationInfo = document.getElementById('location-info'); let activeMarker = null; let scale = 1; const maxScale = 1.5; const minScale = 0.8; // Create markers for all locations locations.forEach(location => { createMarker(location); }); // Handle zoom controls document.getElementById('zoom-in').addEventListener('click', () => { if (scale < maxScale) { scale += 0.1; updateMapScale(); } }); document.getElementById('zoom-out').addEventListener('click', () => { if (scale > minScale) { scale -= 0.1; updateMapScale(); } }); // Filter functionality const filterButtons = document.querySelectorAll('.filter-button'); const activeFilters = new Set(['desert', 'forest', 'mountain', 'coast', 'city']); filterButtons.forEach(button => { button.addEventListener('click', () => { const filterType = button.dataset.type; if (button.classList.contains('active')) { button.classList.remove('active'); activeFilters.delete(filterType); } else { button.classList.add('active'); activeFilters.add(filterType); } updateVisibleMarkers(); }); }); // Function to create a marker function createMarker(location) { const marker = document.createElement('div'); marker.className = `location-marker marker-${location.type}`; marker.dataset.id = location.id; marker.dataset.type = location.type; marker.style.left = `${location.coordinates.x}%`; marker.style.top = `${location.coordinates.y}%`; // Icon based on type const icon = document.createElement('span'); icon.className = 'marker-icon'; // Set icon based on location type switch(location.type) { case 'desert': icon.textContent = '🏜️'; break; case 'forest': icon.textContent = '🌲'; break; case 'mountain': icon.textContent = '⛰️'; break; case 'coast': icon.textContent = '🌊'; break; case 'city': icon.textContent = '🏙️'; break; } marker.appendChild(icon); map.appendChild(marker); // Add event listeners marker.addEventListener('click', (e) => { e.stopPropagation(); showLocationInfo(location, marker); }); } // Function to show location information function showLocationInfo(location, marker) { // Deactivate previous marker animation if any if (activeMarker) { stopRippleEffect(activeMarker); } // Set active marker and start animation activeMarker = marker; startRippleEffect(marker); // Update and display location info const titleElement = locationInfo.querySelector('.location-title'); const typeElement = locationInfo.querySelector('.location-type'); const descriptionElement = locationInfo.querySelector('.location-description'); const highlightsElement = locationInfo.querySelector('.highlights'); titleElement.textContent = location.name; typeElement.textContent = location.type.charAt(0).toUpperCase() + location.type.slice(1); typeElement.className = `location-type type-${location.type}`; descriptionElement.textContent = location.description; // Clear previous highlights highlightsElement.innerHTML = ''; // Add highlights location.highlights.forEach(highlight => { const highlightEl = document.createElement('span'); highlightEl.className = 'highlight'; highlightEl.textContent = highlight; highlightsElement.appendChild(highlightEl); }); // Show info panel locationInfo.classList.add('active'); } // Hide location info when clicking on the map but not on a marker map.addEventListener('click', (e) => { if (e.target === map) { locationInfo.classList.remove('active'); if (activeMarker) { stopRippleEffect(activeMarker); activeMarker = null; } } }); // Function to update visible markers based on filters function updateVisibleMarkers() { const markers = document.querySelectorAll('.location-marker'); markers.forEach(marker => { const markerType = marker.dataset.type; if (activeFilters.has(markerType)) { marker.style.display = 'flex'; } else { marker.style.display = 'none'; } }); } // Function to update map scale function updateMapScale() { map.style.transform = `scale(${scale})`; } // Functions for handling ripple effects function startRippleEffect(marker) { marker.style.zIndex = '20'; } function stopRippleEffect(marker) { marker.style.zIndex = '10'; } // Initial map update updateMapScale(); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> :root { --primary: #3a4750; --secondary: #f6f6f6; --accent: #ff5722; --text: #2d2d2d; --box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12); --transition: all 0.3s ease; } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: var(--secondary); color: var(--text); display: flex; justify-content: center; align-items: center; min-height: 100vh; padding: 20px; overflow-x: hidden; } .container { max-width: 700px; width: 100%; height: 700px; overflow-y: auto; padding: 30px 15px; scrollbar-width: thin; } .container::-webkit-scrollbar { width: 6px; } .container::-webkit-scrollbar-track { background: #f1f1f1; border-radius: 10px; } .container::-webkit-scrollbar-thumb { background: #c3c3c3; border-radius: 10px; } .header { text-align: center; margin-bottom: 30px; } .header h1 { font-size: 2rem; margin-bottom: 10px; color: var(--primary); letter-spacing: -0.5px; } .header p { color: #666; font-size: 0.9rem; max-width: 500px; margin: 0 auto; } .filter-bar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; flex-wrap: wrap; gap: 10px; } .filter-tab { display: flex; gap: 10px; overflow-x: auto; padding-bottom: 5px; scrollbar-width: none; } .filter-tab::-webkit-scrollbar { display: none; } .filter-btn { background: white; border: 1px solid #e0e0e0; padding: 6px 14px; border-radius: 20px; font-size: 0.85rem; cursor: pointer; transition: var(--transition); white-space: nowrap; } .filter-btn:hover { background: #f0f0f0; } .filter-btn.active { background: var(--primary); color: white; border-color: var(--primary); } .search-container { position: relative; } .search-input { padding: 8px 16px 8px 36px; border-radius: 20px; border: 1px solid #e0e0e0; outline: none; width: 200px; font-size: 0.9rem; transition: var(--transition); } .search-input:focus { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(255, 87, 34, 0.2); width: 220px; } .search-icon { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: #999; pointer-events: none; } .product-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 20px; } .product-card { background: white; border-radius: 12px; overflow: hidden; position: relative; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.05); transition: var(--transition); cursor: pointer; } .product-card:hover { transform: translateY(-5px); box-shadow: var(--box-shadow); } .card-img-container { height: 160px; overflow: hidden; position: relative; } .card-img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.5s ease; } .product-card:hover .card-img { transform: scale(1.05); } .ripple-container { position: absolute; top: 0; left: 0; width: 100%; height: 100%; overflow: hidden; z-index: 0; } .ripple { position: absolute; border-radius: 50%; background: rgba(255, 255, 255, 0.4); transform: scale(0); animation: ripple-effect 0.6s ease-out; pointer-events: none; } @keyframes ripple-effect { to { transform: scale(3); opacity: 0; } } .card-content { padding: 15px; position: relative; z-index: 1; } .card-title { font-size: 0.95rem; font-weight: 600; margin-bottom: 5px; letter-spacing: -0.2px; line-height: 1.3; } .card-price { color: var(--accent); font-weight: 700; font-size: 1.1rem; margin-bottom: 10px; } .card-meta { display: flex; justify-content: space-between; align-items: center; font-size: 0.8rem; color: #888; } .rating { display: flex; align-items: center; gap: 3px; } .rating-star { color: gold; } .rating-count { color: #888; } .wishlist-btn { background: none; border: none; color: #bbb; cursor: pointer; font-size: 1.1rem; transition: var(--transition); display: flex; align-items: center; justify-content: center; width: 30px; height: 30px; border-radius: 50%; position: relative; overflow: hidden; } .wishlist-btn:hover { color: var(--accent); background: rgba(255, 87, 34, 0.1); } .wishlist-btn.active { color: var(--accent); } .empty-state { text-align: center; padding: 40px 0; color: #888; display: none; } .empty-state svg { width: 60px; height: 60px; margin-bottom: 20px; color: #ccc; } .empty-state p { font-size: 0.9rem; margin-bottom: 20px; } .empty-state button { background: var(--accent); color: white; border: none; padding: 8px 16px; border-radius: 20px; cursor: pointer; font-size: 0.9rem; transition: var(--transition); } .empty-state button:hover { background: #e64a19; } .loading-skeleton { background: linear-gradient(90deg, #f0f0f0 25%, #e3e3e3 50%, #f0f0f0 75%); background-size: 200% 100%; animation: loading 1.5s infinite; border-radius: 4px; } @keyframes loading { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } } .badge { position: absolute; top: 10px; left: 10px; background: var(--accent); color: white; padding: 3px 8px; border-radius: 4px; font-size: 0.7rem; font-weight: 600; z-index: 2; } .quick-view { position: absolute; bottom: 0; left: 0; width: 100%; padding: 12px; background: rgba(255, 255, 255, 0.95); text-align: center; transform: translateY(100%); transition: transform 0.3s ease; z-index: 2; font-size: 0.85rem; font-weight: 500; color: var(--primary); } .product-card:hover .quick-view { transform: translateY(0); } @media (max-width: 600px) { .product-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 15px; } .card-img-container { height: 140px; } .card-content { padding: 10px; } .card-title { font-size: 0.85rem; } .card-price { font-size: 1rem; } .header h1 { font-size: 1.6rem; } } </style> </head> <body> <div class="container"> <div class="header"> <h1>Modern Essentials</h1> <p>Thoughtfully crafted products for your everyday needs</p> </div> <div class="filter-bar"> <div class="filter-tab"> <button class="filter-btn active">All</button> <button class="filter-btn">Workspace</button> <button class="filter-btn">Home Decor</button> <button class="filter-btn">Kitchen</button> <button class="filter-btn">Tech</button> </div> <div class="search-container"> <svg class="search-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M11 19C15.4183 19 19 15.4183 19 11C19 6.58172 15.4183 3 11 3C6.58172 3 3 6.58172 3 11C3 15.4183 6.58172 19 11 19Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M21 21L16.65 16.65" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> <input type="text" class="search-input" placeholder="Search products..."> </div> </div> <div class="product-grid"> <!-- Product 1 --> <div class="product-card" data-category="workspace"> <div class="ripple-container"></div> <span class="badge">New</span> <div class="card-img-container"> <img src="https://images.unsplash.com/photo-1591710668263-bee1e9db2a26?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80" alt="Minimalist Desk Lamp" class="card-img"> <div class="quick-view">Quick View</div> </div> <div class="card-content"> <h3 class="card-title">Minimalist Desk Lamp</h3> <p class="card-price">$89.99</p> <div class="card-meta"> <div class="rating"> <span class="rating-star">★</span> <span class="rating-value">4.8</span> <span class="rating-count">(124)</span> </div> <button class="wishlist-btn"> <svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M20.84 4.61C20.3292 4.099 19.7228 3.69364 19.0554 3.41708C18.3879 3.14052 17.6725 2.99817 16.95 2.99817C16.2275 2.99817 15.5121 3.14052 14.8446 3.41708C14.1772 3.69364 13.5708 4.099 13.06 4.61L12 5.67L10.94 4.61C9.9083 3.5783 8.50903 2.9987 7.05 2.9987C5.59096 2.9987 4.19169 3.5783 3.16 4.61C2.1283 5.64169 1.54871 7.04097 1.54871 8.5C1.54871 9.95903 2.1283 11.3583 3.16 12.39L4.22 13.45L12 21.23L19.78 13.45L20.84 12.39C21.351 11.8792 21.7563 11.2728 22.0329 10.6054C22.3095 9.93793 22.4518 9.22252 22.4518 8.5C22.4518 7.77748 22.3095 7.06207 22.0329 6.39464C21.7563 5.7272 21.351 5.12076 20.84 4.61V4.61Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> </button> </div> </div> </div> <!-- Product 2 --> <div class="product-card" data-category="home-decor"> <div class="ripple-container"></div> <div class="card-img-container"> <img src="https://images.unsplash.com/photo-1567225557594-88d73e55f2cb?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80" alt="Ceramic Planter Set" class="card-img"> <div class="quick-view">Quick View</div> </div> <div class="card-content"> <h3 class="card-title">Ceramic Planter Set</h3> <p class="card-price">$42.50</p> <div class="card-meta"> <div class="rating"> <span class="rating-star">★</span> <span class="rating-value">4.6</span> <span class="rating-count">(78)</span> </div> <button class="wishlist-btn"> <svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M20.84 4.61C20.3292 4.099 19.7228 3.69364 19.0554 3.41708C18.3879 3.14052 17.6725 2.99817 16.95 2.99817C16.2275 2.99817 15.5121 3.14052 14.8446 3.41708C14.1772 3.69364 13.5708 4.099 13.06 4.61L12 5.67L10.94 4.61C9.9083 3.5783 8.50903 2.9987 7.05 2.9987C5.59096 2.9987 4.19169 3.5783 3.16 4.61C2.1283 5.64169 1.54871 7.04097 1.54871 8.5C1.54871 9.95903 2.1283 11.3583 3.16 12.39L4.22 13.45L12 21.23L19.78 13.45L20.84 12.39C21.351 11.8792 21.7563 11.2728 22.0329 10.6054C22.3095 9.93793 22.4518 9.22252 22.4518 8.5C22.4518 7.77748 22.3095 7.06207 22.0329 6.39464C21.7563 5.7272 21.351 5.12076 20.84 4.61V4.61Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> </button> </div> </div> </div> <!-- Product 3 --> <div class="product-card" data-category="kitchen"> <div class="ripple-container"></div> <span class="badge">Sale</span> <div class="card-img-container"> <img src="https://images.unsplash.com/photo-1585442231525-65b5c7b4d473?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80" alt="Walnut Cutting Board" class="card-img"> <div class="quick-view">Quick View</div> </div> <div class="card-content"> <h3 class="card-title">Walnut Cutting Board</h3> <p class="card-price">$65.00</p> <div class="card-meta"> <div class="rating"> <span class="rating-star">★</span> <span class="rating-value">4.9</span> <span class="rating-count">(192)</span> </div> <button class="wishlist-btn active"> <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> <path d="M20.84 4.61C20.3292 4.099 19.7228 3.69364 19.0554 3.41708C18.3879 3.14052 17.6725 2.99817 16.95 2.99817C16.2275 2.99817 15.5121 3.14052 14.8446 3.41708C14.1772 3.69364 13.5708 4.099 13.06 4.61L12 5.67L10.94 4.61C9.9083 3.5783 8.50903 2.9987 7.05 2.9987C5.59096 2.9987 4.19169 3.5783 3.16 4.61C2.1283 5.64169 1.54871 7.04097 1.54871 8.5C1.54871 9.95903 2.1283 11.3583 3.16 12.39L4.22 13.45L12 21.23L19.78 13.45L20.84 12.39C21.351 11.8792 21.7563 11.2728 22.0329 10.6054C22.3095 9.93793 22.4518 9.22252 22.4518 8.5C22.4518 7.77748 22.3095 7.06207 22.0329 6.39464C21.7563 5.7272 21.351 5.12076 20.84 4.61V4.61Z" stroke="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> </button> </div> </div> </div> <!-- Product 4 --> <div class="product-card" data-category="tech"> <div class="ripple-container"></div> <div class="card-img-container"> <img src="https://images.unsplash.com/photo-1629429407759-01cd3d7cfb38?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80" alt="Wireless Charger" class="card-img"> <div class="quick-view">Quick View</div> </div> <div class="card-content"> <h3 class="card-title">Wireless Charger</h3> <p class="card-price">$34.99</p> <div class="card-meta"> <div class="rating"> <span class="rating-star">★</span> <span class="rating-value">4.5</span> <span class="rating-count">(87)</span> </div> <button class="wishlist-btn"> <svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M20.84 4.61C20.3292 4.099 19.7228 3.69364 19.0554 3.41708C18.3879 3.14052 17.6725 2.99817 16.95 2.99817C16.2275 2.99817 15.5121 3.14052 14.8446 3.41708C14.1772 3.69364 13.5708 4.099 13.06 4.61L12 5.67L10.94 4.61C9.9083 3.5783 8.50903 2.9987 7.05 2.9987C5.59096 2.9987 4.19169 3.5783 3.16 4.61C2.1283 5.64169 1.54871 7.04097 1.54871 8.5C1.54871 9.95903 2.1283 11.3583 3.16 12.39L4.22 13.45L12 21.23L19.78 13.45L20.84 12.39C21.351 11.8792 21.7563 11.2728 22.0329 10.6054C22.3095 9.93793 22.4518 9.22252 22.4518 8.5C22.4518 7.77748 22.3095 7.06207 22.0329 6.39464C21.7563 5.7272 21.351 5.12076 20.84 4.61V4.61Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> </button> </div> </div> </div> <!-- Product 5 --> <div class="product-card" data-category="workspace"> <div class="ripple-container"></div> <div class="card-img-container"> <img src="https://images.unsplash.com/photo-1501876725168-00c445821c9e?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80" alt="Brass Desk Organizer" class="card-img"> <div class="quick-view">Quick View</div> </div> <div class="card-content"> <h3 class="card-title">Brass Desk Organizer</h3> <p class="card-price">$58.00</p> <div class="card-meta"> <div class="rating"> <span class="rating-star">★</span> <span class="rating-value">4.7</span> <span class="rating-count">(45)</span> </div> <button class="wishlist-btn"> <svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M20.84 4.61C20.3292 4.099 19.7228 3.69364 19.0554 3.41708C18.3879 3.14052 17.6725 2.99817 16.95 2.99817C16.2275 2.99817 15.5121 3.14052 14.8446 3.41708C14.1772 3.69364 13.5708 4.099 13.06 4.61L12 5.67L10.94 4.61C9.9083 3.5783 8.50903 2.9987 7.05 2.9987C5.59096 2.9987 4.19169 3.5783 3.16 4.61C2.1283 5.64169 1.54871 7.04097 1.54871 8.5C1.54871 9.95903 2.1283 11.3583 3.16 12.39L4.22 13.45L12 21.23L19.78 13.45L20.84 12.39C21.351 11.8792 21.7563 11.2728 22.0329 10.6054C22.3095 9.93793 22.4518 9.22252 22.4518 8.5C22.4518 7.77748 22.3095 7.06207 22.0329 6.39464C21.7563 5.7272 21.351 5.12076 20.84 4.61V4.61Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> </button> </div> </div> </div> <!-- Product 6 --> <div class="product-card" data-category="home-decor"> <div class="ripple-container"></div> <div class="card-img-container"> <img src="https://images.unsplash.com/photo-1544457070-4cd773b4d71e?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80" alt="Wool Throw Blanket" class="card-img"> <div class="quick-view">Quick View</div> </div> <div class="card-content"> <h3 class="card-title">Wool Throw Blanket</h3> <p class="card-price">$79.00</p> <div class="card-meta"> <div class="rating"> <span class="rating-star">★</span> <span class="rating-value">4.8</span> <span class="rating-count">(103)</span> </div> <button class="wishlist-btn"> <svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M20.84 4.61C20.3292 4.099 19.7228 3.69364 19.0554 3.41708C18.3879 3.14052 17.6725 2.99817 16.95 2.99817C16.2275 2.99817 15.5121 3.14052 14.8446 3.41708C14.1772 3.69364 13.5708 4.099 13.06 4.61L12 5.67L10.94 4.61C9.9083 3.5783 8.50903 2.9987 7.05 2.9987C5.59096 2.9987 4.19169 3.5783 3.16 4.61C2.1283 5.64169 1.54871 7.04097 1.54871 8.5C1.54871 9.95903 2.1283 11.3583 3.16 12.39L4.22 13.45L12 21.23L19.78 13.45L20.84 12.39C21.351 11.8792 21.7563 11.2728 22.0329 10.6054C22.3095 9.93793 22.4518 9.22252 22.4518 8.5C22.4518 7.77748 22.3095 7.06207 22.0329 6.39464C21.7563 5.7272 21.351 5.12076 20.84 4.61V4.61Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> </button> </div> </div> </div> <!-- Empty state (initially hidden) --> <div class="empty-state"> <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M19 2H5C3.89543 2 3 2.89543 3 4V20C3 21.1046 3.89543 22 5 22H19C20.1046 22 21 21.1046 21 20V4C21 2.89543 20.1046 2 19 2Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M9 12H15" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M12 9L12 15" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> <p>No products found matching your search criteria</p> <button>Clear Filters</button> </div> </div> </div> <script> // Ripple effect function const cards = document.querySelectorAll('.product-card'); cards.forEach(card => { const rippleContainer = card.querySelector('.ripple-container'); card.addEventListener('click', function(e) { const rect = rippleContainer.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; const ripple = document.createElement('span'); ripple.classList.add('ripple'); ripple.style.left = x + 'px'; ripple.style.top = y + 'px'; rippleContainer.appendChild(ripple); setTimeout(() => { ripple.remove(); }, 600); }); }); // Wishlist button toggle const wishlistButtons = document.querySelectorAll('.wishlist-btn'); wishlistButtons.forEach(btn => { btn.addEventListener('click', function(e) { e.stopPropagation(); this.classList.toggle('active'); // Toggle heart fill const svg = this.querySelector('svg path'); if (this.classList.contains('active')) { svg.setAttribute('fill', 'currentColor'); svg.setAttribute('stroke', 'none'); } else { svg.setAttribute('fill', 'none'); svg.setAttribute('stroke', 'currentColor'); } }); }); // Filter functionality const filterButtons = document.querySelectorAll('.filter-btn'); filterButtons.forEach(btn => { btn.addEventListener('click', function() { // Remove active class from all buttons filterButtons.forEach(b => b.classList.remove('active')); // Add active class to clicked button this.classList.add('active'); const filterValue = this.textContent.toLowerCase(); if (filterValue === 'all') { cards.forEach(card => { card.style.display = 'block'; }); } else { const category = filterValue.replace(' ', '-'); cards.forEach(card => { if (card.dataset.category === category) { card.style.display = 'block'; } else { card.style.display = 'none'; } }); } // Check if any cards are visible const visibleCards = Array.from(cards).filter(card => card.style.display !== 'none'); const emptyState = document.querySelector('.empty-state'); if (visibleCards.length === 0) { emptyState.style.display = 'block'; } else { emptyState.style.display = 'none'; } }); }); // Search functionality const searchInput = document.querySelector('.search-input'); searchInput.addEventListener('input', function() { const searchValue = this.value.toLowerCase().trim(); cards.forEach(card => { const title = card.querySelector('.card-title').textContent.toLowerCase(); if (title.includes(searchValue)) { card.style.display = 'block'; } else { card.style.display = 'none'; } }); // Check if any cards are visible const visibleCards = Array.from(cards).filter(card => card.style.display !== 'none'); const emptyState = document.querySelector('.empty-state'); if (visibleCards.length === 0) { emptyState.style.display = 'block'; } else { emptyState.style.display = 'none'; } }); // Reset search and filters document.querySelector('.empty-state button').addEventListener('click', function() { searchInput.value = ''; filterButtons.forEach(btn => btn.classList.remove('active')); document.querySelector('.filter-btn:first-child').classList.add('active'); cards.forEach(card => { card.style.display = 'block'; }); document.querySelector('.empty-state').style.display = 'none'; }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Vibesphere Social Sign-Up</title> <style> :root { --primary: #4f46e5; --primary-light: #818cf8; --primary-dark: #4338ca; --secondary: #fb7185; --accent: #38bdf8; --light: #f8fafc; --dark: #0f172a; --success: #10b981; --error: #ef4444; --gradient-start: #4f46e5; --gradient-end: #3b82f6; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; } body { background-color: var(--light); display: flex; justify-content: center; align-items: center; min-height: 100vh; color: var(--dark); background-image: radial-gradient(circle at 10% 20%, rgba(79, 70, 229, 0.05) 0%, transparent 30%), radial-gradient(circle at 90% 80%, rgba(59, 130, 246, 0.07) 0%, transparent 30%); overflow-x: hidden; padding: 20px; } .container { max-width: 650px; width: 100%; background: white; border-radius: 20px; box-shadow: 0 10px 25px rgba(0, 0, 0, 0.05); overflow: hidden; position: relative; } .header { padding: 30px 40px 20px; background: linear-gradient(135deg, var(--gradient-start), var(--gradient-end)); color: white; border-radius: 20px 20px 0 0; position: relative; overflow: hidden; } .header h1 { font-size: 28px; font-weight: 700; margin-bottom: 12px; animation: fadeIn 0.8s ease-out; } .header p { font-size: 16px; opacity: 0.9; line-height: 1.5; animation: fadeIn 1s ease-out; } .form-container { padding: 30px 40px 40px; animation: slideUp 0.8s ease-out; } .form-group { margin-bottom: 25px; position: relative; } .form-group label { display: block; margin-bottom: 8px; font-weight: 500; font-size: 14px; color: var(--dark); } .form-group input { width: 100%; padding: 14px 16px; border: 1px solid #e2e8f0; border-radius: 10px; font-size: 15px; color: var(--dark); background-color: #f8fafc; transition: all 0.3s ease; } .form-group input:focus { outline: none; border-color: var(--primary-light); box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1); background-color: white; } .form-group input:hover { background-color: white; } /* Custom checkbox styling */ .checkbox-container { display: flex; align-items: center; margin-bottom: 25px; cursor: pointer; } .checkbox-container input { position: absolute; opacity: 0; height: 0; width: 0; } .checkmark { height: 20px; width: 20px; background-color: #f8fafc; border: 1px solid #e2e8f0; border-radius: 6px; margin-right: 10px; display: flex; align-items: center; justify-content: center; transition: all 0.2s ease; flex-shrink: 0; } .checkbox-container:hover .checkmark { background-color: #f1f5f9; } .checkbox-container input:checked ~ .checkmark { background-color: var(--primary); border-color: var(--primary); } .checkmark:after { content: ""; display: none; width: 5px; height: 10px; border: solid white; border-width: 0 2px 2px 0; transform: rotate(45deg); } .checkbox-container input:checked ~ .checkmark:after { display: block; } .checkbox-text { font-size: 14px; color: #64748b; line-height: 1.5; } .checkbox-text a { color: var(--primary); text-decoration: none; font-weight: 500; position: relative; } .checkbox-text a:hover { color: var(--primary-dark); } .checkbox-text a:after { content: ""; position: absolute; width: 100%; height: 1px; background: var(--primary); bottom: 0; left: 0; transform: scaleX(0); transform-origin: bottom right; transition: transform 0.3s ease; } .checkbox-text a:hover:after { transform: scaleX(1); transform-origin: bottom left; } /* Button styles with ripple effect */ .btn { background: var(--primary); color: white; border: none; padding: 14px 24px; border-radius: 10px; font-weight: 600; font-size: 16px; cursor: pointer; transition: background 0.3s ease; display: block; width: 100%; position: relative; overflow: hidden; text-align: center; } .btn:focus { outline: none; } .btn:hover { background: var(--primary-dark); } .btn-ripple { position: absolute; background: rgba(255, 255, 255, 0.7); border-radius: 50%; transform: scale(0); animation: ripple 0.7s linear; transform-origin: center; } .social-login { display: flex; justify-content: space-between; gap: 12px; margin-top: 25px; } .social-btn { flex: 1; display: flex; align-items: center; justify-content: center; padding: 12px; border-radius: 10px; border: 1px solid #e2e8f0; background: white; cursor: pointer; transition: all 0.3s ease; position: relative; overflow: hidden; } .social-btn:hover { background: #f8fafc; transform: translateY(-2px); box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05); } .social-btn i { font-size: 22px; } .social-btn.google i { color: #ea4335; } .social-btn.facebook i { color: #1877f2; } .social-btn.twitter i { color: #1da1f2; } .separator { display: flex; align-items: center; text-align: center; margin: 30px 0; color: #94a3b8; } .separator::before, .separator::after { content: ''; flex: 1; border-bottom: 1px solid #e2e8f0; } .separator::before { margin-right: 15px; } .separator::after { margin-left: 15px; } .login-link { text-align: center; margin-top: 25px; font-size: 14px; color: #64748b; } .login-link a { color: var(--primary); text-decoration: none; font-weight: 500; position: relative; } .login-link a:hover { color: var(--primary-dark); } .login-link a:after { content: ""; position: absolute; width: 100%; height: 1px; background: var(--primary); bottom: -1px; left: 0; transform: scaleX(0); transform-origin: bottom right; transition: transform 0.3s ease; } .login-link a:hover:after { transform: scaleX(1); transform-origin: bottom left; } /* Success message */ .success-message { position: fixed; top: 20px; left: 50%; transform: translateX(-50%); background: var(--success); color: white; padding: 14px 20px; border-radius: 10px; font-weight: 500; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); z-index: 1000; opacity: 0; pointer-events: none; transition: opacity 0.3s ease; display: flex; align-items: center; gap: 10px; } .success-message.show { opacity: 1; animation: fadeInUp 0.5s ease-out; } .success-icon { background: rgba(255, 255, 255, 0.2); width: 24px; height: 24px; border-radius: 50%; display: flex; align-items: center; justify-content: center; } /* Decorative elements */ .decoration { position: absolute; z-index: 0; } .decoration-1 { top: 20px; right: 20px; width: 80px; height: 80px; background: rgba(255, 255, 255, 0.1); border-radius: 50%; } .decoration-2 { bottom: -40px; left: -20px; width: 120px; height: 120px; background: rgba(255, 255, 255, 0.05); border-radius: 50%; } @keyframes ripple { to { transform: scale(4); opacity: 0; } } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes slideUp { from { transform: translateY(10px); opacity: 0; } to { transform: translateY(0); opacity: 1; } } @keyframes fadeInUp { from { transform: translate(-50%, 10px); opacity: 0; } to { transform: translate(-50%, 0); opacity: 1; } } /* Responsive adjustments */ @media (max-width: 600px) { .container { border-radius: 15px; } .header { padding: 25px 30px 15px; } .form-container { padding: 25px 30px 30px; } .social-login { flex-direction: column; gap: 10px; } .btn { padding: 12px 20px; } } </style> </head> <body> <div class="container"> <div class="header"> <h1>Join Vibesphere</h1> <p>Connect with friends, discover content that inspires, and share your world with our vibrant community.</p> <div class="decoration decoration-1"></div> <div class="decoration decoration-2"></div> </div> <div class="form-container"> <form id="signup-form"> <div class="form-group"> <label for="fullname">Full Name</label> <input type="text" id="fullname" placeholder="Enter your full name" required> </div> <div class="form-group"> <label for="email">Email Address</label> <input type="email" id="email" placeholder="Enter your email" required> </div> <div class="form-group"> <label for="password">Password</label> <input type="password" id="password" placeholder="Create a strong password" required> </div> <label class="checkbox-container"> <input type="checkbox" id="terms"> <span class="checkmark"></span> <span class="checkbox-text">I agree to Vibesphere's <a href="#">Terms of Service</a> and <a href="#">Privacy Policy</a></span> </label> <button type="submit" class="btn" id="signup-button">Create Account</button> <div class="separator">or continue with</div> <div class="social-login"> <button type="button" class="social-btn google"> <i class="fab fa-google"></i> </button> <button type="button" class="social-btn facebook"> <i class="fab fa-facebook-f"></i> </button> <button type="button" class="social-btn twitter"> <i class="fab fa-twitter"></i> </button> </div> <div class="login-link"> Already have an account? <a href="#">Log in</a> </div> </form> </div> </div> <div class="success-message" id="success-message"> <div class="success-icon"> <svg width="12" height="12" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M20 6L9 17L4 12" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/> </svg> </div> <span>Account created successfully!</span> </div> <!-- Font Awesome for social icons --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"> <script> document.addEventListener('DOMContentLoaded', function() { const buttons = document.querySelectorAll('.btn, .social-btn'); const form = document.getElementById('signup-form'); const successMessage = document.getElementById('success-message'); // Function to create ripple effect function createRipple(event) { const button = event.currentTarget; const circle = document.createElement('span'); const diameter = Math.max(button.clientWidth, button.clientHeight); const radius = diameter / 2; // Get position relative to the button const rect = button.getBoundingClientRect(); const x = event.clientX - rect.left; const y = event.clientY - rect.top; circle.style.width = circle.style.height = `${diameter}px`; circle.style.left = `${x - radius}px`; circle.style.top = `${y - radius}px`; circle.classList.add('btn-ripple'); // Remove existing ripples const ripple = button.querySelector('.btn-ripple'); if (ripple) { ripple.remove(); } button.appendChild(circle); // Remove the ripple after animation completes setTimeout(() => { circle.remove(); }, 700); } // Add ripple effect to all buttons buttons.forEach(button => { button.addEventListener('click', createRipple); }); // Form submission handler form.addEventListener('submit', function(e) { e.preventDefault(); // Simulate form validation const fullname = document.getElementById('fullname').value; const email = document.getElementById('email').value; const password = document.getElementById('password').value; const terms = document.getElementById('terms').checked; if (!fullname || !email || !password || !terms) { // Show validation errors (simplified for this example) if (!terms) { alert('Please agree to the terms and conditions'); } return; } // Show success message successMessage.classList.add('show'); // Hide success message after 3 seconds setTimeout(() => { successMessage.classList.remove('show'); // Reset form form.reset(); }, 3000); }); // Handle social login buttons document.querySelectorAll('.social-btn').forEach(btn => { btn.addEventListener('click', function() { // Show success message (simulating successful social login) successMessage.classList.add('show'); // Hide success message after 3 seconds setTimeout(() => { successMessage.classList.remove('show'); }, 3000); }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>NeonRipple Gaming Interface</title> <style> @import url('https://fonts.googleapis.com/css2?family=Exo+2:wght@400;700;900&family=Orbitron:wght@400;500;700;900&display=swap'); :root { --neon-primary: #00ffff; --neon-secondary: #ff00ff; --neon-tertiary: #00ff00; --neon-quaternary: #ffff00; --dark-bg: #080810; --mid-dark: #101020; --light-accent: #2a2a4a; } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Exo 2', sans-serif; background-color: var(--dark-bg); color: white; width: 100%; height: 100vh; overflow: hidden; display: flex; justify-content: center; align-items: center; } .container { width: 100%; max-width: 700px; height: 700px; padding: 20px; display: flex; flex-direction: column; position: relative; overflow: hidden; } .ambient-bg { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: radial-gradient(circle at center, var(--mid-dark) 0%, var(--dark-bg) 70%); z-index: -1; } .grid-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: linear-gradient(rgba(0, 255, 255, 0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(0, 255, 255, 0.05) 1px, transparent 1px); background-size: 20px 20px; z-index: -1; opacity: 0.5; } header { font-family: 'Orbitron', sans-serif; text-align: center; margin-bottom: 30px; position: relative; } h1 { font-size: 2.5rem; text-transform: uppercase; letter-spacing: 2px; margin-bottom: 10px; background: linear-gradient(to right, var(--neon-primary), var(--neon-secondary)); -webkit-background-clip: text; background-clip: text; color: transparent; text-shadow: 0 0 10px rgba(0, 255, 255, 0.5); } .subtitle { font-size: 1rem; color: rgba(255, 255, 255, 0.7); letter-spacing: 1px; } .controls-container { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; margin-bottom: 30px; } .control-card { background: var(--mid-dark); border: 1px solid var(--light-accent); border-radius: 8px; padding: 20px; display: flex; flex-direction: column; position: relative; overflow: hidden; box-shadow: 0 0 15px rgba(0, 0, 0, 0.3); transition: all 0.3s ease; } .control-card:hover { transform: translateY(-5px); box-shadow: 0 10px 20px rgba(0, 0, 0, 0.4); } .control-title { font-family: 'Orbitron', sans-serif; font-size: 1.2rem; font-weight: 700; margin-bottom: 10px; z-index: 2; } .control-description { font-size: 0.9rem; color: rgba(255, 255, 255, 0.7); margin-bottom: 15px; z-index: 2; } .control-button { width: 100%; padding: 12px; background: var(--light-accent); border: none; border-radius: 5px; color: white; font-family: 'Orbitron', sans-serif; font-size: 1rem; font-weight: 500; cursor: pointer; position: relative; overflow: hidden; z-index: 2; transition: all 0.2s ease; } .ripple-effect { position: absolute; border-radius: 50%; background-color: rgba(255, 255, 255, 0.4); transform: scale(0); animation: ripple 0.8s ease-out; pointer-events: none; } .control-button::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(45deg, transparent 25%, rgba(255, 255, 255, 0.1) 50%, transparent 75%); background-size: 200% 200%; animation: shimmer 2s infinite linear; z-index: -1; } @keyframes shimmer { 0% { background-position: 0% 0%; } 100% { background-position: 200% 200%; } } @keyframes ripple { to { transform: scale(4); opacity: 0; } } .glow-border { position: absolute; top: 0; left: 0; right: 0; bottom: 0; border-radius: 8px; pointer-events: none; z-index: 1; transition: all 0.3s ease; } .action-panel { margin-top: 20px; background: var(--mid-dark); border: 1px solid var(--light-accent); border-radius: 8px; padding: 20px; flex-grow: 1; position: relative; overflow: hidden; } .action-title { font-family: 'Orbitron', sans-serif; font-size: 1.5rem; font-weight: 700; margin-bottom: 15px; text-align: center; } .action-grid { display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: repeat(3, 1fr); gap: 15px; height: calc(100% - 60px); } .action-button { background: var(--light-accent); border: none; border-radius: 5px; color: white; font-family: 'Orbitron', sans-serif; font-weight: 500; cursor: pointer; position: relative; overflow: hidden; transition: all 0.2s ease; display: flex; justify-content: center; align-items: center; } .action-button:active { transform: scale(0.95); } .action-button.primary { grid-column: span 2; background: rgba(0, 255, 255, 0.2); border: 1px solid var(--neon-primary); box-shadow: 0 0 10px rgba(0, 255, 255, 0.3); } .action-button.secondary { background: rgba(255, 0, 255, 0.2); border: 1px solid var(--neon-secondary); box-shadow: 0 0 10px rgba(255, 0, 255, 0.3); } .action-button.tertiary { background: rgba(0, 255, 0, 0.2); border: 1px solid var(--neon-tertiary); box-shadow: 0 0 10px rgba(0, 255, 0, 0.3); } .action-button.quaternary { background: rgba(255, 255, 0, 0.2); border: 1px solid var(--neon-quaternary); box-shadow: 0 0 10px rgba(255, 255, 0, 0.3); } .combo-indicator { position: absolute; bottom: 10px; left: 0; width: 100%; text-align: center; font-family: 'Orbitron', sans-serif; font-size: 1.2rem; color: white; text-shadow: 0 0 10px rgba(255, 255, 255, 0.5); } @media (max-width: 600px) { h1 { font-size: 1.8rem; } .controls-container { grid-template-columns: 1fr; } .action-grid { grid-template-columns: repeat(2, 1fr); grid-template-rows: repeat(6, 1fr); } .action-button.primary { grid-column: span 1; } } </style> </head> <body> <div class="container"> <div class="ambient-bg"></div> <div class="grid-overlay"></div> <header> <h1>NEON RIPPLE</h1> <p class="subtitle">RESPONSIVE GAMING INTERFACE</p> </header> <div class="controls-container"> <div class="control-card" data-color="primary"> <div class="glow-border"></div> <h3 class="control-title">COMBAT CONTROLS</h3> <p class="control-description">High-precision attack patterns with adaptive feedback response</p> <button class="control-button" data-type="primary">ACTIVATE</button> </div> <div class="control-card" data-color="secondary"> <div class="glow-border"></div> <h3 class="control-title">STEALTH MODE</h3> <p class="control-description">Dampen feedback for covert operations in low-visibility environments</p> <button class="control-button" data-type="secondary">ENGAGE</button> </div> <div class="control-card" data-color="tertiary"> <div class="glow-border"></div> <h3 class="control-title">REFLEX BOOST</h3> <p class="control-description">Accelerated response time for critical combat situations</p> <button class="control-button" data-type="tertiary">BOOST</button> </div> <div class="control-card" data-color="quaternary"> <div class="glow-border"></div> <h3 class="control-title">TACTICAL OVERLAY</h3> <p class="control-description">Enhanced spatial awareness with target prioritization</p> <button class="control-button" data-type="quaternary">DEPLOY</button> </div> </div> <div class="action-panel"> <h3 class="action-title">COMMAND CENTER</h3> <div class="action-grid"> <button class="action-button primary" data-action="attack">ATTACK</button> <button class="action-button primary" data-action="defend">DEFEND</button> <button class="action-button secondary" data-action="dash">DASH</button> <button class="action-button secondary" data-action="dodge">DODGE</button> <button class="action-button tertiary" data-action="heal">HEAL</button> <button class="action-button tertiary" data-action="buff">BUFF</button> <button class="action-button tertiary" data-action="shield">SHIELD</button> <button class="action-button quaternary" data-action="ultimate">ULTIMATE</button> <button class="action-button quaternary" data-action="special">SPECIAL</button> <button class="action-button quaternary" data-action="combo">COMBO</button> <button class="action-button primary" data-action="reload">RELOAD</button> <button class="action-button secondary" data-action="interact">INTERACT</button> </div> <div class="combo-indicator">COMBO: <span id="combo-count">0</span>x</div> </div> </div> <script> document.addEventListener('DOMContentLoaded', () => { const controlCards = document.querySelectorAll('.control-card'); const controlButtons = document.querySelectorAll('.control-button'); const actionButtons = document.querySelectorAll('.action-button'); const comboCounter = document.getElementById('combo-count'); let comboCount = 0; let lastButtonPressed = null; let comboTimeout = null; // Color mapping for different button types const colorMap = { primary: { color: 'var(--neon-primary)', shadow: '0 0 20px rgba(0, 255, 255, 0.7)', ripple: 'rgba(0, 255, 255, 0.8)' }, secondary: { color: 'var(--neon-secondary)', shadow: '0 0 20px rgba(255, 0, 255, 0.7)', ripple: 'rgba(255, 0, 255, 0.8)' }, tertiary: { color: 'var(--neon-tertiary)', shadow: '0 0 20px rgba(0, 255, 0, 0.7)', ripple: 'rgba(0, 255, 0, 0.8)' }, quaternary: { color: 'var(--neon-quaternary)', shadow: '0 0 20px rgba(255, 255, 0, 0.7)', ripple: 'rgba(255, 255, 0, 0.8)' } }; // Initialize control card glow effects controlCards.forEach(card => { const colorType = card.getAttribute('data-color'); const glowBorder = card.querySelector('.glow-border'); card.addEventListener('mouseenter', () => { glowBorder.style.boxShadow = `0 0 0 1px ${colorMap[colorType].color}, ${colorMap[colorType].shadow}`; }); card.addEventListener('mouseleave', () => { glowBorder.style.boxShadow = 'none'; }); }); // Create ripple effect on buttons function createRipple(event, customColor = null) { const button = event.currentTarget; const circle = document.createElement('span'); const diameter = Math.max(button.clientWidth, button.clientHeight); const radius = diameter / 2; const rect = button.getBoundingClientRect(); circle.style.width = circle.style.height = `${diameter}px`; circle.style.left = `${event.clientX - rect.left - radius}px`; circle.style.top = `${event.clientY - rect.top - radius}px`; circle.classList.add('ripple-effect'); // Use custom color if provided, otherwise use default white if (customColor) { circle.style.backgroundColor = customColor; } // Remove existing ripples const ripple = button.getElementsByClassName('ripple-effect')[0]; if (ripple) { ripple.remove(); } button.appendChild(circle); } // Add click events to control buttons controlButtons.forEach(button => { button.addEventListener('click', (e) => { const type = button.getAttribute('data-type'); createRipple(e, colorMap[type].ripple); // Flash effect on button press button.style.backgroundColor = colorMap[type].color; button.style.boxShadow = colorMap[type].shadow; setTimeout(() => { button.style.backgroundColor = ''; button.style.boxShadow = ''; }, 300); // Trigger effect on action panel const actionPanel = document.querySelector('.action-panel'); actionPanel.style.boxShadow = `inset 0 0 30px ${colorMap[type].color}`; setTimeout(() => { actionPanel.style.boxShadow = ''; }, 500); }); }); // Add click events to action buttons actionButtons.forEach(button => { button.addEventListener('click', (e) => { const classes = button.classList; let type; if (classes.contains('primary')) type = 'primary'; else if (classes.contains('secondary')) type = 'secondary'; else if (classes.contains('tertiary')) type = 'tertiary'; else if (classes.contains('quaternary')) type = 'quaternary'; createRipple(e, colorMap[type].ripple); // Flash effect button.style.backgroundColor = colorMap[type].color; button.style.boxShadow = colorMap[type].shadow; setTimeout(() => { button.style.backgroundColor = ''; }, 300); // Handle combo counter clearTimeout(comboTimeout); const currentButton = button.getAttribute('data-action'); if (lastButtonPressed && lastButtonPressed !== currentButton) { comboCount++; comboCounter.textContent = comboCount; // Visual feedback for combo comboCounter.style.fontSize = '1.5rem'; comboCounter.style.color = colorMap[type].color; comboCounter.style.textShadow = `0 0 10px ${colorMap[type].color}`; setTimeout(() => { comboCounter.style.fontSize = ''; comboCounter.style.color = ''; comboCounter.style.textShadow = ''; }, 300); } lastButtonPressed = currentButton; // Reset combo after 2 seconds of inactivity comboTimeout = setTimeout(() => { comboCount = 0; comboCounter.textContent = comboCount; lastButtonPressed = null; }, 2000); }); }); // Add hover glow effect to action buttons actionButtons.forEach(button => { const classes = button.classList; let type; if (classes.contains('primary')) type = 'primary'; else if (classes.contains('secondary')) type = 'secondary'; else if (classes.contains('tertiary')) type = 'tertiary'; else if (classes.contains('quaternary')) type = 'quaternary'; button.addEventListener('mouseenter', () => { button.style.boxShadow = colorMap[type].shadow; }); button.addEventListener('mouseleave', () => { button.style.boxShadow = ''; }); }); // Add grid animation effects const gridOverlay = document.querySelector('.grid-overlay'); document.addEventListener('mousemove', (e) => { const x = e.clientX / window.innerWidth - 0.5; const y = e.clientY / window.innerHeight - 0.5; gridOverlay.style.transform = `perspective(1000px) rotateX(${y * 2}deg) rotateY(${-x * 2}deg)`; }); // Add parallax effect to background const ambientBg = document.querySelector('.ambient-bg'); document.addEventListener('mousemove', (e) => { const x = e.clientX / window.innerWidth; const y = e.clientY / window.innerHeight; ambientBg.style.background = `radial-gradient(circle at ${x * 100}% ${y * 100}%, var(--mid-dark) 0%, var(--dark-bg) 70%)`; }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Educational Quiz Platform</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: #f8f9fa; display: flex; justify-content: center; align-items: center; min-height: 700px; width: 100%; max-width: 700px; margin: 0 auto; padding: 20px; overflow-x: hidden; } .quiz-container { background-color: #ffffff; border-radius: 16px; box-shadow: 0 8px 30px rgba(0, 0, 0, 0.06); width: 100%; max-width: 660px; overflow: hidden; position: relative; } .quiz-header { padding: 24px 28px; background: linear-gradient(135deg, #e0f7ff 0%, #f0f4ff 100%); position: relative; overflow: hidden; } .quiz-title { color: #334155; font-size: 1.5rem; font-weight: 600; margin-bottom: 8px; position: relative; z-index: 2; } .quiz-description { color: #64748b; font-size: 0.95rem; line-height: 1.5; position: relative; z-index: 2; } .pattern { position: absolute; top: 0; right: 0; width: 120px; height: 120px; opacity: 0.1; z-index: 1; } .pattern::before, .pattern::after { content: ""; position: absolute; border-radius: 50%; } .pattern::before { width: 80px; height: 80px; background-color: #64b5f6; top: -20px; right: -20px; } .pattern::after { width: 40px; height: 40px; background-color: #e1bee7; top: 40px; right: 30px; } .quiz-body { padding: 24px 28px; } .question-counter { display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px; } .question-number { font-size: 0.85rem; color: #64748b; font-weight: 500; } .progress-container { flex-grow: 1; height: 6px; background-color: #f1f5f9; border-radius: 10px; margin: 0 15px; overflow: hidden; } .progress-bar { height: 100%; background: linear-gradient(90deg, #a5d6a7 0%, #81c784 100%); width: 20%; border-radius: 10px; transition: width 0.5s ease; } .question { font-size: 1.15rem; color: #334155; font-weight: 500; margin-bottom: 24px; line-height: 1.5; } .options-container { display: flex; flex-direction: column; gap: 14px; margin-bottom: 32px; } .option { padding: 16px 20px; background-color: #f8fafc; border: 2px solid #e2e8f0; border-radius: 12px; cursor: pointer; transition: all 0.3s ease; position: relative; overflow: hidden; display: flex; align-items: center; } .option:hover { border-color: #cbd5e1; background-color: #f1f5f9; } .option-letter { display: flex; justify-content: center; align-items: center; width: 28px; height: 28px; border-radius: 50%; background-color: #e2e8f0; color: #64748b; font-size: 0.85rem; font-weight: 600; margin-right: 14px; transition: all 0.3s ease; } .option-text { color: #475569; font-size: 1rem; transition: all 0.3s ease; } .ripple { position: absolute; border-radius: 50%; transform: scale(0); animation: ripple 0.5s linear; pointer-events: none; } @keyframes ripple { to { transform: scale(4); opacity: 0; } } .option.selected { border-width: 2px; } .option.selected .option-letter { color: white; } .option.correct { border-color: #a5d6a7; background-color: #f1f8e9; } .option.correct .option-letter { background-color: #81c784; } .option.correct .ripple { background: rgba(165, 214, 167, 0.3); } .option.incorrect { border-color: #ef9a9a; background-color: #fef0f0; } .option.incorrect .option-letter { background-color: #ef5350; } .option.incorrect .ripple { background: rgba(239, 154, 154, 0.3); } .option.neutral { border-color: #90caf9; background-color: #f1f8ff; } .option.neutral .option-letter { background-color: #64b5f6; } .option.neutral .ripple { background: rgba(144, 202, 249, 0.3); } .option.selected .option-text { font-weight: 500; } .quiz-footer { padding: 20px 28px; border-top: 1px solid #f1f5f9; display: flex; justify-content: space-between; align-items: center; } .back-button, .next-button { padding: 10px 20px; border-radius: 8px; font-size: 0.95rem; font-weight: 500; cursor: pointer; transition: all 0.2s ease; display: flex; align-items: center; gap: 8px; } .back-button { background-color: #f8fafc; color: #64748b; border: 1px solid #e2e8f0; } .back-button:hover { background-color: #f1f5f9; } .next-button { background-color: #64b5f6; color: white; border: none; box-shadow: 0 4px 12px rgba(100, 181, 246, 0.25); } .next-button:hover { background-color: #42a5f5; box-shadow: 0 6px 16px rgba(100, 181, 246, 0.35); } .next-button:disabled { background-color: #cbd5e1; cursor: not-allowed; box-shadow: none; } .result-container { text-align: center; padding: 36px; display: none; } .result-emoji { font-size: 4rem; margin-bottom: 16px; } .result-title { font-size: 1.5rem; color: #334155; font-weight: 600; margin-bottom: 12px; } .result-message { color: #64748b; font-size: 1rem; margin-bottom: 28px; line-height: 1.6; } .score-display { background-color: #f1f5f9; padding: 16px; border-radius: 12px; margin-bottom: 28px; display: flex; justify-content: center; align-items: center; gap: 20px; } .score-item { text-align: center; } .score-value { font-size: 1.8rem; font-weight: 600; color: #334155; margin-bottom: 4px; } .score-label { font-size: 0.85rem; color: #64748b; } .restart-button { padding: 12px 28px; background-color: #64b5f6; color: white; border: none; border-radius: 8px; font-size: 1rem; font-weight: 500; cursor: pointer; transition: all 0.2s ease; box-shadow: 0 4px 12px rgba(100, 181, 246, 0.25); } .restart-button:hover { background-color: #42a5f5; box-shadow: 0 6px 16px rgba(100, 181, 246, 0.35); } .feedback-text { font-size: 0.9rem; color: #64748b; margin-top: 8px; transition: opacity 0.5s ease; opacity: 0; height: 20px; } .feedback-text.visible { opacity: 1; } @media (max-width: 500px) { .quiz-title { font-size: 1.3rem; } .quiz-header, .quiz-body, .quiz-footer { padding: 18px 20px; } .option { padding: 14px 16px; } .question { font-size: 1.05rem; } .back-button, .next-button { padding: 8px 16px; font-size: 0.9rem; } } </style> </head> <body> <div class="quiz-container"> <div class="quiz-header"> <h1 class="quiz-title">Environmental Science Quiz</h1> <p class="quiz-description">Test your knowledge about climate change and environmental sustainability</p> <div class="pattern"></div> </div> <div class="quiz-body"> <div class="question-counter"> <span class="question-number">Question 1 of 5</span> <div class="progress-container"> <div class="progress-bar"></div> </div> <span class="question-number">20%</span> </div> <div class="question"> Which of the following is the largest contributor to global greenhouse gas emissions? </div> <div class="options-container"> <div class="option" data-option="A"> <div class="option-letter">A</div> <div class="option-text">Transportation</div> </div> <div class="option" data-option="B"> <div class="option-letter">B</div> <div class="option-text">Electricity and heat production</div> </div> <div class="option" data-option="C"> <div class="option-letter">C</div> <div class="option-text">Agriculture and forestry</div> </div> <div class="option" data-option="D"> <div class="option-letter">D</div> <div class="option-text">Industrial processes</div> </div> </div> <div class="feedback-text"></div> </div> <div class="quiz-footer"> <button class="back-button" disabled> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <line x1="19" y1="12" x2="5" y2="12"></line> <polyline points="12 19 5 12 12 5"></polyline> </svg> Back </button> <button class="next-button" disabled> Next <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <line x1="5" y1="12" x2="19" y2="12"></line> <polyline points="12 5 19 12 12 19"></polyline> </svg> </button> </div> <div class="result-container"> <div class="result-emoji">🌟</div> <h2 class="result-title">Quiz Complete!</h2> <p class="result-message">You've demonstrated a strong understanding of environmental science concepts. Keep learning to become an eco-champion!</p> <div class="score-display"> <div class="score-item"> <div class="score-value" id="correct-answers">0</div> <div class="score-label">Correct</div> </div> <div class="score-item"> <div class="score-value" id="total-questions">5</div> <div class="score-label">Total</div> </div> <div class="score-item"> <div class="score-value" id="percentage">0%</div> <div class="score-label">Score</div> </div> </div> <button class="restart-button">Try Again</button> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const questions = [ { question: "Which of the following is the largest contributor to global greenhouse gas emissions?", options: [ { letter: "A", text: "Transportation" }, { letter: "B", text: "Electricity and heat production", correct: true }, { letter: "C", text: "Agriculture and forestry" }, { letter: "D", text: "Industrial processes" } ], feedback: "Electricity and heat production account for approximately 25% of global greenhouse gas emissions, making it the largest contributor." }, { question: "What is the primary cause of ocean acidification?", options: [ { letter: "A", text: "Increased water temperature" }, { letter: "B", text: "Plastic pollution" }, { letter: "C", text: "Absorption of CO₂ from the atmosphere", correct: true }, { letter: "D", text: "Agricultural runoff" } ], feedback: "When carbon dioxide dissolves in seawater, it forms carbonic acid, leading to increased ocean acidity which threatens marine ecosystems." }, { question: "Which renewable energy source has shown the most significant cost reduction over the past decade?", options: [ { letter: "A", text: "Solar photovoltaic", correct: true }, { letter: "B", text: "Wind energy" }, { letter: "C", text: "Hydroelectric power" }, { letter: "D", text: "Geothermal energy" } ], feedback: "Solar photovoltaic technology costs have fallen by approximately 90% since 2010, making it increasingly competitive with fossil fuels." }, { question: "Which of the following is an example of a carbon sink?", options: [ { letter: "A", text: "Coal power plant" }, { letter: "B", text: "Deforestation" }, { letter: "C", text: "Ocean ecosystems", correct: true }, { letter: "D", text: "Cement production" } ], feedback: "Oceans absorb about 30% of CO₂ emissions from human activities, making them one of Earth's largest carbon sinks alongside forests." }, { question: "Which approach to sustainable development balances economic, environmental, and social considerations?", options: [ { letter: "A", text: "Circular economy", correct: true }, { letter: "B", text: "Intensive agriculture" }, { letter: "C", text: "Planned obsolescence" }, { letter: "D", text: "Linear consumption model" } ], feedback: "Circular economy models aim to minimize waste by reusing materials and products, creating sustainable economic systems that benefit society while protecting natural resources." } ]; let currentQuestion = 0; let selectedOption = null; let correctAnswers = 0; let answered = false; const optionsContainer = document.querySelector('.options-container'); const nextButton = document.querySelector('.next-button'); const backButton = document.querySelector('.back-button'); const restartButton = document.querySelector('.restart-button'); const questionCounter = document.querySelector('.question-number'); const progressBar = document.querySelector('.progress-bar'); const questionText = document.querySelector('.question'); const quizBody = document.querySelector('.quiz-body'); const quizFooter = document.querySelector('.quiz-footer'); const resultContainer = document.querySelector('.result-container'); const feedbackText = document.querySelector('.feedback-text'); function updateQuestion() { const question = questions[currentQuestion]; questionText.textContent = question.question; const optionsHTML = question.options.map(option => ` <div class="option" data-option="${option.letter}"> <div class="option-letter">${option.letter}</div> <div class="option-text">${option.text}</div> </div> `).join(''); optionsContainer.innerHTML = optionsHTML; questionCounter.textContent = `Question ${currentQuestion + 1} of ${questions.length}`; progressBar.style.width = `${((currentQuestion + 1) / questions.length) * 100}%`; document.querySelectorAll('.question-number')[1].textContent = `${Math.round(((currentQuestion + 1) / questions.length) * 100)}%`; // Reset for new question selectedOption = null; answered = false; nextButton.disabled = true; feedbackText.textContent = ""; feedbackText.classList.remove('visible'); // Add click listeners to options document.querySelectorAll('.option').forEach(option => { option.addEventListener('click', handleOptionClick); }); backButton.disabled = currentQuestion === 0; } function createRippleEffect(e, element, className) { const ripple = document.createElement('span'); ripple.classList.add('ripple'); ripple.classList.add(className); const rect = element.getBoundingClientRect(); const size = Math.max(rect.width, rect.height); ripple.style.width = ripple.style.height = `${size}px`; ripple.style.left = `${e.clientX - rect.left - size / 2}px`; ripple.style.top = `${e.clientY - rect.top - size / 2}px`; element.appendChild(ripple); ripple.addEventListener('animationend', () => { ripple.remove(); }); } function handleOptionClick(e) { if (answered) return; const clickedOption = e.currentTarget; const optionLetter = clickedOption.dataset.option; // Remove existing selected class document.querySelectorAll('.option').forEach(opt => { opt.classList.remove('selected', 'correct', 'incorrect', 'neutral'); }); // Add selected class to clicked option clickedOption.classList.add('selected', 'neutral'); // Create ripple effect createRippleEffect(e, clickedOption, 'neutral'); selectedOption = optionLetter; nextButton.disabled = false; // Display feedback const correctOption = questions[currentQuestion].options.find(opt => opt.correct); if (correctOption && correctOption.letter === optionLetter) { clickedOption.classList.remove('neutral'); clickedOption.classList.add('correct'); feedbackText.textContent = "Correct! " + questions[currentQuestion].feedback; correctAnswers++; } else { clickedOption.classList.remove('neutral'); clickedOption.classList.add('incorrect'); feedbackText.textContent = "Incorrect. " + questions[currentQuestion].feedback; // Highlight correct answer setTimeout(() => { const correctElement = document.querySelector(`.option[data-option="${correctOption.letter}"]`); if (correctElement) { correctElement.classList.add('correct'); } }, 500); } feedbackText.classList.add('visible'); answered = true; } function showResults() { quizBody.style.display = 'none'; quizFooter.style.display = 'none'; resultContainer.style.display = 'block'; document.getElementById('correct-answers').textContent = correctAnswers; document.getElementById('total-questions').textContent = questions.length; document.getElementById('percentage').textContent = `${Math.round((correctAnswers / questions.length) * 100)}%`; const resultTitle = document.querySelector('.result-title'); const resultMessage = document.querySelector('.result-message'); const resultEmoji = document.querySelector('.result-emoji'); if (correctAnswers === questions.length) { resultTitle.textContent = "Perfect Score!"; resultMessage.textContent = "Remarkable! You've mastered environmental science concepts. Your knowledge is key to addressing our planet's challenges."; resultEmoji.textContent = "🏆"; } else if (correctAnswers >= questions.length * 0.8) { resultTitle.textContent = "Excellent Work!"; resultMessage.textContent = "You've demonstrated a strong understanding of environmental science concepts. Keep learning to become an eco-champion!"; resultEmoji.textContent = "🌟"; } else if (correctAnswers >= questions.length * 0.6) { resultTitle.textContent = "Good Job!"; resultMessage.textContent = "You have a solid foundation in environmental science. A bit more study will make you an environmental expert."; resultEmoji.textContent = "👍"; } else { resultTitle.textContent = "Keep Learning"; resultMessage.textContent = "Environmental science has many complex concepts. Review the topics and try again to improve your understanding."; resultEmoji.textContent = "📚"; } } function resetQuiz() { currentQuestion = 0; correctAnswers = 0; selectedOption = null; answered = false; resultContainer.style.display = 'none'; quizBody.style.display = 'block'; quizFooter.style.display = 'flex'; updateQuestion(); } // Button click handlers nextButton.addEventListener('click', () => { if (currentQuestion < questions.length - 1) { currentQuestion++; updateQuestion(); } else { showResults(); } }); backButton.addEventListener('click', () => { if (currentQuestion > 0) { currentQuestion--; updateQuestion(); } }); restartButton.addEventListener('click', resetQuiz); // Initialize the quiz updateQuestion(); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>AudioWave Player</title> <style> :root { --primary-color: #6c33ff; --secondary-color: #00eaff; --accent-color: #ff33a8; --background-color: #0a0a15; --surface-color: #13131e; --text-color: #ffffff; --text-secondary: #8c8c9c; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; } body { background-color: var(--background-color); color: var(--text-color); width: 100%; height: 100vh; display: flex; align-items: center; justify-content: center; overflow: hidden; } .container { width: 100%; max-width: 680px; height: 680px; background-color: var(--surface-color); border-radius: 20px; padding: 20px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4); position: relative; overflow: hidden; display: flex; flex-direction: column; } .top-bar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; } .top-bar .logo { font-size: 1.5rem; font-weight: 800; color: var(--text-color); text-transform: uppercase; letter-spacing: 1px; background: linear-gradient(45deg, var(--secondary-color), var(--primary-color)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; } .top-bar .user-profile { width: 40px; height: 40px; border-radius: 50%; background: linear-gradient(45deg, var(--primary-color), var(--accent-color)); display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; cursor: pointer; transition: transform 0.3s ease; } .top-bar .user-profile:hover { transform: scale(1.1); } .visualizer-container { flex: 1; position: relative; display: flex; align-items: center; justify-content: center; margin-bottom: 20px; overflow: hidden; } .track-info { position: absolute; top: 10px; left: 0; width: 100%; text-align: center; z-index: 2; } .track-title { font-size: 1.8rem; font-weight: 700; margin-bottom: 5px; text-shadow: 0 2px 10px rgba(0, 0, 0, 0.5); } .track-artist { font-size: 1rem; color: var(--text-secondary); margin-bottom: 10px; } .time-info { display: flex; justify-content: space-between; font-size: 0.8rem; color: var(--text-secondary); margin-top: 5px; } .ripple-container { position: absolute; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; overflow: hidden; } .ripple { position: absolute; border-radius: 50%; background: rgba(108, 51, 255, 0.2); transform: scale(0); pointer-events: none; } .visualizer-circle { width: 200px; height: 200px; border-radius: 50%; background: radial-gradient(circle, rgba(20, 20, 35, 0.9) 30%, rgba(10, 10, 21, 0.5) 70%); display: flex; align-items: center; justify-content: center; position: relative; z-index: 1; box-shadow: 0 0 30px rgba(108, 51, 255, 0.3); } .album-art { width: 180px; height: 180px; border-radius: 50%; background-image: url('data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/wAALCAAwADABAREA/8QAHAAAAgIDAQEAAAAAAAAAAAAAAAcGCAIEBQMJ/8QALBAAAgEDAgUDAwUBAAAAAAAAAQIDBAURAAYHEiExQRMiUQgUYRUjMkJxgf/aAAgBAQAAPwC/NMl73TbbWrFJXxNcZFDLTQHnYH5ON1X8nU3U1EFTC01PNHNEwyrxuGVh8gjXO56OKrpnpKmFJ4JByyRuOZWU9wR40o7HdO6OGO7rJT1Ylqbe0tRFGp95gY8w/wCZP40+9Kzivw+teIKwS0bx0e4aZQaOrC+yUr/R/wC3jt54OtPh/vpN0RtQ3KNaS6wL+5CGysg8PGfIP9T2PXpsaX3FPZG597cOLlar3PKsruHiqYuXngmXqki57j5HkEjVb+F/CK87e3zbKvfN4ra6vp3aWjp/TeOnSQEYZywLOVIIJwMjIAzrQv8AxR3jTbsuNohsO1LhT2yRoqaqraZoZZzGcPIiMCVQkZUHqR1Ixq3mlDdtwUdv3Lardcqltv1ldKKc1scatLTzH/XDhwFYeVYDOvPj1Q1FBYbFQWuCWpqKy5QOYYULu0cLrI7YA6BVDE/jVq9ZPGzZ8O/OGl8sKqJJ46dqiAebI/OPyuFb/uqrcANw2raXF22XGvljipq5pbZNK7BVjWddgSegAk5CfgHVtdqPT8ROOl8sd5qn/TdpU1FU04Y4WpqXZebHllTmZvhiB50t/qY3dRVlp29s+knSaoqKj9SrAhyBFHlYww/szkt/xHxpQcOeCW6d8bao9wUt0tlPTVokeP1lkZ1KOVIIVh2x31bTYOxLZsLa9JYLSgKRDnqJscss7fzkb8k9h4AwNM3VbeNnDOy8QrOKW5xNDXQAi31sAAmiJ7gjsyfIPzgjVQ+LvCi/8NLolVJKlxtc7H7O4RryjmGfdGR/F8dR2Pcc2kvs/bd43jvO22ixUs1TNUVKlzGvuji6FpGPZVAyc/jV+LVbaOz2qlttDCkFJSQrDDEvZEUAAD8ACutpS8ZeIkHD3aNdcgyz1hzT0UB/tM46E/CjqT+B5IrJwh4aVm9dzVV73dK9wlrpWrKlqj3SzTE5ZQT1JJ6sewGTgY1cnS54L7CuHEXiHW1N5genfb8bU9LIw5lE7DLuP7YBUDPTOdWG0aNG//V//9k='); background-size: cover; background-position: center; position: relative; transition: transform 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); } .album-art:hover { transform: scale(1.05); } .album-art::after { content: ''; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 15px; height: 15px; background-color: #13131e; border-radius: 50%; box-shadow: 0 0 0 5px rgba(20, 20, 35, 0.9); } .progress-container { width: 100%; height: 6px; background-color: rgba(140, 140, 156, 0.2); border-radius: 3px; overflow: hidden; cursor: pointer; } .progress-bar { height: 100%; width: 45%; background: linear-gradient(to right, var(--primary-color), var(--secondary-color)); border-radius: 3px; transition: width 0.2s ease; } .controls { display: flex; justify-content: space-between; align-items: center; margin-top: 25px; } .controls button { background: none; border: none; cursor: pointer; color: var(--text-color); font-size: 1.2rem; border-radius: 50%; width: 50px; height: 50px; display: flex; align-items: center; justify-content: center; transition: all 0.2s ease; outline: none; } .controls button:hover { background-color: rgba(255, 255, 255, 0.1); } .controls button.play-pause { background: linear-gradient(45deg, var(--primary-color), var(--accent-color)); width: 60px; height: 60px; box-shadow: 0 5px 15px rgba(108, 51, 255, 0.4); } .controls button.play-pause:hover { transform: scale(1.1); } .controls button.play-pause:active { transform: scale(0.95); } .equalizer { display: flex; align-items: flex-end; height: 40px; gap: 3px; position: absolute; bottom: 100px; left: 50%; transform: translateX(-50%); } .eq-bar { width: 4px; background: linear-gradient(to bottom, var(--primary-color), var(--secondary-color)); border-radius: 2px; transition: height 0.2s ease; } .playlist { margin-top: 30px; background-color: rgba(20, 20, 35, 0.5); border-radius: 10px; padding: 15px; max-height: 120px; overflow-y: auto; } .playlist-item { display: flex; align-items: center; padding: 8px 10px; border-radius: 8px; cursor: pointer; transition: background-color 0.2s ease; margin-bottom: 5px; } .playlist-item:hover { background-color: rgba(255, 255, 255, 0.1); } .playlist-item.active { background-color: rgba(108, 51, 255, 0.2); } .playlist-item-number { width: 25px; font-size: 0.9rem; color: var(--text-secondary); } .playlist-item-info { flex: 1; } .playlist-item-title { font-size: 0.9rem; margin-bottom: 2px; } .playlist-item-artist { font-size: 0.8rem; color: var(--text-secondary); } .playlist-item-duration { font-size: 0.8rem; color: var(--text-secondary); } .halo { position: absolute; width: 400px; height: 400px; border-radius: 50%; background: radial-gradient(circle, rgba(108, 51, 255, 0.1) 0%, rgba(255, 51, 168, 0.05) 70%, transparent 100%); animation: pulse 4s infinite ease-in-out; z-index: 0; } @keyframes pulse { 0% { transform: scale(1); opacity: 0.3; } 50% { transform: scale(1.1); opacity: 0.5; } 100% { transform: scale(1); opacity: 0.3; } } .wave { position: absolute; width: 100%; bottom: 0; left: 0; height: 70px; background: url('data:image/svg+xml;utf8,<svg viewBox="0 0 1440 320" xmlns="http://www.w3.org/2000/svg"><path fill="%230a0a15" fill-opacity="1" d="M0,224L48,213.3C96,203,192,181,288,181.3C384,181,480,203,576,213.3C672,224,768,224,864,213.3C960,203,1056,181,1152,176C1248,171,1344,181,1392,186.7L1440,192L1440,320L1392,320C1344,320,1248,320,1152,320C1056,320,960,320,864,320C768,320,672,320,576,320C480,320,384,320,288,320C192,320,96,320,48,320L0,320Z"></path></svg>'); background-size: cover; background-position: center; opacity: 0.3; } /* Custom scrollbar */ ::-webkit-scrollbar { width: 6px; } ::-webkit-scrollbar-track { background: rgba(20, 20, 35, 0.5); border-radius: 3px; } ::-webkit-scrollbar-thumb { background: var(--primary-color); border-radius: 3px; } ::-webkit-scrollbar-thumb:hover { background: var(--secondary-color); } /* Responsive adjustments */ @media (max-width: 700px) { .container { height: 680px; border-radius: 15px; padding: 15px; } .track-title { font-size: 1.5rem; } .visualizer-circle { width: 180px; height: 180px; } .album-art { width: 160px; height: 160px; } .playlist { max-height: 100px; } } @media (max-width: 400px) { .container { padding: 10px; } .visualizer-circle { width: 150px; height: 150px; } .album-art { width: 130px; height: 130px; } .controls button { width: 40px; height: 40px; } .controls button.play-pause { width: 50px; height: 50px; } } /* Ripple effect styling */ @keyframes ripple { 0% { transform: scale(0); opacity: 0.7; } 100% { transform: scale(3); opacity: 0; } } /* Equalizer animation */ @keyframes equalize { 0% { height: 5px; } 50% { height: 30px; } 100% { height: 10px; } } </style> </head> <body> <div class="container"> <div class="top-bar"> <div class="logo">AudioWave</div> <div class="user-profile">JS</div> </div> <div class="visualizer-container"> <div class="halo"></div> <div class="track-info"> <h2 class="track-title">Midnight Echoes</h2> <p class="track-artist">SynthVoid</p> </div> <div class="ripple-container" id="rippleContainer"></div> <div class="visualizer-circle"> <div class="album-art" id="albumArt"></div> </div> <div class="equalizer" id="equalizer"> <div class="eq-bar"></div> <div class="eq-bar"></div> <div class="eq-bar"></div> <div class="eq-bar"></div> <div class="eq-bar"></div> <div class="eq-bar"></div> <div class="eq-bar"></div> <div class="eq-bar"></div> <div class="eq-bar"></div> <div class="eq-bar"></div> <div class="eq-bar"></div> </div> </div> <div class="progress-container" id="progressContainer"> <div class="progress-bar" id="progressBar"></div> </div> <div class="time-info"> <span>2:18</span> <span>5:07</span> </div> <div class="controls"> <button class="shuffle" id="shuffleBtn"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="16 3 21 3 21 8"></polyline> <line x1="4" y1="20" x2="21" y2="3"></line> <polyline points="21 16 21 21 16 21"></polyline> <line x1="15" y1="15" x2="21" y2="21"></line> <line x1="4" y1="4" x2="9" y2="9"></line> </svg> </button> <button class="prev" id="prevBtn"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polygon points="19 20 9 12 19 4 19 20"></polygon> <line x1="5" y1="19" x2="5" y2="5"></line> </svg> </button> <button class="play-pause" id="playPauseBtn"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polygon points="5 3 19 12 5 21 5 3"></polygon> </svg> </button> <button class="next" id="nextBtn"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polygon points="5 4 15 12 5 20 5 4"></polygon> <line x1="19" y1="5" x2="19" y2="19"></line> </svg> </button> <button class="repeat" id="repeatBtn"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="17 1 21 5 17 9"></polyline> <path d="M3 11V9a4 4 0 0 1 4-4h14"></path> <polyline points="7 23 3 19 7 15"></polyline> <path d="M21 13v2a4 4 0 0 1-4 4H3"></path> </svg> </button> </div> <div class="playlist"> <div class="playlist-item active"> <div class="playlist-item-number">1</div> <div class="playlist-item-info"> <div class="playlist-item-title">Midnight Echoes</div> <div class="playlist-item-artist">SynthVoid</div> </div> <div class="playlist-item-duration">5:07</div> </div> <div class="playlist-item"> <div class="playlist-item-number">2</div> <div class="playlist-item-info"> <div class="playlist-item-title">Neon Drift</div> <div class="playlist-item-artist">Electra Beat</div> </div> <div class="playlist-item-duration">4:22</div> </div> <div class="playlist-item"> <div class="playlist-item-number">3</div> <div class="playlist-item-info"> <div class="playlist-item-title">Quantum Pulse</div> <div class="playlist-item-artist">Digital Horizon</div> </div> <div class="playlist-item-duration">3:56</div> </div> </div> <div class="wave"></div> </div> <script> document.addEventListener('DOMContentLoaded', () => { const playPauseBtn = document.getElementById('playPauseBtn'); const prevBtn = document.getElementById('prevBtn'); const nextBtn = document.getElementById('nextBtn'); const shuffleBtn = document.getElementById('shuffleBtn'); const repeatBtn = document.getElementById('repeatBtn'); const progressBar = document.getElementById('progressBar'); const progressContainer = document.getElementById('progressContainer'); const rippleContainer = document.getElementById('rippleContainer'); const albumArt = document.getElementById('albumArt'); const equalizer = document.getElementById('equalizer'); const eqBars = document.querySelectorAll('.eq-bar'); let isPlaying = false; let equalizerInterval; let rotateInterval; let rotationDegree = 0; // Function to create ripple effect function createRipple(e) { const button = e.currentTarget; const ripple = document.createElement('span'); ripple.classList.add('ripple'); // Calculate ripple size const diameter = Math.max(button.clientWidth, button.clientHeight); // Set ripple diameter and position ripple.style.width = ripple.style.height = `${diameter}px`; // For controls if (button.classList.contains('play-pause') || button.classList.contains('prev') || button.classList.contains('next') || button.classList.contains('shuffle') || button.classList.contains('repeat')) { ripple.style.left = `${e.clientX - button.getBoundingClientRect().left - diameter / 2}px`; ripple.style.top = `${e.clientY - button.getBoundingClientRect().top - diameter / 2}px`; button.appendChild(ripple); } // For visualizer container else { const rect = rippleContainer.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; ripple.style.left = `${x - diameter / 2}px`; ripple.style.top = `${y - diameter / 2}px`; rippleContainer.appendChild(ripple); // Trigger beat visualization triggerBeat(); } // Animate ripple ripple.style.animation = 'ripple 0.8s linear'; // Remove after animation completes setTimeout(() => { ripple.remove(); }, 800); } // Function to toggle play/pause state function togglePlayPause() { isPlaying = !isPlaying; // Update icon playPauseBtn.innerHTML = isPlaying ? '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="6" y="4" width="4" height="16"></rect><rect x="14" y="4" width="4" height="16"></rect></svg>' : '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>'; // Start/stop equalizer animation if (isPlaying) { startEqualizer(); startRotation(); } else { stopEqualizer(); stopRotation(); } } // Function to start equalizer animation function startEqualizer() { if (equalizerInterval) clearInterval(equalizerInterval); equalizerInterval = setInterval(() => { eqBars.forEach(bar => { const height = Math.floor(Math.random() * 30) + 5; bar.style.height = `${height}px`; }); }, 100); } // Function to stop equalizer animation function stopEqualizer() { if (equalizerInterval) { clearInterval(equalizerInterval); equalizerInterval = null; // Reset bars eqBars.forEach(bar => { bar.style.height = '5px'; }); } } // Function to start album rotation function startRotation() { if (rotateInterval) clearInterval(rotateInterval); rotateInterval = setInterval(() => { rotationDegree = (rotationDegree + 0.5) % 360; albumArt.style.transform = `rotate(${rotationDegree}deg)`; }, 50); } // Function to stop album rotation function stopRotation() { if (rotateInterval) { clearInterval(rotateInterval); rotateInterval = null; } } // Function to update progress bar function updateProgress(e) { const width = this.clientWidth; const clickX = e.offsetX; const percent = (clickX / width) * 100; progressBar.style.width = `${percent}%`; } // Function to trigger beat visualization function triggerBeat() { // Create halo effect const halo = document.createElement('div'); halo.classList.add('halo'); halo.style.transform = 'scale(0.8)'; halo.style.animation = 'pulse 1s linear'; rippleContainer.appendChild(halo); // Remove after animation setTimeout(() => { halo.remove(); }, 1000); // Animate equalizer bars eqBars.forEach(bar => { const height = Math.floor(Math.random() * 35) + 5; bar.style.height = `${height}px`; // Ease back to normal setTimeout(() => { if (isPlaying) { bar.style.height = `${Math.floor(Math.random() * 25) + 5}px`; } }, 200); }); // Scale album art albumArt.style.transform = `scale(1.1)`; setTimeout(() => { albumArt.style.transform = ''; }, 200); } // Add event listeners playPauseBtn.addEventListener('click', (e) => { createRipple(e); togglePlayPause(); }); prevBtn.addEventListener('click', createRipple); nextBtn.addEventListener('click', createRipple); shuffleBtn.addEventListener('click', createRipple); repeatBtn.addEventListener('click', createRipple); progressContainer.addEventListener('click', updateProgress); // Add click listener to ripple container rippleContainer.addEventListener('click', createRipple); // Handle playlist item clicks const playlistItems = document.querySelectorAll('.playlist-item'); playlistItems.forEach(item => { item.addEventListener('click', () => { // Remove active class from all items playlistItems.forEach(i => i.classList.remove('active')); // Add active class to clicked item item.classList.add('active'); // Update track info const title = item.querySelector('.playlist-item-title').textContent; const artist = item.querySelector('.playlist-item-artist').textContent; document.querySelector('.track-title').textContent = title; document.querySelector('.track-artist').textContent = artist; // Trigger beat visualization triggerBeat(); // Ensure player is playing if (!isPlaying) { togglePlayPause(); } }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Atmospheric - Smart Weather Forecast</title> <style> @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap'); :root { --primary-blue: #4a6fa1; --dark-blue: #334a6d; --light-blue: #c5d8f1; --sky-blue: #87b1e6; --gray-100: #f8f9fa; --gray-200: #e9ecef; --gray-300: #dee2e6; --gray-400: #ced4da; --gray-500: #adb5bd; --gray-600: #6c757d; --gray-700: #495057; --gray-800: #343a40; --gray-900: #212529; --animation-speed: 0.3s; } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Inter', sans-serif; background: linear-gradient(135deg, var(--dark-blue), #1a2639); color: var(--gray-100); height: 100vh; display: flex; justify-content: center; align-items: center; overflow: hidden; } .container { width: 100%; max-width: 700px; height: 100%; max-height: 700px; padding: 2rem; position: relative; overflow: hidden; } .weather-app { background: rgba(255, 255, 255, 0.05); backdrop-filter: blur(10px); border-radius: 24px; padding: 2rem; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); overflow: hidden; position: relative; height: 100%; display: flex; flex-direction: column; } .app-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem; } .logo { font-size: 1.5rem; font-weight: 700; color: var(--gray-100); display: flex; align-items: center; } .logo svg { margin-right: 0.5rem; } .location { display: flex; align-items: center; font-size: 0.9rem; color: var(--gray-300); } .location svg { margin-right: 0.35rem; } .current-weather { display: flex; flex-direction: column; align-items: center; margin-bottom: 2rem; position: relative; } .temp-icon { display: flex; align-items: center; justify-content: center; margin-bottom: 1rem; } .temperature { font-size: 4rem; font-weight: 700; margin-right: 1rem; line-height: 1; } .weather-icon { font-size: 3rem; color: var(--sky-blue); } .weather-description { text-align: center; } .weather-description h2 { font-size: 1.5rem; font-weight: 600; margin-bottom: 0.5rem; } .weather-description p { color: var(--gray-400); font-size: 0.9rem; } .weather-details { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; margin-bottom: 2rem; } .detail-card { background: rgba(255, 255, 255, 0.08); border-radius: 16px; padding: 1rem; display: flex; flex-direction: column; align-items: center; justify-content: center; transition: transform var(--animation-speed) ease; } .detail-card:hover { transform: translateY(-5px); background: rgba(255, 255, 255, 0.12); } .detail-card svg { margin-bottom: 0.5rem; color: var(--light-blue); } .detail-card span { font-size: 1.1rem; font-weight: 600; margin-bottom: 0.25rem; } .detail-card small { color: var(--gray-500); font-size: 0.75rem; } .forecast-heading { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem; } .forecast-heading h3 { font-size: 1.2rem; font-weight: 600; } .forecast-selector { display: flex; gap: 0.5rem; } .forecast-btn { background: transparent; border: none; color: var(--gray-400); font-size: 0.9rem; font-weight: 500; padding: 0.5rem 0.75rem; border-radius: 8px; cursor: pointer; position: relative; overflow: hidden; transition: all 0.3s ease; } .forecast-btn.active { background: var(--primary-blue); color: white; } .forecast-btn:hover:not(.active) { color: white; background: rgba(255, 255, 255, 0.1); } /* Ripple effect */ .ripple { position: absolute; background: rgba(255, 255, 255, 0.3); border-radius: 50%; transform: scale(0); animation: ripple 0.6s linear; pointer-events: none; } @keyframes ripple { to { transform: scale(4); opacity: 0; } } .forecast-content { flex-grow: 1; overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--gray-600) transparent; } .forecast-content::-webkit-scrollbar { width: 6px; } .forecast-content::-webkit-scrollbar-track { background: transparent; } .forecast-content::-webkit-scrollbar-thumb { background-color: var(--gray-600); border-radius: 3px; } .forecast-days { display: none; } .forecast-days.active { display: block; } .forecast-day { display: flex; align-items: center; padding: 0.75rem; border-radius: 12px; margin-bottom: 0.75rem; background: rgba(255, 255, 255, 0.08); transition: transform 0.3s ease, background 0.3s ease; } .forecast-day:hover { transform: translateX(5px); background: rgba(255, 255, 255, 0.12); } .forecast-day-name { width: 100px; font-weight: 600; } .forecast-day-icon { flex: 0 0 40px; text-align: center; color: var(--sky-blue); } .forecast-day-temp { flex: 1; display: flex; justify-content: flex-end; align-items: center; } .forecast-day-high { font-weight: 600; margin-right: 0.5rem; } .forecast-day-low { color: var(--gray-500); } .forecast-hours { display: none; overflow-x: auto; white-space: nowrap; scrollbar-width: none; -ms-overflow-style: none; padding-bottom: 0.5rem; } .forecast-hours::-webkit-scrollbar { display: none; } .forecast-hours.active { display: flex; gap: 0.75rem; } .forecast-hour { flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; padding: 1rem 1.25rem; background: rgba(255, 255, 255, 0.08); border-radius: 16px; transition: transform 0.3s ease, background 0.3s ease; } .forecast-hour:hover { transform: translateY(-5px); background: rgba(255, 255, 255, 0.12); } .forecast-hour-time { font-size: 0.9rem; font-weight: 600; margin-bottom: 0.5rem; } .forecast-hour-icon { margin-bottom: 0.5rem; color: var(--sky-blue); font-size: 1.5rem; } .forecast-hour-temp { font-weight: 600; } @media (max-width: 600px) { .container { padding: 1rem; } .weather-app { padding: 1.5rem; } .temperature { font-size: 3rem; } .weather-details { grid-template-columns: repeat(2, 1fr); } .forecast-heading { flex-direction: column; align-items: flex-start; gap: 0.5rem; } .forecast-day-name { width: 80px; } } /* Weather animation */ .weather-animation { position: absolute; top: 0; left: 0; right: 0; bottom: 0; pointer-events: none; overflow: hidden; } .weather-overlay { position: absolute; top: 0; left: 0; right: 0; bottom: 0; z-index: -1; } .cloud { position: absolute; width: 180px; height: 60px; background: rgba(255, 255, 255, 0.08); border-radius: 50px; filter: blur(10px); animation: float 30s infinite linear; } .cloud:nth-child(1) { top: 15%; left: -10%; animation-duration: 60s; } .cloud:nth-child(2) { top: 45%; left: -15%; animation-duration: 70s; animation-delay: 10s; width: 150px; height: 50px; } .cloud:nth-child(3) { top: 75%; left: -5%; animation-duration: 50s; animation-delay: 5s; width: 120px; height: 40px; } @keyframes float { 0% { transform: translateX(0); } 100% { transform: translateX(calc(100vw + 200px)); } } </style> </head> <body> <div class="container"> <div class="weather-app"> <div class="app-header"> <div class="logo"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z"></path> </svg> Atmospheric </div> <div class="location"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z"></path> <circle cx="12" cy="10" r="3"></circle> </svg> Seattle, WA </div> </div> <div class="current-weather"> <div class="temp-icon"> <div class="temperature">62°</div> <div class="weather-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z"></path> </svg> </div> </div> <div class="weather-description"> <h2>Partly Cloudy</h2> <p>Feels like 59°. Scattered clouds with light winds.</p> </div> </div> <div class="weather-details"> <div class="detail-card"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M12 16a4 4 0 1 0 0-8 4 4 0 0 0 0 8z"></path> <path d="M12 4v2"></path> <path d="M12 18v2"></path> <path d="M4 12H6"></path> <path d="M18 12h2"></path> </svg> <span>10:43 AM</span> <small>SUNRISE</small> </div> <div class="detail-card"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M17 3l-5 5-5-5M12 3v15"></path> <path d="M8 16l4 4 4-4"></path> </svg> <span>7:21 PM</span> <small>SUNSET</small> </div> <div class="detail-card"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M12 3v16M4 15h16M3 15a9 9 0 0 1 18 0"></path> </svg> <span>68%</span> <small>HUMIDITY</small> </div> <div class="detail-card"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M9.59 4.59A2 2 0 1 1 11 8H2m10.59 11.41A2 2 0 1 0 14 16H2m15.73-8.27A2.5 2.5 0 1 1 19.5 12H2"></path> </svg> <span>12 mph</span> <small>WIND</small> </div> <div class="detail-card"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M8 3v3a2 2 0 0 1-2 2H3"></path> <path d="M15 3v3a2 2 0 0 0 2 2h3"></path> <path d="M3 15h3a2 2 0 0 1 2 2v3"></path> <path d="M21 15h-3a2 2 0 0 0-2 2v3"></path> </svg> <span>8 miles</span> <small>VISIBILITY</small> </div> <div class="detail-card"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M12 9a4 4 0 0 0-2 7.5"></path> <path d="M12 3v2"></path> <path d="M6.6 18.4l-1.4 1.4"></path> <path d="M20 12h-2"></path> <path d="M6.6 5.6 5.2 4.2"></path> <path d="M12 21v-2"></path> <path d="M16 12a4 4 0 0 1-4 4"></path> </svg> <span>29.92 inHg</span> <small>PRESSURE</small> </div> </div> <div class="forecast-section"> <div class="forecast-heading"> <h3>Weather Forecast</h3> <div class="forecast-selector"> <button class="forecast-btn active" data-target="hourly">Hourly</button> <button class="forecast-btn" data-target="daily">Daily</button> </div> </div> <div class="forecast-content"> <div class="forecast-hours active" id="hourly"> <div class="forecast-hour"> <div class="forecast-hour-time">Now</div> <div class="forecast-hour-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z"></path> </svg> </div> <div class="forecast-hour-temp">62°</div> </div> <div class="forecast-hour"> <div class="forecast-hour-time">2 PM</div> <div class="forecast-hour-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M12 16a4 4 0 1 0 0-8 4 4 0 0 0 0 8z"></path> <path d="M12 8v-3"></path> <path d="M12 21v-3"></path> <path d="M4.22 10.22l2.12-2.12"></path> <path d="M17.66 17.66l2.12-2.12"></path> <path d="M16 12h3"></path> <path d="M5 12h3"></path> <path d="M6.34 17.66l-2.12-2.12"></path> <path d="M19.78 10.22l-2.12-2.12"></path> </svg> </div> <div class="forecast-hour-temp">65°</div> </div> <div class="forecast-hour"> <div class="forecast-hour-time">3 PM</div> <div class="forecast-hour-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M12 16a4 4 0 1 0 0-8 4 4 0 0 0 0 8z"></path> <path d="M12 8v-3"></path> <path d="M12 21v-3"></path> <path d="M4.22 10.22l2.12-2.12"></path> <path d="M17.66 17.66l2.12-2.12"></path> <path d="M16 12h3"></path> <path d="M5 12h3"></path> <path d="M6.34 17.66l-2.12-2.12"></path> <path d="M19.78 10.22l-2.12-2.12"></path> </svg> </div> <div class="forecast-hour-temp">66°</div> </div> <div class="forecast-hour"> <div class="forecast-hour-time">4 PM</div> <div class="forecast-hour-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z"></path> </svg> </div> <div class="forecast-hour-temp">65°</div> </div> <div class="forecast-hour"> <div class="forecast-hour-time">5 PM</div> <div class="forecast-hour-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z"></path> </svg> </div> <div class="forecast-hour-temp">63°</div> </div> <div class="forecast-hour"> <div class="forecast-hour-time">6 PM</div> <div class="forecast-hour-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z"></path> </svg> </div> <div class="forecast-hour-temp">60°</div> </div> <div class="forecast-hour"> <div class="forecast-hour-time">7 PM</div> <div class="forecast-hour-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z"></path> </svg> </div> <div class="forecast-hour-temp">58°</div> </div> </div> <div class="forecast-days" id="daily"> <div class="forecast-day"> <div class="forecast-day-name">Today</div> <div class="forecast-day-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z"></path> </svg> </div> <div class="forecast-day-temp"> <div class="forecast-day-high">66°</div> <div class="forecast-day-low">54°</div> </div> </div> <div class="forecast-day"> <div class="forecast-day-name">Tuesday</div> <div class="forecast-day-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M12 16a4 4 0 1 0 0-8 4 4 0 0 0 0 8z"></path> <path d="M12 8v-3"></path> <path d="M12 21v-3"></path> <path d="M4.22 10.22l2.12-2.12"></path> <path d="M17.66 17.66l2.12-2.12"></path> <path d="M16 12h3"></path> <path d="M5 12h3"></path> <path d="M6.34 17.66l-2.12-2.12"></path> <path d="M19.78 10.22l-2.12-2.12"></path> </svg> </div> <div class="forecast-day-temp"> <div class="forecast-day-high">70°</div> <div class="forecast-day-low">56°</div> </div> </div> <div class="forecast-day"> <div class="forecast-day-name">Wednesday</div> <div class="forecast-day-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M12 16a4 4 0 1 0 0-8 4 4 0 0 0 0 8z"></path> <path d="M12 8v-3"></path> <path d="M12 21v-3"></path> <path d="M4.22 10.22l2.12-2.12"></path> <path d="M17.66 17.66l2.12-2.12"></path> <path d="M16 12h3"></path> <path d="M5 12h3"></path> <path d="M6.34 17.66l-2.12-2.12"></path> <path d="M19.78 10.22l-2.12-2.12"></path> </svg> </div> <div class="forecast-day-temp"> <div class="forecast-day-high">73°</div> <div class="forecast-day-low">58°</div> </div> </div> <div class="forecast-day"> <div class="forecast-day-name">Thursday</div> <div class="forecast-day-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z"></path> </svg> </div> <div class="forecast-day-temp"> <div class="forecast-day-high">68°</div> <div class="forecast-day-low">57°</div> </div> </div> <div class="forecast-day"> <div class="forecast-day-name">Friday</div> <div class="forecast-day-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M20 16.2A4.5 4.5 0 0 0 17.5 8h-1.8A7 7 0 1 0 4 14.9"></path> <path d="M16 14v6"></path> <path d="M8 14v6"></path> <path d="M12 16v6"></path> </svg> </div> <div class="forecast-day-temp"> <div class="forecast-day-high">64°</div> <div class="forecast-day-low">55°</div> </div> </div> <div class="forecast-day"> <div class="forecast-day-name">Saturday</div> <div class="forecast-day-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M20 16.2A4.5 4.5 0 0 0 17.5 8h-1.8A7 7 0 1 0 4 14.9"></path> <path d="M16 14v6"></path> <path d="M8 14v6"></path> <path d="M12 16v6"></path> </svg> </div> <div class="forecast-day-temp"> <div class="forecast-day-high">62°</div> <div class="forecast-day-low">53°</div> </div> </div> <div class="forecast-day"> <div class="forecast-day-name">Sunday</div> <div class="forecast-day-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z"></path> </svg> </div> <div class="forecast-day-temp"> <div class="forecast-day-high">65°</div> <div class="forecast-day-low">54°</div> </div> </div> </div> </div> </div> <div class="weather-animation"> <div class="weather-overlay"> <div class="cloud"></div> <div class="cloud"></div> <div class="cloud"></div> </div> </div> </div> </div> <script> // Ripple effect for forecast buttons document.querySelectorAll('.forecast-btn').forEach(button => { button.addEventListener('click', function(e) { const rect = button.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; const ripple = document.createElement('span'); ripple.classList.add('ripple'); ripple.style.left = `${x}px`; ripple.style.top = `${y}px`; button.appendChild(ripple); // Remove ripple after animation completes setTimeout(() => { ripple.remove(); }, 600); // Toggle active class on buttons document.querySelectorAll('.forecast-btn').forEach(btn => { btn.classList.remove('active'); }); this.classList.add('active'); // Toggle active class on forecast content const target = this.dataset.target; document.querySelectorAll('.forecast-hours, .forecast-days').forEach(content => { content.classList.remove('active'); }); document.getElementById(target).classList.add('active'); }); }); // Make forecast items interactive document.querySelectorAll('.forecast-hour, .forecast-day').forEach(item => { item.addEventListener('mouseenter', function() { this.style.transform = this.classList.contains('forecast-hour') ? 'translateY(-8px)' : 'translateX(8px)'; }); item.addEventListener('mouseleave', function() { this.style.transform = ''; }); }); // Initialize current time const updateTime = () => { const now = new Date(); const hours = now.getHours(); const minutes = now.getMinutes(); const ampm = hours >= 12 ? 'PM' : 'AM'; const formattedHours = hours % 12 || 12; const formattedMinutes = minutes < 10 ? '0' + minutes : minutes; // Update any time-related elements if needed }; // Run once updateTime(); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> :root { --primary: #3a4750; --secondary: #303841; --accent: #00adb5; --text: #eeeeee; --bg: #f9f9f9; --card: #ffffff; --shadow: rgba(0, 0, 0, 0.05); --toggle-off: #d9d9d9; --toggle-on: #00adb5; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; } body { background-color: var(--bg); color: var(--primary); height: 100vh; display: flex; justify-content: center; align-items: center; overflow: hidden; } .container { width: 700px; height: 700px; max-width: 100%; max-height: 100%; padding: 24px; display: flex; flex-direction: column; overflow-y: auto; scrollbar-width: none; } .container::-webkit-scrollbar { display: none; } header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 32px; } h1 { font-size: 28px; font-weight: 700; color: var(--primary); } .user-profile { display: flex; align-items: center; gap: 12px; } .avatar { width: 40px; height: 40px; background-color: var(--accent); border-radius: 50%; display: flex; align-items: center; justify-content: center; color: white; font-weight: 600; letter-spacing: 1px; position: relative; overflow: hidden; cursor: pointer; } .avatar:after { content: ''; position: absolute; width: 100%; height: 100%; background: radial-gradient(circle, rgba(255,255,255,0.2) 0%, rgba(255,255,255,0) 70%); transform: scale(0); opacity: 0; transition: transform 0.5s, opacity 0.3s; } .avatar:hover:after { transform: scale(2); opacity: 1; } .welcome { font-size: 14px; color: var(--secondary); } .welcome span { display: block; font-weight: 600; font-size: 16px; } .status-summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 16px; margin-bottom: 32px; } .status-card { background-color: var(--card); border-radius: 12px; padding: 16px; box-shadow: 0 4px 12px var(--shadow); display: flex; flex-direction: column; transition: transform 0.2s ease; } .status-card:hover { transform: translateY(-3px); } .card-title { font-size: 14px; color: var(--secondary); margin-bottom: 4px; display: flex; align-items: center; gap: 6px; } .card-title i { font-size: 16px; color: var(--accent); } .card-value { font-size: 24px; font-weight: 700; color: var(--primary); } .card-value.energy { color: #22c55e; } .card-value.temperature { color: #f59e0b; } .card-value.security { color: #3b82f6; } .card-value.lighting { color: #8b5cf6; } .control-groups { display: flex; flex-direction: column; gap: 24px; } .control-group { background-color: var(--card); border-radius: 16px; padding: 20px; box-shadow: 0 4px 16px var(--shadow); } .group-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; } .group-title { font-size: 18px; font-weight: 600; color: var(--primary); display: flex; align-items: center; gap: 8px; } .group-title i { color: var(--accent); } .control-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; } .control-item { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; background-color: var(--bg); border-radius: 10px; transition: all 0.2s ease; } .control-item:hover { background-color: rgba(238, 238, 238, 0.7); } .control-name { font-size: 15px; color: var(--primary); display: flex; align-items: center; gap: 8px; } .control-name i { font-size: 16px; width: 24px; text-align: center; } .toggle { position: relative; width: 48px; height: 24px; background-color: var(--toggle-off); border-radius: 24px; cursor: pointer; transition: background-color 0.2s ease; overflow: hidden; } .toggle-handle { position: absolute; top: 2px; left: 2px; width: 20px; height: 20px; background-color: white; border-radius: 50%; transition: transform 0.2s ease; } .toggle.active { background-color: var(--toggle-on); } .toggle.active .toggle-handle { transform: translateX(24px); } .ripple { position: absolute; border-radius: 50%; background: rgba(255, 255, 255, 0.4); transform: scale(0); animation: ripple 0.6s ease-out; } @keyframes ripple { to { transform: scale(2.5); opacity: 0; } } .scene-container { margin-top: 24px; } .scene-title { font-size: 16px; font-weight: 600; margin-bottom: 16px; color: var(--primary); } .scenes { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 12px; } .scene { background-color: var(--bg); border-radius: 12px; padding: 16px 12px; display: flex; flex-direction: column; align-items: center; gap: 12px; transition: all 0.2s ease; cursor: pointer; position: relative; overflow: hidden; } .scene:hover { background-color: rgba(238, 238, 238, 0.7); transform: translateY(-2px); } .scene.active { background-color: rgba(0, 173, 181, 0.1); border: 1px solid var(--accent); } .scene-icon { width: 44px; height: 44px; background-color: white; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: var(--accent); font-size: 20px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); } .scene.active .scene-icon { background-color: var(--accent); color: white; } .scene-name { font-size: 14px; font-weight: 500; text-align: center; } .footer { margin-top: 32px; text-align: center; font-size: 12px; color: var(--primary); opacity: 0.7; } .smart-stat { margin-top: 16px; padding: 16px; background-color: rgba(0, 173, 181, 0.08); border-radius: 12px; border-left: 3px solid var(--accent); } .stat-title { font-size: 14px; font-weight: 600; margin-bottom: 4px; color: var(--accent); } .stat-value { font-size: 13px; line-height: 1.5; color: var(--secondary); } /* Animation for temperature change */ @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } } .pulse { animation: pulse 1.5s ease-in-out; } .theme-toggle { background: none; border: none; cursor: pointer; color: var(--primary); font-size: 20px; margin-left: auto; margin-right: 16px; } /* Media queries for responsiveness */ @media (max-width: 600px) { .container { padding: 16px; } h1 { font-size: 24px; } .status-summary { grid-template-columns: repeat(2, 1fr); } .control-grid { grid-template-columns: 1fr; } .scenes { grid-template-columns: repeat(2, 1fr); } } @media (max-width: 400px) { .status-summary { grid-template-columns: 1fr; } .scenes { grid-template-columns: 1fr; } } </style> </head> <body> <div class="container"> <header> <h1>Home Control</h1> <button class="theme-toggle" id="themeToggle"> <i class="fas fa-moon"></i> </button> <div class="user-profile"> <div class="welcome"> Good evening, <span>Alex</span> </div> <div class="avatar">A</div> </div> </header> <div class="status-summary"> <div class="status-card"> <div class="card-title"> <i class="fas fa-bolt"></i> Energy </div> <div class="card-value energy">4.2 kWh</div> </div> <div class="status-card"> <div class="card-title"> <i class="fas fa-thermometer-half"></i> Temperature </div> <div class="card-value temperature" id="tempValue">22°C</div> </div> <div class="status-card"> <div class="card-title"> <i class="fas fa-shield-alt"></i> Security </div> <div class="card-value security">Armed</div> </div> <div class="status-card"> <div class="card-title"> <i class="fas fa-lightbulb"></i> Lighting </div> <div class="card-value lighting">3 Active</div> </div> </div> <div class="control-groups"> <div class="control-group"> <div class="group-header"> <div class="group-title"> <i class="fas fa-lightbulb"></i> Lighting </div> </div> <div class="control-grid"> <div class="control-item"> <div class="control-name"> <i class="fas fa-couch"></i> Living Room </div> <div class="toggle" data-control="living-light"> <div class="toggle-handle"></div> </div> </div> <div class="control-item"> <div class="control-name"> <i class="fas fa-utensils"></i> Kitchen </div> <div class="toggle active" data-control="kitchen-light"> <div class="toggle-handle"></div> </div> </div> <div class="control-item"> <div class="control-name"> <i class="fas fa-bed"></i> Bedroom </div> <div class="toggle" data-control="bedroom-light"> <div class="toggle-handle"></div> </div> </div> <div class="control-item"> <div class="control-name"> <i class="fas fa-bath"></i> Bathroom </div> <div class="toggle active" data-control="bathroom-light"> <div class="toggle-handle"></div> </div> </div> </div> </div> <div class="control-group"> <div class="group-header"> <div class="group-title"> <i class="fas fa-thermometer-half"></i> Climate </div> </div> <div class="control-grid"> <div class="control-item"> <div class="control-name"> <i class="fas fa-snowflake"></i> AC System </div> <div class="toggle active" data-control="ac-system"> <div class="toggle-handle"></div> </div> </div> <div class="control-item"> <div class="control-name"> <i class="fas fa-wind"></i> Fan </div> <div class="toggle" data-control="fan"> <div class="toggle-handle"></div> </div> </div> <div class="control-item"> <div class="control-name"> <i class="fas fa-water"></i> Humidifier </div> <div class="toggle" data-control="humidifier"> <div class="toggle-handle"></div> </div> </div> </div> <div class="smart-stat"> <div class="stat-title">Smart Climate Insight</div> <div class="stat-value">AC settings optimized for evening comfort. Current efficiency 92% above average for similar homes in your area.</div> </div> </div> <div class="control-group"> <div class="group-header"> <div class="group-title"> <i class="fas fa-shield-alt"></i> Security </div> </div> <div class="control-grid"> <div class="control-item"> <div class="control-name"> <i class="fas fa-home"></i> Alarm System </div> <div class="toggle active" data-control="alarm"> <div class="toggle-handle"></div> </div> </div> <div class="control-item"> <div class="control-name"> <i class="fas fa-video"></i> Cameras </div> <div class="toggle active" data-control="cameras"> <div class="toggle-handle"></div> </div> </div> <div class="control-item"> <div class="control-name"> <i class="fas fa-door-closed"></i> Door Locks </div> <div class="toggle active" data-control="locks"> <div class="toggle-handle"></div> </div> </div> </div> </div> <div class="scene-container"> <div class="scene-title">Quick Scenes</div> <div class="scenes"> <div class="scene active" data-scene="home"> <div class="scene-icon"> <i class="fas fa-home"></i> </div> <div class="scene-name">Home</div> </div> <div class="scene" data-scene="away"> <div class="scene-icon"> <i class="fas fa-car"></i> </div> <div class="scene-name">Away</div> </div> <div class="scene" data-scene="sleep"> <div class="scene-icon"> <i class="fas fa-moon"></i> </div> <div class="scene-name">Sleep</div> </div> <div class="scene" data-scene="movie"> <div class="scene-icon"> <i class="fas fa-film"></i> </div> <div class="scene-name">Movie</div> </div> </div> </div> </div> <div class="footer"> Your home is running efficiently • Last update: just now </div> </div> <script> document.addEventListener('DOMContentLoaded', () => { // Toggle functionality const toggles = document.querySelectorAll('.toggle'); toggles.forEach(toggle => { toggle.addEventListener('click', function(e) { // Create ripple effect const ripple = document.createElement('div'); ripple.className = 'ripple'; this.appendChild(ripple); // Position the ripple where clicked const rect = this.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; ripple.style.left = `${x}px`; ripple.style.top = `${y}px`; // Toggle active state this.classList.toggle('active'); // Remove ripple after animation completes setTimeout(() => { ripple.remove(); }, 600); // Update stats based on toggle actions updateStats(toggle.dataset.control, toggle.classList.contains('active')); }); }); // Scene selection const scenes = document.querySelectorAll('.scene'); scenes.forEach(scene => { scene.addEventListener('click', function() { // Remove active class from all scenes scenes.forEach(s => s.classList.remove('active')); // Add active class to clicked scene this.classList.add('active'); // Apply scene settings applyScene(this.dataset.scene); // Create ripple effect for scene const ripple = document.createElement('div'); ripple.className = 'ripple'; this.appendChild(ripple); const rect = this.getBoundingClientRect(); ripple.style.left = `${rect.width / 2}px`; ripple.style.top = `${rect.height / 2}px`; setTimeout(() => { ripple.remove(); }, 600); }); }); // Temperature update simulation let temperature = 22; setInterval(() => { const tempElement = document.getElementById('tempValue'); const randomChange = (Math.random() > 0.5 ? 0.1 : -0.1); temperature += randomChange; temperature = Math.round(temperature * 10) / 10; tempElement.textContent = `${temperature.toFixed(1)}°C`; tempElement.classList.add('pulse'); setTimeout(() => { tempElement.classList.remove('pulse'); }, 1500); }, 8000); // Theme toggle const themeToggle = document.getElementById('themeToggle'); themeToggle.addEventListener('click', function() { const root = document.documentElement; const icon = this.querySelector('i'); if (icon.classList.contains('fa-moon')) { // Switch to dark mode root.style.setProperty('--primary', '#eeeeee'); root.style.setProperty('--secondary', '#d9d9d9'); root.style.setProperty('--text', '#303841'); root.style.setProperty('--bg', '#202124'); root.style.setProperty('--card', '#303841'); root.style.setProperty('--shadow', 'rgba(0, 0, 0, 0.2)'); icon.classList.remove('fa-moon'); icon.classList.add('fa-sun'); } else { // Switch to light mode root.style.setProperty('--primary', '#3a4750'); root.style.setProperty('--secondary', '#303841'); root.style.setProperty('--text', '#eeeeee'); root.style.setProperty('--bg', '#f9f9f9'); root.style.setProperty('--card', '#ffffff'); root.style.setProperty('--shadow', 'rgba(0, 0, 0, 0.05)'); icon.classList.remove('fa-sun'); icon.classList.add('fa-moon'); } }); // Function to update statistics based on control changes function updateStats(controlName, isActive) { const energyValue = document.querySelector('.card-value.energy'); const lightingValue = document.querySelector('.card-value.lighting'); if (controlName.includes('light')) { // Update lighting count const currentLights = parseInt(lightingValue.textContent.split(' ')[0]); const newLightCount = isActive ? currentLights + 1 : currentLights - 1; lightingValue.textContent = `${newLightCount} Active`; // Update energy usage const currentEnergy = parseFloat(energyValue.textContent.split(' ')[0]); const newEnergy = isActive ? (currentEnergy + 0.1).toFixed(1) : (currentEnergy - 0.1).toFixed(1); energyValue.textContent = `${newEnergy} kWh`; } if (controlName === 'ac-system' || controlName === 'fan') { // Update energy for climate devices const currentEnergy = parseFloat(energyValue.textContent.split(' ')[0]); const change = controlName === 'ac-system' ? 0.3 : 0.2; const newEnergy = isActive ? (currentEnergy + change).toFixed(1) : (currentEnergy - change).toFixed(1); energyValue.textContent = `${newEnergy} kWh`; } } // Function to apply scene presets function applyScene(sceneName) { const lightToggles = { 'living-light': false, 'kitchen-light': false, 'bedroom-light': false, 'bathroom-light': false }; const securityToggles = { 'alarm': true, 'cameras': true, 'locks': true }; const climateToggles = { 'ac-system': false, 'fan': false, 'humidifier': false }; // Configure scene presets switch(sceneName) { case 'home': lightToggles['living-light'] = true; lightToggles['kitchen-light'] = true; climateToggles['ac-system'] = true; break; case 'away': // All lights off, security on break; case 'sleep': lightToggles['bedroom-light'] = true; climateToggles['fan'] = true; break; case 'movie': lightToggles['living-light'] = true; climateToggles['ac-system'] = true; break; } // Apply settings to toggles Object.keys(lightToggles).forEach(key => { const toggle = document.querySelector(`.toggle[data-control="${key}"]`); if (toggle) { if (lightToggles[key]) { if (!toggle.classList.contains('active')) { toggle.classList.add('active'); updateStats(key, true); } } else { if (toggle.classList.contains('active')) { toggle.classList.remove('active'); updateStats(key, false); } } } }); Object.keys(securityToggles).forEach(key => { const toggle = document.querySelector(`.toggle[data-control="${key}"]`); if (toggle) { if (securityToggles[key]) { if (!toggle.classList.contains('active')) { toggle.classList.add('active'); } } else { if (toggle.classList.contains('active')) { toggle.classList.remove('active'); } } } }); Object.keys(climateToggles).forEach(key => { const toggle = document.querySelector(`.toggle[data-control="${key}"]`); if (toggle) { if (climateToggles[key]) { if (!toggle.classList.contains('active')) { toggle.classList.add('active'); updateStats(key, true); } } else { if (toggle.classList.contains('active')) { toggle.classList.remove('active'); updateStats(key, false); } } } }); // Update lighting count const activeCount = Object.values(lightToggles).filter(val => val).length; const lightingValue = document.querySelector('.card-value.lighting'); lightingValue.textContent = `${activeCount} Active`; } }); </script> <script src="https://kit.fontawesome.com/a076d05399.js" crossorigin="anonymous"></script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Focus Flow - Minimalist Productivity Tool</title> <style> :root { --primary: #2a2a2a; --secondary: #3a3a3a; --accent: #4f9cf9; --text: #f0f0f0; --subtle: #8a8a8a; --background: #202020; --success: #4ecb71; --warning: #fdbe3b; --card-bg: #282828; --shadow: rgba(0, 0, 0, 0.2); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; transition: all 0.2s ease; } body { background-color: var(--background); color: var(--text); height: 700px; width: 700px; overflow-x: hidden; display: flex; flex-direction: column; } .app-container { max-width: 700px; padding: 24px; width: 100%; height: 100%; display: flex; flex-direction: column; } header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; padding-bottom: 16px; border-bottom: 1px solid var(--secondary); } .logo { font-size: 20px; font-weight: 700; letter-spacing: -0.5px; color: var(--text); display: flex; align-items: center; gap: 6px; } .logo-icon { display: inline-block; width: 24px; height: 24px; background-color: var(--accent); border-radius: 8px; position: relative; overflow: hidden; } .logo-icon::after { content: ''; position: absolute; top: 6px; left: 6px; width: 12px; height: 12px; background-color: var(--background); border-radius: 4px; } .tab-container { display: flex; gap: 2px; background-color: var(--secondary); padding: 4px; border-radius: 8px; } .tab { padding: 8px 16px; border-radius: 6px; font-size: 14px; font-weight: 500; color: var(--subtle); cursor: pointer; position: relative; overflow: hidden; border: none; background: transparent; } .tab.active { background-color: var(--card-bg); color: var(--text); } .main-content { display: flex; flex-direction: column; gap: 20px; flex-grow: 1; overflow-y: auto; padding-right: 4px; } .section { background-color: var(--card-bg); border-radius: 12px; padding: 20px; position: relative; } .section-title { font-size: 14px; font-weight: 600; margin-bottom: 16px; color: var(--subtle); text-transform: uppercase; letter-spacing: 1px; } .tasks { display: flex; flex-direction: column; gap: 12px; } .task-item { display: flex; align-items: center; gap: 12px; padding: 12px; border-radius: 8px; background-color: var(--secondary); } .task-complete { opacity: 0.6; } .task-checkbox { width: 20px; height: 20px; border-radius: 6px; border: 2px solid var(--subtle); cursor: pointer; position: relative; overflow: hidden; } .task-checkbox.checked { background-color: var(--accent); border-color: var(--accent); } .task-checkbox.checked::after { content: ''; position: absolute; top: 3px; left: 6px; width: 5px; height: 10px; border: solid white; border-width: 0 2px 2px 0; transform: rotate(45deg); } .task-content { flex-grow: 1; } .task-title { font-size: 15px; font-weight: 500; margin-bottom: 4px; } .task-description { font-size: 13px; color: var(--subtle); } .task-complete .task-title { text-decoration: line-through; color: var(--subtle); } .task-priority { width: 4px; height: 36px; border-radius: 2px; background-color: var(--warning); margin-right: 6px; } .task-priority.high { background-color: #ff5858; } .task-priority.medium { background-color: var(--warning); } .task-priority.low { background-color: var(--success); } .settings-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; } .setting-item { display: flex; justify-content: space-between; align-items: center; } .setting-label { font-size: 14px; color: var(--text); } .toggle { position: relative; width: 44px; height: 24px; cursor: pointer; } .toggle input { opacity: 0; width: 0; height: 0; } .toggle-slider { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: var(--secondary); border-radius: 24px; transition: 0.3s; } .toggle-slider:before { position: absolute; content: ""; height: 18px; width: 18px; left: 3px; bottom: 3px; background-color: var(--text); border-radius: 50%; transition: 0.3s; } input:checked + .toggle-slider { background-color: var(--accent); } input:checked + .toggle-slider:before { transform: translateX(20px); } .action-row { display: flex; gap: 12px; justify-content: flex-end; margin-top: 16px; } button { cursor: pointer; overflow: hidden; position: relative; border: none; outline: none; font-size: 14px; font-weight: 500; transition: all 0.2s ease; } .btn { padding: 10px 16px; border-radius: 8px; display: flex; align-items: center; justify-content: center; gap: 8px; } .btn-primary { background-color: var(--accent); color: white; } .btn-secondary { background-color: var(--secondary); color: var(--text); } .ripple { position: absolute; background-color: rgba(255, 255, 255, 0.2); border-radius: 50%; transform: scale(0); animation: ripple 0.6s linear; pointer-events: none; } @keyframes ripple { 0% { transform: scale(0); opacity: 0.5; } 100% { transform: scale(2.5); opacity: 0; } } .action-icon { width: 16px; height: 16px; display: flex; align-items: center; justify-content: center; } /* Custom scrollbar */ .main-content::-webkit-scrollbar { width: 6px; } .main-content::-webkit-scrollbar-track { background: var(--background); } .main-content::-webkit-scrollbar-thumb { background: var(--secondary); border-radius: 6px; } .main-content::-webkit-scrollbar-thumb:hover { background: var(--subtle); } /* Add task form */ .add-task-form { display: flex; flex-direction: column; gap: 16px; } .form-group { display: flex; flex-direction: column; gap: 8px; } .form-label { font-size: 13px; color: var(--subtle); } .form-input { padding: 12px; border-radius: 8px; border: none; background-color: var(--secondary); color: var(--text); font-size: 14px; } .form-input:focus { outline: 2px solid var(--accent); } textarea.form-input { resize: vertical; min-height: 80px; } .priority-options { display: flex; gap: 12px; } .priority-option { flex: 1; padding: 10px; border-radius: 8px; background-color: var(--secondary); display: flex; align-items: center; justify-content: center; cursor: pointer; position: relative; overflow: hidden; } .priority-option.selected { background-color: var(--card-bg); outline: 2px solid var(--accent); } /* Toast notification */ .toast { position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%); background-color: var(--success); color: white; padding: 12px 20px; border-radius: 8px; font-size: 14px; font-weight: 500; opacity: 0; transition: opacity 0.3s ease; box-shadow: 0 4px 12px rgba(0,0,0,0.1); z-index: 1000; pointer-events: none; } .toast.show { opacity: 1; } .tab-content { display: none; } .tab-content.active { display: block; } @media (max-width: 600px) { .settings-grid { grid-template-columns: 1fr; } .app-container { padding: 16px; } } </style> </head> <body> <div class="app-container"> <header> <div class="logo"> <span class="logo-icon"></span> FocusFlow </div> <div class="tab-container"> <button class="tab active" data-tab="tasks">Tasks</button> <button class="tab" data-tab="add">Add Task</button> <button class="tab" data-tab="settings">Settings</button> </div> </header> <div class="main-content"> <div id="tasks-tab" class="tab-content active"> <div class="section"> <h2 class="section-title">Today's Focus</h2> <div class="tasks"> <div class="task-item"> <div class="task-priority high"></div> <div class="task-checkbox" data-task-id="1"></div> <div class="task-content"> <div class="task-title">Finalize Q3 productivity report</div> <div class="task-description">Include statistics on team efficiency and resource allocation</div> </div> </div> <div class="task-item"> <div class="task-priority medium"></div> <div class="task-checkbox" data-task-id="2"></div> <div class="task-content"> <div class="task-title">Review API documentation</div> <div class="task-description">Focus on authentication and rate limiting sections</div> </div> </div> <div class="task-item task-complete"> <div class="task-priority low"></div> <div class="task-checkbox checked" data-task-id="3"></div> <div class="task-content"> <div class="task-title">Set up weekly team sync</div> <div class="task-description">Create agenda template and send calendar invites</div> </div> </div> </div> </div> <div class="section"> <h2 class="section-title">Upcoming</h2> <div class="tasks"> <div class="task-item"> <div class="task-priority medium"></div> <div class="task-checkbox" data-task-id="4"></div> <div class="task-content"> <div class="task-title">Prepare user testing script</div> <div class="task-description">Include 5-7 key scenarios to validate new dashboard</div> </div> </div> <div class="task-item"> <div class="task-priority low"></div> <div class="task-checkbox" data-task-id="5"></div> <div class="task-content"> <div class="task-title">Update design system documentation</div> <div class="task-description">Add new component patterns and usage guidelines</div> </div> </div> </div> <div class="action-row"> <button class="btn btn-secondary"> <span class="action-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"></polygon> <path d="M15.54 8.46a5 5 0 0 1 0 7.07"></path> <path d="M19.07 4.93a10 10 0 0 1 0 14.14"></path> </svg> </span> Focus Mode </button> <button class="btn btn-primary"> <span class="action-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <line x1="12" y1="5" x2="12" y2="19"></line> <line x1="5" y1="12" x2="19" y2="12"></line> </svg> </span> Add Task </button> </div> </div> </div> <div id="add-task-tab" class="tab-content"> <div class="section"> <h2 class="section-title">Create New Task</h2> <form class="add-task-form"> <div class="form-group"> <label class="form-label">Task Title</label> <input type="text" class="form-input" placeholder="What needs to be done?" required> </div> <div class="form-group"> <label class="form-label">Description</label> <textarea class="form-input" placeholder="Add important details or notes"></textarea> </div> <div class="form-group"> <label class="form-label">Priority</label> <div class="priority-options"> <div class="priority-option" data-priority="low"> Low </div> <div class="priority-option selected" data-priority="medium"> Medium </div> <div class="priority-option" data-priority="high"> High </div> </div> </div> <div class="action-row"> <button type="button" class="btn btn-secondary" id="cancel-task"> Cancel </button> <button type="button" class="btn btn-primary" id="save-task"> Save Task </button> </div> </form> </div> </div> <div id="settings-tab" class="tab-content"> <div class="section"> <h2 class="section-title">Display Settings</h2> <div class="settings-grid"> <div class="setting-item"> <span class="setting-label">Night Mode</span> <label class="toggle"> <input type="checkbox" checked> <span class="toggle-slider"></span> </label> </div> <div class="setting-item"> <span class="setting-label">Reduce Motion</span> <label class="toggle"> <input type="checkbox"> <span class="toggle-slider"></span> </label> </div> <div class="setting-item"> <span class="setting-label">High Contrast</span> <label class="toggle"> <input type="checkbox"> <span class="toggle-slider"></span> </label> </div> <div class="setting-item"> <span class="setting-label">Compact View</span> <label class="toggle"> <input type="checkbox" checked> <span class="toggle-slider"></span> </label> </div> </div> </div> <div class="section"> <h2 class="section-title">Notification Preferences</h2> <div class="settings-grid"> <div class="setting-item"> <span class="setting-label">Task Reminders</span> <label class="toggle"> <input type="checkbox" checked> <span class="toggle-slider"></span> </label> </div> <div class="setting-item"> <span class="setting-label">Focus Alerts</span> <label class="toggle"> <input type="checkbox" checked> <span class="toggle-slider"></span> </label> </div> <div class="setting-item"> <span class="setting-label">Weekly Summary</span> <label class="toggle"> <input type="checkbox" checked> <span class="toggle-slider"></span> </label> </div> <div class="setting-item"> <span class="setting-label">Team Updates</span> <label class="toggle"> <input type="checkbox"> <span class="toggle-slider"></span> </label> </div> </div> <div class="action-row"> <button class="btn btn-primary" id="save-settings"> Save Preferences </button> </div> </div> </div> </div> </div> <div class="toast" id="toast">Settings updated successfully</div> <script> document.addEventListener('DOMContentLoaded', function() { // Tab switching functionality const tabs = document.querySelectorAll('.tab'); const tabContents = document.querySelectorAll('.tab-content'); tabs.forEach(tab => { tab.addEventListener('click', function() { // Ripple effect for tab createRipple(event, this); // Remove active class from all tabs tabs.forEach(t => t.classList.remove('active')); // Add active class to clicked tab this.classList.add('active'); // Hide all tab contents tabContents.forEach(content => content.classList.remove('active')); // Show the corresponding tab content const tabId = this.getAttribute('data-tab'); document.getElementById(`${tabId}-tab`).classList.add('active'); }); }); // Ripple effect for all buttons const buttons = document.querySelectorAll('button, .task-checkbox, .priority-option, .toggle'); buttons.forEach(button => { button.addEventListener('click', function(event) { createRipple(event, this); }); }); // Task checkbox toggle const taskCheckboxes = document.querySelectorAll('.task-checkbox'); taskCheckboxes.forEach(checkbox => { checkbox.addEventListener('click', function() { this.classList.toggle('checked'); const taskItem = this.closest('.task-item'); taskItem.classList.toggle('task-complete'); }); }); // Priority option selection const priorityOptions = document.querySelectorAll('.priority-option'); priorityOptions.forEach(option => { option.addEventListener('click', function() { priorityOptions.forEach(opt => opt.classList.remove('selected')); this.classList.add('selected'); }); }); // Add Task functionality const addTaskBtn = document.querySelector('.btn-primary:last-child'); addTaskBtn.addEventListener('click', function() { const tasksTab = document.querySelector('[data-tab="add"]'); tasksTab.click(); }); // Cancel task creation const cancelTaskBtn = document.getElementById('cancel-task'); cancelTaskBtn.addEventListener('click', function() { const tasksTab = document.querySelector('[data-tab="tasks"]'); tasksTab.click(); }); // Save task (demo functionality) const saveTaskBtn = document.getElementById('save-task'); saveTaskBtn.addEventListener('click', function() { showToast('Task added successfully'); // Clear form and go back to tasks document.querySelector('.add-task-form').reset(); const tasksTab = document.querySelector('[data-tab="tasks"]'); tasksTab.click(); }); // Save settings const saveSettingsBtn = document.getElementById('save-settings'); saveSettingsBtn.addEventListener('click', function() { showToast('Settings updated successfully'); }); // Function to create ripple effect function createRipple(e, element) { const rect = element.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; const ripple = document.createElement('span'); ripple.classList.add('ripple'); ripple.style.left = `${x}px`; ripple.style.top = `${y}px`; const size = Math.max(rect.width, rect.height); ripple.style.width = ripple.style.height = `${size}px`; element.appendChild(ripple); setTimeout(() => { ripple.remove(); }, 600); } // Function to show toast notification function showToast(message) { const toast = document.getElementById('toast'); toast.textContent = message; toast.classList.add('show'); setTimeout(() => { toast.classList.remove('show'); }, 3000); } }); </script> </body> </html>