-
Interactive animated embossed login
HTML
CSS
JavaScript
Welcome
Email Address
Password
Sign In
Create an Account
* { box-sizing: border-box; } body { margin: 0; height: 100vh; display: grid; place-items: center; overflow: hidden; background: linear-gradient(135deg, #0b1220, #111827); font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; perspective: 1000px; } /* --- Interactive Blobs --- */ .blob-container { position: absolute; width: 100%; height: 100%; top: 0; left: 0; pointer-events: none; transition: transform 0.2s ease-out; } .blob { position: absolute; border-radius: 50%; filter: blur(35px); opacity: 0.7; animation: morph 8s ease-in-out infinite, float 12s ease-in-out infinite alternate; } .b1 { width: 280px; height: 280px; background: #3b82f6; left: 20%; top: 15%; } .b2 { width: 240px; height: 240px; background: #8b5cf6; right: 20%; bottom: 15%; animation-duration: 10s, 14s; } .b3 { width: 200px; height: 200px; background: #06b6d4; left: 45%; top: 40%; opacity: 0.5; animation-duration: 12s, 9s; } @keyframes float { to { transform: translate(40px, -40px) scale(1.1); } } @keyframes morph { 0%, 100% { border-radius: 42% 58% 63% 37% / 41% 42% 58% 59%; } 50% { border-radius: 64% 36% 42% 58% / 58% 36% 64% 42%; } } /* --- 3D Glass Card --- */ .card { width: min(380px, 92vw); padding: 40px 36px; border-radius: 28px; background: rgba(255, 255, 255, 0.04); backdrop-filter: blur(20px); border: 1px solid rgba(255, 255, 255, 0.1); box-shadow: 12px 12px 30px rgba(0,0,0,0.4), -8px -8px 18px rgba(255,255,255,0.02); transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)); transition: transform 0.15s ease-out, box-shadow 0.15s ease-out; transform-style: preserve-3d; animation: slideUp 0.8s cubic-bezier(0.2, 0.8, 0.2, 1) forwards; opacity: 0; } @keyframes slideUp { 0% { transform: translateY(60px) scale(0.9); opacity: 0; } 100% { transform: translateY(0) scale(1) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)); opacity: 1; } } .card > * { opacity: 0; transform: translateZ(30px) translateY(20px); animation: fadeIn 0.6s cubic-bezier(0.2, 0.8, 0.2, 1) forwards; } .card h2 { animation-delay: 0.2s; text-align: center; color: #fff; margin-top: 0; font-size: 1.8rem; } .card form { animation-delay: 0.3s; } .card p { animation-delay: 0.6s; } @keyframes fadeIn { to { opacity: 1; transform: translateZ(30px) translateY(0); } } /* --- Inputs --- */ .field { position: relative; margin: 24px 0; } input { width: 100%; padding: 16px; border: 1px solid transparent; border-radius: 14px; background: #1f2937; color: #fff; outline: none; font-size: 1rem; box-shadow: inset 5px 5px 12px rgba(0,0,0,0.5), inset -3px -3px 8px rgba(255,255,255,0.03); transition: 0.3s ease; } input:focus { border-color: rgba(96, 165, 250, 0.5); box-shadow: inset 5px 5px 12px rgba(0,0,0,0.5), inset -3px -3px 8px rgba(255,255,255,0.03), 0 0 15px rgba(59, 130, 246, 0.3); } label { position: absolute; left: 16px; top: 17px; color: #94a3b8; pointer-events: none; transition: 0.3s cubic-bezier(0.4, 0, 0.2, 1); } input:focus + label, input:valid + label { top: -10px; left: 12px; font-size: 12px; background: #1f2937; padding: 2px 8px; border-radius: 6px; color: #60a5fa; box-shadow: 0 4px 6px rgba(0,0,0,0.2); } /* --- Status Messaging System --- */ .msg-wrapper { height: 0; /* Prevents layout jumps */ margin-bottom: 20px; position: relative; display: flex; justify-content: center; } .msg { width: 100%; padding: 12px; border-radius: 10px; font-size: 0.9rem; font-weight: 500; text-align: center; position: absolute; bottom: 0; /* Animation states */ opacity: 0; visibility: hidden; transform: translateY(10px) scale(0.95); transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); } .msg.show { opacity: 1; visibility: visible; transform: translateY(0) scale(1); } .msg.error { background: rgba(239, 68, 68, 0.1); border: 1px solid rgba(239, 68, 68, 0.4); color: #f87171; box-shadow: 0 0 15px rgba(239, 68, 68, 0.2); } .msg.success { background: rgba(34, 197, 94, 0.1); border: 1px solid rgba(34, 197, 94, 0.4); color: #4ade80; box-shadow: 0 0 15px rgba(34, 197, 94, 0.2); } /* --- Button --- */ button { width: 100%; padding: 16px; border: none; border-radius: 14px; background: linear-gradient(90deg, #2563eb, #06b6d4, #8b5cf6); background-size: 200% 100%; color: #fff; font-size: 1rem; font-weight: bold; cursor: pointer; box-shadow: 0 4px 15px rgba(37,99,235,0.2); transition: all 0.3s ease; } button:hover:not(:disabled) { transform: translateY(-3px) translateZ(40px); box-shadow: 0 12px 25px rgba(37,99,235,0.4); background-position: 100% 0; } button:active:not(:disabled) { transform: translateY(1px) translateZ(30px); box-shadow: 0 5px 10px rgba(37,99,235,0.3); } button:disabled { opacity: 0.7; cursor: not-allowed; background-position: 100% 0; } p { text-align: center; color: #cbd5e1; margin-top: 24px; margin-bottom: 0; font-size: 0.9rem; cursor: pointer; transition: color 0.3s; } p:hover { color: #60a5fa; }
const card = document.getElementById('tiltCard'); const blobContainer = document.getElementById('blobContainer'); const loginForm = document.getElementById('loginForm'); const statusMsg = document.getElementById('statusMsg'); const emailInput = document.getElementById('emailInput'); const passwordInput = document.getElementById('passwordInput'); const submitBtn = document.getElementById('submitBtn'); let messageTimeout; // Show Message Function function showMessage(text, type) { // Clear previous timeout if user clicks multiple times quickly if (messageTimeout) clearTimeout(messageTimeout); statusMsg.textContent = text; statusMsg.className = `msg ${type} show`; // Auto-hide after 4 seconds messageTimeout = setTimeout(() => { statusMsg.classList.remove('show'); }, 4000); } // Form Submission Logic loginForm.addEventListener('submit', (e) => { e.preventDefault(); const email = emailInput.value.toLowerCase().trim(); const password = passwordInput.value; // 1. Loading State submitBtn.disabled = true; submitBtn.textContent = 'Signing in...'; statusMsg.classList.remove('show'); // Hide any existing messages // Simulate a network request (800ms delay) setTimeout(() => { // Reset Button submitBtn.disabled = false; submitBtn.textContent = 'Sign In'; // 2. Validation & Logic if (password.length < 6) { showMessage('Password must be at least 6 characters.', 'error'); } else if (email === 'error@test.com') { showMessage('Invalid credentials. Please try again.', 'error'); } else { showMessage('Login successful! Redirecting...', 'success'); // Clear form on success setTimeout(() => { loginForm.reset(); statusMsg.classList.remove('show'); }, 2500); } }, 800); }); // 3D Tilt Effect and Blob Cursor Tracking document.addEventListener('mousemove', (e) => { const xAxis = (window.innerWidth / 2 - e.pageX) / 25; const yAxis = (window.innerHeight / 2 - e.pageY) / 25; card.style.setProperty('--ry', `${-xAxis}deg`); card.style.setProperty('--rx', `${yAxis}deg`); const blobX = (window.innerWidth / 2 - e.pageX) / 15; const blobY = (window.innerHeight / 2 - e.pageY) / 15; blobContainer.style.transform = `translate(${blobX}px, ${blobY}px)`; }); document.addEventListener('mouseleave', () => { card.style.setProperty('--ry', `0deg`); card.style.setProperty('--rx', `0deg`); card.style.transition = 'transform 0.5s ease-out'; setTimeout(() => { card.style.transition = 'transform 0.15s ease-out'; }, 500); blobContainer.style.transform = `translate(0px, 0px)`; });
Live Preview