diff --git a/design-qa.md b/design-qa.md
index 01717f9..9f82a44 100644
--- a/design-qa.md
+++ b/design-qa.md
@@ -3,17 +3,17 @@
- Source visual truth: `docs/design/screens/A01-启动登录引导-栅格验收-412x915.png`
- Target state: `412 × 915`, agreement unchecked.
- Static contract: passed on 2026-07-13.
-- Runtime screenshot: first capture reviewed on 2026-07-13; second capture pending.
+- Runtime screenshot: first capture reviewed on 2026-07-13; second capture pending after the ornamental-asset calibration.
## Evidence
- The first `412 × 915` runtime capture confirms that the red-header height, divider width, both button frames and registration-entry height are close to the reference.
- The same capture shows the seal too high, title clouds too wide, both button content groups too far right, and an agreement row that is too wide and high.
-- The second calibration adds sub-element anchors for those differences; the whole-image layer, registration side lines and four-corner button brackets remain forbidden.
+- The second calibration replaces the incorrect shared cloud artwork with three dedicated transparent assets: button corner flourish, divider center knot and title-side cloud. It also aligns the agreement checkbox and copy on one non-wrapping center line.
## Remaining runtime evidence
-- [P1] Capture the unchecked A-01 page at `412 × 915` in HBuilderX or Android, without browser chrome, after the second calibration and compare it against the source at the same scale.
+- [P1] Capture the unchecked A-01 page at `412 × 915` in HBuilderX or Android, without browser chrome, after the ornamental-asset calibration and compare it against the source at the same scale.
- [P1] Capture `320 × 568` after scrolling to confirm the agreement row and safe area are not clipped.
- Confirm that selecting the agreement enables only the existing A-02 login route; the other entries remain local prepared-state prompts.
diff --git a/docs/design/A01_启动登录引导_设计记录.md b/docs/design/A01_启动登录引导_设计记录.md
index be96f74..a118c18 100644
--- a/docs/design/A01_启动登录引导_设计记录.md
+++ b/docs/design/A01_启动登录引导_设计记录.md
@@ -36,13 +36,13 @@
| 朱砂家祠头图 | 高 139px | 高 253rpx |
| 红头谱印 | 比头图顶边低约 38px | `top: 70rpx` |
| 标题区起点 | 红头后约 82px | `padding-top: 150rpx` |
-| 标题两侧云纹 | 紧贴标题两侧,不扩张标题组宽度 | `56rpx × 34rpx`,标题左右各 12rpx |
-| 标题分隔饰线 | 宽约 234px | 宽 426rpx;上、下间距独立 |
+| 标题两侧云纹 | 紧贴标题两侧,不扩张标题组宽度 | 独立透明素材 `auth-title-cloud-v1.png`,`64rpx × 40rpx`,标题左右各 12rpx |
+| 标题分隔饰线 | 宽约 234px,中心为对称小结 | 宽 426rpx;中结使用独立透明素材 `auth-divider-knot-v1.png`,上、下间距独立 |
| 两个按钮 | x=60px,宽约 291px,高约 65px | `margin: 95rpx 110rpx 0`,高 118rpx |
| 两按钮间距 | 约 28px | `margin-top: 51rpx` |
-| 按钮内框与内容组 | 内框距外边约 3px;图标与文字整体偏左 | `inset: 6rpx`,内容组 `translateX(-20rpx)` |
+| 按钮内框与内容组 | 内框距外边约 3px,四角有卷草角花;图标与文字整体偏左 | `inset: 6rpx`;四角使用同一张 `auth-button-corner-v1.png` 镜像;内容组 `translateX(-20rpx)` |
| 注册入口 | 微信按钮后约 56px;无左右短线 | `margin-top: 98rpx` |
-| 协议行 | 注册入口后约 77px;文案不应撑宽整行 | `margin-top: 141rpx`,字号 20rpx,复选框 30rpx,加安全区 |
+| 协议行 | 注册入口后约 77px;复选框与全部文案同一水平线 | `margin-top: 141rpx`,字号与行高均为 20rpx / 30rpx,复选框 30rpx,`align-items: center`、`white-space: nowrap`,加安全区 |
- 上表是 A-01 运行时布局数值的唯一所有者。320 × 568 时页面允许纵向滚动,根容器不得以 `overflow: hidden` 截断协议行或系统安全区;底部内边距包含 `env(safe-area-inset-bottom)`。
- 仅作静态设计验证,不代表 uni-app 运行时验收;页面实现后仍须在 Android 320 × 568、360 × 640、360 × 800、412 × 915 上重新验收。
@@ -62,6 +62,9 @@
| `docs/design/screens/A01-启动登录引导-效果稿-v3-文字注册入口.png` | A-01 视觉比对依据 | 已归档并由用户确认的 v3 效果稿 | `852 × 1846px` PNG;仅作真实 DOM 页面还原和运行时验收对照,不直接作为页面内容 |
| `static/assets/backgrounds/auth-ancestral-header-v1.png`、`auth-rice-paper-v1.jpg`、`auth-ink-scenery-v1.png` | A-01 分层页面背景 | 2026-07-13 内置图像生成 | 当前 A-01 使用;不得复用 G-01 背景 |
| `static/assets/icons/auth/login-outline-v1.png`、`static/assets/icons/auth/wechat-licensed-v1.png` | A-01 两个按钮图标 | 登录图标复用项目既有资产;微信图标来源与许可见旧记录 | 当前 A-01 使用;微信图标免费使用须在应用“关于/设置”及应用商店描述中保留 Icons8 署名链接 |
+| `static/assets/icons/auth/auth-button-corner-v1.png` | 两个入口按钮的四角卷草装饰 | 2026-07-13 根据 412 × 915 视觉基准生成,去绿幕后保存 | `160 × 160px` 透明 PNG;同一张素材镜像至四角 |
+| `static/assets/icons/auth/auth-divider-knot-v1.png` | 标题上下金线的中心对称中结 | 2026-07-13 根据 412 × 915 视觉基准生成,去绿幕后保存 | `160 × 96px` 透明 PNG;不得改用长祥云 |
+| `static/assets/icons/auth/auth-title-cloud-v1.png` | “家谱”标题左右祥云 | 2026-07-13 根据 412 × 915 视觉基准生成,去绿幕后保存 | `200 × 120px` 透明 PNG;右侧只允许镜像该素材 |
## 4. 静态设计验收与剩余缺口
@@ -70,7 +73,7 @@
- 此结论只验证设计稿与固定栅格,不替代 uni-app 页面实现后的 Android 运行时验收。
- 仍未确定《家谱用户协议》与《隐私政策》的最终页面去向及返回路径;在这两页完成设计前,A-01 不得标记为完整设计完成。
- 页面实现阶段仍须按本记录在 Android 实机或同等运行环境复核四个尺寸的安全区、滚动与文字折行。
-- 2026-07-13 已按 412 × 915 参考图完成第一轮真实 DOM 校准;运行时截图显示容器位置已接近基准,但红头谱印、标题云纹、按钮内容组和协议行仍有子元素偏差,已进入第二轮校准。未取得第二轮同尺寸截图确认前不得标记 A-01 完成。
+- 2026-07-13 已按 412 × 915 参考图完成第二轮子元素校准:已补齐按钮四角透明角花、分隔线中心中结、标题独立祥云,并将协议复选框与文案改为单行居中对齐。未取得第二轮同尺寸运行时截图确认前不得标记 A-01 完成。
## 5. 推进约束
diff --git a/pages/auth/entry.vue b/pages/auth/entry.vue
index 0e4166d..b32b4c7 100644
--- a/pages/auth/entry.vue
+++ b/pages/auth/entry.vue
@@ -11,25 +11,29 @@
-
+
家谱
-
+
-
+
为家族留存可传承的记忆
-
+
+
+
+
+
登录
@@ -37,6 +41,10 @@
+
+
+
+
微信登录
@@ -170,10 +178,7 @@ const prepareAgreement = () => {
line-height: 1;
}
-.title-cloud {
- width: 56rpx;
- height: 34rpx;
-}
+.title-cloud { width: 64rpx; height: 40rpx; }
.title-cloud-left { margin-right: 0; }
.title-cloud-right { margin-left: 0; transform: scaleX(-1); }
@@ -233,8 +238,22 @@ const prepareAgreement = () => {
border-radius: 2rpx;
content: '';
pointer-events: none;
+ z-index: 1;
}
+.button-corner-asset {
+ position: absolute;
+ z-index: 2;
+ width: 54rpx;
+ height: 54rpx;
+ pointer-events: none;
+}
+
+.button-corner-asset--top-left { top: 4rpx; left: 4rpx; }
+.button-corner-asset--top-right { top: 4rpx; right: 4rpx; transform: scaleX(-1); }
+.button-corner-asset--bottom-left { bottom: 4rpx; left: 4rpx; transform: scaleY(-1); }
+.button-corner-asset--bottom-right { right: 4rpx; bottom: 4rpx; transform: scale(-1); }
+
.entry-button--primary {
border-color: #9e170e;
background: #b7170d;
@@ -259,7 +278,7 @@ const prepareAgreement = () => {
.entry-button--primary .entry-button__icon { filter: brightness(0) invert(1); }
.entry-button__content {
position: relative;
- z-index: 1;
+ z-index: 3;
display: flex;
align-items: center;
transform: translateX(-20rpx);
@@ -284,13 +303,13 @@ const prepareAgreement = () => {
.agreement-row {
display: flex;
- align-items: flex-start;
+ align-items: center;
justify-content: center;
margin-top: 141rpx;
padding: 0 44rpx calc(32rpx + env(safe-area-inset-bottom));
color: #6b5a4a;
font-size: 20rpx;
- line-height: 1.7;
+ line-height: 30rpx;
}
.agreement-check {
@@ -301,7 +320,7 @@ const prepareAgreement = () => {
box-sizing: border-box;
width: 30rpx;
height: 30rpx;
- margin: 7rpx 12rpx 0 0;
+ margin: 0 12rpx 0 0;
border: 2rpx solid #b88d4b;
border-radius: 50%;
color: #fffaf0;
@@ -310,6 +329,12 @@ const prepareAgreement = () => {
}
.agreement-check.checked { background: #b7170d; border-color: #b7170d; }
-.agreement-copy { text-align: center; }
+.agreement-copy {
+ display: flex;
+ align-items: center;
+ line-height: 30rpx;
+ text-align: center;
+ white-space: nowrap;
+}
.agreement-link { color: #b7170d; }
diff --git a/static/assets/icons/auth/auth-button-corner-v1.png b/static/assets/icons/auth/auth-button-corner-v1.png
new file mode 100644
index 0000000..e302088
Binary files /dev/null and b/static/assets/icons/auth/auth-button-corner-v1.png differ
diff --git a/static/assets/icons/auth/auth-divider-knot-v1.png b/static/assets/icons/auth/auth-divider-knot-v1.png
new file mode 100644
index 0000000..8c7774e
Binary files /dev/null and b/static/assets/icons/auth/auth-divider-knot-v1.png differ
diff --git a/static/assets/icons/auth/auth-title-cloud-v1.png b/static/assets/icons/auth/auth-title-cloud-v1.png
new file mode 100644
index 0000000..a93f82e
Binary files /dev/null and b/static/assets/icons/auth/auth-title-cloud-v1.png differ
diff --git a/tests/a01-a02-ui-contract.ps1 b/tests/a01-a02-ui-contract.ps1
index b787331..825850c 100644
--- a/tests/a01-a02-ui-contract.ps1
+++ b/tests/a01-a02-ui-contract.ps1
@@ -88,25 +88,43 @@ foreach ($requiredVisualAnchor in @(
'margin-top: 98rpx',
'margin-top: 141rpx',
'top: 70rpx',
- 'width: 56rpx',
+ 'width: 64rpx',
'inset: 6rpx',
'entry-button__content',
'translateX(-20rpx)',
+ 'auth-button-corner-v1.png',
+ 'auth-divider-knot-v1.png',
+ 'auth-title-cloud-v1.png',
+ 'button-corner-asset',
+ 'align-items: center',
+ 'white-space: nowrap',
'font-size: 20rpx',
'width: 30rpx',
'height: 30rpx'
)) {
Assert-Contains -Content $entry -Expected $requiredVisualAnchor -Message "Missing A-01 calibrated visual anchor: $requiredVisualAnchor"
}
-foreach ($rejectedVisualConstruction in @('link-line', 'button-corner', 'class="auth-button primary-button"')) {
+foreach ($rejectedVisualConstruction in @('link-line', 'button-corner--legacy', 'class="auth-button primary-button"')) {
Assert-NotContains -Content $entry -Unexpected $rejectedVisualConstruction -Message "A-01 retains rejected visual construction: $rejectedVisualConstruction"
}
foreach ($forbiddenClass in @('entryGuideVisual', 'guide-art', 'entry-hit', 'width: 750rpx', 'min-height: 1625rpx')) {
Assert-NotContains -Content $entry -Unexpected $forbiddenClass -Message "A-01 must not render the whole design image with $forbiddenClass"
}
-Assert-Contains -Content $entry -Expected '/static/assets/icons/action/create-cloud-v2.png' -Message 'A-01 title and divider must use the local auspicious-cloud asset'
+Assert-NotContains -Content $entry -Unexpected '/static/assets/icons/action/create-cloud-v2.png' -Message 'A-01 must not reuse the mismatched create-cloud asset for its title or divider ornaments'
Assert-Contains -Content $entry -Expected 'filter: brightness(0) invert(1)' -Message 'A-01 primary login icon must render in white'
Assert-NotContains -Content $entry -Unexpected $dividerGlyph -Message 'A-01 divider must not use a text glyph as ornament'
+if (([regex]::Matches($entry, 'button-corner-asset button-corner-asset--')).Count -ne 8) {
+ throw 'A-01 must render the generated ornamental corner asset in all four corners of both entry buttons'
+}
+if (([regex]::Matches($entry, 'auth-divider-knot-v1\.png')).Count -ne 2) {
+ throw 'A-01 must render the dedicated divider-knot asset above and below the subtitle'
+}
+if ($entry -notmatch '(?s)\.agreement-row\s*\{[^}]*align-items:\s*center') {
+ throw 'A-01 agreement checkbox and copy must align on one horizontal center line'
+}
+if ($entry -notmatch '(?s)\.agreement-copy\s*\{[^}]*white-space:\s*nowrap') {
+ throw 'A-01 agreement copy must remain on a single line'
+}
if ($entry -match '(?s)\.auth-page\s*\{[^}]*overflow\s*:\s*hidden') {
throw 'A-01 must allow vertical scrolling on small screens'
}
diff --git a/tests/a01-asset-alpha-audit.ps1 b/tests/a01-asset-alpha-audit.ps1
index d872d6d..6e710d6 100644
--- a/tests/a01-asset-alpha-audit.ps1
+++ b/tests/a01-asset-alpha-audit.ps1
@@ -10,7 +10,10 @@ $backgrounds = @(
)
$icons = @(
'static/assets/icons/auth/login-outline-v1.png',
- 'static/assets/icons/auth/wechat-licensed-v1.png'
+ 'static/assets/icons/auth/wechat-licensed-v1.png',
+ 'static/assets/icons/auth/auth-button-corner-v1.png',
+ 'static/assets/icons/auth/auth-divider-knot-v1.png',
+ 'static/assets/icons/auth/auth-title-cloud-v1.png'
)
foreach ($asset in $backgrounds + $icons) {
@@ -37,7 +40,13 @@ foreach ($asset in $icons) {
}
$bitmap.Dispose()
- if ($width -ne 96 -or $height -ne 96) { throw "$asset must be 96 x 96px." }
+ $expectedSize = switch ($asset) {
+ 'static/assets/icons/auth/auth-button-corner-v1.png' { @(160, 160) }
+ 'static/assets/icons/auth/auth-divider-knot-v1.png' { @(160, 96) }
+ 'static/assets/icons/auth/auth-title-cloud-v1.png' { @(200, 120) }
+ default { @(96, 96) }
+ }
+ if ($width -ne $expectedSize[0] -or $height -ne $expectedSize[1]) { throw "$asset must be $($expectedSize[0]) x $($expectedSize[1])px." }
if (($corners | Where-Object { $_ -ne 0 }).Count -ne 0) { throw "$asset has opaque outer corners." }
if ($visiblePixels -lt 80) { throw "$asset has no usable visible artwork." }
Write-Output "PASS $asset transparent corners and visible artwork"