A Pen by Ugo Nwafor on CodePen.
Created
April 24, 2025 04:41
-
-
Save kelvin-c-web/4fffd889379067805c5b6545fc917554 to your computer and use it in GitHub Desktop.
Sign up & in form
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Flowva - Welcome</title> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"> | |
<style> | |
:root { | |
--primary: #7C4DFF; | |
--primary-light: #EDE7F6; | |
--primary-dark: #651FFF; | |
--accent: #FF80AB; | |
--success: #4CAF50; | |
--error: #F44336; | |
--gray-50: #fafafa; | |
--gray-100: #f5f5f5; | |
--gray-200: #eeeeee; | |
--gray-300: #e0e0e0; | |
--gray-600: #757575; | |
--gray-700: #616161; | |
--radius: 12px; | |
--radius-lg: 16px; | |
--shadow-sm: 0 1px 3px rgba(0,0,0,0.08); | |
--shadow-md: 0 4px 12px rgba(0,0,0,0.1); | |
--transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); | |
} | |
* { | |
margin: 0; | |
padding: 0; | |
box-sizing: border-box; | |
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; | |
} | |
body { | |
background: linear-gradient(135deg, var(--primary-light) 0%, #f5f5fa 100%); | |
min-height: 100vh; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
padding: 20px; | |
color: var(--gray-700); | |
} | |
.container { | |
background-color: white; | |
border-radius: var(--radius-lg); | |
box-shadow: var(--shadow-md); | |
width: 100%; | |
max-width: 420px; | |
padding: 40px; | |
position: relative; | |
overflow: hidden; | |
transition: var(--transition); | |
} | |
.container::before { | |
content: ''; | |
position: absolute; | |
top: 0; | |
left: 0; | |
width: 100%; | |
height: 6px; | |
background: linear-gradient(90deg, var(--primary) 0%, var(--accent) 100%); | |
} | |
.logo { | |
color: var(--primary); | |
font-size: 24px; | |
font-weight: 700; | |
margin-bottom: 30px; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
} | |
.logo svg { | |
margin-right: 10px; | |
width: 28px; | |
height: 28px; | |
} | |
.welcome { | |
font-size: 22px; | |
font-weight: 600; | |
color: var(--gray-700); | |
margin-bottom: 30px; | |
text-align: center; | |
} | |
.form-group { | |
margin-bottom: 20px; | |
position: relative; | |
} | |
.form-group label { | |
display: block; | |
margin-bottom: 8px; | |
font-size: 14px; | |
color: var(--gray-700); | |
font-weight: 500; | |
} | |
.form-group input { | |
width: 100%; | |
padding: 14px 16px; | |
border: 1px solid var(--gray-300); | |
border-radius: var(--radius); | |
font-size: 15px; | |
transition: var(--transition); | |
background-color: var(--gray-50); | |
} | |
.form-group input:focus { | |
border-color: var(--primary); | |
outline: none; | |
box-shadow: 0 0 0 3px rgba(124, 77, 255, 0.2); | |
background-color: white; | |
} | |
.password-toggle { | |
position: absolute; | |
right: 15px; | |
top: 40px; | |
cursor: pointer; | |
color: var(--gray-600); | |
font-size: 14px; | |
} | |
.forgot-password { | |
text-align: right; | |
margin-bottom: 20px; | |
} | |
.forgot-password a { | |
color: var(--gray-600); | |
font-size: 13px; | |
text-decoration: none; | |
transition: var(--transition); | |
} | |
.forgot-password a:hover { | |
color: var(--primary); | |
} | |
.btn { | |
width: 100%; | |
padding: 14px; | |
border: none; | |
border-radius: var(--radius); | |
background-color: var(--primary); | |
color: white; | |
font-size: 15px; | |
font-weight: 500; | |
cursor: pointer; | |
margin-bottom: 20px; | |
transition: var(--transition); | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
gap: 8px; | |
} | |
.btn:hover { | |
background-color: var(--primary-dark); | |
transform: translateY(-2px); | |
box-shadow: 0 4px 8px rgba(124, 77, 255, 0.2); | |
} | |
.btn:active { | |
transform: translateY(0); | |
} | |
.btn-secondary { | |
background-color: white; | |
border: 1px solid var(--gray-300); | |
color: var(--gray-700); | |
} | |
.btn-secondary:hover { | |
background-color: var(--gray-50); | |
transform: translateY(-2px); | |
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.05); | |
} | |
.divider { | |
display: flex; | |
align-items: center; | |
margin: 25px 0; | |
color: var(--gray-600); | |
font-size: 13px; | |
font-weight: 500; | |
} | |
.divider::before, .divider::after { | |
content: ""; | |
flex: 1; | |
border-bottom: 1px solid var(--gray-200); | |
} | |
.divider::before { | |
margin-right: 15px; | |
} | |
.divider::after { | |
margin-left: 15px; | |
} | |
.form-footer { | |
text-align: center; | |
margin-top: 25px; | |
font-size: 14px; | |
color: var(--gray-600); | |
} | |
.form-footer a { | |
color: var(--primary); | |
text-decoration: none; | |
font-weight: 500; | |
transition: var(--transition); | |
} | |
.form-footer a:hover { | |
text-decoration: underline; | |
} | |
#signup-form { | |
display: none; | |
} | |
.form-message { | |
padding: 12px; | |
border-radius: var(--radius); | |
margin-bottom: 20px; | |
font-size: 14px; | |
display: none; | |
} | |
.error-message { | |
background-color: rgba(244, 67, 54, 0.1); | |
color: var(--error); | |
border-left: 4px solid var(--error); | |
} | |
.success-message { | |
background-color: rgba(76, 175, 80, 0.1); | |
color: var(--success); | |
border-left: 4px solid var(--success); | |
} | |
.password-strength { | |
height: 4px; | |
background-color: var(--gray-200); | |
border-radius: 2px; | |
margin-top: 8px; | |
overflow: hidden; | |
} | |
.strength-meter { | |
height: 100%; | |
width: 0%; | |
transition: var(--transition); | |
} | |
.weak { | |
background-color: #FF5252; | |
width: 33%; | |
} | |
.medium { | |
background-color: #FFC107; | |
width: 66%; | |
} | |
.strong { | |
background-color: #4CAF50; | |
width: 100%; | |
} | |
.password-hint { | |
font-size: 12px; | |
color: var(--gray-600); | |
margin-top: 4px; | |
display: none; | |
} | |
.animate-form { | |
animation: fadeInUp 0.5s; | |
} | |
@keyframes fadeInUp { | |
from { | |
opacity: 0; | |
transform: translateY(20px); | |
} | |
to { | |
opacity: 1; | |
transform: translateY(0); | |
} | |
} | |
@media (max-width: 480px) { | |
.container { | |
padding: 30px 20px; | |
} | |
.welcome { | |
font-size: 20px; | |
} | |
} | |
</style> | |
</head> | |
<body> | |
<div class="container"> | |
<!-- Sign In Form --> | |
<form id="signin-form" class="animate-form"> | |
<div class="logo"> | |
<svg viewBox="0 0 24 24" fill="currentColor"> | |
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z"/> | |
</svg> | |
Flowva | |
</div> | |
<div class="welcome">Welcome back</div> | |
<div id="signin-message" class="form-message"></div> | |
<div class="form-group"> | |
<label for="email">Email</label> | |
<input type="email" id="email" placeholder="[email protected]" required> | |
</div> | |
<div class="form-group"> | |
<label for="password">Password</label> | |
<input type="password" id="password" placeholder="••••••••" required> | |
<span class="password-toggle" id="toggle-password">Show</span> | |
</div> | |
<div class="forgot-password"> | |
<a href="#" id="forgot-password">Forgot password?</a> | |
</div> | |
<button type="submit" class="btn"> | |
<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="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"></path> | |
<polyline points="10 17 15 12 10 7"></polyline> | |
<line x1="15" y1="12" x2="3" y2="12"></line> | |
</svg> | |
Sign in | |
</button> | |
<div class="divider">or continue with</div> | |
<button type="button" class="btn btn-secondary" id="google-login"> | |
<svg width="18" height="18" viewBox="0 0 24 24"> | |
<path d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z" fill="#4285F4"/> | |
<path d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z" fill="#34A853"/> | |
<path d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z" fill="#FBBC05"/> | |
<path d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z" fill="#EA4335"/> | |
</svg> | |
</button> | |
<div class="form-footer"> | |
Don't have an account? <a href="#" id="show-signup">Sign up</a> | |
</div> | |
</form> | |
<!-- Sign Up Form --> | |
<form id="signup-form" class="animate-form"> | |
<div class="logo"> | |
<svg viewBox="0 0 24 24" fill="currentColor"> | |
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z"/> | |
</svg> | |
Flowva | |
</div> | |
<div class="welcome">Join Flowva today</div> | |
<div id="signup-message" class="form-message"></div> | |
<div class="form-group"> | |
<label for="signup-email">Email</label> | |
<input type="email" id="signup-email" placeholder="[email protected]" required> | |
</div> | |
<div class="form-group"> | |
<label for="signup-password">Password</label> | |
<input type="password" id="signup-password" placeholder="••••••••" required> | |
<span class="password-toggle" id="toggle-signup-password">Show</span> | |
<div class="password-strength"> | |
<div class="strength-meter" id="password-meter"></div> | |
</div> | |
<div class="password-hint" id="password-hint"> | |
Use at least 8 characters with a mix of letters, numbers & symbols | |
</div> | |
</div> | |
<div class="form-group"> | |
<label for="confirm-password">Confirm Password</label> | |
<input type="password" id="confirm-password" placeholder="••••••••" required> | |
<span class="password-toggle" id="toggle-confirm-password">Show</span> | |
</div> | |
<button type="submit" class="btn"> | |
<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="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"></path> | |
</svg> | |
Create account | |
</button> | |
<div class="divider">or continue with</div> | |
<button type="button" class="btn btn-secondary" id="google-signup"> | |
<svg width="18" height="18" viewBox="0 0 24 24"> | |
<path d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z" fill="#4285F4"/> | |
<path d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z" fill="#34A853"/> | |
<path d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z" fill="#FBBC05"/> | |
<path d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z" fill="#EA4335"/> | |
</svg> | |
</button> | |
<div class="form-footer"> | |
Already have an account? <a href="#" id="show-signin">Sign in</a> | |
</div> | |
</form> | |
<!-- Forgot Password Form --> | |
<form id="forgot-form" class="animate-form" style="display: none;"> | |
<div class="logo"> | |
<svg viewBox="0 0 24 24" fill="currentColor"> | |
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z"/> | |
</svg> | |
Flowva | |
</div> | |
<div class="welcome">Reset your password</div> | |
<div id="forgot-message" class="form-message"></div> | |
<div class="form-group"> | |
<label for="forgot-email">Email</label> | |
<input type="email" id="forgot-email" placeholder="[email protected]" required> | |
</div> | |
<button type="submit" class="btn"> | |
<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="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path> | |
<polyline points="22,6 12,13 2,6"></polyline> | |
</svg> | |
Send reset link | |
</button> | |
<div class="form-footer"> | |
Remember your password? <a href="#" id="show-signin-from-forgot">Sign in</a> | |
</div> | |
</form> | |
</div> | |
<script> | |
// Toggle between forms | |
document.getElementById('show-signup').addEventListener('click', function(e) { | |
e.preventDefault(); | |
toggleForms('signup-form'); | |
}); | |
document.getElementById('show-signin').addEventListener('click', function(e) { | |
e.preventDefault(); | |
toggleForms('signin-form'); | |
}); | |
document.getElementById('forgot-password').addEventListener('click', function(e) { | |
e.preventDefault(); | |
toggleForms('forgot-form'); | |
}); | |
document.getElementById('show-signin-from-forgot').addEventListener('click', function(e) { | |
e.preventDefault(); | |
toggleForms('signin-form'); | |
}); | |
function toggleForms(formToShow) { | |
const forms = ['signin-form', 'signup-form', 'forgot-form']; | |
forms.forEach(formId => { | |
const form = document.getElementById(formId); | |
if (formId === formToShow) { | |
form.style.display = 'block'; | |
form.classList.add('animate__animated', 'animate__fadeInUp'); | |
} else { | |
form.style.display = 'none'; | |
form.classList.remove('animate__animated', 'animate__fadeInUp'); | |
} | |
}); | |
} | |
// Password toggle functionality | |
function setupPasswordToggle(toggleId, inputId) { | |
const toggle = document.getElementById(toggleId); | |
const input = document.getElementById(inputId); | |
toggle.addEventListener('click', function(e) { | |
e.preventDefault(); | |
if (input.type === 'password') { | |
input.type = 'text'; | |
toggle.textContent = 'Hide'; | |
} else { | |
input.type = 'password'; | |
toggle.textContent = 'Show'; | |
} | |
}); | |
} | |
setupPasswordToggle('toggle-password', 'password'); | |
setupPasswordToggle('toggle-signup-password', 'signup-password'); | |
setupPasswordToggle('toggle-confirm-password', 'confirm-password'); | |
// Password strength meter | |
document.getElementById('signup-password').addEventListener('input', function(e) { | |
const password = e.target.value; | |
const meter = document.getElementById('password-meter'); | |
const hint = document.getElementById('password-hint'); | |
// Reset | |
meter.className = 'strength-meter'; | |
hint.style.display = 'none'; | |
if (password.length === 0) return; | |
hint.style.display = 'block'; | |
// Check password strength | |
let strength = 0; | |
// Length | |
if (password.length > 7) strength++; | |
// Contains both lower and uppercase characters | |
if (password.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/)) strength++; | |
// Contains numbers | |
if (password.match(/([0-9])/)) strength++; | |
// Contains special chars | |
if (password.match(/([!,%,&,@,#,$,^,*,?,_,~])/)) strength++; | |
// Update meter | |
if (password.length < 6) { | |
meter.classList.add('weak'); | |
} else if (strength <= 2) { | |
meter.classList.add('medium'); | |
} else { | |
meter.classList.add('strong'); | |
} | |
}); | |
// Form submission handling with validation | |
document.getElementById('signin-form').addEventListener('submit', function(e) { | |
e.preventDefault(); | |
const email = document.getElementById('email').value; | |
const password = document.getElementById('password').value; | |
const message = document.getElementById('signin-message'); | |
// Simple validation | |
if (!email || !password) { | |
showMessage(message, 'Please fill in all fields', 'error'); | |
return; | |
} | |
// Simulate API call | |
showMessage(message, 'Signing in...', 'success'); | |
setTimeout(() => { | |
showMessage(message, 'Welcome back! Redirecting...', 'success'); | |
// In a real app, you would redirect or update UI here | |
}, 1500); | |
}); | |
document.getElementById('signup-form').addEventListener('submit', function(e) { | |
e.preventDefault(); | |
const email = document.getElementById('signup-email').value; | |
const password = document.getElementById('signup-password').value; | |
const confirmPassword = document.getElementById('confirm-password').value; | |
const message = document.getElementById('signup-message'); | |
// Validation | |
if (!email || !password || !confirmPassword) { | |
showMessage(message, 'Please fill in all fields', 'error'); | |
return; | |
} | |
if (password !== confirmPassword) { | |
showMessage(message, 'Passwords do not match', 'error'); | |
return; | |
} | |
if (password.length < 8) { | |
showMessage(message, 'Password must be at least 8 characters', 'error'); | |
return; | |
} | |
// Simulate API call | |
showMessage(message, 'Creating your account...', 'success'); | |
setTimeout(() => { | |
showMessage(message, 'Account created successfully! Welcome to Flowva.', 'success'); | |
// In a real app, you would redirect or update UI here | |
}, 1500); | |
}); | |
document.getElementById('forgot-form').addEventListener('submit', function(e) { | |
e.preventDefault(); | |
const email = document.getElementById('forgot-email').value; | |
const message = document.getElementById('forgot-message'); | |
if (!email) { | |
showMessage(message, 'Please enter your email', 'error'); | |
return; | |
} | |
// Simulate API call | |
showMessage(message, 'Sending reset link...', 'success'); | |
setTimeout(() => { | |
showMessage(message, 'Reset link sent to your email', 'success'); | |
}, 1500); | |
}); | |
function showMessage(element, text, type) { | |
element.textContent = text; | |
element.className = `form-message ${type}-message`; | |
element.style.display = 'block'; | |
// Hide message after 5 seconds | |
setTimeout(() => { | |
element.style.display = 'none'; | |
}, 5000); | |
} | |
// Google login/signup | |
document.getElementById('google-login').addEventListener('click', function() { | |
const message = document.getElementById('signin-message'); | |
showMessage(message, 'Redirecting to Google...', 'success'); | |
}); | |
document.getElementById('google-signup').addEventListener('click', function() { | |
const message = document.getElementById('signup-message'); | |
showMessage(message, 'Redirecting to Google...', 'success'); | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment