iye f420af2069
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 6s
chore: 全量推送 · 累积页面改动 + Next.js 工程骨架 + v1/ 归档 + 文档
页面 (电商AI平台/)
- account / team / settings / index / products / projects: 累积迭代
- restraint.css: 设计 token 补充
- login.html / register.html: 新增登录注册页
- _ARCHIVE.md: 归档说明

Next.js 工程骨架
- app/ + components/: 新一代 SPA 雏形 (page / layout / sidebar / topbar / GridBg / Icon)
- package.json / package-lock.json / next.config.mjs / tsconfig.json / postcss.config.mjs / next-env.d.ts

历史归档 / 文档
- v1/: 原 V1 静态稿镜像 (含 mockup-A/B/C)
- PRD.md / deployment-guide.md / _check.html
- ui参考/ / screenshots/

杂项
- .gitignore 调整
- 删除根 README.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 21:16:46 +08:00

208 lines
13 KiB
HTML

<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>登录 · 流·Studio</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/restraint.css?v=202605211643">
<style>
body { margin: 0; min-height: 100vh; background: var(--background-base); display: grid; place-items: center; padding: 32px 24px; }
.auth-wrap { width: 100%; max-width: 980px; display: grid; grid-template-columns: minmax(0, 1fr) 420px; gap: 0; background: var(--surface); border: 1px solid var(--border-faint); border-radius: var(--r-md); position: relative; overflow: hidden; min-height: 560px; }
/* 4 装订线 */
.auth-wrap::before, .auth-wrap::after,
.auth-wrap > .corner-tr, .auth-wrap > .corner-bl {
content: ''; position: absolute; width: 14px; height: 14px;
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 22 21' fill='%23e8e8e8'%3E%3Cpath d='M10.5 4C10.5 7.31371 7.81371 10 4.5 10H0.5V11H4.5C7.81371 11 10.5 13.6863 10.5 17V21H11.5V17C11.5 13.6863 14.1863 11 17.5 11H21.5V10H17.5C14.1863 10 11.5 7.31371 11.5 4V0H10.5V4Z'/%3E%3C/svg%3E") no-repeat center;
background-size: contain; pointer-events: none; z-index: 2;
}
.auth-wrap::before { top: -7px; left: -7px; }
.auth-wrap::after { bottom: -7px; right: -7px; }
.auth-wrap > .corner-tr { top: -7px; right: -7px; }
.auth-wrap > .corner-bl { bottom: -7px; left: -7px; }
/* 左侧品牌区 · 深色 */
.auth-brand { background: var(--accent-black); color: var(--accent-white); padding: 40px 44px; display: flex; flex-direction: column; position: relative; overflow: hidden; }
.auth-brand .logo { display: flex; align-items: center; gap: 10px; font-size: 18px; font-weight: 700; letter-spacing: -.01em; }
.auth-brand .logo .ic { width: 28px; height: 28px; background: var(--heat); border-radius: 6px; display: grid; place-items: center; }
.auth-brand .logo .ic svg { width: 16px; height: 16px; color: var(--accent-white); }
.auth-brand .tag { font-family: var(--font-mono); font-size: 10.5px; color: rgba(255,255,255,.5); letter-spacing: .08em; text-transform: uppercase; margin-top: 4px; }
.auth-brand .hero { margin-top: auto; margin-bottom: auto; }
.auth-brand .hero h1 { font-size: 30px; font-weight: 700; letter-spacing: -.02em; line-height: 1.2; margin: 0 0 14px; }
.auth-brand .hero h1 .h { color: var(--heat); }
.auth-brand .hero p { font-size: 13.5px; color: rgba(255,255,255,.62); line-height: 1.7; max-width: 320px; margin: 0; }
/* ASCII 装饰行 */
.auth-brand .ascii { font-family: var(--font-mono); font-size: 10.5px; color: rgba(255,255,255,.32); letter-spacing: .04em; line-height: 1.8; margin-top: 28px; }
.auth-brand .ascii .ln .k { color: rgba(255,255,255,.5); }
.auth-brand .ascii .ln .v { color: var(--heat); }
.auth-brand .foot { font-family: var(--font-mono); font-size: 10.5px; color: rgba(255,255,255,.32); letter-spacing: .04em; margin-top: 22px; display: flex; gap: 14px; }
.auth-brand .foot a { color: rgba(255,255,255,.5); text-decoration: none; }
.auth-brand .foot a:hover { color: var(--heat); }
/* 右侧表单区 */
.auth-form { padding: 44px 44px 36px; display: flex; flex-direction: column; }
.auth-form .h-row { display: flex; align-items: baseline; gap: 8px; margin-bottom: 4px; }
.auth-form h2 { font-size: 22px; font-weight: 600; letter-spacing: -.012em; margin: 0; }
.auth-form .sub { font-family: var(--font-mono); font-size: 10.5px; color: var(--black-alpha-48); letter-spacing: .06em; text-transform: uppercase; }
.auth-form .lead { font-size: 13px; color: var(--black-alpha-56); margin: 0 0 28px; }
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 16px; }
.field-label { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--black-alpha-56); font-family: var(--font-mono); letter-spacing: .02em; }
.field-label .req { color: var(--accent-crimson); }
.field-input-wrap { position: relative; }
.field-input-wrap .ic-l { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: var(--black-alpha-32); width: 14px; height: 14px; pointer-events: none; }
.field input { width: 100%; box-sizing: border-box; padding: 11px 12px 11px 36px; font-size: 13.5px; background: var(--surface); border: 1px solid var(--border-faint); border-radius: var(--r-md); font-family: inherit; color: var(--accent-black); transition: border-color var(--t-base), box-shadow var(--t-base); }
.field input:focus { outline: none; border-color: var(--heat); box-shadow: 0 0 0 3px var(--heat-12); }
.field input::placeholder { color: var(--black-alpha-32); }
.field .toggle-pwd { position: absolute; right: 12px; top: 50%; transform: translateY(-50%); width: 18px; height: 18px; color: var(--black-alpha-48); cursor: pointer; background: none; border: 0; padding: 0; display: grid; place-items: center; }
.field .toggle-pwd:hover { color: var(--accent-black); }
.row-between { display: flex; align-items: center; justify-content: space-between; margin: 4px 0 22px; font-size: 12.5px; }
.row-between label { display: inline-flex; align-items: center; gap: 6px; color: var(--black-alpha-56); cursor: pointer; user-select: none; }
.row-between label input { width: 13px; height: 13px; accent-color: var(--heat); }
.row-between a { color: var(--heat); text-decoration: none; font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .02em; }
.row-between a:hover { text-decoration: underline; }
.btn-cta { background: var(--heat); color: var(--accent-white); border: 1px solid var(--heat); border-radius: var(--r-md); padding: 12px 14px; font-size: 14px; font-weight: 600; cursor: pointer; font-family: inherit; transition: box-shadow var(--t-base), transform var(--t-base); display: inline-flex; align-items: center; justify-content: center; gap: 8px; }
.btn-cta:hover { box-shadow: 0 4px 14px rgba(250,93,25,.28); }
.btn-cta:active { transform: translateY(1px); }
.btn-cta svg { width: 15px; height: 15px; }
.divider { display: flex; align-items: center; gap: 10px; margin: 22px 0 18px; }
.divider .line { flex: 1; height: 1px; background: var(--border-faint); }
.divider .txt { font-family: var(--font-mono); font-size: 10.5px; color: var(--black-alpha-32); letter-spacing: .08em; text-transform: uppercase; }
.sso-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.sso-btn { background: var(--surface); border: 1px solid var(--border-faint); border-radius: var(--r-md); padding: 10px 12px; font-size: 12.5px; color: var(--accent-black); cursor: pointer; font-family: inherit; display: inline-flex; align-items: center; justify-content: center; gap: 8px; transition: border-color var(--t-base); }
.sso-btn:hover { border-color: var(--black-alpha-32); }
.sso-btn svg { width: 14px; height: 14px; }
.switch-row { margin-top: auto; padding-top: 28px; text-align: center; font-size: 12.5px; color: var(--black-alpha-56); }
.switch-row a { color: var(--heat); text-decoration: none; font-weight: 500; }
.switch-row a:hover { text-decoration: underline; }
/* 响应式 */
@media (max-width: 820px) {
.auth-wrap { grid-template-columns: 1fr; min-height: 0; }
.auth-brand { padding: 32px 28px; }
.auth-brand .ascii { display: none; }
.auth-form { padding: 32px 28px; }
}
/* 顶部小返回链(可选) */
.top-back { position: fixed; top: 20px; left: 24px; font-family: var(--font-mono); font-size: 11px; color: var(--black-alpha-48); text-decoration: none; letter-spacing: .04em; }
.top-back:hover { color: var(--heat); }
</style>
</head>
<body>
<a class="top-back" href="index.html">← 返回工作台</a>
<div class="auth-wrap">
<span class="corner-tr" aria-hidden></span><span class="corner-bl" aria-hidden></span>
<!-- 左:品牌 -->
<aside class="auth-brand">
<div class="logo">
<span class="ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2 L19 7 V17 L12 22 L5 17 V7 Z"/><path d="M12 2 V22"/><path d="M5 7 L19 17"/></svg></span>
<span>流·Studio</span>
</div>
<div class="tag">// SHORT-VIDEO COMMERCE PLATFORM</div>
<div class="hero">
<h1>AI 全流程<br><span class="h">短剧化</span>带货生成</h1>
<p>商品 → AI 脚本 → 故事板 → Seedance 视频片段 → 一键导出 9:16 ≤60s 成片。</p>
</div>
<div class="ascii">
<div class="ln"><span class="k">// step·1</span> &nbsp; 脚本生成 &nbsp; &nbsp; <span class="v">●●●●●</span></div>
<div class="ln"><span class="k">// step·2</span> &nbsp; 基础资产 &nbsp; &nbsp; <span class="v">●●●●○</span></div>
<div class="ln"><span class="k">// step·3</span> &nbsp; 故事板 &nbsp; &nbsp; &nbsp; <span class="v">●●●○○</span></div>
<div class="ln"><span class="k">// step·4</span> &nbsp; 视频片段 &nbsp; &nbsp; <span class="v">●●○○○</span></div>
<div class="ln"><span class="k">// step·5</span> &nbsp; 拼接导出 &nbsp; &nbsp; <span class="v">●○○○○</span></div>
</div>
<div class="foot">
<a href="#">关于</a>
<a href="#">定价</a>
<a href="#">联系</a>
<a href="#">隐私</a>
</div>
</aside>
<!-- 右:表单 -->
<main class="auth-form">
<div class="h-row">
<h2>登录</h2>
<span class="sub">// /auth/login</span>
</div>
<p class="lead">使用团队邀请邮箱登录,接受邀请后自动加入对应团队。</p>
<form id="login-form" autocomplete="off" onsubmit="event.preventDefault(); doLogin();">
<div class="field">
<label class="field-label" for="auth-email">邮箱 <span class="req">*</span></label>
<div class="field-input-wrap">
<svg class="ic-l" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z"/><path d="m22 6-10 7L2 6"/></svg>
<input type="email" id="auth-email" placeholder="name@company.com" value="li@shop.com" required>
</div>
</div>
<div class="field">
<label class="field-label" for="auth-pwd">密码 <span class="req">*</span></label>
<div class="field-input-wrap">
<svg class="ic-l" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
<input type="password" id="auth-pwd" placeholder="••••••••" value="demo-1234" required>
<button type="button" class="toggle-pwd" aria-label="切换密码可见" onclick="togglePwd()">
<svg id="pwd-eye" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M2 12s4-7 10-7 10 7 10 7-4 7-10 7-10-7-10-7z"/><circle cx="12" cy="12" r="3"/></svg>
</button>
</div>
</div>
<div class="row-between">
<label><input type="checkbox" checked> 记住我 7 天</label>
<a href="#" onclick="event.preventDefault();alert('演示稿 · 真实流程为重置密码邮件');">忘记密码?</a>
</div>
<button class="btn-cta" type="submit">
登录
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
</button>
<div class="divider"><span class="line"></span><span class="txt">OR</span><span class="line"></span></div>
<div class="sso-row">
<button type="button" class="sso-btn" onclick="alert('演示稿 · 微信扫码登录占位');">
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M9 4C5 4 2 6.5 2 9.5c0 1.7 1 3.2 2.5 4.2L4 16l2.2-1.1c.7.2 1.5.3 2.3.3-.3-.5-.5-1.1-.5-1.7 0-2.8 2.9-5 6.5-5h.5C14.6 6 12 4 9 4zm-2 3.5c.6 0 1 .4 1 1s-.4 1-1 1-1-.4-1-1 .4-1 1-1zm4 0c.6 0 1 .4 1 1s-.4 1-1 1-1-.4-1-1 .4-1 1-1zM15 9c-3.3 0-6 2.2-6 5s2.7 5 6 5c.7 0 1.4-.1 2-.3L19 20l-.4-1.7c1.4-.9 2.4-2.3 2.4-3.8 0-2.8-2.7-5-6-5zm-2 2.5c.6 0 1 .4 1 1s-.4 1-1 1-1-.4-1-1 .4-1 1-1zm4 0c.6 0 1 .4 1 1s-.4 1-1 1-1-.4-1-1 .4-1 1-1z"/></svg>
微信扫码
</button>
<button type="button" class="sso-btn" onclick="alert('演示稿 · 飞书 SSO 占位');">
<svg viewBox="0 0 24 24" fill="currentColor"><rect x="3" y="3" width="18" height="18" rx="3"/></svg>
飞书 SSO
</button>
</div>
<div class="switch-row">
还没账号? <a href="register.html">注册团队 →</a>
</div>
</form>
</main>
</div>
<script>
function togglePwd() {
const inp = document.getElementById('auth-pwd');
inp.type = inp.type === 'password' ? 'text' : 'password';
}
function doLogin() {
const btn = document.querySelector('.btn-cta');
btn.innerHTML = '<span style="font-family:var(--font-mono);font-size:12px;letter-spacing:.04em;">// 验证中...</span>';
btn.disabled = true;
setTimeout(() => { location.href = 'index.html'; }, 700);
}
</script>
</body>
</html>