auto-save 2026-05-15 16:33 (~4)
This commit is contained in:
@@ -1,12 +1,5 @@
|
||||
{
|
||||
"entries": [
|
||||
{
|
||||
"files_changed": 7,
|
||||
"hash": "3684917",
|
||||
"message": "auto-save 2026-05-14 01:05 (+4, ~3)",
|
||||
"ts": "2026-05-14T01:06:06+08:00",
|
||||
"type": "commit"
|
||||
},
|
||||
{
|
||||
"files_changed": 8,
|
||||
"hash": "4610ef8",
|
||||
@@ -3251,6 +3244,13 @@
|
||||
"type": "session-heartbeat",
|
||||
"message": "Codex 会话活跃 · 最近命令:codex · 1 项未提交变更 · 最近提交:auto-save 2026-05-15 16:22 (~1)",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-05-15T16:27:46+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-05-15 16:27 (~3)",
|
||||
"hash": "ecc5894",
|
||||
"files_changed": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -942,6 +942,16 @@ SubjectAsset {
|
||||
<h2>变更记录</h2>
|
||||
<p>这个记录不是 git log 的替代品。它记录“产品理解发生了什么变化、影响了哪些源码、你以后描述需求时该怎么说”。后续每次改功能都要补一条。</p>
|
||||
<div class="changelog">
|
||||
<article class="change">
|
||||
<header>
|
||||
<h3>2026-05-15 · 登录页角色视觉样式升级</h3>
|
||||
<span class="tag rose">UI</span>
|
||||
</header>
|
||||
<div class="body">
|
||||
<p><strong>改动:</strong>在保留四个几何角色结构的基础上,增加底座阴影、发光边、玻璃高光、内部面板和状态点,让角色更像 SKG 内容工作台里的小模块,而不是纯色几何块。</p>
|
||||
<p><strong>影响:</strong><code>web/components/login/animated-login-characters.tsx</code>、<code>web/app/globals.css</code>、<code>docs/source-analysis.html</code>。</p>
|
||||
</div>
|
||||
</article>
|
||||
<article class="change">
|
||||
<header>
|
||||
<h3>2026-05-15 · 登录页角色取消默认上下浮动</h3>
|
||||
|
||||
@@ -205,46 +205,104 @@
|
||||
transform: translateX(-50%) scale(0.74);
|
||||
transform-origin: bottom center;
|
||||
}
|
||||
.login-character-base {
|
||||
position: absolute;
|
||||
left: 28px;
|
||||
right: 18px;
|
||||
bottom: -12px;
|
||||
height: 28px;
|
||||
border-radius: 999px;
|
||||
background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.48), rgba(0, 0, 0, 0) 72%);
|
||||
filter: blur(1px);
|
||||
}
|
||||
.login-figure {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
transform-origin: bottom center;
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(255, 255, 255, 0.16);
|
||||
transition:
|
||||
transform 0.7s cubic-bezier(0.4, 0, 0.2, 1),
|
||||
height 0.55s cubic-bezier(0.4, 0, 0.2, 1),
|
||||
opacity 0.2s ease;
|
||||
will-change: transform;
|
||||
filter: drop-shadow(0 28px 34px rgba(0, 0, 0, 0.32));
|
||||
filter: drop-shadow(0 28px 34px rgba(0, 0, 0, 0.34));
|
||||
}
|
||||
.login-figure::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(105deg, rgba(255, 255, 255, 0.16), transparent 34%, rgba(0, 0, 0, 0.12));
|
||||
background:
|
||||
linear-gradient(105deg, rgba(255, 255, 255, 0.2), transparent 30%, rgba(0, 0, 0, 0.15)),
|
||||
linear-gradient(180deg, rgba(255, 255, 255, 0.06), transparent 28%);
|
||||
pointer-events: none;
|
||||
}
|
||||
.login-figure--purple {
|
||||
left: 70px;
|
||||
width: 180px;
|
||||
height: 400px;
|
||||
.login-figure__rim {
|
||||
position: absolute;
|
||||
inset: 8px;
|
||||
z-index: 1;
|
||||
background: #6c3ff5;
|
||||
border-radius: 0;
|
||||
border: 1px solid rgba(255, 255, 255, 0.16);
|
||||
border-radius: inherit;
|
||||
opacity: 0.85;
|
||||
pointer-events: none;
|
||||
}
|
||||
.login-figure__shine {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
left: 18%;
|
||||
top: 18%;
|
||||
width: 42%;
|
||||
height: 11%;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.22);
|
||||
transform: rotate(-14deg);
|
||||
pointer-events: none;
|
||||
}
|
||||
.login-figure__panel {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
border: 1px solid rgba(255, 255, 255, 0.13);
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
pointer-events: none;
|
||||
}
|
||||
.login-figure__signal {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
pointer-events: none;
|
||||
}
|
||||
.login-figure__signal span {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.56);
|
||||
box-shadow: 0 0 12px rgba(255, 255, 255, 0.24);
|
||||
}
|
||||
.login-figure--purple {
|
||||
left: 72px;
|
||||
width: 176px;
|
||||
height: 392px;
|
||||
z-index: 1;
|
||||
background: linear-gradient(165deg, #9b7bff 0%, #6c3ff5 46%, #3e1eb8 100%);
|
||||
border-radius: 22px 22px 8px 8px;
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.26);
|
||||
}
|
||||
.login-figure--black {
|
||||
left: 240px;
|
||||
width: 120px;
|
||||
height: 310px;
|
||||
z-index: 2;
|
||||
background: #2d2d2d;
|
||||
border-radius: 0;
|
||||
background: linear-gradient(165deg, #34343a 0%, #202126 48%, #111217 100%);
|
||||
border-radius: 18px 18px 6px 6px;
|
||||
border-color: rgba(170, 160, 255, 0.18);
|
||||
}
|
||||
.login-figure--orange {
|
||||
left: 0;
|
||||
width: 240px;
|
||||
height: 150px;
|
||||
z-index: 3;
|
||||
background: #ff9b6b;
|
||||
background: linear-gradient(160deg, #ffb27f 0%, #ff8f61 56%, #dc6f48 100%);
|
||||
border-radius: 120px 120px 0 0;
|
||||
}
|
||||
.login-figure--yellow {
|
||||
@@ -252,9 +310,66 @@
|
||||
width: 140px;
|
||||
height: 230px;
|
||||
z-index: 4;
|
||||
background: #e8d754;
|
||||
background: linear-gradient(160deg, #fff17a 0%, #e8d754 58%, #bfa73a 100%);
|
||||
border-radius: 70px 70px 0 0;
|
||||
}
|
||||
.login-figure--purple .login-figure__panel {
|
||||
left: 22px;
|
||||
bottom: 88px;
|
||||
width: 36px;
|
||||
height: 152px;
|
||||
border-radius: 999px;
|
||||
}
|
||||
.login-figure--purple .login-figure__signal {
|
||||
left: 26px;
|
||||
bottom: 46px;
|
||||
}
|
||||
.login-figure--black .login-figure__panel {
|
||||
right: 16px;
|
||||
bottom: 40px;
|
||||
width: 12px;
|
||||
height: 190px;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
.login-figure--black .login-figure__signal {
|
||||
right: 18px;
|
||||
top: 88px;
|
||||
flex-direction: column;
|
||||
}
|
||||
.login-figure--orange .login-figure__panel {
|
||||
left: 42px;
|
||||
bottom: 24px;
|
||||
width: 88px;
|
||||
height: 18px;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.16);
|
||||
}
|
||||
.login-figure--orange .login-figure__signal {
|
||||
right: 54px;
|
||||
bottom: 28px;
|
||||
}
|
||||
.login-figure--yellow .login-figure__panel {
|
||||
left: 24px;
|
||||
bottom: 44px;
|
||||
width: 92px;
|
||||
height: 24px;
|
||||
border-radius: 999px;
|
||||
background: rgba(45, 45, 45, 0.08);
|
||||
border-color: rgba(45, 45, 45, 0.12);
|
||||
}
|
||||
.login-figure--yellow .login-figure__shine {
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
.login-figure--yellow .login-figure__signal {
|
||||
left: 34px;
|
||||
top: 124px;
|
||||
}
|
||||
.login-figure--yellow .login-figure__signal span,
|
||||
.login-figure--orange .login-figure__signal span {
|
||||
background: rgba(45, 45, 45, 0.36);
|
||||
box-shadow: none;
|
||||
}
|
||||
.login-eyes {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
|
||||
@@ -8,13 +8,14 @@ type FigureSpec = {
|
||||
id: "purple" | "black" | "orange" | "yellow"
|
||||
eyeKind: EyeKind
|
||||
mouth?: "purple" | "orange" | "yellow"
|
||||
marks?: number
|
||||
}
|
||||
|
||||
const FIGURES: FigureSpec[] = [
|
||||
{ id: "purple", eyeKind: "eye", mouth: "purple" },
|
||||
{ id: "black", eyeKind: "small-eye" },
|
||||
{ id: "orange", eyeKind: "pupil", mouth: "orange" },
|
||||
{ id: "yellow", eyeKind: "pupil", mouth: "yellow" },
|
||||
{ id: "purple", eyeKind: "eye", mouth: "purple", marks: 3 },
|
||||
{ id: "black", eyeKind: "small-eye", marks: 2 },
|
||||
{ id: "orange", eyeKind: "pupil", mouth: "orange", marks: 2 },
|
||||
{ id: "yellow", eyeKind: "pupil", mouth: "yellow", marks: 3 },
|
||||
]
|
||||
|
||||
function Eyes({ figure, kind }: { figure: FigureSpec["id"]; kind: EyeKind }) {
|
||||
@@ -45,6 +46,14 @@ function Mouth({ type }: { type: NonNullable<FigureSpec["mouth"]> }) {
|
||||
function Figure({ spec }: { spec: FigureSpec }) {
|
||||
return (
|
||||
<div className={`login-figure login-figure--${spec.id}`}>
|
||||
<span className="login-figure__rim" />
|
||||
<span className="login-figure__shine" />
|
||||
<span className="login-figure__panel" />
|
||||
<span className="login-figure__signal">
|
||||
{Array.from({ length: spec.marks ?? 0 }).map((_, index) => (
|
||||
<span key={index} />
|
||||
))}
|
||||
</span>
|
||||
<Eyes figure={spec.id} kind={spec.eyeKind} />
|
||||
{spec.mouth ? <Mouth type={spec.mouth} /> : null}
|
||||
</div>
|
||||
@@ -72,6 +81,7 @@ export function AnimatedLoginCharacters({
|
||||
>
|
||||
<div className="login-stage-grid" />
|
||||
<div className="login-characters-container">
|
||||
<div className="login-character-base" />
|
||||
{FIGURES.map((spec) => (
|
||||
<Figure key={spec.id} spec={spec} />
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user