Hướng dẫn code UI đăng nhập/đăng ký cao cấp
Có sẵn trong bản này 🔵 Giao diện xanh futuristic / premium 🔐 Đăng nhập 👤 Đăng ký 🔄 Chuyển cảnh Login ↔ Register ✨ Glassmorphism 🌌 Background particle 💫 Orb ánh sáng chuyển động ⭕ Các vòng năng lượng chuyển động 🕸️ Grid 3D background ⚡ Loading screen khi mở trang 🔒 Show/hide password
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Account Center | Muathemewpgiare</title>
<!-- Font Awesome -->
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css">
<!-- CSS -->
<link rel="stylesheet" href="style.css">
</head>
<body class="muathemewpgiare-auth">
<!-- ================================
LOADING SCREEN
================================= -->
<div class="muathemewpgiare-loader" id="mwgLoader">
<div class="mwg-loader-orbit">
<div class="mwg-loader-core">
<i class="fa-solid fa-bolt"></i>
</div>
</div>
<div class="mwg-loader-title">
MUATHEME<span>WPGIARE</span>
</div>
<div class="mwg-loader-progress">
<span></span>
</div>
<div class="mwg-loader-text">
Đang khởi tạo hệ thống...
</div>
</div>
<!-- ================================
BACKGROUND
================================= -->
<div class="mwg-background">
<div class="mwg-grid"></div>
<div class="mwg-orb mwg-orb-1"></div>
<div class="mwg-orb mwg-orb-2"></div>
<div class="mwg-orb mwg-orb-3"></div>
<div class="mwg-ring mwg-ring-1"></div>
<div class="mwg-ring mwg-ring-2"></div>
<div class="mwg-ring mwg-ring-3"></div>
<canvas id="mwgParticles"></canvas>
</div>
<!-- ================================
MAIN
================================= -->
<main class="mwg-auth-wrapper">
<section class="mwg-auth-card" id="mwgAuthCard">
<!-- ============================
VISUAL PANEL
============================= -->
<div class="mwg-visual-panel">
<div class="mwg-visual-glow"></div>
<div class="mwg-brand">
<div class="mwg-brand-icon">
<i class="fa-solid fa-bolt"></i>
</div>
<div>
<strong>MUATHEMEWPGIARE</strong>
<small>Digital Experience</small>
</div>
</div>
<div class="mwg-visual-content">
<span class="mwg-eyebrow">
<i class="fa-solid fa-sparkles"></i>
PREMIUM ACCOUNT
</span>
<h1>
Một tài khoản.
<strong>Toàn bộ trải nghiệm.</strong>
</h1>
<p>
Đăng nhập để quản lý tài khoản, sản phẩm,
đơn hàng và toàn bộ hệ sinh thái của
Muathemewpgiare.
</p>
<div class="mwg-feature-list">
<div class="mwg-feature">
<div class="mwg-feature-icon">
<i class="fa-solid fa-shield-halved"></i>
</div>
<div>
<strong>Bảo mật hiện đại</strong>
<span>Thông tin được bảo vệ an toàn</span>
</div>
</div>
<div class="mwg-feature">
<div class="mwg-feature-icon">
<i class="fa-solid fa-bolt"></i>
</div>
<div>
<strong>Truy cập nhanh</strong>
<span>Trải nghiệm mượt mà trên mọi thiết bị</span>
</div>
</div>
<div class="mwg-feature">
<div class="mwg-feature-icon">
<i class="fa-solid fa-layer-group"></i>
</div>
<div>
<strong>Một hệ sinh thái</strong>
<span>Quản lý mọi thứ trong một nơi</span>
</div>
</div>
</div>
</div>
<div class="mwg-visual-footer">
<span>© 2026 Muathemewpgiare.com</span>
<div class="mwg-socials">
<a href="#">
<i class="fa-brands fa-facebook-f"></i>
</a>
<a href="#">
<i class="fa-brands fa-youtube"></i>
</a>
<a href="#">
<i class="fa-brands fa-github"></i>
</a>
</div>
</div>
</div>
<!-- ============================
FORM PANEL
============================= -->
<div class="mwg-form-panel">
<div class="mwg-form-stage">
<!-- ========================
LOGIN
========================= -->
<form class="mwg-form mwg-login-form active"
id="mwgLoginForm">
<div class="mwg-form-header">
<div class="mwg-mobile-logo">
<i class="fa-solid fa-bolt"></i>
</div>
<span class="mwg-form-label">
CHÀO MỪNG TRỞ LẠI
</span>
<h2>Đăng nhập</h2>
<p>
Đăng nhập vào tài khoản của bạn
để tiếp tục.
</p>
</div>
<!-- EMAIL -->
<div class="mwg-input-group">
<label>Email</label>
<div class="mwg-input-wrap">
<i class="fa-regular fa-envelope"></i>
<input
type="email"
id="mwgLoginEmail"
placeholder="name@example.com"
autocomplete="email"
required
>
</div>
</div>
<!-- PASSWORD -->
<div class="mwg-input-group">
<div class="mwg-label-row">
<label>Mật khẩu</label>
<a href="#" id="mwgForgot">
Quên mật khẩu?
</a>
</div>
<div class="mwg-input-wrap">
<i class="fa-solid fa-lock"></i>
<input
type="password"
id="mwgLoginPassword"
placeholder="Nhập mật khẩu"
autocomplete="current-password"
required
>
<button
type="button"
class="mwg-password-toggle"
data-target="mwgLoginPassword"
>
<i class="fa-regular fa-eye"></i>
</button>
</div>
</div>
<!-- REMEMBER -->
<label class="mwg-checkbox">
<input type="checkbox">
<span class="mwg-checkmark">
<i class="fa-solid fa-check"></i>
</span>
<span>Ghi nhớ đăng nhập</span>
</label>
<!-- BUTTON -->
<button
type="submit"
class="mwg-main-button"
>
<span>Đăng nhập</span>
<i class="fa-solid fa-arrow-right"></i>
<div class="mwg-button-shine"></div>
</button>
<!-- DIVIDER -->
<div class="mwg-divider">
<span>hoặc tiếp tục với</span>
</div>
<!-- SOCIAL -->
<div class="mwg-social-login">
<button type="button">
<i class="fa-brands fa-google"></i>
Google
</button>
<button type="button">
<i class="fa-brands fa-facebook-f"></i>
Facebook
</button>
</div>
<div class="mwg-switch">
<span>Chưa có tài khoản?</span>
<button
type="button"
id="mwgShowRegister"
>
Tạo tài khoản
<i class="fa-solid fa-arrow-right"></i>
</button>
</div>
</form>
<!-- ========================
REGISTER
========================= -->
<form class="mwg-form mwg-register-form"
id="mwgRegisterForm">
<div class="mwg-form-header">
<div class="mwg-mobile-logo">
<i class="fa-solid fa-user-plus"></i>
</div>
<span class="mwg-form-label">
THAM GIA NGAY
</span>
<h2>Tạo tài khoản</h2>
<p>
Tạo tài khoản mới chỉ mất vài giây.
</p>
</div>
<!-- NAME -->
<div class="mwg-input-group">
<label>Họ và tên</label>
<div class="mwg-input-wrap">
<i class="fa-regular fa-user"></i>
<input
type="text"
id="mwgRegisterName"
placeholder="Nguyễn Văn A"
autocomplete="name"
required
>
</div>
</div>
<!-- EMAIL -->
<div class="mwg-input-group">
<label>Email</label>
<div class="mwg-input-wrap">
<i class="fa-regular fa-envelope"></i>
<input
type="email"
id="mwgRegisterEmail"
placeholder="name@example.com"
autocomplete="email"
required
>
</div>
</div>
<!-- PASSWORD -->
<div class="mwg-input-group">
<label>Mật khẩu</label>
<div class="mwg-input-wrap">
<i class="fa-solid fa-lock"></i>
<input
type="password"
id="mwgRegisterPassword"
placeholder="Tối thiểu 8 ký tự"
autocomplete="new-password"
required
>
<button
type="button"
class="mwg-password-toggle"
data-target="mwgRegisterPassword"
>
<i class="fa-regular fa-eye"></i>
</button>
</div>
<!-- PASSWORD STRENGTH -->
<div class="mwg-strength">
<div class="mwg-strength-bars">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<small id="mwgStrengthText">
Độ mạnh mật khẩu
</small>
</div>
</div>
<!-- CONFIRM -->
<div class="mwg-input-group">
<label>Xác nhận mật khẩu</label>
<div class="mwg-input-wrap">
<i class="fa-solid fa-shield-halved"></i>
<input
type="password"
id="mwgRegisterConfirm"
placeholder="Nhập lại mật khẩu"
autocomplete="new-password"
required
>
</div>
</div>
<label class="mwg-checkbox mwg-terms">
<input type="checkbox" required>
<span class="mwg-checkmark">
<i class="fa-solid fa-check"></i>
</span>
<span>
Tôi đồng ý với
<a href="#">Điều khoản</a>
và
<a href="#">Chính sách</a>
</span>
</label>
<!-- REGISTER BUTTON -->
<button
type="submit"
class="mwg-main-button"
>
<span>Tạo tài khoản</span>
<i class="fa-solid fa-user-plus"></i>
<div class="mwg-button-shine"></div>
</button>
<div class="mwg-switch">
<span>Đã có tài khoản?</span>
<button
type="button"
id="mwgShowLogin"
>
Đăng nhập
<i class="fa-solid fa-arrow-right"></i>
</button>
</div>
</form>
</div>
</div>
</section>
</main>
<!-- TOAST -->
<div class="mwg-toast" id="mwgToast">
<div class="mwg-toast-icon">
<i class="fa-solid fa-check"></i>
</div>
<div>
<strong id="mwgToastTitle">
Thành công
</strong>
<span id="mwgToastMessage">
Thao tác thành công.
</span>
</div>
<button id="mwgToastClose">
<i class="fa-solid fa-xmark"></i>
</button>
</div>
<!-- JS -->
<script src="script.js"></script>
</body>
</html>/* =========================================================
MUATHEMEWPGIARE AUTH UI
Author: muathemewpgiare.com
========================================================= */
:root {
--mwg-blue: #087cff;
--mwg-blue-light: #31b7ff;
--mwg-blue-dark: #0754c9;
--mwg-bg: #030914;
--mwg-panel: rgba(7, 19, 37, .78);
--mwg-border: rgba(255,255,255,.10);
--mwg-text: #f5f9ff;
--mwg-muted: #8c9bb2;
--mwg-radius: 30px;
--mwg-shadow:
0 40px 100px rgba(0,0,0,.45),
0 0 80px rgba(0,126,255,.10);
}
/* =========================================================
RESET
========================================================= */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
min-height: 100vh;
overflow-x: hidden;
font-family:
Inter,
system-ui,
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
sans-serif;
color: var(--mwg-text);
background: var(--mwg-bg);
}
button,
input {
font: inherit;
}
button {
border: 0;
}
a {
color: inherit;
text-decoration: none;
}
/* =========================================================
LOADER
========================================================= */
.muathemewpgiare-loader {
position: fixed;
inset: 0;
z-index: 99999;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background:
radial-gradient(
circle at center,
rgba(0,126,255,.14),
transparent 30%
),
#020711;
transition:
opacity .8s ease,
visibility .8s ease;
}
.muathemewpgiare-loader.is-hidden {
opacity: 0;
visibility: hidden;
}
.mwg-loader-orbit {
width: 90px;
height: 90px;
display: grid;
place-items: center;
border-radius: 50%;
border: 1px solid rgba(49,183,255,.25);
box-shadow:
0 0 25px rgba(0,126,255,.25),
inset 0 0 30px rgba(0,126,255,.1);
animation: mwgLoaderSpin 3s linear infinite;
}
.mwg-loader-core {
width: 48px;
height: 48px;
display: grid;
place-items: center;
border-radius: 16px;
color: white;
background:
linear-gradient(
135deg,
var(--mwg-blue),
var(--mwg-blue-light)
);
box-shadow:
0 0 35px rgba(0,145,255,.65);
animation: mwgLoaderCore 1.6s ease-in-out infinite;
}
.mwg-loader-title {
margin-top: 30px;
font-size: 14px;
font-weight: 800;
letter-spacing: 5px;
}
.mwg-loader-title span {
color: var(--mwg-blue-light);
}
.mwg-loader-progress {
width: 180px;
height: 3px;
margin-top: 22px;
overflow: hidden;
border-radius: 20px;
background: rgba(255,255,255,.08);
}
.mwg-loader-progress span {
display: block;
width: 40%;
height: 100%;
border-radius: inherit;
background:
linear-gradient(
90deg,
transparent,
#fff,
var(--mwg-blue-light)
);
animation: mwgLoading 1.4s ease-in-out infinite;
}
.mwg-loader-text {
margin-top: 12px;
font-size: 11px;
color: #71829c;
}
/* =========================================================
BACKGROUND
========================================================= */
.mwg-background {
position: fixed;
inset: 0;
overflow: hidden;
pointer-events: none;
}
.mwg-background canvas {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
opacity: .65;
}
.mwg-grid {
position: absolute;
inset: -50%;
background-image:
linear-gradient(
rgba(31,133,255,.045) 1px,
transparent 1px
),
linear-gradient(
90deg,
rgba(31,133,255,.045) 1px,
transparent 1px
);
background-size: 55px 55px;
transform: perspective(500px)
rotateX(62deg)
translateY(-80px)
scale(1.8);
mask-image:
linear-gradient(
to bottom,
transparent,
black 35%,
black 70%,
transparent
);
animation: mwgGridMove 18s linear infinite;
}
.mwg-orb {
position: absolute;
border-radius: 50%;
filter: blur(2px);
mix-blend-mode: screen;
opacity: .65;
}
.mwg-orb-1 {
width: 500px;
height: 500px;
top: -250px;
left: -150px;
background:
radial-gradient(
circle,
rgba(0,128,255,.28),
transparent 70%
);
animation: mwgFloat1 12s ease-in-out infinite;
}
.mwg-orb-2 {
width: 650px;
height: 650px;
right: -300px;
bottom: -300px;
background:
radial-gradient(
circle,
rgba(0,203,255,.20),
transparent 70%
);
animation: mwgFloat2 15s ease-in-out infinite;
}
.mwg-orb-3 {
width: 280px;
height: 280px;
top: 45%;
left: 45%;
background:
radial-gradient(
circle,
rgba(0,91,255,.15),
transparent 70%
);
animation: mwgPulse 7s ease-in-out infinite;
}
.mwg-ring {
position: absolute;
border: 1px solid rgba(0,153,255,.09);
border-radius: 50%;
}
.mwg-ring-1 {
width: 700px;
height: 700px;
left: -250px;
bottom: -400px;
animation: mwgRing 25s linear infinite;
}
.mwg-ring-2 {
width: 1000px;
height: 1000px;
right: -500px;
top: -500px;
animation: mwgRing 35s linear infinite reverse;
}
.mwg-ring-3 {
width: 420px;
height: 420px;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
border-style: dashed;
animation: mwgRing 20s linear infinite;
}
/* =========================================================
MAIN
========================================================= */
.mwg-auth-wrapper {
position: relative;
z-index: 5;
min-height: 100vh;
display: grid;
place-items: center;
padding: 35px;
}
.mwg-auth-card {
position: relative;
width: min(1180px, 100%);
min-height: 720px;
display: grid;
grid-template-columns: 46% 54%;
overflow: hidden;
border: 1px solid rgba(255,255,255,.11);
border-radius: var(--mwg-radius);
background:
linear-gradient(
135deg,
rgba(255,255,255,.07),
rgba(255,255,255,.015)
);
backdrop-filter: blur(30px);
box-shadow: var(--mwg-shadow);
animation: mwgCardIn 1.1s cubic-bezier(.16,1,.3,1);
}
/* =========================================================
VISUAL PANEL
========================================================= */
.mwg-visual-panel {
position: relative;
padding: 48px;
overflow: hidden;
display: flex;
flex-direction: column;
background:
linear-gradient(
145deg,
rgba(0,105,255,.30),
rgba(2,15,34,.78)
);
border-right: 1px solid rgba(255,255,255,.08);
}
.mwg-visual-panel::before {
content: "";
position: absolute;
inset: 0;
background:
radial-gradient(
circle at 20% 20%,
rgba(56,188,255,.22),
transparent 32%
),
radial-gradient(
circle at 80% 80%,
rgba(0,85,255,.18),
transparent 35%
);
}
.mwg-visual-glow {
position: absolute;
width: 300px;
height: 300px;
right: -130px;
top: 100px;
border-radius: 50%;
background: rgba(0,174,255,.18);
filter: blur(80px);
animation: mwgPulse 5s ease-in-out infinite;
}
.mwg-brand {
position: relative;
z-index: 2;
display: flex;
align-items: center;
gap: 14px;
}
.mwg-brand-icon {
width: 45px;
height: 45px;
display: grid;
place-items: center;
border-radius: 14px;
background:
linear-gradient(
135deg,
#087cff,
#24c7ff
);
box-shadow:
0 10px 35px rgba(0,126,255,.35);
}
.mwg-brand strong {
display: block;
font-size: 13px;
letter-spacing: 2px;
}
.mwg-brand small {
display: block;
margin-top: 4px;
color: #8ca8c9;
font-size: 10px;
letter-spacing: 1px;
}
.mwg-visual-content {
position: relative;
z-index: 2;
margin: auto 0;
}
.mwg-eyebrow {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 8px 12px;
border: 1px solid rgba(73,194,255,.22);
border-radius: 50px;
background: rgba(0,126,255,.08);
color: #6fcfff;
font-size: 9px;
font-weight: 800;
letter-spacing: 2px;
}
.mwg-visual-content h1 {
max-width: 460px;
margin-top: 25px;
font-size: clamp(36px, 4vw, 56px);
line-height: 1.02;
letter-spacing: -2px;
}
.mwg-visual-content h1 strong {
display: block;
color: transparent;
background:
linear-gradient(
90deg,
#fff,
#46caff
);
background-clip: text;
-webkit-background-clip: text;
}
.mwg-visual-content > p {
max-width: 470px;
margin-top: 25px;
color: #94a9c3;
font-size: 14px;
line-height: 1.8;
}
.mwg-feature-list {
margin-top: 35px;
display: grid;
gap: 14px;
}
.mwg-feature {
display: flex;
align-items: center;
gap: 13px;
}
.mwg-feature-icon {
width: 40px;
height: 40px;
flex: 0 0 40px;
display: grid;
place-items: center;
border: 1px solid rgba(69,185,255,.16);
border-radius: 12px;
background: rgba(0,126,255,.08);
color: #4fc7ff;
}
.mwg-feature strong {
display: block;
font-size: 12px;
}
.mwg-feature span {
display: block;
margin-top: 3px;
color: #71859f;
font-size: 10px;
}
.mwg-visual-footer {
position: relative;
z-index: 2;
display: flex;
align-items: center;
justify-content: space-between;
color: #60758e;
font-size: 10px;
}
.mwg-socials {
display: flex;
gap: 8px;
}
.mwg-socials a {
width: 31px;
height: 31px;
display: grid;
place-items: center;
border: 1px solid rgba(255,255,255,.08);
border-radius: 9px;
transition: .3s ease;
}
.mwg-socials a:hover {
color: white;
background: var(--mwg-blue);
border-color: var(--mwg-blue);
transform: translateY(-3px);
}
/* =========================================================
FORM PANEL
========================================================= */
.mwg-form-panel {
position: relative;
display: flex;
align-items: center;
padding: 65px 70px;
background:
linear-gradient(
145deg,
rgba(3,11,24,.58),
rgba(2,9,20,.82)
);
}
.mwg-form-stage {
position: relative;
width: 100%;
}
.mwg-form {
width: 100%;
}
.mwg-form-header {
margin-bottom: 30px;
}
.mwg-form-label {
color: #48c6ff;
font-size: 9px;
font-weight: 800;
letter-spacing: 2px;
}
.mwg-form-header h2 {
margin-top: 8px;
font-size: 34px;
letter-spacing: -1px;
}
.mwg-form-header p {
margin-top: 8px;
color: #71839c;
font-size: 13px;
}
.mwg-mobile-logo {
display: none;
}
/* =========================================================
FORM SWITCH ANIMATION
========================================================= */
.mwg-login-form,
.mwg-register-form {
transition:
opacity .55s ease,
transform .55s cubic-bezier(.16,1,.3,1),
visibility .55s;
}
.mwg-register-form {
position: absolute;
top: 0;
left: 0;
opacity: 0;
visibility: hidden;
transform:
translateX(70px)
scale(.97);
}
.mwg-login-form.is-exiting {
opacity: 0;
transform:
translateX(-70px)
scale(.97);
visibility: hidden;
}
.mwg-register-form.active {
position: relative;
opacity: 1;
visibility: visible;
transform:
translateX(0)
scale(1);
}
.mwg-login-form.active {
opacity: 1;
visibility: visible;
transform:
translateX(0)
scale(1);
}
/* =========================================================
INPUT
========================================================= */
.mwg-input-group {
margin-bottom: 19px;
}
.mwg-input-group label,
.mwg-label-row label {
display: block;
margin-bottom: 8px;
color: #b6c5d8;
font-size: 11px;
font-weight: 600;
}
.mwg-label-row {
display: flex;
justify-content: space-between;
}
.mwg-label-row a {
color: #4bc7ff;
font-size: 10px;
}
.mwg-input-wrap {
position: relative;
display: flex;
align-items: center;
}
.mwg-input-wrap > i {
position: absolute;
left: 17px;
color: #5f7794;
font-size: 13px;
transition: .3s;
}
.mwg-input-wrap input {
width: 100%;
height: 52px;
padding:
0 48px;
border: 1px solid rgba(255,255,255,.08);
outline: none;
border-radius: 13px;
color: white;
background:
rgba(255,255,255,.035);
transition:
border-color .3s,
box-shadow .3s,
background .3s;
}
.mwg-input-wrap input::placeholder {
color: #53657c;
}
.mwg-input-wrap input:focus {
border-color: rgba(35,166,255,.65);
background:
rgba(0,126,255,.055);
box-shadow:
0 0 0 4px rgba(0,126,255,.08),
0 0 30px rgba(0,126,255,.08);
}
.mwg-input-wrap:focus-within > i {
color: #3ebcff;
}
.mwg-password-toggle {
position: absolute;
right: 13px;
width: 32px;
height: 32px;
display: grid;
place-items: center;
cursor: pointer;
color: #61758d;
background: transparent;
border-radius: 8px;
transition: .25s;
}
.mwg-password-toggle:hover {
color: #42c3ff;
background: rgba(0,126,255,.08);
}
/* =========================================================
CHECKBOX
========================================================= */
.mwg-checkbox {
position: relative;
display: flex;
align-items: flex-start;
gap: 9px;
margin: 5px 0 20px;
color: #71839b;
font-size: 10px;
cursor: pointer;
}
.mwg-checkbox input {
position: absolute;
opacity: 0;
}
.mwg-checkmark {
width: 17px;
height: 17px;
flex: 0 0 17px;
display: grid;
place-items: center;
border: 1px solid rgba(255,255,255,.16);
border-radius: 5px;
transition: .25s;
}
.mwg-checkmark i {
opacity: 0;
color: white;
font-size: 8px;
}
.mwg-checkbox input:checked + .mwg-checkmark {
border-color: var(--mwg-blue);
background: var(--mwg-blue);
box-shadow:
0 0 15px rgba(0,126,255,.3);
}
.mwg-checkbox input:checked + .mwg-checkmark i {
opacity: 1;
}
.mwg-terms a {
color: #4dc7ff;
}
/* =========================================================
MAIN BUTTON
========================================================= */
.mwg-main-button {
position: relative;
width: 100%;
height: 55px;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
cursor: pointer;
border-radius: 14px;
color: white;
font-size: 12px;
font-weight: 800;
background:
linear-gradient(
100deg,
#0757d9,
#078eff 55%,
#26c7ff
);
box-shadow:
0 14px 35px rgba(0,126,255,.25);
transition:
transform .3s,
box-shadow .3s;
}
.mwg-main-button:hover {
transform: translateY(-3px);
box-shadow:
0 20px 45px rgba(0,126,255,.35);
}
.mwg-main-button:active {
transform: translateY(0) scale(.98);
}
.mwg-button-shine {
position: absolute;
top: 0;
left: -100%;
width: 60%;
height: 100%;
transform: skewX(-20deg);
background:
linear-gradient(
90deg,
transparent,
rgba(255,255,255,.28),
transparent
);
transition: left .8s;
}
.mwg-main-button:hover .mwg-button-shine {
left: 130%;
}
/* =========================================================
DIVIDER
========================================================= */
.mwg-divider {
display: flex;
align-items: center;
gap: 12px;
margin: 25px 0;
color: #51647c;
font-size: 9px;
}
.mwg-divider::before,
.mwg-divider::after {
content: "";
flex: 1;
height: 1px;
background:
linear-gradient(
90deg,
transparent,
rgba(255,255,255,.09)
);
}
.mwg-divider::after {
background:
linear-gradient(
90deg,
rgba(255,255,255,.09),
transparent
);
}
/* =========================================================
SOCIAL LOGIN
========================================================= */
.mwg-social-login {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px;
}
.mwg-social-login button {
height: 45px;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
cursor: pointer;
border: 1px solid rgba(255,255,255,.08);
border-radius: 11px;
color: #9aabc0;
background: rgba(255,255,255,.025);
font-size: 10px;
transition: .3s;
}
.mwg-social-login button:hover {
color: white;
border-color: rgba(0,146,255,.3);
background: rgba(0,126,255,.08);
transform: translateY(-2px);
}
.mwg-social-login i {
font-size: 13px;
}
/* =========================================================
SWITCH
========================================================= */
.mwg-switch {
display: flex;
justify-content: center;
align-items: center;
gap: 5px;
margin-top: 27px;
color: #667a93;
font-size: 10px;
}
.mwg-switch button {
display: inline-flex;
align-items: center;
gap: 6px;
cursor: pointer;
color: #46c5ff;
background: transparent;
font-size: 10px;
font-weight: 700;
}
.mwg-switch button i {
transition: transform .3s;
}
.mwg-switch button:hover i {
transform: translateX(4px);
}
/* =========================================================
PASSWORD STRENGTH
========================================================= */
.mwg-strength {
margin-top: 8px;
}
.mwg-strength-bars {
display: grid;
grid-template-columns: repeat(4,1fr);
gap: 4px;
}
.mwg-strength-bars span {
height: 3px;
border-radius: 10px;
background: rgba(255,255,255,.08);
transition: .3s;
}
.mwg-strength-bars.level-1 span:nth-child(1),
.mwg-strength-bars.level-2 span:nth-child(-n+2),
.mwg-strength-bars.level-3 span:nth-child(-n+3),
.mwg-strength-bars.level-4 span {
background: #24b8ff;
box-shadow:
0 0 8px rgba(36,184,255,.35);
}
.mwg-strength small {
display: block;
margin-top: 6px;
color: #60758e;
font-size: 8px;
}
/* =========================================================
TOAST
========================================================= */
.mwg-toast {
position: fixed;
z-index: 999999;
right: 25px;
bottom: 25px;
min-width: 300px;
display: flex;
align-items: center;
gap: 12px;
padding: 14px;
border: 1px solid rgba(255,255,255,.1);
border-radius: 15px;
background:
rgba(7,19,37,.92);
backdrop-filter: blur(20px);
box-shadow:
0 20px 60px rgba(0,0,0,.4);
transform:
translateY(30px)
translateX(20px);
opacity: 0;
visibility: hidden;
transition:
.45s cubic-bezier(.16,1,.3,1);
}
.mwg-toast.show {
transform:
translateY(0)
translateX(0);
opacity: 1;
visibility: visible;
}
.mwg-toast-icon {
width: 38px;
height: 38px;
display: grid;
place-items: center;
border-radius: 11px;
color: white;
background:
linear-gradient(
135deg,
#087cff,
#24c7ff
);
}
.mwg-toast strong,
.mwg-toast span {
display: block;
}
.mwg-toast strong {
font-size: 11px;
}
.mwg-toast span {
margin-top: 3px;
color: #74869e;
font-size: 9px;
}
.mwg-toast > button {
margin-left: auto;
color: #63758b;
cursor: pointer;
background: transparent;
}
/* =========================================================
RIPPLE
========================================================= */
.mwg-ripple {
position: absolute;
width: 5px;
height: 5px;
pointer-events: none;
border-radius: 50%;
background: rgba(255,255,255,.5);
transform:
translate(-50%, -50%)
scale(0);
animation: mwgRipple .65s ease-out forwards;
}
/* =========================================================
ANIMATIONS
========================================================= */
@keyframes mwgCardIn {
from {
opacity: 0;
transform:
translateY(50px)
scale(.96);
filter: blur(10px);
}
to {
opacity: 1;
transform:
translateY(0)
scale(1);
filter: blur(0);
}
}
@keyframes mwgLoaderSpin {
to {
transform: rotate(360deg);
}
}
@keyframes mwgLoaderCore {
0%,100% {
transform: scale(.92);
}
50% {
transform: scale(1.05);
}
}
@keyframes mwgLoading {
0% {
transform: translateX(-120%);
}
100% {
transform: translateX(350%);
}
}
@keyframes mwgGridMove {
to {
transform:
perspective(500px)
rotateX(62deg)
translateY(55px)
scale(1.8);
}
}
@keyframes mwgFloat1 {
0%,100% {
transform: translate(0,0);
}
50% {
transform: translate(70px,50px);
}
}
@keyframes mwgFloat2 {
0%,100% {
transform: translate(0,0);
}
50% {
transform: translate(-60px,-50px);
}
}
@keyframes mwgPulse {
0%,100% {
transform: scale(.9);
opacity: .5;
}
50% {
transform: scale(1.1);
opacity: .85;
}
}
@keyframes mwgRing {
to {
transform:
rotate(360deg);
}
}
@keyframes mwgRipple {
to {
opacity: 0;
transform:
translate(-50%, -50%)
scale(35);
}
}
/* =========================================================
RESPONSIVE
========================================================= */
@media (max-width: 950px) {
.mwg-auth-card {
grid-template-columns: 1fr;
min-height: auto;
}
.mwg-visual-panel {
display: none;
}
.mwg-form-panel {
min-height: 700px;
padding: 55px 60px;
}
.mwg-mobile-logo {
width: 44px;
height: 44px;
display: grid;
place-items: center;
margin-bottom: 20px;
border-radius: 13px;
color: white;
background:
linear-gradient(
135deg,
#087cff,
#24c7ff
);
box-shadow:
0 12px 30px rgba(0,126,255,.25);
}
}
@media (max-width: 600px) {
.mwg-auth-wrapper {
padding: 15px;
}
.mwg-auth-card {
border-radius: 22px;
}
.mwg-form-panel {
min-height: 670px;
padding:
40px 25px;
}
.mwg-form-header h2 {
font-size: 29px;
}
.mwg-social-login {
grid-template-columns: 1fr;
}
.mwg-toast {
right: 15px;
bottom: 15px;
left: 15px;
min-width: 0;
}
}
@media (max-width: 380px) {
.mwg-form-panel {
padding: 30px 18px;
}
.mwg-form-header h2 {
font-size: 26px;
}
.mwg-main-button {
height: 52px;
}
}
/* =========================================================
ACCESSIBILITY
========================================================= */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: .01ms !important;
animation-iteration-count: 1 !important;
scroll-behavior: auto !important;
transition-duration: .01ms !important;
}
}/* =========================================================
MUATHEMEWPGIARE AUTH EXPERIENCE
Author: muathemewpgiare.com
========================================================= */
(() => {
"use strict";
/* =====================================================
DOM
===================================================== */
const $ = (selector, parent = document) =>
parent.querySelector(selector);
const $$ = (selector, parent = document) =>
[...parent.querySelectorAll(selector)];
const loader = $("#mwgLoader");
const authCard = $("#mwgAuthCard");
const loginForm = $("#mwgLoginForm");
const registerForm = $("#mwgRegisterForm");
const showRegister = $("#mwgShowRegister");
const showLogin = $("#mwgShowLogin");
const toast = $("#mwgToast");
const toastTitle = $("#mwgToastTitle");
const toastMessage = $("#mwgToastMessage");
const toastClose = $("#mwgToastClose");
const particlesCanvas = $("#mwgParticles");
/* =====================================================
PAGE LOADER
===================================================== */
window.addEventListener("load", () => {
setTimeout(() => {
loader.classList.add("is-hidden");
}, 900);
});
/* =====================================================
FORM SWITCH
===================================================== */
let switching = false;
function switchToRegister() {
if (switching) return;
switching = true;
loginForm.classList.add("is-exiting");
loginForm.classList.remove("active");
setTimeout(() => {
registerForm.classList.add("active");
authCard.classList.add("mwg-register-mode");
switching = false;
}, 280);
}
function switchToLogin() {
if (switching) return;
switching = true;
registerForm.classList.remove("active");
setTimeout(() => {
loginForm.classList.remove("is-exiting");
loginForm.classList.add("active");
authCard.classList.remove("mwg-register-mode");
switching = false;
}, 280);
}
showRegister?.addEventListener(
"click",
switchToRegister
);
showLogin?.addEventListener(
"click",
switchToLogin
);
/* =====================================================
PASSWORD TOGGLE
===================================================== */
$$(".mwg-password-toggle").forEach(button => {
button.addEventListener("click", () => {
const targetId =
button.dataset.target;
const input =
document.getElementById(targetId);
if (!input) return;
const icon =
button.querySelector("i");
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"
);
}
});
});
/* =====================================================
PASSWORD STRENGTH
===================================================== */
const registerPassword =
$("#mwgRegisterPassword");
const strengthBars =
$(".mwg-strength-bars");
const strengthText =
$("#mwgStrengthText");
function calculatePasswordStrength(password) {
let score = 0;
if (password.length >= 8)
score++;
if (password.length >= 12)
score++;
if (/[A-Z]/.test(password))
score++;
if (/[0-9]/.test(password))
score++;
if (/[^A-Za-z0-9]/.test(password))
score++;
return Math.min(score, 4);
}
registerPassword?.addEventListener(
"input",
() => {
const value =
registerPassword.value.trim();
const level =
calculatePasswordStrength(value);
strengthBars.className =
"mwg-strength-bars";
if (level > 0) {
strengthBars.classList.add(
`level-${level}`
);
}
const labels = [
"Độ mạnh mật khẩu",
"Rất yếu",
"Yếu",
"Khá tốt",
"Mật khẩu mạnh"
];
strengthText.textContent =
labels[level];
}
);
/* =====================================================
TOAST
===================================================== */
let toastTimer;
function showToast(
title,
message
) {
toastTitle.textContent = title;
toastMessage.textContent = message;
toast.classList.add("show");
clearTimeout(toastTimer);
toastTimer = setTimeout(() => {
toast.classList.remove("show");
}, 4000);
}
toastClose?.addEventListener(
"click",
() => toast.classList.remove("show")
);
/* =====================================================
LOGIN
===================================================== */
loginForm?.addEventListener(
"submit",
event => {
event.preventDefault();
const email =
$("#mwgLoginEmail").value.trim();
const password =
$("#mwgLoginPassword").value;
if (!email || !password) {
showToast(
"Thiếu thông tin",
"Vui lòng nhập đầy đủ thông tin."
);
return;
}
const button =
loginForm.querySelector(
".mwg-main-button"
);
setButtonLoading(
button,
"Đang xác thực..."
);
setTimeout(() => {
resetButton(
button,
"Đăng nhập",
"fa-arrow-right"
);
showToast(
"Demo thành công",
"Đăng nhập đã được xử lý."
);
}, 1600);
}
);
/* =====================================================
REGISTER
===================================================== */
registerForm?.addEventListener(
"submit",
event => {
event.preventDefault();
const name =
$("#mwgRegisterName").value.trim();
const email =
$("#mwgRegisterEmail").value.trim();
const password =
$("#mwgRegisterPassword").value;
const confirm =
$("#mwgRegisterConfirm").value;
if (!name || !email || !password || !confirm) {
showToast(
"Thiếu thông tin",
"Vui lòng hoàn thành biểu mẫu."
);
return;
}
if (password.length < 8) {
showToast(
"Mật khẩu chưa đủ mạnh",
"Mật khẩu cần tối thiểu 8 ký tự."
);
return;
}
if (password !== confirm) {
showToast(
"Mật khẩu không khớp",
"Vui lòng kiểm tra lại mật khẩu."
);
return;
}
const button =
registerForm.querySelector(
".mwg-main-button"
);
setButtonLoading(
button,
"Đang tạo tài khoản..."
);
setTimeout(() => {
resetButton(
button,
"Tạo tài khoản",
"fa-user-plus"
);
showToast(
"Tạo tài khoản thành công",
`Chào mừng ${name}!`
);
}, 1800);
}
);
/* =====================================================
BUTTON LOADING
===================================================== */
function setButtonLoading(
button,
text
) {
if (!button) return;
button.dataset.original =
button.innerHTML;
button.innerHTML = `
<i class="fa-solid fa-circle-notch fa-spin"></i>
<span>${text}</span>
`;
button.disabled = true;
button.style.pointerEvents =
"none";
}
function resetButton(
button,
text,
icon
) {
if (!button) return;
button.innerHTML = `
<span>${text}</span>
<i class="fa-solid ${icon}"></i>
<div class="mwg-button-shine"></div>
`;
button.disabled = false;
button.style.pointerEvents =
"";
}
/* =====================================================
FORGOT PASSWORD
===================================================== */
$("#mwgForgot")?.addEventListener(
"click",
event => {
event.preventDefault();
showToast(
"Khôi phục mật khẩu",
"Demo: hệ thống sẽ gửi liên kết khôi phục."
);
}
);
/* =====================================================
SOCIAL BUTTONS
===================================================== */
$$(".mwg-social-login button")
.forEach(button => {
button.addEventListener(
"click",
() => {
const provider =
button.textContent.trim();
showToast(
"Đăng nhập mạng xã hội",
`${provider} đang ở chế độ demo.`
);
}
);
});
/* =====================================================
RIPPLE EFFECT
===================================================== */
$$(".mwg-main-button").forEach(button => {
button.addEventListener(
"click",
event => {
const rect =
button.getBoundingClientRect();
const ripple =
document.createElement("span");
ripple.className =
"mwg-ripple";
ripple.style.left =
`${event.clientX - rect.left}px`;
ripple.style.top =
`${event.clientY - rect.top}px`;
button.appendChild(ripple);
setTimeout(() => {
ripple.remove();
}, 700);
}
);
});
/* =====================================================
MOUSE PARALLAX
===================================================== */
const card =
$(".mwg-auth-card");
if (
window.matchMedia(
"(pointer:fine)"
).matches
) {
document.addEventListener(
"mousemove",
event => {
const x =
(event.clientX /
window.innerWidth -
.5);
const y =
(event.clientY /
window.innerHeight -
.5);
const orb1 =
$(".mwg-orb-1");
const orb2 =
$(".mwg-orb-2");
if (orb1) {
orb1.style.transform =
`translate(
${x * 25}px,
${y * 25}px
)`;
}
if (orb2) {
orb2.style.transform =
`translate(
${x * -20}px,
${y * -20}px
)`;
}
if (card) {
card.style.setProperty(
"--mwg-mx",
`${x * 4}deg`
);
card.style.setProperty(
"--mwg-my",
`${y * -4}deg`
);
}
}
);
}
/* =====================================================
PARTICLES
===================================================== */
const canvas =
particlesCanvas;
const ctx =
canvas?.getContext("2d");
let particles = [];
function resizeCanvas() {
if (!canvas) return;
const ratio =
Math.min(
window.devicePixelRatio || 1,
2
);
canvas.width =
window.innerWidth * ratio;
canvas.height =
window.innerHeight * ratio;
canvas.style.width =
`${window.innerWidth}px`;
canvas.style.height =
`${window.innerHeight}px`;
ctx.setTransform(
ratio,
0,
0,
ratio,
0,
0
);
}
function createParticles() {
if (!canvas) return;
particles = [];
const amount =
Math.min(
75,
Math.floor(
window.innerWidth / 18
)
);
for (
let i = 0;
i < amount;
i++
) {
particles.push({
x:
Math.random() *
window.innerWidth,
y:
Math.random() *
window.innerHeight,
size:
Math.random() * 1.5 + .4,
speedX:
(Math.random() - .5) * .25,
speedY:
(Math.random() - .5) * .25,
opacity:
Math.random() * .5 + .15
});
}
}
function animateParticles() {
if (!canvas || !ctx)
return;
ctx.clearRect(
0,
0,
window.innerWidth,
window.innerHeight
);
particles.forEach(p => {
p.x += p.speedX;
p.y += p.speedY;
if (p.x < -10)
p.x = window.innerWidth + 10;
if (p.x > window.innerWidth + 10)
p.x = -10;
if (p.y < -10)
p.y = window.innerHeight + 10;
if (p.y > window.innerHeight + 10)
p.y = -10;
ctx.beginPath();
ctx.arc(
p.x,
p.y,
p.size,
0,
Math.PI * 2
);
ctx.fillStyle =
`rgba(
60,
190,
255,
${p.opacity}
)`;
ctx.fill();
});
requestAnimationFrame(
animateParticles
);
}
resizeCanvas();
createParticles();
animateParticles();
window.addEventListener(
"resize",
() => {
resizeCanvas();
createParticles();
}
);
})();
Ctrl1 HTML
Ctrl2 CSS
Ctrl3 JS
Ctrl↵ Reload