fix(auth): LoginView fidelity port from design zip

- Narrative: N (not 5) 个订阅, matching design intent
- Add '// 你的订阅,已经付过钱了' n-kicker above headline
- Port route-demo panel (POST /v1/chat/completions → pool → 200 OK)
- Port n-bottom live status bar (green dot + ai.puro.im operational)
- Replace ⬢ emoji with inline SVG hexagon (crisp at all sizes)

All Vue auth logic preserved: OAuth sections, Turnstile, 2FA modal,
forgot-password, form validation, v-model bindings.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
mini
2026-04-19 22:45:54 +08:00
parent 6291dc40d0
commit 046765632d

View File

@@ -2,10 +2,18 @@
<AuthLayout>
<template #narrative>
<div class="auth-narrative-inner">
<div class="brand"><span class="hex"></span><span>PURO AI</span></div>
<div class="auth-narrative-hero">
<div class="auth-narrative-headline">
<span class="num-5">5</span> 个订阅<br>
<router-link to="/" class="brand">
<svg viewBox="0 0 24 24" width="22" height="22" fill="none">
<path d="M12 2L21 7V17L12 22L3 17V7L12 2Z" stroke="currentColor" stroke-width="1.8" fill="rgba(34, 211, 238, 0.08)"/>
<path d="M12 7L17 9.5V14.5L12 17L7 14.5V9.5L12 7Z" fill="currentColor"/>
</svg>
<span>PURO AI</span>
</router-link>
<div>
<div class="n-kicker">// 你的订阅,已经付过钱了</div>
<div class="auth-narrative-headline" style="margin-top: 12px;">
<span class="num-n">N</span> 个订阅<br>
<span class="num-1">1</span> key
</div>
<p class="auth-narrative-sub">
@@ -14,7 +22,22 @@
<span class="auth-narrative-tagline">PURO纯粹 AI 调用回归本质</span>
</p>
</div>
<div class="auth-narrative-foot">Claude · ChatGPT · Codex · Gemini</div>
<div class="route-demo">
<div class="row"><span class="k">POST</span><span class="v">/v1/chat/completions</span></div>
<div class="row"><span class="k">model</span><span class="pill-inline">claude-sonnet-4-5</span></div>
<div class="row"><span class="k">route </span><span class="pill-inline amber">claude-pool-03</span></div>
<div class="row"><span class="k">status</span><span><span class="dot-g"></span><span style="color:var(--green)">200</span><span style="color:var(--text-3); margin:0 6px;">·</span>213ms<span style="color:var(--text-3); margin:0 6px;">·</span>42 tok</span></div>
</div>
<div class="auth-narrative-foot n-bottom">
<span>Claude</span><span class="sep">·</span>
<span>ChatGPT</span><span class="sep">·</span>
<span>Codex</span><span class="sep">·</span>
<span>Gemini</span>
<span class="sep">|</span>
<span class="live"><span class="dot"></span>ai.puro.im · operational</span>
</div>
</div>
</template>
@@ -464,15 +487,26 @@ function handle2FACancel(): void {
color: var(--text-0);
}
.brand {
display: flex;
display: inline-flex;
align-items: center;
gap: 8px;
gap: 10px;
font-weight: 700;
font-size: 18px;
font-size: 15px;
letter-spacing: -0.01em;
color: var(--text-0);
text-decoration: none;
}
.brand .hex {
.brand svg {
color: var(--cyan);
font-size: 24px;
flex-shrink: 0;
}
.n-kicker {
font-family: var(--font-mono);
font-size: 12px;
letter-spacing: 0.1em;
color: var(--cyan);
margin-bottom: 0;
}
.auth-narrative-headline {
@@ -482,7 +516,7 @@ function handle2FACancel(): void {
letter-spacing: -0.03em;
margin-bottom: 24px;
}
.auth-narrative-headline .num-5 { color: var(--amber); }
.auth-narrative-headline .num-n { color: var(--amber); }
.auth-narrative-headline .num-1 { color: var(--cyan); }
.auth-narrative-sub {
font-size: 15px;
@@ -495,9 +529,71 @@ function handle2FACancel(): void {
font-size: 12px;
color: var(--text-3);
}
/* Route demo panel */
.route-demo {
font-family: var(--font-mono);
font-size: 12px;
background: rgba(2, 6, 23, 0.6);
border: 1px solid var(--border);
border-radius: var(--r-md, 8px);
padding: 18px 22px;
max-width: 440px;
}
.route-demo .row {
display: flex;
gap: 20px;
padding: 4px 0;
align-items: center;
}
.route-demo .k { color: var(--text-3); min-width: 70px; }
.route-demo .v { color: var(--text-0); }
.route-demo .pill-inline {
padding: 2px 8px;
border-radius: 4px;
background: rgba(34, 211, 238, 0.08);
border: 1px solid rgba(34, 211, 238, 0.25);
color: var(--cyan);
}
.route-demo .pill-inline.amber {
background: rgba(251, 191, 36, 0.08);
border-color: rgba(251, 191, 36, 0.25);
color: var(--amber);
}
.route-demo .dot-g {
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--green);
display: inline-block;
margin-right: 6px;
box-shadow: 0 0 0 3px rgba(52, 211, 153, 0.15);
}
/* Bottom status bar */
.auth-narrative-foot {
font-size: 12px;
color: var(--text-3);
font-family: var(--font-mono);
}
.n-bottom {
display: flex;
gap: 14px;
align-items: center;
flex-wrap: wrap;
}
.n-bottom .sep { color: var(--border-2, rgba(255,255,255,0.12)); }
.n-bottom .live {
color: var(--green, #34d399);
display: inline-flex;
align-items: center;
gap: 6px;
}
.n-bottom .live .dot {
width: 5px;
height: 5px;
border-radius: 50%;
background: var(--green, #34d399);
box-shadow: 0 0 6px var(--green, #34d399);
}
</style>