* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.login-container {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
min-height: 100vh;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
display: flex;
align-items: center;
justify-content: center;
padding: 2rem;
position: relative;
overflow: hidden;
}
.background-shapes {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
}
.shape {
position: absolute;
border-radius: 50%;
background: rgba(255, 255, 255, 0.1);
animation: float 6s ease-in-out infinite;
}
.shape-1 {
width: 200px;
height: 200px;
top: 10%;
left: 10%;
animation-delay: 0s;
}
.shape-2 {
width: 150px;
height: 150px;
top: 60%;
right: 10%;
animation-delay: 2s;
}
.shape-3 {
width: 100px;
height: 100px;
bottom: 20%;
left: 20%;
animation-delay: 4s;
}
@keyframes float {
0%, 100% {
transform: translateY(0px) rotate(0deg);
}
50% {
transform: translateY(-20px) rotate(180deg);
}
}
.login-card {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 20px;
padding: 2.5rem;
width: 100%;
max-width: 420px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
animation: slideUp 0.6s ease-out;
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.login-header {
text-align: center;
margin-bottom: 2rem;
}
.logo {
display: flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
margin-bottom: 1rem;
}
.logo-icon {
font-size: 2rem;
animation: pulse 2s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
}
.logo-text {
color: white;
font-size: 1.8rem;
font-weight: 700;
letter-spacing: -0.5px;
}
.welcome-text {
color: rgba(255, 255, 255, 0.8);
font-size: 0.95rem;
line-height: 1.5;
}
.form-group {
margin-bottom: 1.5rem;
}
.input-container {
position: relative;
}
.form-input {
width: 100%;
padding: 1rem 1rem 1rem 0;
background: transparent;
border: none;
border-bottom: 2px solid rgba(255, 255, 255, 0.3);
color: white;
font-size: 1rem;
transition: all 0.3s ease;
outline: none;
}
.form-input:focus {
border-bottom-color: rgba(255, 255, 255, 0.8);
}
.form-input:focus + .form-label,
.form-input:valid + .form-label {
transform: translateY(-1.5rem) scale(0.8);
color: rgba(255, 255, 255, 0.9);
}
.form-label {
position: absolute;
top: 1rem;
left: 0;
color: rgba(255, 255, 255, 0.6);
font-size: 1rem;
transition: all 0.3s ease;
pointer-events: none;
transform-origin: left top;
}
.input-highlight {
position: absolute;
bottom: 0;
left: 0;
width: 0;
height: 2px;
background: linear-gradient(90deg, #fff, rgba(255, 255, 255, 0.8));
transition: width 0.3s ease;
}
.form-input:focus ~ .input-highlight {
width: 100%;
}
.password-toggle {
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
background: none;
border: none;
color: rgba(255, 255, 255, 0.6);
cursor: pointer;
padding: 0.5rem;
transition: color 0.3s ease;
}
.password-toggle:hover {
color: rgba(255, 255, 255, 0.9);
}
.error-message {
color: #ff6b6b;
font-size: 0.85rem;
margin-top: 0.5rem;
opacity: 0;
transform: translateY(-10px);
transition: all 0.3s ease;
}
.error-message.show {
opacity: 1;
transform: translateY(0);
}
.form-options {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 2rem;
}
.checkbox-container {
display: flex;
align-items: center;
cursor: pointer;
user-select: none;
}
.checkbox-container input {
display: none;
}
.checkmark {
width: 18px;
height: 18px;
border: 2px solid rgba(255, 255, 255, 0.4);
border-radius: 4px;
margin-right: 0.5rem;
position: relative;
transition: all 0.3s ease;
}
.checkbox-container input:checked + .checkmark {
background: rgba(255, 255, 255, 0.2);
border-color: rgba(255, 255, 255, 0.8);
}
.checkbox-container input:checked + .checkmark::after {
content: 'β';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
font-size: 12px;
font-weight: bold;
}
.checkbox-text {
color: rgba(255, 255, 255, 0.8);
font-size: 0.9rem;
}
.forgot-link {
color: rgba(255, 255, 255, 0.8);
text-decoration: none;
font-size: 0.9rem;
transition: color 0.3s ease;
}
.forgot-link:hover {
color: white;
}
.login-button {
width: 100%;
padding: 1rem;
background: rgba(255, 255, 255, 0.2);
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 12px;
color: white;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
margin-bottom: 1.5rem;
}
.login-button:hover {
background: rgba(255, 255, 255, 0.3);
transform: translateY(-2px);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
}
.login-button:active {
transform: translateY(0);
}
.button-loader {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 20px;
height: 20px;
border: 2px solid transparent;
border-top: 2px solid white;
border-radius: 50%;
animation: spin 1s linear infinite;
opacity: 0;
transition: opacity 0.3s ease;
}
.login-button.loading .button-text {
opacity: 0;
}
.login-button.loading .button-loader {
opacity: 1;
}
.divider {
position: relative;
text-align: center;
margin: 1.5rem 0;
}
.divider::before {
content: '';
position: absolute;
top: 50%;
left: 0;
right: 0;
height: 1px;
background: rgba(255, 255, 255, 0.2);
}
.divider-text {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(20px);
padding: 0 1rem;
color: rgba(255, 255, 255, 0.6);
font-size: 0.85rem;
}
.social-login {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
margin-bottom: 1.5rem;
}
.social-button {
padding: 0.75rem;
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 8px;
color: white;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
font-size: 0.9rem;
}
.social-button:hover {
background: rgba(255, 255, 255, 0.2);
transform: translateY(-1px);
}
.signup-text {
text-align: center;
color: rgba(255, 255, 255, 0.7);
font-size: 0.9rem;
}
.signup-link {
color: white;
text-decoration: none;
font-weight: 600;
transition: color 0.3s ease;
}
.signup-link:hover {
color: rgba(255, 255, 255, 0.8);
}
/* Responsive Design */
@media (max-width: 480px) {
.login-container {
padding: 1rem;
}
.login-card {
padding: 2rem 1.5rem;
}
.social-login {
grid-template-columns: 1fr;
}
}
class GlassmorphismLogin {
constructor() {
this.form = document.getElementById('loginForm');
this.emailInput = document.getElementById('email');
this.passwordInput = document.getElementById('password');
this.passwordToggle = document.getElementById('passwordToggle');
this.loginButton = this.form.querySelector('.login-button');
this.init();
}
init() {
this.setupEventListeners();
this.setupValidation();
}
setupEventListeners() {
// Password toggle
this.passwordToggle.addEventListener('click', () => {
this.togglePassword();
});
// Form submission
this.form.addEventListener('submit', (e) => {
e.preventDefault();
this.handleSubmit();
});
// Input validation on blur
this.emailInput.addEventListener('blur', () => {
this.validateEmail();
});
this.passwordInput.addEventListener('blur', () => {
this.validatePassword();
});
// Clear errors on input
this.emailInput.addEventListener('input', () => {
this.clearError('emailError');
});
this.passwordInput.addEventListener('input', () => {
this.clearError('passwordError');
});
}
setupValidation() {
// Add floating label behavior
[this.emailInput, this.passwordInput].forEach(input => {
if (input.value) {
input.classList.add('has-value');
}
input.addEventListener('input', () => {
if (input.value) {
input.classList.add('has-value');
} else {
input.classList.remove('has-value');
}
});
});
}
togglePassword() {
const type = this.passwordInput.type === 'password' ? 'text' : 'password';
this.passwordInput.type = type;
const icon = this.passwordToggle.querySelector('.toggle-icon');
icon.textContent = type === 'password' ? 'ποΈ' : 'π';
}
validateEmail() {
const email = this.emailInput.value.trim();
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!email) {
this.showError('emailError', 'Email is required');
return false;
}
if (!emailRegex.test(email)) {
this.showError('emailError', 'Please enter a valid email address');
return false;
}
this.clearError('emailError');
return true;
}
validatePassword() {
const password = this.passwordInput.value;
if (!password) {
this.showError('passwordError', 'Password is required');
return false;
}
if (password.length < 6) {
this.showError('passwordError', 'Password must be at least 6 characters');
return false;
}
this.clearError('passwordError');
return true;
}
showError(elementId, message) {
const errorElement = document.getElementById(elementId);
errorElement.textContent = message;
errorElement.classList.add('show');
}
clearError(elementId) {
const errorElement = document.getElementById(elementId);
errorElement.classList.remove('show');
}
async handleSubmit() {
const isEmailValid = this.validateEmail();
const isPasswordValid = this.validatePassword();
if (!isEmailValid || !isPasswordValid) {
return;
}
// Show loading state
this.loginButton.classList.add('loading');
this.loginButton.disabled = true;
try {
// Simulate API call
await this.simulateLogin();
// Success feedback
this.showSuccess();
} catch (error) {
this.showError('passwordError', 'Invalid credentials. Please try again.');
} finally {
// Remove loading state
this.loginButton.classList.remove('loading');
this.loginButton.disabled = false;
}
}
simulateLogin() {
return new Promise((resolve, reject) => {
setTimeout(() => {
// Simulate success/failure
const success = Math.random() > 0.3;
if (success) {
resolve();
} else {
reject(new Error('Login failed'));
}
}, 2000);
});
}
showSuccess() {
const buttonText = this.loginButton.querySelector('.button-text');
buttonText.textContent = 'Success! Redirecting...';
setTimeout(() => {
buttonText.textContent = 'Sign In';
// Here you would typically redirect to dashboard
console.log('Redirecting to dashboard...');
}, 1500);
}
}
// Initialize the login form
document.addEventListener('DOMContentLoaded', () => {
new GlassmorphismLogin();
});