MediumUntitled | by Lamerveille | Medium
Sitemap
Lamerveille

Lamerveille

4 min readAug 25, 2025

--

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Flash19 | Register</title>

<!-- Fonts & Icons -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@100..900&family=Poppins:wght@100;200;300;400;500;600;700;800;900&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" />

<!-- Optional vendor CSS you had -->
<link rel="stylesheet" href="https://flash19.com/asset/theme2/frontend/css/cookie.css" />
<link rel="stylesheet" href="https://flash19.com/asset/common/css/font-awsome.min.css" />
<link rel="stylesheet" href="https://flash19.com/asset/theme2/frontend/css/style.css" />

<!-- hCaptcha (replace data-sitekey) -->
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>

<style>
* { box-sizing: border-box; margin: 0; padding: 0; } /* ✅ fixed padding typo */
body { font-family: "Poppins", sans-serif; color: #000; }

.signup-container { display: flex; height: 100vh; width: 100%; background: #145629; }
.left-section { flex: 1; background: url("https://www.transparenttextures.com/patterns/asfalt-dark.png") repeat center/cover; background-color: #145629; display: flex; justify-content: center; flex-direction: column; padding: 30px; border-top-right-radius: 70px; }
.top-header { display: flex; gap: 16px; align-items: center; }
.top-header h1 { font-size: 36px; margin-top: 6px; color: #fff; }
.illustration { max-width: 80%; max-height: 80%; object-fit: contain; z-index: 1; }

.form-section { flex: 1; display: flex; justify-content: center; align-items: center; background: #fff; padding: 2rem; position: relative; }
.form-container { width: 100%; max-width: 420px; }
.form-logo { width: 100px; height: 100px; }
@media (min-width: 768px) { .form-logo { display: none; } }

h2 { font-size: 1.8rem; margin-bottom: 1.25rem; text-align: center; }
form { display: flex; flex-direction: column; gap: 10px; }
label { font-size: 0.9rem; margin-top: 0.3rem; }
input[type="text"], input[type="email"], input[type="password"] { padding: 0.65rem; border-radius: 6px; border: 1px solid #000; width: 100%; }
input:focus { outline: none; border: 1px solid #13c636; box-shadow: 0 0 0 3px rgba(19,198,54,0.15); }

.password-field { position: relative; }
.toggle-visibility { position: absolute; right: 10px; top: 50%; transform: translateY(-50%); cursor: pointer; border: none; background: transparent; }

.checkbox { display: flex; align-items: center; gap: 8px; font-size: 0.9rem; margin-top: 6px; }
.checkbox a { color: #145629; font-weight: 600; text-decoration: none; }

.captcha-wrap { margin-top: 10px; }

button[type="submit"] { background-color: #145629; color: #fff; padding: 0.8rem; border: none; border-radius: 8px; margin-top: 0.6rem; cursor: pointer; font-size: 1rem; }
button[type="submit"]:hover { background-color: #229f3a; }

.social-login { display: flex; justify-content: center; gap: 12px; margin-top: 1rem; }
.register { margin-top: 8px; }
.register-link { color: #145629; font-weight: 500; }

@media (max-width: 768px) {
.signup-container { display: block; background: #145629; }
.left-section { display: none; }
.form-section { background: url("https://www.transparenttextures.com/patterns/asfalt-dark.png") repeat center/contain, #145629; padding: 2rem 1rem; }
.form-container { margin: 0 auto; background: #fff; padding: 1.25rem; border-radius: 12px; box-shadow: 0 4px 10px rgba(0,0,0,0.08); }
}

/* Simple toast (optional) */
.toast { position: fixed; top: 20px; right: 20px; padding: 14px 22px; font-family: 'Poppins', sans-serif; font-size: 14px; color: #fff; border-radius: 12px; backdrop-filter: blur(10px); z-index: 10000; box-shadow: 0 8px 24px rgba(0,0,0,0.2); border: 1px solid rgba(255,255,255,0.1); opacity: 0; transform: translateY(-15px) scale(0.95); transition: opacity 0.3s ease, transform 0.3s ease; }
.toast.success { background: linear-gradient(92deg, #042911 0%, #0c470e 50%, #38a309 100%); }
.toast.show { opacity: 1; transform: translateY(0) scale(1); }
</style>
</head>

<body>
<div class="signup-container" role="main">
<!-- Left -->
<div class="left-section" aria-hidden="true">
<div class="top-header">
<img class="form-logo" alt="Flash19 logo" src="https://flash19.com/public/uploads/logo.png" />
<h1>Welcome to Flash19<br />Join Us Now!</h1>
</div>
<img class="illustration" alt="Illustration of mobile sign up" src="https://flash19.com/storage/app/public/images/side-picture.svg" />
</div>

<!-- Right/Form -->
<div class="form-section">
<div class="form-container">
<img class="form-logo" alt="Flash19 logo" src="https://flash19.com/public/uploads/logo.png" />
<h2>Join Flash19</h2>

<!-- NOTE: point action to your backend (same origin) -->
<form id="register-form" method="post" action="/register">
<!-- CSRF token will be injected by the server as a hidden input if you serve this file via Express with csurf -->

<label for="username">Username</label>
<input id="username" name="username" placeholder="Enter Your Username" required minlength="3" maxlength="32" autocomplete="username" />

<label for="email">Email</label>
<input id="email" type="email" name="email" placeholder="Enter Your Email" required autocomplete="email" />

<label for="password">Password</label>
<div class="password-field">
<input id="password" type="password" name="password" placeholder="Enter Your Password" required minlength="8" autocomplete="new-password" />
<button type="button" class="toggle-visibility" aria-label="Toggle password visibility" data-target="password">
<i class="far fa-eye" aria-hidden="true"></i>
</button>
</div>

<label for="password_confirmation">Confirm Password</label>
<div class="password-field">
<input id="password_confirmation" type="password" name="password_confirmation" placeholder="Confirm password" required minlength="8" autocomplete="new-password" />
<button type="button" class="toggle-visibility" aria-label="Toggle password confirmation visibility" data-target="password_confirmation">
<i class="far fa-eye" aria-hidden="true"></i>
</button>
</div>

<div class="checkbox">
<input id="notABotCheckbox" type="checkbox" required />
<label for="notABotCheckbox">I agree to the Terms</label>
</div>

<!-- hCaptcha widget -->
<div class="captcha-wrap">
<div class="h-captcha" data-sitekey="YOUR_HCAPTCHA_SITE_KEY"></div>
</div>

<button class="submit-btn" type="submit">Register</button>
</form>

<div class="social-login">
<span class="register">Already have an account?&nbsp;<a class="register-link" href="/login">Login</a></span>
</div>
</div>
</div>
</div>

<script>
// Remove popup script entirely (it referenced missing #popup-overlay / #close-btn)

// Password visibility toggle (adds/removes fa-eye / fa-eye-slash)
document.addEventListener('click', function (e) {
const btn = e.target.closest('.toggle-visibility');
if (!btn) return;
const inputId = btn.getAttribute('data-target');
const input = document.getElementById(inputId);
const icon = btn.querySelector('i');
if (!input) return;
if (input.type === 'password') {
input.type = 'text';
icon.classList.remove('fa-eye');
icon.classList.add('fa-eye-slash');
} else {
input.type = 'password';
icon.classList.remove('fa-eye-slash');
icon.classList.add('fa-eye');
}
});

// Simple client-side guard (server will enforce real validation)
document.getElementById('register-form').addEventListener('submit', function (e) {
const pwd = document.getElementById('password').value;
const cfm = document.getElementById('password_confirmation').value;
if (pwd !== cfm) {
e.preventDefault();
showToast('Passwords do not match', 'success');
}
});

function showToast(message) {
const t = document.createElement('div');
t.className = 'toast success';
t.textContent = message;
document.body.appendChild(t);
requestAnimationFrame(() => t.classList.add('show'));
setTimeout(() => t.classList.remove('show'));
setTimeout(() => t.remove(), 600);
}
</script>
</body>
</html>

--

--