Neumorphism, a design trend that blends skeuomorphism and flat design, has taken the UI world by storm. Its soft, extruded plastic look creates a tactile, almost 3D effect that is both modern and nostalgic.
In this article, we explore ten stunning examples of neumorphism in action. These designs showcase the versatility and elegance of this emerging trend.
CODE1
Here's the code:
CODETEXT1
CODE2
Here's the code:
CODETEXT2
CODE3
Here's the code:
CODETEXT3
CODE4
Here's the code:
CODETEXT4
CODE5
Here's the code:
CODETEXT5
Subframe's drag-and-drop interface and intuitive, responsive canvas make it effortless to design pixel-perfect Neumorphism UI. Loved by designers and developers alike, Subframe ensures your creations are both stunning and functional.
Start for free and bring your Neumorphic designs to life today!
CODE6
Here's the code:
CODETEXT6
CODE7
Here's the code:
CODETEXT7
CODE8
Here's the code:
CODETEXT8
CODE9
Here's the code:
CODETEXT9
CODE10
Here's the code:
CODETEXT10
Ready to elevate your UI designs? With Subframe, you can create pixel-perfect interfaces, including stunning Neumorphic designs, in minutes. Our drag-and-drop editor and beautifully crafted components make the process efficient and enjoyable.
Don't wait to bring your ideas to life. Start for free and begin designing immediately!
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Smart Home Dashboard</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: #e0e5ec; display: flex; justify-content: center; align-items: center; min-height: 700px; width: 100%; overflow: hidden; padding: 20px; } .dashboard { width: 100%; max-width: 650px; background-color: #e0e5ec; border-radius: 24px; box-shadow: 10px 10px 20px #a3b1c6, -10px -10px 20px #ffffff; padding: 30px; transition: all 0.3s ease; } .dashboard-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 25px; } .dashboard-title { color: #6c7a89; font-size: 1.8rem; font-weight: 600; } .user-profile { display: flex; align-items: center; gap: 10px; } .user-avatar { width: 40px; height: 40px; border-radius: 50%; background: linear-gradient(145deg, #b8c0ca, #dae1f0); box-shadow: 3px 3px 6px #a3b1c6, -3px -3px 6px #ffffff; display: flex; justify-content: center; align-items: center; color: #6c7a89; font-weight: bold; } .user-name { color: #6c7a89; font-size: 0.9rem; font-weight: 600; } .rooms-section { display: flex; flex-wrap: wrap; gap: 15px; margin-bottom: 25px; } .room-tab { padding: 10px 15px; border-radius: 12px; background-color: #e0e5ec; box-shadow: 3px 3px 6px #a3b1c6, -3px -3px 6px #ffffff; color: #6c7a89; font-size: 0.9rem; cursor: pointer; transition: all 0.3s ease; } .room-tab.active { background: #e0e5ec; box-shadow: inset 3px 3px 6px #a3b1c6, inset -3px -3px 6px #ffffff; color: #5d9cec; } .room-tab:hover:not(.active) { transform: translateY(-2px); box-shadow: 4px 4px 8px #a3b1c6, -4px -4px 8px #ffffff; } .controls-section { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 20px; margin-bottom: 25px; } .control-button { position: relative; height: 190px; background-color: #e0e5ec; border-radius: 20px; box-shadow: 6px 6px 12px #a3b1c6, -6px -6px 12px #ffffff; padding: 20px; display: flex; flex-direction: column; justify-content: space-between; cursor: pointer; transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); overflow: hidden; } .control-button:hover { transform: translateY(-5px); box-shadow: 8px 8px 16px #a3b1c6, -8px -8px 16px #ffffff; } .control-button:active { transform: translateY(0); box-shadow: inset 6px 6px 12px #a3b1c6, inset -6px -6px 12px #ffffff; } .control-button.active { box-shadow: inset 6px 6px 12px #a3b1c6, inset -6px -6px 12px #ffffff; } .control-button.active .control-icon { color: #5d9cec; } .control-button.active .control-status { color: #5d9cec; } .control-icon { font-size: 1.8rem; color: #6c7a89; margin-bottom: 15px; transition: all 0.3s ease; } .control-name { font-size: 1.1rem; font-weight: 600; color: #4b5a69; margin-bottom: 5px; } .control-status { font-size: 0.9rem; color: #91a1b4; display: flex; align-items: center; transition: all 0.3s ease; } .wave-animation { position: absolute; bottom: 0; left: 0; width: 100%; height: 0; background: rgba(93, 156, 236, 0.08); border-radius: 50%; transform: translate(-50%, -50%); transition: width 0.6s ease-out, height 0.6s ease-out; } .control-button.active .wave-animation { width: 300%; height: 300%; } .status-dot { width: 8px; height: 8px; border-radius: 50%; background-color: #a3b1c6; margin-right: 6px; transition: all 0.3s ease; } .control-button.active .status-dot { background-color: #5d9cec; } .temperature-slider { width: 100%; margin-top: 20px; position: relative; height: 20px; } .slider-track { position: absolute; width: 100%; height: 8px; background-color: #e0e5ec; border-radius: 4px; box-shadow: inset 2px 2px 4px #a3b1c6, inset -2px -2px 4px #ffffff; } .slider-fill { position: absolute; height: 8px; width: 40%; background: linear-gradient(90deg, #e0e5ec, #5d9cec); border-radius: 4px; transition: width 0.3s ease; } .slider-thumb { position: absolute; width: 20px; height: 20px; background-color: #e0e5ec; border-radius: 50%; box-shadow: 2px 2px 4px #a3b1c6, -2px -2px 4px #ffffff; top: -6px; left: 40%; cursor: pointer; transition: all 0.2s ease; } .slider-thumb:hover { transform: scale(1.1); box-shadow: 3px 3px 6px #a3b1c6, -3px -3px 6px #ffffff; } .slider-thumb:active { transform: scale(0.95); box-shadow: 1px 1px 2px #a3b1c6, -1px -1px 2px #ffffff; } .bottom-controls { display: flex; justify-content: space-between; align-items: center; } .mode-switch { display: flex; background-color: #e0e5ec; border-radius: 12px; box-shadow: inset 3px 3px 6px #a3b1c6, inset -3px -3px 6px #ffffff; padding: 3px; } .mode-option { padding: 8px 15px; border-radius: 10px; font-size: 0.9rem; color: #6c7a89; cursor: pointer; transition: all 0.3s ease; } .mode-option.active { background-color: #e0e5ec; box-shadow: 3px 3px 6px #a3b1c6, -3px -3px 6px #ffffff; color: #5d9cec; } .scene-button { padding: 10px 16px; border-radius: 12px; background-color: #e0e5ec; box-shadow: 3px 3px 6px #a3b1c6, -3px -3px 6px #ffffff; color: #6c7a89; font-size: 0.9rem; display: flex; align-items: center; gap: 8px; cursor: pointer; transition: all 0.3s ease; } .scene-button:hover { transform: translateY(-2px); box-shadow: 4px 4px 8px #a3b1c6, -4px -4px 8px #ffffff; color: #5d9cec; } .scene-button:active { transform: translateY(0); box-shadow: inset 3px 3px 6px #a3b1c6, inset -3px -3px 6px #ffffff; } .scene-icon { font-size: 0.9rem; } /* Responsive adjustments */ @media (max-width: 600px) { .dashboard { padding: 20px; } .dashboard-title { font-size: 1.5rem; } .controls-section { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 15px; } .control-button { height: 150px; padding: 15px; } .control-icon { font-size: 1.5rem; } .control-name { font-size: 1rem; } .bottom-controls { flex-direction: column; gap: 15px; align-items: flex-start; } .mode-switch { width: 100%; justify-content: space-between; } } @media (max-width: 400px) { .rooms-section { display: flex; flex-wrap: nowrap; overflow-x: auto; padding-bottom: 10px; margin-bottom: 15px; scrollbar-width: none; } .rooms-section::-webkit-scrollbar { display: none; } .room-tab { flex: 0 0 auto; } } </style> </head> <body> <div class="dashboard"> <div class="dashboard-header"> <h1 class="dashboard-title">Living Room</h1> <div class="user-profile"> <div class="user-name">Emma Wilson</div> <div class="user-avatar">EW</div> </div> </div> <div class="rooms-section"> <div class="room-tab active">Living Room</div> <div class="room-tab">Kitchen</div> <div class="room-tab">Bedroom</div> <div class="room-tab">Bathroom</div> <div class="room-tab">Office</div> </div> <div class="controls-section"> <div class="control-button" data-control="lights"> <div class="wave-animation"></div> <div class="control-icon">💡</div> <div class="control-info"> <div class="control-name">Ambient Lights</div> <div class="control-status"><span class="status-dot"></span>Off</div> </div> </div> <div class="control-button" data-control="blinds"> <div class="wave-animation"></div> <div class="control-icon">🪟</div> <div class="control-info"> <div class="control-name">Smart Blinds</div> <div class="control-status"><span class="status-dot"></span>Closed</div> </div> </div> <div class="control-button" data-control="thermostat"> <div class="wave-animation"></div> <div class="control-icon">🌡️</div> <div class="control-info"> <div class="control-name">Thermostat</div> <div class="control-status"><span class="status-dot"></span>22°C</div> </div> <div class="temperature-slider"> <div class="slider-track"></div> <div class="slider-fill"></div> <div class="slider-thumb"></div> </div> </div> <div class="control-button" data-control="music"> <div class="wave-animation"></div> <div class="control-icon">🎵</div> <div class="control-info"> <div class="control-name">Music System</div> <div class="control-status"><span class="status-dot"></span>Stopped</div> </div> </div> </div> <div class="bottom-controls"> <div class="mode-switch"> <div class="mode-option active">Home</div> <div class="mode-option">Away</div> <div class="mode-option">Night</div> </div> <div class="scene-button"> <span class="scene-icon">✨</span> <span>Movie Night</span> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Control buttons functionality const controlButtons = document.querySelectorAll('.control-button'); controlButtons.forEach(button => { button.addEventListener('click', function() { const controlType = this.getAttribute('data-control'); const statusElement = this.querySelector('.control-status'); const statusDot = this.querySelector('.status-dot'); // Toggle active state this.classList.toggle('active'); // Update status text based on control type if (controlType === 'lights') { statusElement.innerHTML = this.classList.contains('active') ? '<span class="status-dot"></span>On - 80%' : '<span class="status-dot"></span>Off'; } else if (controlType === 'blinds') { statusElement.innerHTML = this.classList.contains('active') ? '<span class="status-dot"></span>Open - 75%' : '<span class="status-dot"></span>Closed'; } else if (controlType === 'thermostat') { // Thermostat is handled separately with the slider } else if (controlType === 'music') { statusElement.innerHTML = this.classList.contains('active') ? '<span class="status-dot"></span>Playing - Jazz' : '<span class="status-dot"></span>Stopped'; } }); }); // Temperature slider functionality const thermostatButton = document.querySelector('[data-control="thermostat"]'); const sliderThumb = document.querySelector('.slider-thumb'); const sliderFill = document.querySelector('.slider-fill'); const thermostatStatus = thermostatButton.querySelector('.control-status'); let isDragging = false; // Temperature slider interactions sliderThumb.addEventListener('mousedown', startDrag); sliderThumb.addEventListener('touchstart', startDrag); document.addEventListener('mousemove', drag); document.addEventListener('touchmove', drag); document.addEventListener('mouseup', endDrag); document.addEventListener('touchend', endDrag); function startDrag(e) { e.preventDefault(); isDragging = true; thermostatButton.classList.add('active'); } function drag(e) { if (!isDragging) return; const track = document.querySelector('.slider-track'); const trackRect = track.getBoundingClientRect(); // Get position (handle both mouse and touch) let clientX; if (e.type === 'touchmove') { clientX = e.touches[0].clientX; } else { clientX = e.clientX; } // Calculate position percentage let position = (clientX - trackRect.left) / trackRect.width; position = Math.max(0, Math.min(1, position)); // Update thumb and fill positions sliderThumb.style.left = `${position * 100}%`; sliderFill.style.width = `${position * 100}%`; // Calculate and update temperature (18-30°C range) const temperature = Math.round(18 + position * 12); thermostatStatus.innerHTML = `<span class="status-dot"></span>${temperature}°C`; } function endDrag() { isDragging = false; } // Room tabs functionality const roomTabs = document.querySelectorAll('.room-tab'); const dashboardTitle = document.querySelector('.dashboard-title'); roomTabs.forEach(tab => { tab.addEventListener('click', function() { roomTabs.forEach(t => t.classList.remove('active')); this.classList.add('active'); dashboardTitle.textContent = this.textContent; }); }); // Mode switch functionality const modeOptions = document.querySelectorAll('.mode-option'); modeOptions.forEach(option => { option.addEventListener('click', function() { modeOptions.forEach(o => o.classList.remove('active')); this.classList.add('active'); }); }); // Scene button functionality const sceneButton = document.querySelector('.scene-button'); sceneButton.addEventListener('click', function() { // Activate movie night scene controlButtons.forEach(button => { const controlType = button.getAttribute('data-control'); const statusElement = button.querySelector('.control-status'); if (controlType === 'lights') { button.classList.add('active'); statusElement.innerHTML = '<span class="status-dot"></span>On - 30%'; } else if (controlType === 'blinds') { button.classList.add('active'); statusElement.innerHTML = '<span class="status-dot"></span>Closed - 100%'; } else if (controlType === 'thermostat') { button.classList.add('active'); statusElement.innerHTML = '<span class="status-dot"></span>23°C'; sliderThumb.style.left = '45%'; sliderFill.style.width = '45%'; } else if (controlType === 'music') { button.classList.add('active'); statusElement.innerHTML = '<span class="status-dot"></span>Playing - Ambient'; } }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>PeakSecure Mobile Banking</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } :root { --bg-color: #e6eef8; --primary-color: #5e72e4; --secondary-color: #3e4676; --shadow-light: 6px 6px 12px #c8d8e7, -6px -6px 12px #ffffff; --shadow-inset: inset 2px 2px 5px #c8d8e7, inset -2px -2px 5px #ffffff; --shadow-hover: 8px 8px 15px #c4d4e3, -8px -8px 15px #ffffff; --error-color: #ff4d6b; } body { width: 100%; height: 100vh; background: var(--bg-color); display: flex; justify-content: center; align-items: center; overflow: hidden; } .container { width: 100%; max-width: 650px; height: 660px; padding: 30px; position: relative; overflow: hidden; } .login-container { background: var(--bg-color); border-radius: 20px; box-shadow: var(--shadow-light); padding: 30px; position: relative; z-index: 2; overflow: hidden; transition: all 0.5s ease; } .security-badge { position: absolute; top: 20px; right: 20px; display: flex; align-items: center; gap: 5px; font-size: 12px; color: var(--secondary-color); opacity: 0.8; } .security-badge svg { width: 16px; height: 16px; } .security-badge.pulse { animation: pulse 2s infinite; } @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } } h1 { color: var(--secondary-color); margin-bottom: 10px; font-size: 24px; font-weight: 700; } p.subtitle { color: #758096; margin-bottom: 30px; font-size: 14px; line-height: 1.6; } .form-group { margin-bottom: 25px; position: relative; } .form-group label { display: block; margin-bottom: 12px; color: var(--secondary-color); font-weight: 600; font-size: 14px; transition: all 0.3s ease; } .input-container { position: relative; } .input-icon { position: absolute; left: 16px; top: 50%; transform: translateY(-50%); color: #a1a9c3; transition: all 0.3s ease; } .input-field { width: 100%; padding: 16px 16px 16px 45px; border: none; border-radius: 12px; background: var(--bg-color); box-shadow: var(--shadow-inset); color: var(--secondary-color); font-size: 15px; transition: all 0.3s ease; outline: none; } .input-field:focus { box-shadow: var(--shadow-light); transform: translateY(-2px); } .input-field:focus + .input-icon { color: var(--primary-color); } .input-field.error { box-shadow: inset 2px 2px 5px #e4c8c8, inset -2px -2px 5px #ffffff; } .error-message { color: var(--error-color); font-size: 12px; margin-top: 6px; display: none; } .error-message.visible { display: block; animation: fadeIn 0.3s ease-in-out; } @keyframes fadeIn { 0% { opacity: 0; transform: translateY(-5px); } 100% { opacity: 1; transform: translateY(0); } } .toggle-password { position: absolute; right: 16px; top: 50%; transform: translateY(-50%); cursor: pointer; color: #a1a9c3; transition: all 0.3s ease; background: none; border: none; padding: 0; } .toggle-password:hover { color: var(--primary-color); } .remember-forgot { display: flex; justify-content: space-between; align-items: center; margin-bottom: 30px; font-size: 14px; } .remember-container { display: flex; align-items: center; } .custom-checkbox { width: 22px; height: 22px; border-radius: 6px; background: var(--bg-color); box-shadow: var(--shadow-inset); margin-right: 10px; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; transition: all 0.3s ease; position: relative; } .custom-checkbox.checked { box-shadow: var(--shadow-light); } .custom-checkbox.checked::after { content: ''; width: 10px; height: 10px; border-radius: 3px; background: var(--primary-color); position: absolute; animation: checkboxPop 0.3s forwards; } @keyframes checkboxPop { 0% { transform: scale(0); } 50% { transform: scale(1.2); } 100% { transform: scale(1); } } .remember-text { color: var(--secondary-color); } .forgot-link { color: var(--primary-color); text-decoration: none; transition: all 0.3s ease; position: relative; } .forgot-link::after { content: ''; position: absolute; width: 0; height: 1px; bottom: -2px; left: 0; background-color: var(--primary-color); transition: width 0.3s ease; } .forgot-link:hover::after { width: 100%; } .login-btn { width: 100%; padding: 16px; border: none; border-radius: 12px; background: var(--bg-color); box-shadow: var(--shadow-light); color: var(--primary-color); font-weight: 700; font-size: 16px; cursor: pointer; transition: all 0.3s ease; position: relative; overflow: hidden; } .login-btn::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); transition: all 0.5s ease; } .login-btn:hover { box-shadow: var(--shadow-hover); transform: translateY(-3px); } .login-btn:hover::before { left: 100%; } .login-btn.loading { pointer-events: none; color: transparent; } .login-btn.loading::after { content: ''; position: absolute; width: 20px; height: 20px; border: 3px solid rgba(94, 114, 228, 0.3); border-top: 3px solid var(--primary-color); border-radius: 50%; top: 50%; left: 50%; transform: translate(-50%, -50%); animation: spin 1s linear infinite; } @keyframes spin { 0% { transform: translate(-50%, -50%) rotate(0deg); } 100% { transform: translate(-50%, -50%) rotate(360deg); } } .divider { display: flex; align-items: center; margin: 25px 0; color: #a1a9c3; font-size: 13px; } .divider::before, .divider::after { content: ''; flex: 1; height: 1px; background: #d8e1ec; } .divider::before { margin-right: 15px; } .divider::after { margin-left: 15px; } .biometric-container { display: flex; justify-content: center; margin-top: 10px; } .biometric-btn { width: 60px; height: 60px; border-radius: 50%; background: var(--bg-color); box-shadow: var(--shadow-light); border: none; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.3s ease; color: var(--secondary-color); } .biometric-btn:hover { box-shadow: var(--shadow-hover); transform: translateY(-3px); } .biometric-btn svg { width: 24px; height: 24px; transition: all 0.3s ease; } .biometric-btn:hover svg { color: var(--primary-color); } .biometric-label { text-align: center; margin-top: 10px; font-size: 12px; color: var(--secondary-color); } .floating-particles { position: absolute; width: 100%; height: 100%; top: 0; left: 0; pointer-events: none; z-index: 1; } .particle { position: absolute; border-radius: 50%; opacity: 0.2; animation: float 15s infinite ease-in-out; } @keyframes float { 0% { transform: translateY(0) rotate(0deg); } 50% { transform: translateY(-20px) rotate(180deg); } 100% { transform: translateY(0) rotate(360deg); } } @media (max-width: 600px) { .container { padding: 15px; height: 100vh; } .login-container { padding: 20px; } h1 { font-size: 20px; } .input-field { padding: 14px 14px 14px 40px; } } </style> </head> <body> <div class="container"> <div class="floating-particles" id="particles"></div> <div class="login-container"> <div class="security-badge pulse"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path> </svg> <span>256-bit Secure</span> </div> <h1>Welcome to PeakSecure Banking</h1> <p class="subtitle">Securely access your accounts with our multi-layer authentication system. Your financial security is our top priority.</p> <form id="login-form"> <div class="form-group"> <label for="account-number">Account Number</label> <div class="input-container"> <input type="text" id="account-number" class="input-field" placeholder="Enter your 10-digit account number" maxlength="10" autocomplete="off"> <svg class="input-icon" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path> <circle cx="12" cy="7" r="4"></circle> </svg> </div> <div id="account-error" class="error-message">Please enter a valid 10-digit account number</div> </div> <div class="form-group"> <label for="password">Password</label> <div class="input-container"> <input type="password" id="password" class="input-field" placeholder="Enter your secure password"> <svg class="input-icon" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect> <path d="M7 11V7a5 5 0 0 1 10 0v4"></path> </svg> <button type="button" class="toggle-password" id="toggle-password"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path> <circle cx="12" cy="12" r="3"></circle> </svg> </button> </div> <div id="password-error" class="error-message">Password must be at least 8 characters</div> </div> <div class="remember-forgot"> <div class="remember-container"> <div class="custom-checkbox" id="remember-checkbox"></div> <span class="remember-text">Remember this device</span> </div> <a href="#" class="forgot-link">Forgot Password?</a> </div> <button type="button" id="login-button" class="login-btn">Secure Login</button> <div class="divider">or use biometric authentication</div> <div class="biometric-container"> <div> <button type="button" class="biometric-btn" id="biometric-btn"> <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 11c0 3.53-2.46 6.5-6 6.5a6.5 6.5 0 0 1-6-6.5c0-3.53 2.47-6.5 6-6.5a6.5 6.5 0 0 1 6 6.5z"></path> <path d="M12 11c0-3.53 2.46-6.5 6-6.5a6.5 6.5 0 0 1 6 6.5c0 3.53-2.47 6.5-6 6.5a6.5 6.5 0 0 1-6-6.5z"></path> <path d="M0 11h24"></path> </svg> </button> <div class="biometric-label">Fingerprint / Face ID</div> </div> </div> </form> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Create floating particles const particlesContainer = document.getElementById('particles'); const colors = ['#5e72e4', '#3e4676', '#6C8FB8']; for (let i = 0; i < 15; i++) { const particle = document.createElement('div'); particle.classList.add('particle'); const size = Math.random() * 30 + 10; const color = colors[Math.floor(Math.random() * colors.length)]; particle.style.width = `${size}px`; particle.style.height = `${size}px`; particle.style.background = color; particle.style.left = `${Math.random() * 100}%`; particle.style.top = `${Math.random() * 100}%`; particle.style.animationDelay = `${Math.random() * 5}s`; particle.style.animationDuration = `${Math.random() * 10 + 10}s`; particlesContainer.appendChild(particle); } // Form validation const accountNumberInput = document.getElementById('account-number'); const passwordInput = document.getElementById('password'); const accountError = document.getElementById('account-error'); const passwordError = document.getElementById('password-error'); const loginButton = document.getElementById('login-button'); const togglePasswordBtn = document.getElementById('toggle-password'); const rememberCheckbox = document.getElementById('remember-checkbox'); const biometricBtn = document.getElementById('biometric-btn'); // Format account number as user types accountNumberInput.addEventListener('input', function(e) { // Remove non-digits let value = this.value.replace(/\D/g, ''); // Limit to 10 digits if (value.length > 10) { value = value.substring(0, 10); } this.value = value; // Hide error if field is not empty if (value.length > 0) { accountError.classList.remove('visible'); this.classList.remove('error'); } }); // Password input validation passwordInput.addEventListener('input', function() { if (this.value.length > 0) { passwordError.classList.remove('visible'); this.classList.remove('error'); } }); // Toggle password visibility togglePasswordBtn.addEventListener('click', function() { const type = passwordInput.getAttribute('type') === 'password' ? 'text' : 'password'; passwordInput.setAttribute('type', type); // Change the eye icon const eyeIcon = this.querySelector('svg'); if (type === 'text') { eyeIcon.innerHTML = ` <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path> <line x1="1" y1="1" x2="23" y2="23"></line> <path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94"></path> <path d="M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19"></path> `; } else { eyeIcon.innerHTML = ` <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path> <circle cx="12" cy="12" r="3"></circle> `; } }); // Remember me toggle rememberCheckbox.addEventListener('click', function() { this.classList.toggle('checked'); }); // Login button click handler loginButton.addEventListener('click', function() { let isValid = true; // Validate account number if (accountNumberInput.value.length !== 10) { accountError.classList.add('visible'); accountNumberInput.classList.add('error'); isValid = false; } // Validate password if (passwordInput.value.length < 8) { passwordError.classList.add('visible'); passwordInput.classList.add('error'); isValid = false; } if (isValid) { // Show loading state this.classList.add('loading'); // Simulate login process setTimeout(() => { // Success simulation this.classList.remove('loading'); // Reset form accountNumberInput.value = ''; passwordInput.value = ''; if (rememberCheckbox.classList.contains('checked')) { rememberCheckbox.classList.remove('checked'); } // Show success message const form = document.getElementById('login-form'); form.innerHTML = ` <div style="text-align: center; padding: 20px;"> <svg xmlns="http://www.w3.org/2000/svg" width="60" height="60" viewBox="0 0 24 24" fill="none" stroke="#5e72e4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-bottom: 20px;"> <path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path> <polyline points="22 4 12 14.01 9 11.01"></polyline> </svg> <h2 style="color: #3e4676; margin-bottom: 10px;">Authentication Successful</h2> <p style="color: #758096; margin-bottom: 20px;">Welcome back to PeakSecure Banking</p> <button type="button" class="login-btn" onclick="location.reload()">Back to Login</button> </div> `; }, 2000); } }); // Biometric authentication biometricBtn.addEventListener('click', function() { this.classList.add('loading'); const btnSvg = this.querySelector('svg'); const originalSvg = btnSvg.innerHTML; btnSvg.innerHTML = `<circle cx="12" cy="12" r="10"></circle><path d="M16 12.5a4 4 0 0 1-8 0"></path>`; setTimeout(() => { btnSvg.innerHTML = originalSvg; // Show loading state on login button loginButton.classList.add('loading'); // Simulate authentication process setTimeout(() => { // Success simulation loginButton.classList.remove('loading'); // Show success message const form = document.getElementById('login-form'); form.innerHTML = ` <div style="text-align: center; padding: 20px;"> <svg xmlns="http://www.w3.org/2000/svg" width="60" height="60" viewBox="0 0 24 24" fill="none" stroke="#5e72e4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-bottom: 20px;"> <path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path> <polyline points="22 4 12 14.01 9 11.01"></polyline> </svg> <h2 style="color: #3e4676; margin-bottom: 10px;">Biometric Authentication Successful</h2> <p style="color: #758096; margin-bottom: 20px;">Welcome back to PeakSecure Banking</p> <button type="button" class="login-btn" onclick="location.reload()">Back to Login</button> </div> `; }, 1500); }, 1500); }); }); </script> </body> </html>
<html> <head> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: #e6eef8; height: 700px; width: 700px; display: flex; justify-content: center; align-items: center; overflow: hidden; } .container { width: 380px; height: 650px; border-radius: 40px; background: #e6eef8; box-shadow: 20px 20px 60px #c4cad3, -20px -20px 60px #ffffff; padding: 30px; position: relative; overflow: hidden; } .header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 25px; } .title { font-size: 24px; font-weight: 700; color: #556b8c; } .avatar { width: 50px; height: 50px; border-radius: 50%; background: linear-gradient(145deg, #f0f8ff, #c9d6e8); box-shadow: 5px 5px 10px #c4cad3, -5px -5px 10px #ffffff; display: flex; justify-content: center; align-items: center; color: #7f9dc1; font-size: 24px; font-weight: bold; cursor: pointer; transition: all 0.3s ease; } .avatar:hover { transform: scale(1.05); box-shadow: 7px 7px 14px #c4cad3, -7px -7px 14px #ffffff; } .stats { display: flex; justify-content: space-between; margin-bottom: 25px; } .stat-box { width: 100px; height: 100px; border-radius: 30px; background: #e6eef8; box-shadow: 8px 8px 16px #c4cad3, -8px -8px 16px #ffffff; display: flex; flex-direction: column; justify-content: center; align-items: center; transition: all 0.3s ease; cursor: pointer; } .stat-box:hover { transform: translateY(-5px); box-shadow: 10px 10px 20px #c4cad3, -10px -10px 20px #ffffff; } .stat-value { font-size: 24px; font-weight: 700; color: #556b8c; margin-bottom: 5px; } .stat-label { font-size: 14px; color: #7f9dc1; } .section-title { font-size: 18px; font-weight: 600; color: #556b8c; margin: 25px 0 15px; } .toggle-section { display: flex; justify-content: space-between; margin-bottom: 15px; align-items: center; } .toggle-label { font-size: 16px; color: #556b8c; } .toggle { position: relative; width: 60px; height: 34px; } .toggle input { opacity: 0; width: 0; height: 0; } .slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #dfe8f5; box-shadow: inset 4px 4px 8px #c4cad3, inset -4px -4px 8px #ffffff; transition: .4s; border-radius: 34px; } .slider:before { position: absolute; content: ""; height: 26px; width: 26px; left: 4px; bottom: 4px; background: linear-gradient(145deg, #f0f8ff, #c9d6e8); box-shadow: 3px 3px 5px #c4cad3, -3px -3px 5px #ffffff; transition: .4s; border-radius: 50%; } input:checked + .slider { background-color: #dfe8f5; box-shadow: inset 4px 4px 8px #c4cad3, inset -4px -4px 8px #ffffff; } input:checked + .slider:before { transform: translateX(26px); background: linear-gradient(145deg, #a8c8ff, #8eaad7); } input:checked + .slider:after { opacity: 1; } .slider:after { content: ""; position: absolute; top: 0; left: 0; right: 0; bottom: 0; border-radius: 34px; box-shadow: 0 0 15px #a8c8ff; opacity: 0; transition: .4s; z-index: -1; } .control-buttons { display: flex; justify-content: space-between; margin-top: 25px; } .control-button { width: 100px; height: 45px; border-radius: 20px; background: #e6eef8; box-shadow: 6px 6px 12px #c4cad3, -6px -6px 12px #ffffff; display: flex; justify-content: center; align-items: center; color: #7f9dc1; font-weight: 600; font-size: 14px; cursor: pointer; transition: all 0.3s ease; border: none; outline: none; } .control-button:hover { box-shadow: 8px 8px 16px #c4cad3, -8px -8px 16px #ffffff; color: #556b8c; } .control-button:active { box-shadow: inset 6px 6px 12px #c4cad3, inset -6px -6px 12px #ffffff; } .goal-slider-container { margin-top: 25px; margin-bottom: 15px; } .goal-slider { width: 100%; -webkit-appearance: none; height: 15px; border-radius: 15px; background: #dfe8f5; box-shadow: inset 4px 4px 8px #c4cad3, inset -4px -4px 8px #ffffff; outline: none; margin-top: 10px; } .goal-slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 30px; height: 30px; border-radius: 50%; background: linear-gradient(145deg, #a8c8ff, #8eaad7); cursor: pointer; box-shadow: 3px 3px 5px #c4cad3, -3px -3px 5px #ffffff; transition: all 0.3s ease; } .goal-slider::-webkit-slider-thumb:hover { transform: scale(1.1); box-shadow: 5px 5px 10px #c4cad3, -5px -5px 10px #ffffff; } .goal-labels { display: flex; justify-content: space-between; margin-top: 5px; } .goal-label { font-size: 12px; color: #7f9dc1; } .goal-value { font-size: 20px; font-weight: 700; color: #556b8c; text-align: center; margin-bottom: 10px; } .pulse-button { width: 60px; height: 60px; position: absolute; bottom: 30px; right: 30px; border-radius: 50%; background: linear-gradient(145deg, #a8c8ff, #8eaad7); box-shadow: 8px 8px 16px #c4cad3, -8px -8px 16px #ffffff; display: flex; justify-content: center; align-items: center; color: white; font-size: 24px; cursor: pointer; transition: all 0.3s ease; z-index: 10; } .pulse-button:hover { transform: scale(1.05); box-shadow: 10px 10px 20px #c4cad3, -10px -10px 20px #ffffff; } .pulse-button:after { content: ""; position: absolute; width: 100%; height: 100%; border-radius: 50%; animation: pulse 2s infinite; box-shadow: 0 0 0 0 rgba(168, 200, 255, 0.7); opacity: 0; z-index: -1; } .pulse-button.active:after { opacity: 1; } @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(168, 200, 255, 0.7); } 70% { box-shadow: 0 0 0 20px rgba(168, 200, 255, 0); } 100% { box-shadow: 0 0 0 0 rgba(168, 200, 255, 0); } } .progress-ring-container { display: flex; flex-direction: column; align-items: center; margin-top: 20px; } .progress-ring-wrapper { position: relative; width: 120px; height: 120px; } .progress-ring { transform: rotate(-90deg); width: 120px; height: 120px; } .progress-ring-circle { fill: transparent; stroke-width: 8; stroke-linecap: round; stroke-dasharray: 339.3; stroke-dashoffset: 339.3; transition: stroke-dashoffset 0.5s ease-in-out; } .progress-ring-bg { stroke: #dfe8f5; stroke-width: 8; fill: transparent; } .progress-ring-text { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 20px; font-weight: 700; color: #556b8c; } .progress-label { margin-top: 10px; font-size: 16px; color: #7f9dc1; font-weight: 600; } @media (max-width: 400px) { .container { width: 320px; padding: 20px; height: 620px; } .stat-box { width: 85px; height: 85px; } .stat-value { font-size: 20px; } .control-button { width: 90px; font-size: 13px; } } </style> </head> <body> <div class="container"> <div class="header"> <h1 class="title">NeuFit Tracker</h1> <div class="avatar">JS</div> </div> <div class="stats"> <div class="stat-box"> <div class="stat-value">8,432</div> <div class="stat-label">Steps</div> </div> <div class="stat-box"> <div class="stat-value">3.2</div> <div class="stat-label">Miles</div> </div> <div class="stat-box"> <div class="stat-value">248</div> <div class="stat-label">Calories</div> </div> </div> <div class="progress-ring-container"> <div class="progress-ring-wrapper"> <svg class="progress-ring" width="120" height="120"> <circle class="progress-ring-bg" cx="60" cy="60" r="54" /> <circle class="progress-ring-circle" cx="60" cy="60" r="54" stroke="#a8c8ff" /> </svg> <div class="progress-ring-text">68%</div> </div> <div class="progress-label">Daily Goal Progress</div> </div> <h2 class="section-title">Activity Settings</h2> <div class="toggle-section"> <span class="toggle-label">Step Counting</span> <label class="toggle"> <input type="checkbox" checked> <span class="slider"></span> </label> </div> <div class="toggle-section"> <span class="toggle-label">Heart Rate Monitor</span> <label class="toggle"> <input type="checkbox" checked> <span class="slider"></span> </label> </div> <div class="toggle-section"> <span class="toggle-label">Sleep Tracking</span> <label class="toggle"> <input type="checkbox"> <span class="slider"></span> </label> </div> <div class="toggle-section"> <span class="toggle-label">Workout Detection</span> <label class="toggle"> <input type="checkbox" checked> <span class="slider"></span> </label> </div> <h2 class="section-title">Daily Step Goal</h2> <div class="goal-value" id="goal-value">10,000 steps</div> <div class="goal-slider-container"> <input type="range" min="5000" max="20000" value="10000" step="500" class="goal-slider" id="goal-slider"> <div class="goal-labels"> <span class="goal-label">5,000</span> <span class="goal-label">20,000</span> </div> </div> <div class="control-buttons"> <button class="control-button">History</button> <button class="control-button">Insights</button> <button class="control-button">Share</button> </div> <div class="pulse-button" id="pulse-button"> <i>+</i> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Set initial progress const progressRing = document.querySelector('.progress-ring-circle'); const circumference = 2 * Math.PI * 54; progressRing.style.strokeDasharray = `${circumference}`; function setProgress(percent) { const offset = circumference - (percent / 100 * circumference); progressRing.style.strokeDashoffset = offset; } // Set initial progress to 68% setProgress(68); // Goal slider functionality const goalSlider = document.getElementById('goal-slider'); const goalValue = document.getElementById('goal-value'); goalSlider.addEventListener('input', function() { const value = this.value; const formattedValue = parseInt(value).toLocaleString(); goalValue.textContent = `${formattedValue} steps`; // Update progress based on new goal const currentSteps = 8432; const newPercent = Math.round((currentSteps / value) * 100); setProgress(newPercent); document.querySelector('.progress-ring-text').textContent = `${newPercent}%`; }); // Toggle switch animations const toggles = document.querySelectorAll('.toggle input'); toggles.forEach(toggle => { toggle.addEventListener('change', function() { if (this.checked) { this.nextElementSibling.style.boxShadow = 'inset 4px 4px 8px #c4cad3, inset -4px -4px 8px #ffffff, 0 0 10px rgba(168, 200, 255, 0.5)'; } else { this.nextElementSibling.style.boxShadow = 'inset 4px 4px 8px #c4cad3, inset -4px -4px 8px #ffffff'; } }); }); // Pulse button animation toggle const pulseButton = document.getElementById('pulse-button'); pulseButton.addEventListener('click', function() { this.classList.toggle('active'); }); // Stats box animation const statBoxes = document.querySelectorAll('.stat-box'); statBoxes.forEach(box => { box.addEventListener('click', function() { this.style.transform = 'scale(0.95)'; setTimeout(() => { this.style.transform = 'translateY(-5px)'; }, 200); }); }); // Control buttons effects const controlButtons = document.querySelectorAll('.control-button'); controlButtons.forEach(button => { button.addEventListener('mousedown', function() { this.style.boxShadow = 'inset 6px 6px 12px #c4cad3, inset -6px -6px 12px #ffffff'; }); button.addEventListener('mouseup', function() { this.style.boxShadow = '6px 6px 12px #c4cad3, -6px -6px 12px #ffffff'; }); button.addEventListener('mouseleave', function() { this.style.boxShadow = '6px 6px 12px #c4cad3, -6px -6px 12px #ffffff'; }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Neumorphic E-commerce Product Showcase</title> <style> :root { --bg-color: #ebecf0; --shadow-light: #ffffff; --shadow-dark: #c8c9cc; --text-color: #2d3142; --accent-color: #6c63ff; --secondary-color: #ff6b6b; --tertiary-color: #43aa8b; --card-radius: 20px; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; } body { background-color: var(--bg-color); display: flex; flex-direction: column; justify-content: center; align-items: center; min-height: 700px; padding: 2rem 1rem; color: var(--text-color); overflow-x: hidden; } header { text-align: center; margin-bottom: 2rem; max-width: 600px; } h1 { font-size: 2rem; margin-bottom: 0.5rem; position: relative; display: inline-block; } h1::after { content: ''; position: absolute; bottom: -5px; left: 50%; transform: translateX(-50%); width: 70%; height: 3px; background: linear-gradient(90deg, var(--accent-color), var(--secondary-color)); border-radius: 2px; } .subtitle { font-size: 1rem; color: #5d5f6b; margin-bottom: 1.5rem; } .filter-container { display: flex; justify-content: center; gap: 0.8rem; margin-bottom: 2rem; flex-wrap: wrap; } .filter-btn { padding: 0.6rem 1.2rem; border: none; border-radius: 30px; background-color: var(--bg-color); color: var(--text-color); cursor: pointer; font-weight: 500; font-size: 0.9rem; transition: all 0.3s ease; box-shadow: 4px 4px 10px var(--shadow-dark), -4px -4px 10px var(--shadow-light); } .filter-btn:hover { box-shadow: 6px 6px 12px var(--shadow-dark), -6px -6px 12px var(--shadow-light); } .filter-btn.active { background: var(--accent-color); color: white; box-shadow: inset 3px 3px 6px rgba(0, 0, 0, 0.2), inset -3px -3px 6px rgba(255, 255, 255, 0.1); } .product-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 1.8rem; max-width: 680px; width: 100%; } .product-card { background-color: var(--bg-color); border-radius: var(--card-radius); padding: 1.2rem; position: relative; overflow: hidden; transition: all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1); box-shadow: 8px 8px 16px var(--shadow-dark), -8px -8px 16px var(--shadow-light); transform-style: preserve-3d; cursor: pointer; } .product-card::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(145deg, rgba(255, 255, 255, 0.05), rgba(0, 0, 0, 0.05)); border-radius: inherit; z-index: 0; } .product-card:hover { transform: translateY(-10px) scale(1.02); box-shadow: 12px 12px 20px var(--shadow-dark), -12px -12px 20px var(--shadow-light); } .product-card:hover .product-img { transform: scale(1.08); } .product-card:hover .card-shine { opacity: 1; } .product-card:hover .buy-btn { opacity: 1; transform: translateY(0); } .card-shine { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient( 135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0) 40%, rgba(255, 255, 255, 0) 60%, rgba(255, 255, 255, 0.1) 100% ); opacity: 0; z-index: 1; transition: opacity 0.5s ease; border-radius: inherit; pointer-events: none; } .img-container { width: 100%; height: 140px; border-radius: calc(var(--card-radius) - 5px); overflow: hidden; position: relative; margin-bottom: 1rem; background-color: white; box-shadow: inset 3px 3px 6px rgba(0, 0, 0, 0.1); } .product-img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.5s ease; } .tag { position: absolute; top: 10px; left: 10px; background-color: var(--secondary-color); color: white; padding: 0.3rem 0.6rem; border-radius: 20px; font-size: 0.7rem; font-weight: 600; z-index: 2; box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.2); } .product-info { position: relative; z-index: 2; } .product-name { font-size: 1rem; font-weight: 600; margin-bottom: 0.4rem; color: var(--text-color); } .product-description { font-size: 0.8rem; color: #5d5f6b; margin-bottom: 0.8rem; line-height: 1.4; } .price-row { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.8rem; } .price { font-weight: 700; font-size: 1.1rem; color: var(--accent-color); } .original-price { text-decoration: line-through; font-size: 0.85rem; color: #8a8c99; margin-right: 0.6rem; } .rating { display: flex; align-items: center; gap: 0.2rem; } .rating-star { color: #ffd700; font-size: 0.8rem; } .rating-count { font-size: 0.75rem; color: #5d5f6b; } .buy-btn { width: 100%; padding: 0.7rem 0; border: none; border-radius: 30px; background-color: var(--accent-color); color: white; font-weight: 600; font-size: 0.9rem; cursor: pointer; transition: all 0.3s ease; opacity: 0.8; transform: translateY(5px); box-shadow: 3px 3px 8px var(--shadow-dark); position: relative; overflow: hidden; } .buy-btn:hover { background-color: #5a52e0; } .buy-btn::after { content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background: linear-gradient( transparent, rgba(255, 255, 255, 0.2), transparent ); transform: rotate(30deg); transition: transform 0.6s ease; z-index: 1; } .buy-btn:hover::after { transform: rotate(30deg) translate(100%, 100%); } /* Badge for limited time offers */ .badge { position: absolute; top: -8px; right: -8px; width: 55px; height: 55px; background: var(--tertiary-color); border-radius: 50%; display: flex; justify-content: center; align-items: center; color: white; font-size: 0.7rem; font-weight: 700; z-index: 3; box-shadow: 3px 3px 8px rgba(0, 0, 0, 0.2); animation: pulse 2s infinite; transform-origin: center; } @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.08); } 100% { transform: scale(1); } } .badge span { text-align: center; line-height: 1.1; padding: 0.2rem; } .no-results { width: 100%; text-align: center; padding: 2rem; font-size: 1.2rem; color: #5d5f6b; grid-column: 1 / -1; } @media (max-width: 600px) { .product-grid { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); } h1 { font-size: 1.7rem; } .filter-btn { padding: 0.5rem 1rem; font-size: 0.8rem; } } @media (max-width: 400px) { .product-grid { grid-template-columns: 1fr; } } /* Animation for product card entrance */ @keyframes fadeInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .product-card { animation: fadeInUp 0.5s ease forwards; } </style> </head> <body> <header> <h1>Artisan Tech Collection</h1> <p class="subtitle">Premium devices crafted with precision, designed for the modern minimalist</p> </header> <div class="filter-container"> <button class="filter-btn active" data-category="all">All Products</button> <button class="filter-btn" data-category="audio">Audio</button> <button class="filter-btn" data-category="wearables">Wearables</button> <button class="filter-btn" data-category="accessories">Accessories</button> </div> <div class="product-grid"> <div class="product-card" data-category="audio"> <div class="card-shine"></div> <div class="img-container"> <img class="product-img" src="https://images.unsplash.com/photo-1546435770-a3e426bf472b?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2865&q=80" alt="Echo Wireless Earbuds"> <div class="tag">New</div> </div> <div class="product-info"> <h3 class="product-name">Echo Wireless Earbuds</h3> <p class="product-description">Precision-crafted earbuds with active noise cancellation and 36-hour battery life.</p> <div class="price-row"> <div> <span class="original-price">$149.99</span> <span class="price">$129.99</span> </div> <div class="rating"> <span class="rating-star">★★★★★</span> <span class="rating-count">(124)</span> </div> </div> <button class="buy-btn">Add to Cart</button> </div> </div> <div class="product-card" data-category="wearables"> <div class="card-shine"></div> <div class="badge"><span>20% OFF</span></div> <div class="img-container"> <img class="product-img" src="https://images.unsplash.com/photo-1579586337278-3befd40fd17a?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2872&q=80" alt="Nova Smart Watch"> </div> <div class="product-info"> <h3 class="product-name">Nova Smart Watch</h3> <p class="product-description">Ultra-thin ceramic watch with 7-day battery and comprehensive health tracking.</p> <div class="price-row"> <div> <span class="original-price">$299.99</span> <span class="price">$239.99</span> </div> <div class="rating"> <span class="rating-star">★★★★☆</span> <span class="rating-count">(87)</span> </div> </div> <button class="buy-btn">Add to Cart</button> </div> </div> <div class="product-card" data-category="accessories"> <div class="card-shine"></div> <div class="img-container"> <img class="product-img" src="https://images.unsplash.com/photo-1629429408209-1f912961dbd8?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2874&q=80" alt="Pulse Wireless Charger"> <div class="tag">Bestseller</div> </div> <div class="product-info"> <h3 class="product-name">Pulse Wireless Charger</h3> <p class="product-description">Sleek 3-in-1 wireless charger for all your devices with status indicator light.</p> <div class="price-row"> <div> <span class="price">$79.99</span> </div> <div class="rating"> <span class="rating-star">★★★★★</span> <span class="rating-count">(215)</span> </div> </div> <button class="buy-btn">Add to Cart</button> </div> </div> <div class="product-card" data-category="audio"> <div class="card-shine"></div> <div class="img-container"> <img class="product-img" src="https://images.unsplash.com/photo-1545127398-14699f92334b?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2835&q=80" alt="Aura Noise-Cancelling Headphones"> </div> <div class="product-info"> <h3 class="product-name">Aura Headphones</h3> <p class="product-description">Premium adaptive noise cancellation with sustainably sourced materials.</p> <div class="price-row"> <div> <span class="original-price">$349.99</span> <span class="price">$299.99</span> </div> <div class="rating"> <span class="rating-star">★★★★☆</span> <span class="rating-count">(92)</span> </div> </div> <button class="buy-btn">Add to Cart</button> </div> </div> <div class="product-card" data-category="accessories"> <div class="card-shine"></div> <div class="badge"><span>15% OFF</span></div> <div class="img-container"> <img class="product-img" src="https://images.unsplash.com/photo-1624913503273-5f9c4e980dba?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2787&q=80" alt="Zen Powerbank"> </div> <div class="product-info"> <h3 class="product-name">Zen Powerbank</h3> <p class="product-description">10,000mAh portable charger with PD fast charging and aluminum exterior.</p> <div class="price-row"> <div> <span class="original-price">$89.99</span> <span class="price">$76.49</span> </div> <div class="rating"> <span class="rating-star">★★★★★</span> <span class="rating-count">(176)</span> </div> </div> <button class="buy-btn">Add to Cart</button> </div> </div> <div class="product-card" data-category="wearables"> <div class="card-shine"></div> <div class="img-container"> <img class="product-img" src="https://images.unsplash.com/photo-1571145551427-5bafa11abc2d?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2787&q=80" alt="Luna Fitness Tracker"> <div class="tag">Popular</div> </div> <div class="product-info"> <h3 class="product-name">Luna Fitness Tracker</h3> <p class="product-description">Slim wristband with 24/7 heart monitoring and customizable activity goals.</p> <div class="price-row"> <div> <span class="price">$89.99</span> </div> <div class="rating"> <span class="rating-star">★★★★☆</span> <span class="rating-count">(143)</span> </div> </div> <button class="buy-btn">Add to Cart</button> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Products fade-in animation with delay const productCards = document.querySelectorAll('.product-card'); productCards.forEach((card, index) => { card.style.animationDelay = `${index * 0.1}s`; }); // Filter functionality const filterButtons = document.querySelectorAll('.filter-btn'); filterButtons.forEach(button => { button.addEventListener('click', function() { // Toggle active state on buttons filterButtons.forEach(btn => btn.classList.remove('active')); this.classList.add('active'); const category = this.dataset.category; filterProducts(category); }); }); function filterProducts(category) { const products = document.querySelectorAll('.product-card'); let visibleCount = 0; products.forEach(product => { if (category === 'all' || product.dataset.category === category) { product.style.display = 'block'; // Reset animation product.style.animation = 'none'; product.offsetHeight; // Trigger reflow product.style.animation = 'fadeInUp 0.5s ease forwards'; product.style.animationDelay = `${visibleCount * 0.1}s`; visibleCount++; } else { product.style.display = 'none'; } }); // Check if no results found const noResultsElement = document.querySelector('.no-results'); if (visibleCount === 0) { if (!noResultsElement) { const noResults = document.createElement('div'); noResults.className = 'no-results'; noResults.textContent = 'No products found in this category'; document.querySelector('.product-grid').appendChild(noResults); } } else if (noResultsElement) { noResultsElement.remove(); } } // 3D tilt effect on hover productCards.forEach(card => { card.addEventListener('mousemove', handleTilt); card.addEventListener('mouseleave', resetTilt); }); function handleTilt(e) { const card = this; const rect = card.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; const centerX = rect.width / 2; const centerY = rect.height / 2; const tiltX = (y - centerY) / 10; const tiltY = (centerX - x) / 10; card.style.transform = `perspective(1000px) rotateX(${tiltX}deg) rotateY(${tiltY}deg) translateY(-10px) scale(1.02)`; } function resetTilt() { this.style.transform = ''; } // Buy button click animation const buyButtons = document.querySelectorAll('.buy-btn'); buyButtons.forEach(button => { button.addEventListener('click', function(e) { e.preventDefault(); // Add ripple effect const ripple = document.createElement('span'); ripple.classList.add('ripple'); this.appendChild(ripple); const originalText = this.textContent; this.textContent = 'Added ✓'; this.style.backgroundColor = 'var(--tertiary-color)'; setTimeout(() => { this.textContent = originalText; this.style.backgroundColor = ''; ripple.remove(); }, 1500); }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>EduNeu | Login Portal</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } :root { --bg-color: #e6eef8; --primary-color: #4a7bfc; --text-color: #2c3e50; --shadow-dark: #c8d4e2; --shadow-light: #ffffff; --error-color: #e74c3c; --success-color: #2ecc71; } body { display: flex; justify-content: center; align-items: center; min-height: 100vh; background-color: var(--bg-color); padding: 20px; overflow-x: hidden; } .container { width: 100%; max-width: 650px; position: relative; z-index: 1; } .login-card { background-color: var(--bg-color); border-radius: 30px; box-shadow: 10px 10px 20px var(--shadow-dark), -10px -10px 20px var(--shadow-light); padding: 40px; position: relative; overflow: hidden; transition: all 0.3s ease; } .login-card:hover { transform: translateY(-5px); box-shadow: 12px 12px 24px var(--shadow-dark), -12px -12px 24px var(--shadow-light); } .blob { position: absolute; width: 300px; height: 300px; background: linear-gradient(135deg, rgba(74, 123, 252, 0.1), rgba(74, 123, 252, 0.05)); border-radius: 50%; filter: blur(40px); z-index: -1; animation: blob-move 15s infinite alternate ease-in-out; } .blob-1 { top: -150px; left: -150px; } .blob-2 { bottom: -150px; right: -150px; animation-delay: 5s; } @keyframes blob-move { 0% { transform: translate(0, 0) scale(1); } 50% { transform: translate(30px, 30px) scale(1.2); } 100% { transform: translate(-30px, 20px) scale(0.8); } } .logo { text-align: center; margin-bottom: 30px; } .logo-icon { width: 80px; height: 80px; background-color: var(--bg-color); border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; box-shadow: 5px 5px 10px var(--shadow-dark), -5px -5px 10px var(--shadow-light); margin-bottom: 15px; } .logo-icon svg { width: 45px; height: 45px; fill: var(--primary-color); } h1 { color: var(--text-color); font-size: 28px; margin-bottom: 10px; font-weight: 600; } .tagline { color: #7f8c8d; font-size: 16px; margin-bottom: 40px; } .form-group { margin-bottom: 25px; position: relative; } .form-label { display: block; margin-bottom: 12px; color: var(--text-color); font-weight: 500; font-size: 15px; transition: all 0.3s ease; } .input-with-icon { position: relative; } .input-with-icon svg { position: absolute; left: 15px; top: 50%; transform: translateY(-50%); width: 20px; height: 20px; fill: #95a5a6; transition: all 0.3s ease; } .input-field { width: 100%; padding: 16px 16px 16px 45px; border: none; border-radius: 15px; background-color: var(--bg-color); color: var(--text-color); font-size: 16px; transition: all 0.3s ease; box-shadow: inset 4px 4px 8px var(--shadow-dark), inset -4px -4px 8px var(--shadow-light); } .input-field:focus { outline: none; box-shadow: inset 6px 6px 12px var(--shadow-dark), inset -6px -6px 12px var(--shadow-light); } .input-field:focus + svg { fill: var(--primary-color); } .password-toggle { position: absolute; right: 15px; top: 50%; transform: translateY(-50%); cursor: pointer; z-index: 2; } .password-toggle svg { width: 20px; height: 20px; fill: #95a5a6; transition: all 0.3s ease; } .password-toggle:hover svg { fill: var(--primary-color); } .remember-forgot { display: flex; justify-content: space-between; align-items: center; margin-bottom: 30px; flex-wrap: wrap; } .checkbox-container { display: flex; align-items: center; } .custom-checkbox { width: 22px; height: 22px; border-radius: 6px; background-color: var(--bg-color); margin-right: 10px; position: relative; box-shadow: inset 2px 2px 4px var(--shadow-dark), inset -2px -2px 4px var(--shadow-light); cursor: pointer; transition: all 0.3s ease; } .custom-checkbox svg { position: absolute; width: 14px; height: 14px; top: 50%; left: 50%; transform: translate(-50%, -50%); fill: var(--primary-color); opacity: 0; transition: all 0.3s ease; } .checkbox-input { display: none; } .checkbox-input:checked + .custom-checkbox { background-color: rgba(74, 123, 252, 0.1); } .checkbox-input:checked + .custom-checkbox svg { opacity: 1; } .remember-text { color: #7f8c8d; font-size: 14px; } .forgot-link { color: var(--primary-color); text-decoration: none; font-size: 14px; font-weight: 600; transition: all 0.3s ease; } .forgot-link:hover { text-decoration: underline; } .login-button { width: 100%; padding: 16px; border: none; border-radius: 15px; background-color: var(--bg-color); color: var(--primary-color); font-size: 16px; font-weight: 600; cursor: pointer; transition: all 0.3s ease; box-shadow: 6px 6px 12px var(--shadow-dark), -6px -6px 12px var(--shadow-light); position: relative; overflow: hidden; z-index: 1; } .login-button::before { content: ""; position: absolute; top: 0; left: 0; width: 0%; height: 100%; background-color: var(--primary-color); transition: all 0.4s ease; z-index: -1; border-radius: 15px; } .login-button:hover { color: white; transform: translateY(-2px); box-shadow: 8px 8px 16px var(--shadow-dark), -8px -8px 16px var(--shadow-light); } .login-button:hover::before { width: 100%; } .login-button:active { transform: translateY(0); box-shadow: 4px 4px 8px var(--shadow-dark), -4px -4px 8px var(--shadow-light); } .divider { display: flex; align-items: center; margin: 30px 0; color: #7f8c8d; font-size: 14px; } .divider::before, .divider::after { content: ""; flex: 1; height: 1px; background-color: #d5dde5; } .divider::before { margin-right: 15px; } .divider::after { margin-left: 15px; } .social-login { display: flex; justify-content: center; gap: 20px; } .social-button { width: 60px; height: 60px; border-radius: 50%; border: none; background-color: var(--bg-color); cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.3s ease; box-shadow: 5px 5px 10px var(--shadow-dark), -5px -5px 10px var(--shadow-light); } .social-button:hover { transform: translateY(-3px); box-shadow: 7px 7px 14px var(--shadow-dark), -7px -7px 14px var(--shadow-light); } .social-button:active { transform: translateY(0); box-shadow: 3px 3px 6px var(--shadow-dark), -3px -3px 6px var(--shadow-light); } .social-button svg { width: 24px; height: 24px; } .signup-link { text-align: center; margin-top: 30px; color: #7f8c8d; font-size: 14px; } .signup-link a { color: var(--primary-color); text-decoration: none; font-weight: 600; transition: all 0.3s ease; } .signup-link a:hover { text-decoration: underline; } .error-message { color: var(--error-color); font-size: 13px; margin-top: 8px; display: none; font-weight: 500; } /* Animations */ @keyframes shake { 0%, 100% {transform: translateX(0);} 10%, 30%, 50%, 70%, 90% {transform: translateX(-5px);} 20%, 40%, 60%, 80% {transform: translateX(5px);} } .shake { animation: shake 0.5s cubic-bezier(.36,.07,.19,.97) both; } .loading-dots { display: none; justify-content: center; align-items: center; gap: 5px; } .loading-dots span { width: 6px; height: 6px; border-radius: 50%; background-color: currentColor; display: inline-block; animation: dot-pulse 1.5s infinite ease-in-out; } .loading-dots span:nth-child(2) { animation-delay: 0.2s; } .loading-dots span:nth-child(3) { animation-delay: 0.4s; } @keyframes dot-pulse { 0%, 100% { transform: scale(0.8); opacity: 0.5; } 50% { transform: scale(1.2); opacity: 1; } } /* Responsive design */ @media (max-width: 600px) { .login-card { padding: 30px 20px; } .remember-forgot { flex-direction: column; align-items: flex-start; gap: 15px; } .social-login { gap: 15px; } .social-button { width: 50px; height: 50px; } } /* Success animation */ .success-checkmark { width: 80px; height: 80px; margin: 0 auto; position: relative; display: none; } .check-icon { width: 80px; height: 80px; position: relative; border-radius: 50%; box-sizing: content-box; border: 4px solid var(--success-color); } .check-icon::before { top: 48px; left: 17px; width: 25px; transform: rotate(45deg); animation: success-icon-before 0.4s; } .check-icon::after { top: 44px; left: 27px; width: 50px; transform: rotate(135deg); animation: success-icon-after 0.4s; } .check-icon::before, .check-icon::after { content: ''; height: 4px; background-color: var(--success-color); display: block; border-radius: 2px; position: absolute; z-index: 10; } @keyframes success-icon-before { 0% { width: 0; right: 15px; top: 40px; } 100% { width: 25px; right: 15px; top: 48px; } } @keyframes success-icon-after { 0% { width: 0; left: 27px; top: 48px; } 100% { width: 50px; left: 27px; top: 44px; } } /* Theme toggle */ .theme-toggle { position: absolute; top: 20px; right: 20px; width: 40px; height: 40px; background-color: var(--bg-color); border-radius: 50%; cursor: pointer; display: flex; align-items: center; justify-content: center; box-shadow: 3px 3px 6px var(--shadow-dark), -3px -3px 6px var(--shadow-light); transition: all 0.3s ease; z-index: 2; } .theme-toggle:hover { transform: scale(1.1); } .theme-toggle svg { width: 22px; height: 22px; fill: var(--text-color); transition: all 0.3s ease; } /* Dark theme */ body.dark-theme { --bg-color: #1a2130; --shadow-dark: #121722; --shadow-light: #22293a; --text-color: #e0e6ed; } body.dark-theme .theme-toggle svg.moon { display: none; } body.dark-theme .theme-toggle svg.sun { display: block; } body:not(.dark-theme) .theme-toggle svg.moon { display: block; } body:not(.dark-theme) .theme-toggle svg.sun { display: none; } </style> </head> <body> <div class="container"> <div class="theme-toggle" id="themeToggle"> <svg class="moon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M12 22c5.523 0 10-4.477 10-10s-4.477-10-10-10s-10 4.477-10 10s4.477 10 10 10zm0-2c-4.418 0-8-3.582-8-8s3.582-8 8-8s8 3.582 8 8s-3.582 8-8 8zm-5-8a5 5 0 1 1 10 0a5 5 0 0 1-10 0z"/> </svg> <svg class="sun" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M12 18a6 6 0 1 1 0-12a6 6 0 0 1 0 12zm0-2a4 4 0 1 0 0-8a4 4 0 0 0 0 8zM11 1h2v3h-2V1zm0 19h2v3h-2v-3zM3.515 4.929l1.414-1.414L7.05 5.636L5.636 7.05L3.515 4.93zM16.95 18.364l1.414-1.414l2.121 2.121l-1.414 1.414l-2.121-2.121zm2.121-14.85l1.414 1.415l-2.121 2.121l-1.414-1.414l2.121-2.121zM5.636 16.95l1.414 1.414l-2.121 2.121l-1.414-1.414l2.121-2.121zM23 11v2h-3v-2h3zM4 11v2H1v-2h3z"/> </svg> </div> <div class="login-card"> <div class="blob blob-1"></div> <div class="blob blob-2"></div> <div class="logo"> <div class="logo-icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M12 3L1 9L5 11.18V17.18L12 21L19 17.18V11.18L21 10.09V16H23V9L12 3ZM18.82 9L12 12.72L5.18 9L12 5.28L18.82 9ZM17 15.99L12 18.72L7 15.99V12.27L12 15L17 12.27V15.99Z"/> </svg> </div> <h1>EduNeu Academy</h1> <p class="tagline">Where learning meets innovation and community</p> </div> <form id="loginForm"> <div class="form-group"> <label class="form-label" for="email">Email</label> <div class="input-with-icon"> <input type="email" id="email" class="input-field" placeholder="[email protected]" autocomplete="email"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/> </svg> </div> <div class="error-message" id="emailError">Please enter a valid educational email address</div> </div> <div class="form-group"> <label class="form-label" for="password">Password</label> <div class="input-with-icon"> <input type="password" id="password" class="input-field" placeholder="Enter your password" autocomplete="current-password"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2s2 .9 2 2s-.9 2-2 2zM9 8V6c0-1.66 1.34-3 3-3s3 1.34 3 3v2H9z"/> </svg> <div class="password-toggle" id="passwordToggle"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="show-password"> <path d="M12 9a3 3 0 1 0 0 6a3 3 0 0 0 0-6zm0 8a5 5 0 1 1 0-10a5 5 0 0 1 0 10zm0-15a11 11 0 0 0-11 8a11.24 11.24 0 0 0 11 8a11 11 0 0 0 11-8a11.24 11.24 0 0 0-11-8z"/> </svg> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="hide-password" style="display: none;"> <path d="M12 9a3 3 0 1 0 0 6a3 3 0 0 0 0-6zm0 8a5 5 0 1 1 0-10a5 5 0 0 1 0 10zm0-15a11 11 0 0 0-11 8a11.24 11.24 0 0 0 11 8a11 11 0 0 0 11-8a11.24 11.24 0 0 0-11-8zm0 14a9.12 9.12 0 0 1-9-6a9.12 9.12 0 0 1 9-6a9.12 9.12 0 0 1 9 6a9.12 9.12 0 0 1-9 6z"/> </svg> </div> </div> <div class="error-message" id="passwordError">Password must be at least 6 characters</div> </div> <div class="remember-forgot"> <div class="checkbox-container"> <input type="checkbox" id="rememberMe" class="checkbox-input"> <label for="rememberMe" class="custom-checkbox"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z"/> </svg> </label> <span class="remember-text">Remember this device</span> </div> <a href="#" class="forgot-link">Forgot password?</a> </div> <button type="submit" class="login-button" id="loginButton"> <span class="button-text">Log in to your account</span> <div class="loading-dots"> <span></span> <span></span> <span></span> </div> </button> <div class="success-checkmark"> <div class="check-icon"></div> </div> <div class="divider">or continue with</div> <div class="social-login"> <button type="button" class="social-button" aria-label="Google"> <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" style="fill: #DB4437"> <path d="M12.24 10.285V14.4h6.806c-.275 1.765-2.056 5.174-6.806 5.174-4.095 0-7.439-3.389-7.439-7.574s3.345-7.574 7.439-7.574c2.33 0 3.891.989 4.785 1.849l3.254-3.138C18.189 1.186 15.479 0 12.24 0c-6.635 0-12 5.365-12 12s5.365 12 12 12c6.926 0 11.52-4.869 11.52-11.726 0-.788-.085-1.39-.189-1.989H12.24z"/> </svg> </button> <button type="button" class="social-button" aria-label="Microsoft"> <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" style="fill: #00A4EF"> <path d="M11.4 24H0V12.6h11.4V24zM24 24H12.6V12.6H24V24zM11.4 11.4H0V0h11.4v11.4zm12.6 0H12.6V0H24v11.4z"/> </svg> </button> <button type="button" class="social-button" aria-label="Apple"> <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" style="fill: #555555"> <path d="M18.71 19.5c-.83 1.24-1.71 2.45-3.05 2.47-1.34.03-1.77-.79-3.29-.79-1.53 0-2 .77-3.27.82-1.31.05-2.3-1.32-3.14-2.53C4.25 17 2.94 12.45 4.7 9.39c.87-1.52 2.43-2.48 4.12-2.51 1.28-.02 2.5.87 3.29.87.78 0 2.26-1.07 3.81-.91.65.03 2.47.26 3.64 1.98-.09.06-2.17 1.28-2.15 3.81.03 3.02 2.65 4.03 2.68 4.04-.03.07-.42 1.44-1.38 2.83M13 3.5c.73-.83 1.94-1.46 2.94-1.5.13 1.17-.34 2.35-1.04 3.19-.69.85-1.83 1.51-2.95 1.42-.15-1.15.41-2.35 1.05-3.11z"/> </svg> </button> </div> <div class="signup-link"> New to EduNeu Academy? <a href="#">Create an account</a> </div> </form> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Theme toggle const themeToggle = document.getElementById('themeToggle'); const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)'); // Check if user has a saved preference const savedTheme = localStorage.getItem('theme'); if (savedTheme === 'dark' || (!savedTheme && prefersDarkScheme.matches)) { document.body.classList.add('dark-theme'); } themeToggle.addEventListener('click', function() { document.body.classList.toggle('dark-theme'); const theme = document.body.classList.contains('dark-theme') ? 'dark' : 'light'; localStorage.setItem('theme', theme); }); // Password visibility toggle const passwordInput = document.getElementById('password'); const passwordToggle = document.getElementById('passwordToggle'); const showPasswordIcon = passwordToggle.querySelector('.show-password'); const hidePasswordIcon = passwordToggle.querySelector('.hide-password'); passwordToggle.addEventListener('click', function() { if (passwordInput.type === 'password') { passwordInput.type = 'text'; showPasswordIcon.style.display = 'none'; hidePasswordIcon.style.display = 'block'; } else { passwordInput.type = 'password'; showPasswordIcon.style.display = 'block'; hidePasswordIcon.style.display = 'none'; } passwordInput.focus(); }); // Form validation const loginForm = document.getElementById('loginForm'); const emailInput = document.getElementById('email'); const emailError = document.getElementById('emailError'); const passwordError = document.getElementById('passwordError'); const loginButton = document.getElementById('loginButton'); const buttonText = loginButton.querySelector('.button-text'); const loadingDots = loginButton.querySelector('.loading-dots'); const successCheckmark = document.querySelector('.success-checkmark'); loginForm.addEventListener('submit', function(e) { e.preventDefault(); let isValid = true; // Email validation if (!emailInput.value || !emailInput.value.includes('@') || !emailInput.value.includes('.edu')) { emailError.style.display = 'block'; emailInput.parentElement.classList.add('shake'); setTimeout(() => { emailInput.parentElement.classList.remove('shake'); }, 500); isValid = false; } else { emailError.style.display = 'none'; } // Password validation if (passwordInput.value.length < 6) { passwordError.style.display = 'block'; passwordInput.parentElement.classList.add('shake'); setTimeout(() => { passwordInput.parentElement.classList.remove('shake'); }, 500); isValid = false; } else { passwordError.style.display = 'none'; } if (isValid) { // Show loading buttonText.style.display = 'none'; loadingDots.style.display = 'flex'; // Simulate login process setTimeout(() => { loadingDots.style.display = 'none'; successCheckmark.style.display = 'block'; setTimeout(() => { // Reset form for demo purposes successCheckmark.style.display = 'none'; buttonText.style.display = 'block'; loginForm.reset(); }, 2000); }, 1500); } }); // Focus and blur effects for inputs const inputs = document.querySelectorAll('.input-field'); inputs.forEach(input => { input.addEventListener('focus', function() { this.parentElement.querySelector('svg').style.fill = 'var(--primary-color)'; }); input.addEventListener('blur', function() { if (!this.value) { this.parentElement.querySelector('svg').style.fill = '#95a5a6'; } }); }); // Animate elements on page load setTimeout(() => { document.querySelectorAll('.form-group, .remember-forgot, .login-button, .divider, .social-login, .signup-link').forEach((el, index) => { el.style.opacity = '0'; el.style.transform = 'translateY(20px)'; el.style.transition = `all 0.4s ease ${index * 0.1}s`; setTimeout(() => { el.style.opacity = '1'; el.style.transform = 'translateY(0)'; }, 100); }); }, 300); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>SoundSphere Control Panel</title> <style> :root { --base-bg: #e6e7ee; --accent: #7f5af0; --accent-alt: #6c4ad6; --dark-shadow: rgba(163, 177, 198, 0.6); --light-shadow: rgba(255, 255, 255, 0.9); --text-primary: #2b2c34; --text-secondary: #5a5a6e; --panel-width: 650px; --panel-height: 650px; --slider-height: 10px; --slider-thumb-size: 24px; --knob-size: 80px; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: var(--base-bg); display: flex; justify-content: center; align-items: center; height: 100vh; color: var(--text-primary); } .control-panel { width: var(--panel-width); height: var(--panel-height); background-color: var(--base-bg); border-radius: 20px; box-shadow: 8px 8px 16px var(--dark-shadow), -8px -8px 16px var(--light-shadow); padding: 30px; display: flex; flex-direction: column; position: relative; overflow: hidden; } .header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 25px; position: relative; } .logo { font-size: 24px; font-weight: 700; display: flex; align-items: center; color: var(--text-primary); } .logo-icon { height: 30px; width: 30px; border-radius: 50%; background: linear-gradient(145deg, var(--accent), var(--accent-alt)); margin-right: 10px; position: relative; overflow: hidden; } .logo-icon::before { content: ""; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); height: 10px; width: 10px; background-color: var(--light-shadow); border-radius: 50%; } .now-playing { margin: 5px 0 25px; padding: 20px; border-radius: 15px; box-shadow: inset 3px 3px 6px var(--dark-shadow), inset -3px -3px 6px var(--light-shadow); position: relative; overflow: hidden; } .track-info { display: flex; align-items: center; } .album-art { width: 80px; height: 80px; border-radius: 10px; box-shadow: 4px 4px 8px var(--dark-shadow), -4px -4px 8px var(--light-shadow); background: linear-gradient(145deg, #f2f3fa, #d8d9e0); overflow: hidden; position: relative; } .album-art img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.3s ease; } .album-art:hover img { transform: scale(1.05); } .track-details { margin-left: 20px; flex: 1; } .track-name { font-size: 18px; font-weight: 600; margin-bottom: 5px; color: var(--text-primary); } .artist-name { font-size: 14px; color: var(--text-secondary); margin-bottom: 10px; } .progress-bar { margin-top: 20px; width: 100%; height: var(--slider-height); border-radius: 5px; box-shadow: inset 3px 3px 6px var(--dark-shadow), inset -3px -3px 6px var(--light-shadow); position: relative; overflow: hidden; } .progress-fill { height: 100%; width: 35%; background: linear-gradient(90deg, var(--accent), var(--accent-alt)); border-radius: 5px; transition: width 0.2s ease; } .time-display { display: flex; justify-content: space-between; margin-top: 8px; font-size: 12px; color: var(--text-secondary); } .controls-container { display: flex; justify-content: space-between; margin-top: 25px; } .media-controls { display: flex; justify-content: center; gap: 20px; margin-bottom: 30px; } .control-btn { width: 50px; height: 50px; border-radius: 50%; box-shadow: 5px 5px 10px var(--dark-shadow), -5px -5px 10px var(--light-shadow); display: flex; justify-content: center; align-items: center; cursor: pointer; transition: all 0.2s ease; border: none; background-color: var(--base-bg); color: var(--text-primary); } .control-btn:hover { box-shadow: 3px 3px 6px var(--dark-shadow), -3px -3px 6px var(--light-shadow); transform: translateY(2px); } .control-btn:active { box-shadow: inset 3px 3px 6px var(--dark-shadow), inset -3px -3px 6px var(--light-shadow); transform: translateY(4px); } .play-btn { width: 60px; height: 60px; position: relative; } .play-icon, .pause-icon { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 20px; height: 20px; transition: opacity 0.3s ease; } .play-icon { opacity: 1; } .pause-icon { opacity: 0; } .play-btn.playing .play-icon { opacity: 0; } .play-btn.playing .pause-icon { opacity: 1; } .control-btn i { font-size: 20px; } .play-btn i { font-size: 24px; color: var(--accent); } .sliders-section { margin-top: 10px; display: grid; grid-template-columns: 1fr 1fr; gap: 30px; } .slider-container { display: flex; flex-direction: column; align-items: center; } .slider { -webkit-appearance: none; width: 100%; height: var(--slider-height); border-radius: 5px; background: var(--base-bg); box-shadow: inset 3px 3px 6px var(--dark-shadow), inset -3px -3px 6px var(--light-shadow); outline: none; margin: 20px 0; position: relative; } .slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: var(--slider-thumb-size); height: var(--slider-thumb-size); border-radius: 50%; background: linear-gradient(145deg, var(--accent), var(--accent-alt)); cursor: pointer; box-shadow: 3px 3px 6px var(--dark-shadow), -3px -3px 6px var(--light-shadow); transition: all 0.2s ease; } .slider::-webkit-slider-thumb:hover { transform: scale(1.1); } .slider::-moz-range-thumb { width: var(--slider-thumb-size); height: var(--slider-thumb-size); border-radius: 50%; background: linear-gradient(145deg, var(--accent), var(--accent-alt)); cursor: pointer; box-shadow: 3px 3px 6px var(--dark-shadow), -3px -3px 6px var(--light-shadow); border: none; transition: all 0.2s ease; } .slider::-moz-range-thumb:hover { transform: scale(1.1); } .slider-title { font-weight: 600; margin-bottom: 10px; color: var(--text-primary); } .volume-knob-container { margin-top: 30px; display: flex; justify-content: center; } .volume-knob { width: var(--knob-size); height: var(--knob-size); border-radius: 50%; box-shadow: 8px 8px 16px var(--dark-shadow), -8px -8px 16px var(--light-shadow); position: relative; display: flex; justify-content: center; align-items: center; cursor: pointer; user-select: none; } .knob-inner { width: 70%; height: 70%; border-radius: 50%; background: var(--base-bg); box-shadow: inset 4px 4px 8px var(--dark-shadow), inset -4px -4px 8px var(--light-shadow); position: relative; display: flex; justify-content: center; align-items: center; } .knob-indicator { position: absolute; top: 10%; left: 50%; width: 3px; height: 35%; background-color: var(--accent); transform-origin: bottom center; border-radius: 5px; } .volume-level { margin-top: 10px; text-align: center; font-weight: 600; color: var(--text-secondary); } .equalizer-toggles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 15px; margin-top: 20px; } .eq-toggle { padding: 12px; border-radius: 10px; box-shadow: 4px 4px 8px var(--dark-shadow), -4px -4px 8px var(--light-shadow); text-align: center; cursor: pointer; transition: all 0.2s ease; font-size: 14px; color: var(--text-secondary); } .eq-toggle.active { box-shadow: inset 4px 4px 8px var(--dark-shadow), inset -4px -4px 8px var(--light-shadow); color: var(--accent); } .eq-toggle:hover { color: var(--accent-alt); } .visualizer { height: 50px; margin-top: 20px; display: flex; align-items: flex-end; justify-content: center; gap: 3px; } .bar { width: 5px; height: 5px; background: var(--accent); border-radius: 2px; transition: height 0.1s ease; } .playback-panel { margin-top: 20px; display: flex; justify-content: center; gap: 15px; } .playback-option { width: 40px; height: 40px; border-radius: 50%; display: flex; justify-content: center; align-items: center; background-color: var(--base-bg); box-shadow: 3px 3px 6px var(--dark-shadow), -3px -3px 6px var(--light-shadow); cursor: pointer; color: var(--text-secondary); transition: all 0.2s ease; } .playback-option:hover { color: var(--accent); } .playback-option.active { color: var(--accent); box-shadow: inset 3px 3px 6px var(--dark-shadow), inset -3px -3px 6px var(--light-shadow); } .pulse-effect { position: absolute; top: 0; left: 0; width: 100%; height: 100%; border-radius: 20px; background: radial-gradient(circle, rgba(127, 90, 240, 0.1) 0%, rgba(127, 90, 240, 0) 70%); opacity: 0; pointer-events: none; z-index: 1; } @keyframes pulse { 0% { transform: scale(0.95); opacity: 0.7; } 50% { transform: scale(1.05); opacity: 0.3; } 100% { transform: scale(0.95); opacity: 0.7; } } .playing .pulse-effect { opacity: 1; animation: pulse 2s ease-in-out infinite; } /* Responsive Adjustments */ @media (max-width: 700px) { .control-panel { width: 90%; height: auto; padding: 20px; } .sliders-section { grid-template-columns: 1fr; gap: 20px; } .volume-knob { --knob-size: 70px; } .media-controls { gap: 10px; } .control-btn { width: 45px; height: 45px; } .play-btn { width: 55px; height: 55px; } .equalizer-toggles { grid-template-columns: repeat(3, 1fr); } } @media (max-width: 400px) { .equalizer-toggles { grid-template-columns: repeat(2, 1fr); } .track-info { flex-direction: column; align-items: flex-start; } .track-details { margin-left: 0; margin-top: 15px; } } </style> </head> <body> <div class="control-panel"> <div class="pulse-effect"></div> <div class="header"> <div class="logo"> <div class="logo-icon"></div> <span>SoundSphere</span> </div> </div> <div class="now-playing"> <div class="track-info"> <div class="album-art"> <img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgZmlsbD0ibm9uZSI+CiAgPHJlY3Qgd2lkdGg9IjEwMCIgaGVpZ2h0PSIxMDAiIGZpbGw9IiM3ZjVhZjAiLz4KICA8Y2lyY2xlIGN4PSI1MCIgY3k9IjUwIiByPSIyNSIgZmlsbD0iI2ZmZiIvPgogIDxjaXJjbGUgY3g9IjUwIiBjeT0iNTAiIHI9IjUiIGZpbGw9IiM3ZjVhZjAiLz4KPC9zdmc+" alt="Album Art"> </div> <div class="track-details"> <div class="track-name">Midnight Odyssey</div> <div class="artist-name">Lunar Echoes</div> <div class="progress-bar"> <div class="progress-fill" id="progressFill"></div> </div> <div class="time-display"> <span class="current-time">1:45</span> <span class="total-time">4:32</span> </div> </div> </div> </div> <div class="media-controls"> <button class="control-btn" id="prevBtn"> <i>◀◀</i> </button> <button class="control-btn play-btn" id="playBtn"> <span class="play-icon">▶</span> <span class="pause-icon">❚❚</span> </button> <button class="control-btn" id="nextBtn"> <i>▶▶</i> </button> </div> <div class="sliders-section"> <div class="slider-container"> <div class="slider-title">Bass</div> <input type="range" min="0" max="100" value="65" class="slider" id="bassSlider"> </div> <div class="slider-container"> <div class="slider-title">Treble</div> <input type="range" min="0" max="100" value="55" class="slider" id="trebleSlider"> </div> </div> <div class="volume-knob-container"> <div class="volume-knob" id="volumeKnob"> <div class="knob-inner"> <div class="knob-indicator" id="knobIndicator"></div> </div> </div> </div> <div class="volume-level" id="volumeLevel">Volume: 75%</div> <div class="equalizer-toggles"> <div class="eq-toggle" data-eq="acoustic">Acoustic</div> <div class="eq-toggle active" data-eq="balanced">Balanced</div> <div class="eq-toggle" data-eq="electronic">Electronic</div> </div> <div class="visualizer" id="visualizer"> <div class="bar"></div> <div class="bar"></div> <div class="bar"></div> <div class="bar"></div> <div class="bar"></div> <div class="bar"></div> <div class="bar"></div> <div class="bar"></div> <div class="bar"></div> <div class="bar"></div> <div class="bar"></div> <div class="bar"></div> <div class="bar"></div> <div class="bar"></div> <div class="bar"></div> <div class="bar"></div> <div class="bar"></div> <div class="bar"></div> <div class="bar"></div> <div class="bar"></div> </div> <div class="playback-panel"> <div class="playback-option" data-mode="repeat">🔁</div> <div class="playback-option active" data-mode="shuffle">🔀</div> <div class="playback-option" data-mode="repeat-one">🔂</div> </div> </div> <script> // Volume Knob Control const volumeKnob = document.getElementById('volumeKnob'); const knobIndicator = document.getElementById('knobIndicator'); const volumeLevel = document.getElementById('volumeLevel'); let currentRotation = 0; let currentVolume = 75; let isDragging = false; let startAngle = 0; // Set initial rotation knobIndicator.style.transform = `rotate(${currentVolume * 2.7}deg)`; volumeKnob.addEventListener('mousedown', (e) => { isDragging = true; const knobRect = volumeKnob.getBoundingClientRect(); const knobCenterX = knobRect.left + knobRect.width / 2; const knobCenterY = knobRect.top + knobRect.height / 2; startAngle = Math.atan2(e.clientY - knobCenterY, e.clientX - knobCenterX) * 180 / Math.PI; document.addEventListener('mousemove', handleDrag); document.addEventListener('mouseup', () => { isDragging = false; document.removeEventListener('mousemove', handleDrag); }); }); function handleDrag(e) { if (!isDragging) return; const knobRect = volumeKnob.getBoundingClientRect(); const knobCenterX = knobRect.left + knobRect.width / 2; const knobCenterY = knobRect.top + knobRect.height / 2; const currentAngle = Math.atan2(e.clientY - knobCenterY, e.clientX - knobCenterX) * 180 / Math.PI; let deltaAngle = currentAngle - startAngle; // Accumulate rotation currentRotation += deltaAngle; startAngle = currentAngle; // Constrain rotation to 0-270 degrees currentRotation = Math.max(0, Math.min(270, currentRotation)); // Update volume (0-100) currentVolume = Math.round(currentRotation / 2.7); // Update UI knobIndicator.style.transform = `rotate(${currentRotation}deg)`; volumeLevel.textContent = `Volume: ${currentVolume}%`; } // Touch support for volume knob volumeKnob.addEventListener('touchstart', (e) => { e.preventDefault(); isDragging = true; const touch = e.touches[0]; const knobRect = volumeKnob.getBoundingClientRect(); const knobCenterX = knobRect.left + knobRect.width / 2; const knobCenterY = knobRect.top + knobRect.height / 2; startAngle = Math.atan2(touch.clientY - knobCenterY, touch.clientX - knobCenterX) * 180 / Math.PI; document.addEventListener('touchmove', handleTouchDrag); document.addEventListener('touchend', () => { isDragging = false; document.removeEventListener('touchmove', handleTouchDrag); }); }); function handleTouchDrag(e) { if (!isDragging) return; e.preventDefault(); const touch = e.touches[0]; const knobRect = volumeKnob.getBoundingClientRect(); const knobCenterX = knobRect.left + knobRect.width / 2; const knobCenterY = knobRect.top + knobRect.height / 2; const currentAngle = Math.atan2(touch.clientY - knobCenterY, touch.clientX - knobCenterX) * 180 / Math.PI; let deltaAngle = currentAngle - startAngle; currentRotation += deltaAngle; startAngle = currentAngle; currentRotation = Math.max(0, Math.min(270, currentRotation)); currentVolume = Math.round(currentRotation / 2.7); knobIndicator.style.transform = `rotate(${currentRotation}deg)`; volumeLevel.textContent = `Volume: ${currentVolume}%`; } // Play/Pause Button const playBtn = document.getElementById('playBtn'); let isPlaying = false; playBtn.addEventListener('click', () => { isPlaying = !isPlaying; playBtn.classList.toggle('playing'); document.querySelector('.control-panel').classList.toggle('playing'); if (isPlaying) { startVisualizer(); } else { stopVisualizer(); } }); // Visualizer Animation const visualizer = document.getElementById('visualizer'); const bars = visualizer.querySelectorAll('.bar'); let visualizerInterval; function startVisualizer() { if (visualizerInterval) clearInterval(visualizerInterval); visualizerInterval = setInterval(() => { bars.forEach(bar => { const height = Math.floor(Math.random() * 45) + 5; bar.style.height = `${height}px`; }); }, 100); } function stopVisualizer() { clearInterval(visualizerInterval); bars.forEach(bar => { bar.style.height = '5px'; }); } // Progress bar animation const progressFill = document.getElementById('progressFill'); let progressWidth = 35; let progressDirection = 1; let progressInterval; function animateProgress() { if (progressInterval) clearInterval(progressInterval); if (isPlaying) { progressInterval = setInterval(() => { if (progressWidth >= 100) { progressDirection = -1; } else if (progressWidth <= 0) { progressDirection = 1; } progressWidth += progressDirection * 0.5; progressFill.style.width = `${progressWidth}%`; // Update time display const currentTimeEl = document.querySelector('.current-time'); const totalTime = 272; // 4:32 in seconds const currentTimeSeconds = Math.floor(totalTime * (progressWidth / 100)); const minutes = Math.floor(currentTimeSeconds / 60); const seconds = currentTimeSeconds % 60; currentTimeEl.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`; }, 100); } else { clearInterval(progressInterval); } } // Play button also controls progress playBtn.addEventListener('click', () => { if (isPlaying) { animateProgress(); } else { clearInterval(progressInterval); } }); // EQ toggle buttons const eqToggles = document.querySelectorAll('.eq-toggle'); eqToggles.forEach(toggle => { toggle.addEventListener('click', () => { eqToggles.forEach(t => t.classList.remove('active')); toggle.classList.add('active'); }); }); // Playback options const playbackOptions = document.querySelectorAll('.playback-option'); playbackOptions.forEach(option => { option.addEventListener('click', () => { playbackOptions.forEach(o => o.classList.remove('active')); option.classList.add('active'); }); }); // Bass and Treble sliders with smooth animation const bassSlider = document.getElementById('bassSlider'); const trebleSlider = document.getElementById('trebleSlider'); // Create a cool gradient effect based on slider value function updateSliderBackground(slider) { const value = slider.value; const percentage = (value / slider.max) * 100; slider.style.background = `linear-gradient(90deg, var(--accent) ${percentage}%, var(--base-bg) ${percentage}%)`; } bassSlider.addEventListener('input', () => updateSliderBackground(bassSlider)); trebleSlider.addEventListener('input', () => updateSliderBackground(trebleSlider)); // Initialize slider backgrounds updateSliderBackground(bassSlider); updateSliderBackground(trebleSlider); // Previous and Next buttons const prevBtn = document.getElementById('prevBtn'); const nextBtn = document.getElementById('nextBtn'); prevBtn.addEventListener('click', () => { // Simulate track change with visual feedback prevBtn.style.transform = 'scale(0.9)'; setTimeout(() => { prevBtn.style.transform = 'none'; }, 200); }); nextBtn.addEventListener('click', () => { // Simulate track change with visual feedback nextBtn.style.transform = 'scale(0.9)'; setTimeout(() => { nextBtn.style.transform = 'none'; }, 200); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Fintech Dashboard Sidebar</title> <style> :root { --background: #e0e5ec; --text-primary: #333; --text-secondary: #666; --accent: #4d7cfe; --accent-light: #7b9aff; --positive: #00c853; --negative: #ff5252; --shadow-light: #ffffff; --shadow-dark: #a3b1c6; --card-bg: #e6eaf0; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; } body { background-color: var(--background); display: flex; height: 100vh; width: 100%; overflow: hidden; } .dashboard-container { display: flex; width: 100%; height: 100%; } .sidebar { width: 280px; height: 100%; background-color: var(--background); padding: 24px 16px; display: flex; flex-direction: column; position: relative; transition: width 0.3s ease; overflow: hidden; } .brand { display: flex; align-items: center; margin-bottom: 32px; padding-left: 12px; } .brand-logo { width: 40px; height: 40px; border-radius: 12px; background: var(--background); box-shadow: 5px 5px 10px var(--shadow-dark), -5px -5px 10px var(--shadow-light); display: flex; align-items: center; justify-content: center; margin-right: 12px; } .logo-inner { width: 24px; height: 24px; background: var(--accent); border-radius: 6px; position: relative; overflow: hidden; } .logo-inner::before { content: ""; position: absolute; width: 14px; height: 14px; background: var(--background); border-radius: 3px; top: 5px; left: 5px; } .brand-name { font-size: 20px; font-weight: 700; color: var(--text-primary); } .nav-section { margin-bottom: 24px; } .nav-title { font-size: 12px; text-transform: uppercase; letter-spacing: 1.2px; color: var(--text-secondary); margin-bottom: 12px; padding-left: 16px; font-weight: 600; } .nav-item { display: flex; align-items: center; padding: 14px 18px; margin-bottom: 12px; border-radius: 12px; cursor: pointer; color: var(--text-primary); position: relative; transition: all 0.2s ease; background: var(--background); box-shadow: 5px 5px 10px var(--shadow-dark), -5px -5px 10px var(--shadow-light); } .nav-item.active { color: var(--accent); background: var(--background); box-shadow: inset 5px 5px 10px var(--shadow-dark), inset -5px -5px 10px var(--shadow-light); } .nav-item:hover:not(.active) { transform: translateY(-2px); box-shadow: 6px 6px 12px var(--shadow-dark), -6px -6px 12px var(--shadow-light); } .nav-item:active:not(.active) { transform: translateY(0); box-shadow: inset 3px 3px 6px var(--shadow-dark), inset -3px -3px 6px var(--shadow-light); } .nav-item i { margin-right: 12px; font-size: 20px; width: 24px; text-align: center; } .nav-text { font-size: 15px; font-weight: 500; } .badge { background: var(--accent); color: white; font-size: 11px; font-weight: 600; padding: 3px 8px; border-radius: 10px; margin-left: auto; box-shadow: 2px 2px 5px var(--shadow-dark), -2px -2px 5px var(--shadow-light); } .badge.green { background: var(--positive); } .badge.red { background: var(--negative); } .user-profile { margin-top: auto; padding: 16px; border-radius: 12px; box-shadow: 5px 5px 10px var(--shadow-dark), -5px -5px 10px var(--shadow-light); display: flex; align-items: center; } .user-avatar { width: 40px; height: 40px; border-radius: 50%; background: var(--background); box-shadow: inset 3px 3px 6px var(--shadow-dark), inset -3px -3px 6px var(--shadow-light); margin-right: 12px; overflow: hidden; display: flex; align-items: center; justify-content: center; } .user-avatar i { font-size: 20px; color: var(--accent); } .user-info { flex: 1; } .user-name { font-size: 15px; font-weight: 600; color: var(--text-primary); margin-bottom: 2px; } .user-role { font-size: 12px; color: var(--text-secondary); } .toggle-btn { width: 32px; height: 32px; border-radius: 8px; background: var(--background); box-shadow: 3px 3px 6px var(--shadow-dark), -3px -3px 6px var(--shadow-light); display: flex; align-items: center; justify-content: center; cursor: pointer; transition: all 0.2s ease; margin-left: auto; } .toggle-btn:hover { box-shadow: 4px 4px 8px var(--shadow-dark), -4px -4px 8px var(--shadow-light); } .toggle-btn:active { box-shadow: inset 2px 2px 4px var(--shadow-dark), inset -2px -2px 4px var(--shadow-light); } .toggle-btn i { font-size: 16px; color: var(--text-secondary); } .content-preview { flex: 1; padding: 24px; display: flex; flex-direction: column; overflow: hidden; } .content-header { font-size: 24px; font-weight: 700; color: var(--text-primary); margin-bottom: 24px; padding-left: 8px; } .card { background: var(--card-bg); border-radius: 16px; box-shadow: 5px 5px 10px var(--shadow-dark), -5px -5px 10px var(--shadow-light); padding: 20px; margin-bottom: 20px; flex: 1; display: flex; flex-direction: column; } .card-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; } .card-title { font-size: 18px; font-weight: 600; color: var(--text-primary); } .card-subtitle { color: var(--text-secondary); font-size: 14px; margin-top: 4px; } .balance-overview { display: flex; gap: 16px; margin-bottom: 24px; } .balance-card { flex: 1; padding: 20px; border-radius: 12px; box-shadow: inset 3px 3px 6px var(--shadow-dark), inset -3px -3px 6px var(--shadow-light); } .balance-label { font-size: 14px; color: var(--text-secondary); margin-bottom: 8px; } .balance-amount { font-size: 24px; font-weight: 700; color: var(--text-primary); } .balance-change { display: flex; align-items: center; font-size: 13px; margin-top: 8px; } .balance-change.positive { color: var(--positive); } .balance-change.negative { color: var(--negative); } .balance-change i { margin-right: 4px; font-size: 14px; } /* Collapsed sidebar styles */ .sidebar.collapsed { width: 80px; } .sidebar.collapsed .brand-name, .sidebar.collapsed .nav-text, .sidebar.collapsed .badge, .sidebar.collapsed .user-info, .sidebar.collapsed .nav-title { display: none; } .sidebar.collapsed .nav-item { justify-content: center; padding: 14px 10px; } .sidebar.collapsed .nav-item i { margin-right: 0; } .sidebar.collapsed .user-profile { justify-content: center; padding: 16px 10px; } .sidebar.collapsed .user-avatar { margin-right: 0; } .sidebar.collapsed .toggle-btn { margin: 16px auto 0; } /* Responsive styles */ @media (max-width: 700px) { .sidebar { width: 80px; } .brand-name, .nav-text, .badge, .user-info, .nav-title { display: none; } .nav-item { justify-content: center; padding: 14px 10px; } .nav-item i { margin-right: 0; } .user-profile { justify-content: center; padding: 16px 10px; } .user-avatar { margin-right: 0; } .toggle-btn { margin: 16px auto 0; } .content-preview { padding: 16px; } } /* Custom animation for badge pulse */ @keyframes pulse { 0% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.1); opacity: 0.9; } 100% { transform: scale(1); opacity: 1; } } .badge.pulse { animation: pulse 1.5s infinite; } /* Loading animation for dashboard */ @keyframes shimmer { 0% { background-position: -1000px 0; } 100% { background-position: 1000px 0; } } .loading { background: linear-gradient(90deg, var(--card-bg) 25%, #edf0f5 50%, var(--card-bg) 75%); background-size: 1000px 100%; animation: shimmer 2s infinite linear; border-radius: 8px; height: 20px; margin-bottom: 8px; } .loading.sm { width: 30%; } .loading.md { width: 70%; } .loading.lg { width: 100%; } /* For icons, using custom CSS instead of loading a font library */ i.icon { display: inline-block; width: 1em; height: 1em; position: relative; } .icon-home::before { content: '⌂'; } .icon-dashboard::before { content: '📊'; } .icon-transactions::before { content: '↔️'; } .icon-investments::before { content: '📈'; } .icon-cards::before { content: '💳'; } .icon-analytics::before { content: '📉'; } .icon-settings::before { content: '⚙️'; } .icon-help::before { content: '❓'; } .icon-user::before { content: '👤'; } .icon-chevron::before { content: '«'; } .icon-arrow-up::before { content: '↑'; } .icon-arrow-down::before { content: '↓'; } .icon-dots::before { content: '⋮'; } </style> </head> <body> <div class="dashboard-container"> <div class="sidebar"> <div class="brand"> <div class="brand-logo"> <div class="logo-inner"></div> </div> <div class="brand-name">FinEdge</div> </div> <div class="nav-section"> <div class="nav-title">Main Menu</div> <div class="nav-item active"> <i class="icon icon-dashboard"></i> <span class="nav-text">Dashboard</span> </div> <div class="nav-item"> <i class="icon icon-transactions"></i> <span class="nav-text">Transactions</span> <span class="badge pulse">3</span> </div> <div class="nav-item"> <i class="icon icon-cards"></i> <span class="nav-text">Cards</span> </div> <div class="nav-item"> <i class="icon icon-investments"></i> <span class="nav-text">Investments</span> <span class="badge green">+4.2%</span> </div> </div> <div class="nav-section"> <div class="nav-title">Financial Tools</div> <div class="nav-item"> <i class="icon icon-analytics"></i> <span class="nav-text">Analytics</span> </div> <div class="nav-item"> <i class="icon icon-home"></i> <span class="nav-text">Loan Manager</span> <span class="badge red">Due</span> </div> <div class="nav-item"> <i class="icon icon-settings"></i> <span class="nav-text">Settings</span> </div> <div class="nav-item"> <i class="icon icon-help"></i> <span class="nav-text">Support</span> </div> </div> <div class="user-profile"> <div class="user-avatar"> <i class="icon icon-user"></i> </div> <div class="user-info"> <div class="user-name">Alex Morgan</div> <div class="user-role">Premium Account</div> </div> <div class="toggle-btn" id="toggle-sidebar"> <i class="icon icon-chevron"></i> </div> </div> </div> <div class="content-preview"> <div class="content-header">Dashboard Overview</div> <div class="balance-overview"> <div class="balance-card"> <div class="balance-label">Available Balance</div> <div class="balance-amount">$24,563.50</div> <div class="balance-change positive"> <i class="icon icon-arrow-up"></i> 3.2% from last month </div> </div> <div class="balance-card"> <div class="balance-label">Savings Goal</div> <div class="balance-amount">$12,000.00</div> <div class="balance-change positive"> <i class="icon icon-arrow-up"></i> 68% completed </div> </div> </div> <div class="card"> <div class="card-header"> <div> <div class="card-title">Recent Transactions</div> <div class="card-subtitle">Last 7 days activity</div> </div> <i class="icon icon-dots"></i> </div> <div class="loading lg"></div> <div class="loading md"></div> <div class="loading lg"></div> <div class="loading md"></div> <div class="loading sm"></div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Sidebar toggle functionality const toggleBtn = document.getElementById('toggle-sidebar'); const sidebar = document.querySelector('.sidebar'); toggleBtn.addEventListener('click', function() { sidebar.classList.toggle('collapsed'); // Rotate the chevron icon const chevron = this.querySelector('i'); if (sidebar.classList.contains('collapsed')) { chevron.innerHTML = '»'; } else { chevron.innerHTML = '«'; } }); // Navigation item click effect const navItems = document.querySelectorAll('.nav-item'); navItems.forEach(item => { item.addEventListener('click', function() { // Remove active class from all items navItems.forEach(nav => nav.classList.remove('active')); // Add active class to clicked item this.classList.add('active'); // Apply press effect temporarily this.style.transform = 'scale(0.95)'; setTimeout(() => { this.style.transform = ''; }, 200); }); }); // Add hover sound effect const hoverSound = new Audio(); navItems.forEach(item => { item.addEventListener('mouseenter', function() { if (!this.classList.contains('active')) { const randomDelay = Math.random() * 0.1; this.style.transitionDelay = `${randomDelay}s`; } }); item.addEventListener('mouseleave', function() { this.style.transitionDelay = '0s'; }); }); // Simulate loading content setTimeout(() => { const loadingElements = document.querySelectorAll('.loading'); loadingElements.forEach(el => { el.style.animation = 'none'; el.style.background = 'var(--card-bg)'; }); }, 2000); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> :root { --bg-color: #f0e6e0; --shadow-dark: #d1c7c1; --shadow-light: #fff; --accent-color: #e2836e; --text-color: #4a4a4a; --bubble-user: #f8d9d0; --bubble-agent: #e8f0f8; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: var(--bg-color); color: var(--text-color); display: flex; flex-direction: column; height: 700px; width: 100%; max-width: 700px; margin: 0 auto; padding: 20px; overflow: hidden; } .chat-container { display: flex; flex-direction: column; height: 100%; border-radius: 24px; background-color: var(--bg-color); box-shadow: 8px 8px 16px var(--shadow-dark), -8px -8px 16px var(--shadow-light); padding: 20px; overflow: hidden; } .chat-header { display: flex; align-items: center; padding-bottom: 16px; border-bottom: 1px solid rgba(0, 0, 0, 0.05); margin-bottom: 16px; } .agent-avatar { width: 48px; height: 48px; border-radius: 50%; background-color: var(--bg-color); box-shadow: inset 2px 2px 5px var(--shadow-dark), inset -2px -2px 5px var(--shadow-light), 2px 2px 5px var(--shadow-dark), -2px -2px 5px var(--shadow-light); display: flex; align-items: center; justify-content: center; margin-right: 14px; overflow: hidden; } .agent-avatar img { width: 70%; height: 70%; } .agent-info { flex: 1; } .agent-name { font-weight: 600; font-size: 1.1rem; margin-bottom: 4px; } .agent-status { font-size: 0.85rem; color: #6b6b6b; display: flex; align-items: center; } .status-dot { width: 8px; height: 8px; border-radius: 50%; background-color: #4caf50; margin-right: 6px; position: relative; } .status-dot::after { content: ''; position: absolute; width: 100%; height: 100%; border-radius: 50%; background-color: #4caf50; opacity: 0.4; animation: pulse 2s infinite; } .chat-messages { flex: 1; overflow-y: auto; padding-right: 6px; margin-bottom: 16px; scroll-behavior: smooth; } .chat-messages::-webkit-scrollbar { width: 6px; } .chat-messages::-webkit-scrollbar-thumb { background-color: var(--shadow-dark); border-radius: 10px; } .message { display: flex; margin-bottom: 16px; position: relative; max-width: 80%; } .message.user { margin-left: auto; flex-direction: row-reverse; } .message-bubble { padding: 12px 18px; border-radius: 18px; box-shadow: inset 2px 2px 5px var(--shadow-dark), inset -2px -2px 5px var(--shadow-light); position: relative; transform-origin: center bottom; } .message.user .message-bubble { background-color: var(--bubble-user); border-bottom-right-radius: 4px; } .message.agent .message-bubble { background-color: var(--bubble-agent); border-bottom-left-radius: 4px; } .message-time { font-size: 0.7rem; color: #888; margin-top: 5px; text-align: right; } .typing-indicator { display: flex; padding: 8px 16px; align-items: center; margin-bottom: 16px; display: none; } .typing-dot { width: 8px; height: 8px; border-radius: 50%; background-color: var(--accent-color); margin: 0 2px; animation: typingAnimation 1.2s infinite ease-in-out; } .typing-dot:nth-child(2) { animation-delay: 0.2s; } .typing-dot:nth-child(3) { animation-delay: 0.4s; } .chat-input-container { border-radius: 20px; background-color: var(--bg-color); box-shadow: inset 3px 3px 7px var(--shadow-dark), inset -3px -3px 7px var(--shadow-light); padding: 5px; display: flex; margin-top: auto; position: relative; transition: all 0.3s ease; } .chat-input-container:focus-within { box-shadow: inset 4px 4px 8px var(--shadow-dark), inset -4px -4px 8px var(--shadow-light), 0 0 0 3px rgba(226, 131, 110, 0.15); } .chat-input { flex: 1; border: none; outline: none; padding: 12px 16px; border-radius: 20px; font-size: 0.95rem; background: transparent; color: var(--text-color); } .chat-input::placeholder { color: #999; } .send-button { width: 42px; height: 42px; border-radius: 50%; border: none; background-color: var(--bg-color); box-shadow: 3px 3px 7px var(--shadow-dark), -3px -3px 7px var(--shadow-light); color: var(--accent-color); font-size: 1.2rem; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.2s ease; margin: 3px; } .send-button:hover { background-color: var(--accent-color); color: white; transform: translateY(-2px); } .send-button:active { box-shadow: inset 2px 2px 5px rgba(0, 0, 0, 0.2), inset -2px -2px 5px rgba(255, 255, 255, 0.7); transform: translateY(0); } .action-buttons { display: flex; margin-bottom: 12px; justify-content: center; } .action-button { background-color: var(--bg-color); border: none; border-radius: 16px; padding: 8px 16px; margin: 0 6px; font-size: 0.85rem; font-weight: 500; color: var(--accent-color); cursor: pointer; box-shadow: 3px 3px 6px var(--shadow-dark), -3px -3px 6px var(--shadow-light); transition: all 0.2s ease; } .action-button:hover { box-shadow: 4px 4px 8px var(--shadow-dark), -4px -4px 8px var(--shadow-light); transform: translateY(-2px); } .action-button:active { box-shadow: inset 2px 2px 5px var(--shadow-dark), inset -2px -2px 5px var(--shadow-light); transform: translateY(0); } .new-message { animation: newMessagePop 0.5s forwards; } @keyframes pulse { 0% { transform: scale(1); opacity: 0.7; } 70% { transform: scale(1.5); opacity: 0; } 100% { transform: scale(1); opacity: 0; } } @keyframes typingAnimation { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-5px); } } @keyframes newMessagePop { 0% { transform: scale(0.8); opacity: 0; } 50% { transform: scale(1.05); } 100% { transform: scale(1); opacity: 1; } } @media (max-width: 500px) { .chat-container { border-radius: 16px; padding: 15px; } .message { max-width: 90%; } .action-buttons { flex-wrap: wrap; } .action-button { margin-bottom: 8px; } } </style> </head> <body> <div class="chat-container"> <div class="chat-header"> <div class="agent-avatar"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="var(--accent-color)" width="24" height="24"> <path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"></path> </svg> </div> <div class="agent-info"> <div class="agent-name">Sarah | Customer Support</div> <div class="agent-status"> <span class="status-dot"></span> Online and ready to help </div> </div> </div> <div class="chat-messages" id="chatMessages"> <div class="message agent"> <div class="message-bubble"> Hi there! I'm Sarah from the support team. How can I help you with your recent order today? <div class="message-time">11:02 AM</div> </div> </div> </div> <div class="action-buttons"> <button class="action-button" data-message="I need help tracking my order">Track my order</button> <button class="action-button" data-message="I'd like to request a return">Request return</button> <button class="action-button" data-message="My item arrived damaged">Report issue</button> </div> <div class="typing-indicator" id="typingIndicator"> <div class="typing-dot"></div> <div class="typing-dot"></div> <div class="typing-dot"></div> </div> <div class="chat-input-container"> <input type="text" class="chat-input" id="chatInput" placeholder="Type your message here..." autocomplete="off"> <button class="send-button" id="sendButton"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <line x1="22" y1="2" x2="11" y2="13"></line> <polygon points="22 2 15 22 11 13 2 9 22 2"></polygon> </svg> </button> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const chatMessages = document.getElementById('chatMessages'); const chatInput = document.getElementById('chatInput'); const sendButton = document.getElementById('sendButton'); const typingIndicator = document.getElementById('typingIndicator'); const actionButtons = document.querySelectorAll('.action-button'); // Agent responses based on user messages const responses = { 'track': { text: "I'd be happy to help you track your order! Your order #38291 is currently in transit and should arrive by Wednesday. You can also track it in real-time through the link I just sent to your email.", delay: 1500 }, 'return': { text: "I understand you'd like to make a return. No problem! For your Eco-Friendly Bamboo Desk Set purchased on April 15th, you have until May 15th to return. Would you like me to send you our prepaid return label?", delay: 2000 }, 'damaged': { text: "I'm so sorry to hear your item arrived damaged! That's certainly not the experience we want for you. Could you please send a photo of the damage so I can process your replacement immediately? No need to return the damaged item.", delay: 2200 }, 'default': { text: "Thanks for reaching out! I'm looking into this for you right now. Could you please provide a bit more detail about your question so I can give you the most accurate assistance?", delay: 1800 } }; // Time formatting function function formatTime() { const now = new Date(); return now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); } // Send message function function sendMessage(text) { if (!text.trim()) return; // Add user message const userMessage = document.createElement('div'); userMessage.className = 'message user new-message'; userMessage.innerHTML = ` <div class="message-bubble"> ${text} <div class="message-time">${formatTime()}</div> </div> `; chatMessages.appendChild(userMessage); // Clear input chatInput.value = ''; // Scroll to bottom chatMessages.scrollTop = chatMessages.scrollHeight; // Show typing indicator setTimeout(() => { typingIndicator.style.display = 'flex'; chatMessages.scrollTop = chatMessages.scrollHeight; }, 500); // Determine response based on message content let responseObj = responses.default; if (text.toLowerCase().includes('track') || text.toLowerCase().includes('where is my order')) { responseObj = responses.track; } else if (text.toLowerCase().includes('return') || text.toLowerCase().includes('refund')) { responseObj = responses.return; } else if (text.toLowerCase().includes('damaged') || text.toLowerCase().includes('broken')) { responseObj = responses.damaged; } // Send agent response after delay setTimeout(() => { typingIndicator.style.display = 'none'; const agentMessage = document.createElement('div'); agentMessage.className = 'message agent new-message'; agentMessage.innerHTML = ` <div class="message-bubble"> ${responseObj.text} <div class="message-time">${formatTime()}</div> </div> `; chatMessages.appendChild(agentMessage); // Scroll to bottom again chatMessages.scrollTop = chatMessages.scrollHeight; }, responseObj.delay); } // Send button click event sendButton.addEventListener('click', () => { sendMessage(chatInput.value); }); // Enter key press event chatInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') { sendMessage(chatInput.value); } }); // Action buttons click events actionButtons.forEach(button => { button.addEventListener('click', () => { const message = button.getAttribute('data-message'); sendMessage(message); }); }); // Focus input on load setTimeout(() => { chatInput.focus(); }, 500); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Enterprise Calendar Scheduler</title> <style> :root { --bg-color: #e6eef9; --primary-color: #4a6fa5; --secondary-color: #8da9d2; --text-color: #2c3e50; --light-shadow: rgba(255, 255, 255, 0.8); --dark-shadow: rgba(174, 174, 192, 0.4); --selected-color: #7ea6e0; --event-color-1: #f6d365; --event-color-2: #fda085; --event-color-3: #6dd5ed; --event-color-4: #a8e063; --red-accent: #e95f71; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { display: flex; justify-content: center; align-items: center; min-height: 700px; background-color: var(--bg-color); padding: 20px; overflow: hidden; } .container { width: 100%; max-width: 670px; height: 650px; background-color: var(--bg-color); border-radius: 30px; box-shadow: 12px 12px 24px var(--dark-shadow), -12px -12px 24px var(--light-shadow); overflow: hidden; position: relative; display: flex; flex-direction: column; } .header { padding: 20px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid rgba(0, 0, 0, 0.05); } .header h1 { color: var(--text-color); font-size: 1.6rem; font-weight: 600; } .controls { display: flex; gap: 10px; } .btn { width: 40px; height: 40px; border-radius: 12px; border: none; background-color: var(--bg-color); color: var(--text-color); display: flex; justify-content: center; align-items: center; cursor: pointer; box-shadow: 5px 5px 10px var(--dark-shadow), -5px -5px 10px var(--light-shadow); transition: all 0.3s ease; } .btn:hover { box-shadow: 3px 3px 6px var(--dark-shadow), -3px -3px 6px var(--light-shadow); } .btn:active { box-shadow: inset 3px 3px 6px var(--dark-shadow), inset -3px -3px 6px var(--light-shadow); } .btn i { font-size: 1.2rem; } .month-selector { display: flex; justify-content: space-between; align-items: center; padding: 15px 20px; } .month-year { display: flex; align-items: center; gap: 10px; } .month { color: var(--primary-color); font-size: 1.4rem; font-weight: 600; } .year { color: var(--secondary-color); font-size: 1.2rem; } .add-event-btn { padding: 8px 16px; border-radius: 12px; border: none; background-color: var(--primary-color); color: white; font-weight: 500; cursor: pointer; box-shadow: 3px 3px 6px var(--dark-shadow), -3px -3px 6px var(--light-shadow); transition: all 0.3s ease; display: flex; align-items: center; gap: 6px; } .add-event-btn:hover { background-color: var(--selected-color); } .weekdays { display: grid; grid-template-columns: repeat(7, 1fr); padding: 10px 15px; margin-bottom: 5px; } .weekday { text-align: center; color: var(--secondary-color); font-weight: 600; font-size: 0.9rem; } .calendar-grid { display: grid; grid-template-columns: repeat(7, 1fr); grid-template-rows: repeat(6, 1fr); gap: 10px; padding: 10px 15px; flex-grow: 1; } .day { position: relative; aspect-ratio: 1; border-radius: 15px; background-color: var(--bg-color); box-shadow: 5px 5px 10px var(--dark-shadow), -5px -5px 10px var(--light-shadow); display: flex; flex-direction: column; justify-content: flex-start; align-items: center; padding: 5px; cursor: pointer; transition: all 0.25s ease; overflow: hidden; } .day:hover { transform: translateY(-2px); box-shadow: 7px 7px 14px var(--dark-shadow), -7px -7px 14px var(--light-shadow); } .day.inactive { opacity: 0.5; cursor: default; } .day.today { background: linear-gradient(145deg, var(--bg-color), #f0f5ff); border: 1px solid var(--light-shadow); } .day.selected { box-shadow: inset 3px 3px 6px var(--dark-shadow), inset -3px -3px 6px var(--light-shadow); transform: translateY(0); } .day-number { font-size: 1rem; font-weight: 500; color: var(--text-color); margin-bottom: 5px; width: 25px; height: 25px; display: flex; justify-content: center; align-items: center; border-radius: 50%; transition: all 0.3s ease; } .day.today .day-number { background-color: var(--primary-color); color: white; } .day.selected .day-number { background-color: var(--selected-color); color: white; } .day-events { width: 100%; display: flex; flex-direction: column; gap: 3px; align-items: center; margin-top: 3px; } .event { width: 90%; padding: 3px 5px; border-radius: 4px; font-size: 0.65rem; color: var(--text-color); text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; box-shadow: 1px 1px 2px var(--dark-shadow), -1px -1px 2px var(--light-shadow); } .event.type-1 { background: linear-gradient(to right, var(--event-color-1), var(--event-color-2)); } .event.type-2 { background: linear-gradient(to right, var(--event-color-3), #2193b0); } .event.type-3 { background: linear-gradient(to right, var(--event-color-4), #56ab2f); } .event.type-4 { background: linear-gradient(to right, var(--red-accent), #f9d423); } .event-modal { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); display: flex; justify-content: center; align-items: center; z-index: 100; opacity: 0; visibility: hidden; transition: opacity 0.3s ease; } .event-modal.active { opacity: 1; visibility: visible; } .event-form { width: 90%; max-width: 400px; background-color: var(--bg-color); border-radius: 20px; box-shadow: 8px 8px 16px var(--dark-shadow), -8px -8px 16px var(--light-shadow); padding: 25px; transform: scale(0.9); transition: transform 0.3s ease; } .event-modal.active .event-form { transform: scale(1); } .form-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; } .form-header h2 { color: var(--primary-color); font-size: 1.4rem; } .close-btn { background: none; border: none; color: var(--text-color); font-size: 1.5rem; cursor: pointer; } .form-group { margin-bottom: 15px; } .form-group label { display: block; margin-bottom: 5px; color: var(--text-color); font-weight: 500; } .form-control { width: 100%; padding: 12px 15px; border-radius: 12px; border: none; background-color: var(--bg-color); color: var(--text-color); box-shadow: inset 3px 3px 6px var(--dark-shadow), inset -3px -3px 6px var(--light-shadow); font-size: 1rem; transition: all 0.3s ease; } .form-control:focus { outline: none; box-shadow: inset 4px 4px 8px var(--dark-shadow), inset -4px -4px 8px var(--light-shadow); } .form-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px; } .btn-cancel { padding: 10px 15px; border-radius: 12px; border: none; background-color: var(--bg-color); color: var(--text-color); font-weight: 500; cursor: pointer; box-shadow: 3px 3px 6px var(--dark-shadow), -3px -3px 6px var(--light-shadow); transition: all 0.3s ease; } .btn-save { padding: 10px 20px; border-radius: 12px; border: none; background-color: var(--primary-color); color: white; font-weight: 500; cursor: pointer; box-shadow: 3px 3px 6px var(--dark-shadow), -3px -3px 6px var(--light-shadow); transition: all 0.3s ease; } .btn-save:hover { background-color: var(--selected-color); } .color-picker { display: flex; gap: 10px; margin-top: 5px; } .color-option { width: 25px; height: 25px; border-radius: 50%; cursor: pointer; box-shadow: 2px 2px 4px var(--dark-shadow), -2px -2px 4px var(--light-shadow); transition: transform 0.2s ease; } .color-option:hover { transform: scale(1.1); } .color-option.selected { transform: scale(1.1); border: 2px solid white; } .color-1 { background: linear-gradient(to right, var(--event-color-1), var(--event-color-2)); } .color-2 { background: linear-gradient(to right, var(--event-color-3), #2193b0); } .color-3 { background: linear-gradient(to right, var(--event-color-4), #56ab2f); } .color-4 { background: linear-gradient(to right, var(--red-accent), #f9d423); } @media (max-width: 500px) { .container { height: 600px; } .header h1 { font-size: 1.3rem; } .day-number { font-size: 0.9rem; } .event { font-size: 0.6rem; } } /* Loading animation */ .loader { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: var(--bg-color); display: flex; justify-content: center; align-items: center; z-index: 200; flex-direction: column; gap: 15px; transition: opacity 0.5s ease, visibility 0.5s ease; } .loader.hidden { opacity: 0; visibility: hidden; } .loader-text { color: var(--primary-color); font-weight: 600; letter-spacing: 1px; } .loading-circle { width: 60px; height: 60px; border-radius: 50%; background: var(--bg-color); box-shadow: 8px 8px 16px var(--dark-shadow), -8px -8px 16px var(--light-shadow); display: flex; justify-content: center; align-items: center; position: relative; } .loading-circle::before { content: ''; position: absolute; width: 85%; height: 85%; border-radius: 50%; background: var(--bg-color); box-shadow: inset 4px 4px 8px var(--dark-shadow), inset -4px -4px 8px var(--light-shadow); } .loading-circle::after { content: ''; position: absolute; width: 100%; height: 100%; border-radius: 50%; border-top: 3px solid var(--primary-color); border-right: 3px solid transparent; border-bottom: 3px solid transparent; border-left: 3px solid transparent; animation: spin 1s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } </style> </head> <body> <div class="container"> <div class="loader"> <div class="loading-circle"></div> <div class="loader-text">INITIALIZING CALENDAR</div> </div> <div class="header"> <h1>Enterprise Calendar</h1> <div class="controls"> <button class="btn" id="view-btn"> <i>🗏</i> </button> <button class="btn" id="sync-btn"> <i>↻</i> </button> </div> </div> <div class="month-selector"> <div class="month-year"> <span class="month" id="current-month">May</span> <span class="year" id="current-year">2024</span> </div> <button class="add-event-btn" id="add-event"> <i>✚</i> Schedule </button> </div> <div class="weekdays"> <div class="weekday">MON</div> <div class="weekday">TUE</div> <div class="weekday">WED</div> <div class="weekday">THU</div> <div class="weekday">FRI</div> <div class="weekday">SAT</div> <div class="weekday">SUN</div> </div> <div class="calendar-grid" id="calendar-grid"> <!-- Calendar days will be generated by JavaScript --> </div> <div class="event-modal" id="event-modal"> <div class="event-form"> <div class="form-header"> <h2>Schedule Event</h2> <button class="close-btn" id="close-modal">×</button> </div> <div class="form-group"> <label for="event-title">Event Title</label> <input type="text" class="form-control" id="event-title" placeholder="Enter event title"> </div> <div class="form-group"> <label for="event-date">Date</label> <input type="date" class="form-control" id="event-date"> </div> <div class="form-group"> <label for="event-time">Time</label> <input type="time" class="form-control" id="event-time"> </div> <div class="form-group"> <label>Event Category</label> <div class="color-picker"> <div class="color-option color-1" data-color="1"></div> <div class="color-option color-2" data-color="2"></div> <div class="color-option color-3" data-color="3"></div> <div class="color-option color-4" data-color="4"></div> </div> </div> <div class="form-actions"> <button class="btn-cancel" id="cancel-event">Cancel</button> <button class="btn-save" id="save-event">Save Event</button> </div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Loader animation setTimeout(() => { document.querySelector('.loader').classList.add('hidden'); }, 1500); // Calendar data const now = new Date(); let currentMonth = now.getMonth(); let currentYear = now.getFullYear(); let selectedDay = null; let selectedColorOption = 1; let events = [ { id: 1, title: "Team Standup", date: new Date(2024, 4, 15), time: "09:00", color: 1 }, { id: 2, title: "Product Review", date: new Date(2024, 4, 15), time: "14:00", color: 3 }, { id: 3, title: "Client Meeting", date: new Date(2024, 4, 18), time: "11:30", color: 2 }, { id: 4, title: "Quarterly Planning", date: new Date(2024, 4, 22), time: "13:00", color: 4 }, { id: 5, title: "Release Deployment", date: new Date(2024, 4, 25), time: "16:00", color: 1 } ]; // DOM elements const calendarGrid = document.getElementById('calendar-grid'); const currentMonthElem = document.getElementById('current-month'); const currentYearElem = document.getElementById('current-year'); const eventModal = document.getElementById('event-modal'); const addEventBtn = document.getElementById('add-event'); const closeModalBtn = document.getElementById('close-modal'); const cancelEventBtn = document.getElementById('cancel-event'); const saveEventBtn = document.getElementById('save-event'); const eventDateInput = document.getElementById('event-date'); const eventTitleInput = document.getElementById('event-title'); const eventTimeInput = document.getElementById('event-time'); const colorOptions = document.querySelectorAll('.color-option'); const syncBtn = document.getElementById('sync-btn'); const viewBtn = document.getElementById('view-btn'); // Month names const monthNames = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]; // Initialize calendar function initCalendar() { currentMonthElem.textContent = monthNames[currentMonth]; currentYearElem.textContent = currentYear; renderCalendar(); } // Render calendar function renderCalendar() { calendarGrid.innerHTML = ''; const firstDay = new Date(currentYear, currentMonth, 1); const lastDay = new Date(currentYear, currentMonth + 1, 0); const daysInMonth = lastDay.getDate(); // Adjust for Monday as first day of week (0 = Monday, 6 = Sunday) let startingDay = firstDay.getDay() - 1; if (startingDay === -1) startingDay = 6; // Sunday is 6 // Previous month days const prevMonthLastDay = new Date(currentYear, currentMonth, 0).getDate(); for (let i = startingDay - 1; i >= 0; i--) { const dayElem = createDayElement(prevMonthLastDay - i, true); calendarGrid.appendChild(dayElem); } // Current month days for (let i = 1; i <= daysInMonth; i++) { const dayElem = createDayElement(i, false); const currentDate = new Date(currentYear, currentMonth, i); const isToday = currentDate.toDateString() === now.toDateString(); if (isToday) { dayElem.classList.add('today'); } // Add events to the day const dayEvents = events.filter(event => { return event.date.getDate() === i && event.date.getMonth() === currentMonth && event.date.getFullYear() === currentYear; }); if (dayEvents.length > 0) { const dayEventsContainer = document.createElement('div'); dayEventsContainer.className = 'day-events'; dayEvents.forEach(event => { const eventElem = document.createElement('div'); eventElem.className = `event type-${event.color}`; eventElem.textContent = event.title; eventElem.title = `${event.title} - ${event.time}`; dayEventsContainer.appendChild(eventElem); }); dayElem.appendChild(dayEventsContainer); } dayElem.addEventListener('click', () => { // Remove selected class from previously selected day const prevSelected = document.querySelector('.day.selected'); if (prevSelected) { prevSelected.classList.remove('selected'); } // Add selected class to clicked day dayElem.classList.add('selected'); selectedDay = new Date(currentYear, currentMonth, i); }); calendarGrid.appendChild(dayElem); } // Next month days const totalCells = 42; // 6 rows * 7 days const remainingCells = totalCells - (startingDay + daysInMonth); for (let i = 1; i <= remainingCells; i++) { const dayElem = createDayElement(i, true); calendarGrid.appendChild(dayElem); } } // Create a day element function createDayElement(day, inactive) { const dayElem = document.createElement('div'); dayElem.className = 'day'; if (inactive) { dayElem.classList.add('inactive'); } const dayNumber = document.createElement('div'); dayNumber.className = 'day-number'; dayNumber.textContent = day; dayElem.appendChild(dayNumber); return dayElem; } // Color option selection colorOptions.forEach(option => { option.addEventListener('click', () => { // Remove selected class from all options colorOptions.forEach(o => o.classList.remove('selected')); // Add selected class to clicked option option.classList.add('selected'); // Update selected color selectedColorOption = option.dataset.color; }); }); // Select first color option by default colorOptions[0].classList.add('selected'); // Event handlers addEventBtn.addEventListener('click', () => { // Reset form eventTitleInput.value = ''; // Set default date to selected day or today const defaultDate = selectedDay || new Date(); const formattedDate = formatDate(defaultDate); eventDateInput.value = formattedDate; // Set default time const now = new Date(); const hours = String(now.getHours()).padStart(2, '0'); const minutes = String(Math.ceil(now.getMinutes() / 15) * 15 % 60).padStart(2, '0'); eventTimeInput.value = `${hours}:${minutes}`; // Show modal eventModal.classList.add('active'); }); closeModalBtn.addEventListener('click', () => { eventModal.classList.remove('active'); }); cancelEventBtn.addEventListener('click', () => { eventModal.classList.remove('active'); }); saveEventBtn.addEventListener('click', () => { const title = eventTitleInput.value.trim(); if (!title) { // Simple validation - show error effect on input eventTitleInput.style.boxShadow = 'inset 3px 3px 6px rgba(174, 174, 192, 0.4), inset -3px -3px 6px rgba(255, 255, 255, 0.8), 0 0 0 2px rgba(233, 95, 113, 0.5)'; setTimeout(() => { eventTitleInput.style.boxShadow = ''; }, 1000); return; } const dateParts = eventDateInput.value.split('-'); const date = new Date( parseInt(dateParts[0]), parseInt(dateParts[1]) - 1, parseInt(dateParts[2]) ); // Create new event const newEvent = { id: events.length + 1, title: title, date: date, time: eventTimeInput.value, color: selectedColorOption }; // Add to events array events.push(newEvent); // Close modal eventModal.classList.remove('active'); // Re-render calendar renderCalendar(); // Show success feedback const addEventBtn = document.getElementById('add-event'); addEventBtn.textContent = '✓ Added'; addEventBtn.style.backgroundColor = 'var(--event-color-4)'; setTimeout(() => { addEventBtn.innerHTML = '<i>✚</i> Schedule'; addEventBtn.style.backgroundColor = ''; }, 1500); }); // Sync button animation syncBtn.addEventListener('click', function() { this.style.transform = 'rotate(360deg)'; setTimeout(() => { this.style.transform = ''; }, 500); // Show syncing animation document.querySelector('.loader').classList.remove('hidden'); document.querySelector('.loader-text').textContent = 'SYNCING CALENDAR'; setTimeout(() => { document.querySelector('.loader').classList.add('hidden'); }, 1000); }); // View button animation viewBtn.addEventListener('click', function() { this.style.transform = 'scale(0.9)'; setTimeout(() => { this.style.transform = ''; }, 150); }); // Helper function to format date for input element function formatDate(date) { const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); return `${year}-${month}-${day}`; } // Initialize calendar initCalendar(); // Prevent event propagation in modal document.querySelector('.event-form').addEventListener('click', (e) => { e.stopPropagation(); }); // Close modal when clicking outside eventModal.addEventListener('click', () => { eventModal.classList.remove('active'); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>RideNow: Neumorphic Ride-Sharing App</title> <style> :root { --primary-color: #e0e5ec; --secondary-color: #4a6cf7; --dark-color: #2a3747; --light-color: #f8f9fa; --shadow-light: #ffffff; --shadow-dark: #a3b1c6; --text-color: #333; --success-color: #4CAF50; --warning-color: #FF9800; --active-color: #3a57e8; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', sans-serif; } body { width: 100%; height: 100vh; background-color: var(--primary-color); display: flex; justify-content: center; align-items: center; overflow: hidden; position: relative; } .app-container { width: 100%; max-width: 700px; height: 700px; background-color: var(--primary-color); border-radius: 30px; position: relative; overflow: hidden; box-shadow: 10px 10px 20px var(--shadow-dark), -10px -10px 20px var(--shadow-light); } .header { width: 100%; height: 60px; padding: 0 20px; display: flex; justify-content: space-between; align-items: center; background-color: var(--primary-color); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05); position: relative; z-index: 10; } .logo { font-weight: 700; font-size: 24px; color: var(--secondary-color); } .user-profile { width: 40px; height: 40px; border-radius: 50%; background: var(--primary-color); box-shadow: 3px 3px 6px var(--shadow-dark), -3px -3px 6px var(--shadow-light); display: flex; justify-content: center; align-items: center; cursor: pointer; transition: all 0.3s ease; } .user-profile:hover { box-shadow: inset 2px 2px 5px var(--shadow-dark), inset -2px -2px 5px var(--shadow-light); } .user-profile i { color: var(--secondary-color); font-size: 18px; } .map-container { width: 100%; height: calc(100% - 60px - 100px); position: relative; overflow: hidden; background: url('https://api.mapbox.com/styles/v1/mapbox/light-v10/static/-73.98,40.76,12,0/600x540?access_token=pk.dummy') center/cover no-repeat; filter: saturate(0.8) brightness(1.05); } .map-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(to bottom, rgba(224, 229, 236, 0.15), rgba(224, 229, 236, 0.1)); pointer-events: none; } .pin { position: absolute; width: 40px; height: 40px; border-radius: 50%; background: var(--primary-color); display: flex; justify-content: center; align-items: center; cursor: pointer; transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); z-index: 5; box-shadow: 6px 6px 12px var(--shadow-dark), -6px -6px 12px var(--shadow-light); } .pin.active { transform: scale(1.1); background: var(--active-color); box-shadow: 4px 4px 8px rgba(58, 87, 232, 0.4), -4px -4px 8px rgba(255, 255, 255, 0.8), inset 1px 1px 2px rgba(58, 87, 232, 0.2); } .pin.active i { color: white; } .pin.pickup { top: 40%; left: 35%; } .pin.dropoff { top: 30%; left: 55%; } .pin.car { top: 50%; left: 45%; background: var(--light-color); } .pin i { font-size: 18px; color: var(--secondary-color); transition: all 0.3s ease; } .pin.car i { color: var(--warning-color); } .pin::after { content: ''; position: absolute; width: 100%; height: 100%; border-radius: 50%; z-index: -1; opacity: 0; animation: pulse 2s infinite; box-shadow: 0 0 0 rgba(74, 108, 247, 0.4); } .pin.active::after { opacity: 1; } @keyframes pulse { 0% { transform: scale(1); box-shadow: 0 0 0 0 rgba(74, 108, 247, 0.4); } 70% { transform: scale(1.2); box-shadow: 0 0 0 10px rgba(74, 108, 247, 0); } 100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(74, 108, 247, 0); } } .action-buttons { width: 100%; height: 100px; display: flex; justify-content: space-around; align-items: center; padding: 0 20px; background-color: var(--primary-color); position: relative; z-index: 10; } .action-btn { width: 60px; height: 60px; border-radius: 50%; background: var(--primary-color); box-shadow: 6px 6px 12px var(--shadow-dark), -6px -6px 12px var(--shadow-light); display: flex; justify-content: center; align-items: center; cursor: pointer; transition: all 0.3s ease; position: relative; overflow: hidden; } .action-btn::before { content: ''; position: absolute; width: 100%; height: 100%; background: linear-gradient(45deg, transparent, rgba(255, 255, 255, 0.3), transparent); top: 0; left: -100%; transition: all 0.5s ease; } .action-btn:hover::before { left: 100%; } .action-btn:active { box-shadow: inset 4px 4px 8px var(--shadow-dark), inset -4px -4px 8px var(--shadow-light); } .action-btn i { font-size: 22px; color: var(--secondary-color); } .action-btn.book { width: 120px; height: 60px; border-radius: 30px; background: var(--secondary-color); color: white; font-weight: 600; box-shadow: 6px 6px 12px rgba(74, 108, 247, 0.3), -6px -6px 12px rgba(255, 255, 255, 0.8); transition: all 0.3s ease; } .action-btn.book:hover { transform: translateY(-2px); box-shadow: 8px 8px 16px rgba(74, 108, 247, 0.4), -6px -6px 12px rgba(255, 255, 255, 0.8); } .action-btn.book:active { transform: translateY(1px); box-shadow: 4px 4px 8px rgba(74, 108, 247, 0.4), -4px -4px 8px rgba(255, 255, 255, 0.8), inset 1px 1px 2px rgba(0, 0, 0, 0.2); } .tooltip { position: absolute; background: var(--light-color); color: var(--dark-color); padding: 8px 15px; border-radius: 20px; font-size: 14px; font-weight: 500; box-shadow: 4px 4px 8px var(--shadow-dark), -4px -4px 8px var(--shadow-light); opacity: 0; transform: translateY(10px); transition: all 0.3s ease; pointer-events: none; z-index: 100; white-space: nowrap; } .tooltip.active { opacity: 1; transform: translateY(0); } .tooltip.pickup { top: calc(40% - 70px); left: 35%; } .tooltip.dropoff { top: calc(30% - 70px); left: 55%; } .tooltip.car { top: calc(50% - 70px); left: 45%; } .tooltip::after { content: ''; position: absolute; width: 10px; height: 10px; background: var(--light-color); bottom: -5px; left: 50%; transform: translateX(-50%) rotate(45deg); box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.1); } .ride-details { position: absolute; bottom: 120px; left: 50%; transform: translateX(-50%); width: 90%; padding: 20px; background: var(--primary-color); border-radius: 20px; box-shadow: 6px 6px 12px var(--shadow-dark), -6px -6px 12px var(--shadow-light); display: flex; flex-direction: column; opacity: 0; transform: translateY(20px) translateX(-50%); transition: all 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275); z-index: 20; } .ride-details.active { opacity: 1; transform: translateY(0) translateX(-50%); } .ride-header { display: flex; justify-content: space-between; margin-bottom: 15px; } .ride-time { font-weight: 700; color: var(--dark-color); } .ride-price { font-weight: 700; color: var(--secondary-color); } .ride-route { display: flex; margin-bottom: 15px; } .route-line { width: 2px; background: linear-gradient(to bottom, var(--secondary-color), var(--warning-color)); margin: 0 15px; position: relative; } .route-line::before, .route-line::after { content: ''; position: absolute; width: 10px; height: 10px; border-radius: 50%; left: -4px; } .route-line::before { top: 0; background: var(--secondary-color); } .route-line::after { bottom: 0; background: var(--warning-color); } .route-points { flex: 1; } .route-point { margin-bottom: 15px; } .route-point:last-child { margin-bottom: 0; } .point-label { font-size: 12px; color: var(--dark-color); opacity: 0.7; } .point-address { font-weight: 600; color: var(--dark-color); } .toggle-container { position: absolute; top: 85px; right: 20px; z-index: 10; } .theme-toggle { width: 60px; height: 30px; background: var(--primary-color); border-radius: 15px; box-shadow: inset 2px 2px 5px var(--shadow-dark), inset -2px -2px 5px var(--shadow-light); position: relative; cursor: pointer; display: flex; align-items: center; padding: 0 5px; justify-content: space-between; } .theme-toggle i { font-size: 14px; color: var(--dark-color); opacity: 0.7; } .toggle-ball { position: absolute; width: 24px; height: 24px; background: var(--secondary-color); border-radius: 50%; box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.2); left: 3px; transition: transform 0.3s ease; } .theme-toggle.dark .toggle-ball { transform: translateX(30px); } /* Dark mode styles */ body.dark-mode { --primary-color: #2a3747; --shadow-light: #3a4a5e; --shadow-dark: #1e2935; --text-color: #fff; --light-color: #3a4a5e; } body.dark-mode .pin { background: var(--dark-color); } body.dark-mode .pin i { color: #fff; } body.dark-mode .pin.car { background: var(--light-color); } body.dark-mode .user-profile i, body.dark-mode .action-btn i { color: #fff; } body.dark-mode .tooltip { background: var(--light-color); color: #fff; } body.dark-mode .tooltip::after { background: var(--light-color); } body.dark-mode .logo { color: var(--secondary-color); } body.dark-mode .ride-time, body.dark-mode .point-address { color: #fff; } body.dark-mode .point-label { color: #ccc; } body.dark-mode .map-container { filter: brightness(0.8) saturate(0.8); } @media (max-width: 500px) { .app-container { border-radius: 0; height: 100vh; width: 100%; } .ride-details { width: 90%; padding: 15px; } .action-btn { width: 50px; height: 50px; } .action-btn.book { width: 100px; height: 50px; } .route-point { margin-bottom: 10px; } } /* Loading animation */ .loading-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: var(--primary-color); display: flex; justify-content: center; align-items: center; z-index: 1000; transition: opacity 0.5s ease, visibility 0.5s ease; } .loading-overlay.hidden { opacity: 0; visibility: hidden; } .loader { width: 60px; height: 60px; border-radius: 50%; position: relative; animation: rotate 1.5s linear infinite; } .loader::before { content: ""; box-sizing: border-box; position: absolute; inset: 0px; border-radius: 50%; border: 5px solid var(--secondary-color); animation: prixClipFix 2s linear infinite; } @keyframes rotate { 100% { transform: rotate(360deg) } } @keyframes prixClipFix { 0% { clip-path: polygon(50% 50%, 0 0, 0 0, 0 0, 0 0, 0 0) } 25% { clip-path: polygon(50% 50%, 0 0, 100% 0, 100% 0, 100% 0, 100% 0) } 50% { clip-path: polygon(50% 50%, 0 0, 100% 0, 100% 100%, 100% 100%, 100% 100%) } 75% { clip-path: polygon(50% 50%, 0 0, 100% 0, 100% 100%, 0 100%, 0 100%) } 100% { clip-path: polygon(50% 50%, 0 0, 100% 0, 100% 100%, 0 100%, 0 0) } } </style> <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet"> </head> <body> <div class="loading-overlay"> <div class="loader"></div> </div> <div class="app-container"> <div class="header"> <div class="logo">RideNow</div> <div class="user-profile"> <i class="fas fa-user"></i> </div> </div> <div class="map-container"> <div class="map-overlay"></div> <div class="toggle-container"> <div class="theme-toggle"> <i class="fas fa-sun"></i> <i class="fas fa-moon"></i> <div class="toggle-ball"></div> </div> </div> <div class="pin pickup"> <i class="fas fa-map-marker-alt"></i> </div> <div class="tooltip pickup">Current Location - 350 Fifth Ave</div> <div class="pin dropoff"> <i class="fas fa-flag-checkered"></i> </div> <div class="tooltip dropoff">Madison Square Garden</div> <div class="pin car"> <i class="fas fa-car"></i> </div> <div class="tooltip car">Tesla Model 3 (3 mins away)</div> <div class="ride-details"> <div class="ride-header"> <div class="ride-time"> <i class="far fa-clock"></i> 12 min </div> <div class="ride-price">$18.50</div> </div> <div class="ride-route"> <div class="route-line"></div> <div class="route-points"> <div class="route-point"> <div class="point-label">PICKUP</div> <div class="point-address">350 Fifth Avenue</div> </div> <div class="route-point"> <div class="point-label">DROPOFF</div> <div class="point-address">Madison Square Garden</div> </div> </div> </div> </div> </div> <div class="action-buttons"> <div class="action-btn"> <i class="fas fa-location-arrow"></i> </div> <div class="action-btn book">Book Now</div> <div class="action-btn"> <i class="fas fa-star"></i> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Show loading animation const loadingOverlay = document.querySelector('.loading-overlay'); // Hide loading animation after 2 seconds setTimeout(() => { loadingOverlay.classList.add('hidden'); }, 2000); // Pin interaction const pins = document.querySelectorAll('.pin'); const tooltips = document.querySelectorAll('.tooltip'); const rideDetails = document.querySelector('.ride-details'); pins.forEach(pin => { pin.addEventListener('click', function() { // Toggle active class on the clicked pin this.classList.toggle('active'); // Show corresponding tooltip const pinClass = this.classList[1]; // pickup, dropoff or car const tooltip = document.querySelector(`.tooltip.${pinClass}`); tooltip.classList.toggle('active'); // Auto hide tooltip after 3 seconds setTimeout(() => { tooltip.classList.remove('active'); }, 3000); // If it's the dropoff pin, toggle ride details if (pinClass === 'dropoff') { rideDetails.classList.toggle('active'); } }); }); // Book now button interaction const bookBtn = document.querySelector('.action-btn.book'); bookBtn.addEventListener('click', function() { // Activate all pins pins.forEach(pin => { pin.classList.add('active'); }); // Show ride details rideDetails.classList.add('active'); // Add a success animation to the button this.style.background = 'var(--success-color)'; this.innerHTML = 'Booked!'; // Reset button after 2 seconds setTimeout(() => { this.style.background = 'var(--secondary-color)'; this.innerHTML = 'Book Now'; }, 2000); }); // Dark mode toggle const themeToggle = document.querySelector('.theme-toggle'); const body = document.body; themeToggle.addEventListener('click', function() { this.classList.toggle('dark'); body.classList.toggle('dark-mode'); }); // Action buttons animation const actionBtns = document.querySelectorAll('.action-btn'); actionBtns.forEach(btn => { btn.addEventListener('mousedown', function() { this.style.transform = 'scale(0.95)'; }); btn.addEventListener('mouseup', function() { this.style.transform = 'scale(1)'; }); btn.addEventListener('mouseleave', function() { this.style.transform = 'scale(1)'; }); }); // Initialize map interactions // Simulate pin dropping animation setTimeout(() => { pins[0].style.animation = 'dropIn 0.6s cubic-bezier(0.34, 1.56, 0.64, 1)'; pins[0].style.opacity = '1'; }, 2200); setTimeout(() => { pins[1].style.animation = 'dropIn 0.6s cubic-bezier(0.34, 1.56, 0.64, 1)'; pins[1].style.opacity = '1'; }, 2400); setTimeout(() => { pins[2].style.animation = 'dropIn 0.6s cubic-bezier(0.34, 1.56, 0.64, 1)'; pins[2].style.opacity = '1'; }, 2600); // Add the animation keyframes dynamically const style = document.createElement('style'); style.textContent = ` @keyframes dropIn { 0% { transform: translateY(-20px); opacity: 0; } 100% { transform: translateY(0); opacity: 1; } } `; document.head.appendChild(style); // Simulate current location finding setTimeout(() => { pins[0].classList.add('active'); setTimeout(() => { pins[0].classList.remove('active'); }, 2000); }, 3000); }); </script> </body> </html>