367 lines
17 KiB
HTML
367 lines
17 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
|
<title>可乐 - 忘记密码 (Apple 极简白)</title>
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Noto+Sans+SC:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
|
<style>
|
|
*,*::before,*::after{margin:0;padding:0;box-sizing:border-box}
|
|
body{font-family:'Inter',-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;-webkit-font-smoothing:antialiased}
|
|
|
|
/* ===== Light Mode ===== */
|
|
.page{min-height:100vh;display:flex;flex-direction:column;align-items:center;padding:0;position:relative;overflow:hidden}
|
|
.page.light{background:#f5f5f7;color:#1d1d1f}
|
|
.page.dark{background:#000;color:#f5f5f7}
|
|
|
|
/* Theme switcher */
|
|
.theme-switch{position:fixed;top:16px;right:16px;z-index:100;display:flex;background:#e5e5ea;border-radius:10px;padding:3px}
|
|
.page.dark .theme-switch{background:#2c2c2e}
|
|
.theme-btn{padding:6px 14px;border:none;border-radius:8px;font-size:12px;font-weight:600;cursor:pointer;font-family:inherit;transition:all .25s}
|
|
.page.light .theme-btn{background:transparent;color:#86868b}
|
|
.page.light .theme-btn.active{background:#fff;color:#1d1d1f;box-shadow:0 1px 3px rgba(0,0,0,.08)}
|
|
.page.dark .theme-btn{background:transparent;color:rgba(255,255,255,.35)}
|
|
.page.dark .theme-btn.active{background:#3a3a3c;color:#fff}
|
|
|
|
/* Content */
|
|
.content{width:100%;padding:48px 32px 0;position:relative;z-index:1}
|
|
|
|
/* Logo */
|
|
.logo{width:56px;height:56px;border-radius:16px;display:inline-flex;align-items:center;justify-content:center;font-size:28px}
|
|
.page.light .logo{background:#1d1d1f}
|
|
.page.dark .logo{background:rgba(255,255,255,.1)}
|
|
|
|
/* Header */
|
|
.header{text-align:center;margin-bottom:36px}
|
|
.title{font-size:28px;font-weight:800;letter-spacing:-.5px;margin-top:16px}
|
|
.subtitle{font-size:15px;margin-top:6px}
|
|
.page.light .title{color:#1d1d1f}
|
|
.page.light .subtitle{color:#86868b}
|
|
.page.dark .title{color:#fff}
|
|
.page.dark .subtitle{color:rgba(255,255,255,.4)}
|
|
|
|
/* ===== Steps Bar ===== */
|
|
.steps{display:flex;width:100%;margin-bottom:36px}
|
|
.steps .step{flex:1;text-align:center;position:relative;padding:16px 0}
|
|
.steps .step::after{content:'';position:absolute;bottom:0;left:50%;right:-50%;height:2px;border-radius:1px}
|
|
.steps .step:last-child::after{display:none}
|
|
.steps .step-num{width:28px;height:28px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;margin-bottom:8px;transition:all .3s}
|
|
.steps .step-label{display:block;font-size:12px;font-weight:600;transition:all .3s}
|
|
|
|
/* Light steps */
|
|
.page.light .steps .step{color:#c7c7cc}
|
|
.page.light .steps .step::after{background:#e5e5ea}
|
|
.page.light .steps .step-num{background:#e5e5ea;color:#aeaeb2}
|
|
.page.light .steps .step.active{color:#1d1d1f}
|
|
.page.light .steps .step.active::after{background:#667eea}
|
|
.page.light .steps .step.active .step-num{background:#1d1d1f;color:#fff}
|
|
.page.light .steps .step.done .step-num{background:#34d399;color:#fff}
|
|
.page.light .steps .step.done{color:#34d399}
|
|
.page.light .steps .step.done::after{background:#34d399}
|
|
|
|
/* Dark steps */
|
|
.page.dark .steps .step{color:rgba(255,255,255,.2)}
|
|
.page.dark .steps .step::after{background:rgba(255,255,255,.08)}
|
|
.page.dark .steps .step-num{background:rgba(255,255,255,.08);color:rgba(255,255,255,.25)}
|
|
.page.dark .steps .step.active{color:#fff}
|
|
.page.dark .steps .step.active::after{background:#667eea}
|
|
.page.dark .steps .step.active .step-num{background:#667eea;color:#fff}
|
|
.page.dark .steps .step.done .step-num{background:#34d399;color:#fff}
|
|
.page.dark .steps .step.done{color:#34d399}
|
|
.page.dark .steps .step.done::after{background:#34d399}
|
|
|
|
/* ===== Tabs (login/register style segmented) ===== */
|
|
.tabs{display:flex;border-radius:12px;padding:4px;margin-bottom:32px;width:100%}
|
|
.page.light .tabs{background:#f0f0f2}
|
|
.page.dark .tabs{background:#1c1c1e}
|
|
.tab{flex:1;padding:11px 0;text-align:center;border-radius:10px;font-size:14px;font-weight:600;border:none;cursor:pointer;transition:all .3s cubic-bezier(.25,.1,.25,1);font-family:inherit}
|
|
.page.light .tab{background:transparent;color:#86868b}
|
|
.page.light .tab.active{background:#fff;color:#1d1d1f;box-shadow:0 1px 3px rgba(0,0,0,.08),0 1px 2px rgba(0,0,0,.06)}
|
|
.page.dark .tab{background:transparent;color:rgba(255,255,255,.35)}
|
|
.page.dark .tab.active{background:#2c2c2e;color:#fff;box-shadow:0 1px 4px rgba(0,0,0,.3)}
|
|
|
|
/* ===== Form steps ===== */
|
|
.form-step{display:none;width:100%}
|
|
.form-step.active{display:flex;flex-direction:column;animation:fadeSlide .35s ease}
|
|
@keyframes fadeSlide{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
|
|
|
|
/* Inputs - Apple style */
|
|
.field{margin-bottom:16px}
|
|
.field label{display:block;font-size:13px;font-weight:600;margin-bottom:8px}
|
|
.page.light .field label{color:#333}
|
|
.page.dark .field label{color:rgba(255,255,255,.6)}
|
|
.input{width:100%;height:52px;border-radius:12px;padding:0 16px;font-size:16px;outline:none;transition:all .25s;font-family:inherit}
|
|
.page.light .input{border:1.5px solid #e5e5ea;background:#fff;color:#1d1d1f}
|
|
.page.light .input::placeholder{color:#c7c7cc}
|
|
.page.light .input:focus{border-color:#667eea;box-shadow:0 0 0 3px rgba(102,126,234,.12)}
|
|
.page.dark .input{border:1.5px solid rgba(255,255,255,.1);background:#1c1c1e;color:#fff}
|
|
.page.dark .input::placeholder{color:rgba(255,255,255,.25)}
|
|
.page.dark .input:focus{border-color:rgba(102,126,234,.6);box-shadow:0 0 0 3px rgba(102,126,234,.12)}
|
|
|
|
/* Code row */
|
|
.code-row{display:flex;gap:10px;margin-bottom:16px;align-items:stretch}
|
|
.code-row .input{flex:1;margin-bottom:0}
|
|
.code-btn{flex-shrink:0;height:52px;padding:0 18px;border-radius:12px;font-size:13px;font-weight:600;cursor:pointer;transition:all .2s;font-family:inherit;white-space:nowrap}
|
|
.page.light .code-btn{border:1.5px solid #e5e5ea;background:#fafafa;color:#667eea}
|
|
.page.light .code-btn:hover:not(:disabled){border-color:#667eea;background:#f0f0ff}
|
|
.page.dark .code-btn{border:1.5px solid rgba(255,255,255,.1);background:#1c1c1e;color:#667eea}
|
|
.page.dark .code-btn:hover:not(:disabled){background:rgba(102,126,234,.12);color:#8b9cf7}
|
|
.code-btn:disabled{opacity:.5;cursor:not-allowed}
|
|
|
|
/* Primary button - Apple black style */
|
|
.btn-primary{width:100%;height:54px;border-radius:14px;border:none;font-size:17px;font-weight:600;cursor:pointer;transition:all .3s;margin-top:8px;letter-spacing:.2px;font-family:inherit}
|
|
.btn-primary:active{transform:scale(.97);opacity:.9}
|
|
.page.light .btn-primary{background:#1d1d1f;color:#fff}
|
|
.page.dark .btn-primary{background:#fff;color:#000}
|
|
|
|
/* Ghost button */
|
|
.btn-ghost{width:100%;height:54px;border-radius:14px;font-size:15px;font-weight:600;cursor:pointer;margin-top:12px;transition:all .3s;font-family:inherit}
|
|
.page.light .btn-ghost{border:1.5px solid #e5e5ea;background:#fff;color:#1d1d1f}
|
|
.page.light .btn-ghost:hover{border-color:#d2d2d7;background:#fafafa}
|
|
.page.dark .btn-ghost{border:1.5px solid rgba(255,255,255,.12);background:transparent;color:rgba(255,255,255,.8)}
|
|
.page.dark .btn-ghost:hover{border-color:rgba(255,255,255,.2)}
|
|
|
|
/* Back link */
|
|
.back-link{display:inline-flex;align-items:center;gap:6px;font-size:14px;cursor:pointer;margin-bottom:24px;font-weight:500;font-family:inherit;border:none;background:none;padding:0;transition:color .2s}
|
|
.page.light .back-link{color:#667eea}
|
|
.page.dark .back-link{color:#667eea}
|
|
.back-link:hover{text-decoration:underline}
|
|
|
|
/* Email badge */
|
|
.email-badge{display:inline-flex;align-items:center;gap:8px;padding:12px 16px;border-radius:12px;margin-bottom:20px;font-size:14px;font-weight:500}
|
|
.page.light .email-badge{background:#f0f0f2;color:#667eea}
|
|
.page.dark .email-badge{background:rgba(102,126,234,.1);color:#8b9cf7;border:1px solid rgba(255,255,255,.08)}
|
|
|
|
/* Password rules */
|
|
.rules{padding:14px 16px;border-radius:12px;margin-top:14px;margin-bottom:8px}
|
|
.page.light .rules{background:#f8f8fa;border:1px solid #e5e5ea}
|
|
.page.dark .rules{background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.08)}
|
|
.rules p{font-size:13px;line-height:2}
|
|
.page.light .rules p{color:#86868b}
|
|
.page.dark .rules p{color:rgba(255,255,255,.35)}
|
|
.rules strong{font-weight:600}
|
|
.page.light .rules strong{color:#1d1d1f}
|
|
.page.dark .rules strong{color:rgba(255,255,255,.6)}
|
|
|
|
/* Success */
|
|
.success{display:none;text-align:center;padding:48px 0}
|
|
.success.active{display:block;animation:fadeSlide .4s ease}
|
|
.success .check{width:72px;height:72px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-size:36px;margin-bottom:20px}
|
|
.page.light .success .check{background:#f0fff4}
|
|
.page.dark .success .check{background:rgba(52,211,153,.1)}
|
|
.success h2{font-size:22px;font-weight:800;margin-bottom:8px;letter-spacing:-.3px}
|
|
.page.light .success h2{color:#1d1d1f}
|
|
.page.dark .success h2{color:#fff}
|
|
.success p{font-size:15px;margin-bottom:32px}
|
|
.page.light .success p{color:#86868b}
|
|
.page.dark .success p{color:rgba(255,255,255,.4)}
|
|
|
|
/* Divider */
|
|
.divider{display:flex;align-items:center;gap:16px;margin:28px 0 24px;width:100%}
|
|
.divider::before,.divider::after{content:'';flex:1;height:.5px}
|
|
.page.light .divider::before,.page.light .divider::after{background:#d2d2d7}
|
|
.page.dark .divider::before,.page.dark .divider::after{background:rgba(255,255,255,.08)}
|
|
.divider span{font-size:13px;white-space:nowrap;font-weight:500}
|
|
.page.light .divider span{color:#86868b}
|
|
.page.dark .divider span{color:rgba(255,255,255,.3)}
|
|
|
|
/* Agreement */
|
|
.agreement{text-align:center;font-size:12px;line-height:1.7;padding:16px 20px 32px;margin-top:16px}
|
|
.page.light .agreement{color:#aeaeb2}
|
|
.page.dark .agreement{color:rgba(255,255,255,.2)}
|
|
.agree-link{background:none;border:none;font-size:12px;cursor:pointer;padding:0;font-weight:500;font-family:inherit}
|
|
.page.light .agree-link{color:#8e8e93}
|
|
.page.dark .agree-link{color:rgba(255,255,255,.35)}
|
|
|
|
@media(max-width:480px){
|
|
.content{padding-left:24px!important;padding-right:24px!important}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<!-- Light -->
|
|
<div class="page light" id="lightPage">
|
|
<div class="theme-switch">
|
|
<button class="theme-btn active" onclick="switchTheme('light')">☀️ 浅色</button>
|
|
<button class="theme-btn" onclick="switchTheme('dark')">🌙 深色</button>
|
|
</div>
|
|
<div class="content">
|
|
<div class="header">
|
|
<div class="logo">🥤</div>
|
|
<h1 class="title">找回密码</h1>
|
|
<p class="subtitle">别担心,我们帮你重置密码</p>
|
|
</div>
|
|
|
|
<!-- Steps -->
|
|
<div class="steps" id="lightSteps">
|
|
<div class="step active"><div class="step-num">1</div><div class="step-label">验证身份</div></div>
|
|
<div class="step"><div class="step-num">2</div><div class="step-label">重置密码</div></div>
|
|
</div>
|
|
|
|
<!-- Step 1: Verify -->
|
|
<div class="form-step active" id="lightStep0">
|
|
<div class="field">
|
|
<label>邮箱地址</label>
|
|
<input class="input" type="email" placeholder="请输入注册邮箱" id="lightEmail">
|
|
</div>
|
|
<div class="code-row">
|
|
<input class="input" type="text" placeholder="验证码" maxlength="8">
|
|
<button class="code-btn" onclick="sendCode(this)" id="lightSendBtn">获取验证码</button>
|
|
</div>
|
|
<button class="btn-primary" onclick="goStep(1,'light')">下一步</button>
|
|
<div class="divider"><span>或</span></div>
|
|
<button class="btn-ghost" onclick="window.location.href='/login'">返回登录</button>
|
|
</div>
|
|
|
|
<!-- Step 2: Reset -->
|
|
<div class="form-step" id="lightStep1">
|
|
<button class="back-link" onclick="goStep(0,'light')">← 返回验证</button>
|
|
<div class="email-badge" id="lightEmailDisplay">✉️ user@example.com</div>
|
|
<div class="field">
|
|
<label>验证码</label>
|
|
<input class="input" type="text" placeholder="请输入验证码" maxlength="8">
|
|
</div>
|
|
<div class="field">
|
|
<label>新密码</label>
|
|
<input class="input" type="password" placeholder="至少8位,包含字母和数字">
|
|
</div>
|
|
<div class="field">
|
|
<label>确认密码</label>
|
|
<input class="input" type="password" placeholder="请再次输入新密码">
|
|
</div>
|
|
<div class="rules">
|
|
<p><strong>•</strong> 至少8个字符</p>
|
|
<p><strong>•</strong> 包含字母和数字</p>
|
|
<p><strong>•</strong> 建议12位以上更安全</p>
|
|
</div>
|
|
<button class="btn-primary" onclick="resetPwd('light')">重置密码</button>
|
|
</div>
|
|
|
|
<!-- Success -->
|
|
<div class="success" id="lightSuccess">
|
|
<div class="check">✅</div>
|
|
<h2>密码重置成功!</h2>
|
|
<p>你的密码已更新,现在可以使用新密码登录了</p>
|
|
<button class="btn-primary" onclick="location.reload()">返回登录</button>
|
|
</div>
|
|
|
|
<div class="agreement">
|
|
继续即表示你同意
|
|
<button class="agree-link">用户协议</button>
|
|
和
|
|
<button class="agree-link">隐私政策</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Dark (hidden by default) -->
|
|
<div class="page dark" id="darkPage" style="display:none">
|
|
<div class="theme-switch">
|
|
<button class="theme-btn" onclick="switchTheme('light')">☀️ 浅色</button>
|
|
<button class="theme-btn active" onclick="switchTheme('dark')">🌙 深色</button>
|
|
</div>
|
|
<div class="content">
|
|
<div class="header">
|
|
<div class="logo">🥤</div>
|
|
<h1 class="title">找回密码</h1>
|
|
<p class="subtitle">别担心,我们帮你重置密码</p>
|
|
</div>
|
|
|
|
<div class="steps" id="darkSteps">
|
|
<div class="step active"><div class="step-num">1</div><div class="step-label">验证身份</div></div>
|
|
<div class="step"><div class="step-num">2</div><div class="step-label">重置密码</div></div>
|
|
</div>
|
|
|
|
<div class="form-step active" id="darkStep0">
|
|
<div class="field">
|
|
<label>邮箱地址</label>
|
|
<input class="input" type="email" placeholder="请输入注册邮箱" id="darkEmail">
|
|
</div>
|
|
<div class="code-row">
|
|
<input class="input" type="text" placeholder="验证码" maxlength="8">
|
|
<button class="code-btn" onclick="sendCode(this)" id="darkSendBtn">获取验证码</button>
|
|
</div>
|
|
<button class="btn-primary" onclick="goStep(1,'dark')">下一步</button>
|
|
<div class="divider"><span>或</span></div>
|
|
<button class="btn-ghost" onclick="window.location.href='/login'">返回登录</button>
|
|
</div>
|
|
|
|
<div class="form-step" id="darkStep1">
|
|
<button class="back-link" onclick="goStep(0,'dark')">← 返回验证</button>
|
|
<div class="email-badge" id="darkEmailDisplay">✉️ user@example.com</div>
|
|
<div class="field">
|
|
<label>验证码</label>
|
|
<input class="input" type="text" placeholder="请输入验证码" maxlength="8">
|
|
</div>
|
|
<div class="field">
|
|
<label>新密码</label>
|
|
<input class="input" type="password" placeholder="至少8位,包含字母和数字">
|
|
</div>
|
|
<div class="field">
|
|
<label>确认密码</label>
|
|
<input class="input" type="password" placeholder="请再次输入新密码">
|
|
</div>
|
|
<div class="rules">
|
|
<p><strong>•</strong> 至少8个字符</p>
|
|
<p><strong>•</strong> 包含字母和数字</p>
|
|
<p><strong>•</strong> 建议12位以上更安全</p>
|
|
</div>
|
|
<button class="btn-primary" onclick="resetPwd('dark')">重置密码</button>
|
|
</div>
|
|
|
|
<div class="success" id="darkSuccess">
|
|
<div class="check">✅</div>
|
|
<h2>密码重置成功!</h2>
|
|
<p>你的密码已更新,现在可以使用新密码登录了</p>
|
|
<button class="btn-primary" onclick="location.reload()">返回登录</button>
|
|
</div>
|
|
|
|
<div class="agreement">
|
|
继续即表示你同意
|
|
<button class="agree-link">用户协议</button>
|
|
和
|
|
<button class="agree-link">隐私政策</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function switchTheme(t){
|
|
document.getElementById('lightPage').style.display=t==='light'?'flex':'none';
|
|
document.getElementById('darkPage').style.display=t==='dark'?'flex':'none';
|
|
document.querySelectorAll('.theme-btn').forEach(function(b){b.classList.remove('active')});
|
|
document.querySelectorAll('.theme-btn').forEach(function(b){
|
|
if((t==='light'&&b.textContent.includes('浅色'))||(t==='dark'&&b.textContent.includes('深色')))b.classList.add('active');
|
|
});
|
|
}
|
|
function sendCode(btn){
|
|
var s=60;btn.disabled=true;
|
|
var iv=setInterval(function(){s--;btn.textContent=s+'s';if(s<=0){clearInterval(iv);btn.disabled=false;btn.textContent='获取验证码'}},1000);
|
|
}
|
|
function goStep(n,theme){
|
|
var steps=document.getElementById(theme+'Steps').querySelectorAll('.step');
|
|
steps.forEach(function(s,i){
|
|
s.classList.remove('active','done');
|
|
if(i<n)s.classList.add('done');
|
|
if(i===n)s.classList.add('active');
|
|
});
|
|
for(var i=0;i<2;i++){
|
|
var el=document.getElementById(theme+'Step'+i);
|
|
if(el)el.classList.remove('active');
|
|
}
|
|
document.getElementById(theme+'Step'+n).classList.add('active');
|
|
if(n===1){
|
|
var em=document.getElementById(theme+'Email').value||'user@example.com';
|
|
document.getElementById(theme+'EmailDisplay').textContent='✉️ '+em;
|
|
}
|
|
}
|
|
function resetPwd(theme){
|
|
document.getElementById(theme+'Step1').classList.remove('active');
|
|
document.getElementById(theme+'Success').classList.add('active');
|
|
var steps=document.getElementById(theme+'Steps').querySelectorAll('.step');
|
|
steps.forEach(function(s){s.classList.remove('active');s.classList.add('done')});
|
|
}
|
|
</script>
|
|
</body>
|
|
</html> |