fix: calibrate A01 entry visual layout

This commit is contained in:
rain
2026-07-13 15:35:16 +08:00
parent bd50f15d5c
commit f7d6d3cfb1
8 changed files with 139 additions and 129 deletions
+13 -29
View File
@@ -1,36 +1,20 @@
# A-01 v3 Visual QA
# A-01 Runtime Visual QA
- Source visual truth: `docs/design/screens/A01-启动登录引导-效果稿-v3-文字注册入口.png`
- Target viewport: `430 × 932`, unchecked agreement state.
- Implementation screenshot: unavailable.
- Source visual truth: `docs/design/screens/A01-启动登录引导-栅格验收-412x915.png`
- Target state: `412 × 915`, agreement unchecked.
- Static contract: passed on 2026-07-13.
- Runtime screenshot: pending.
## Evidence
- The selected source image was opened and measured at `852 × 1846px`; it corresponds exactly to the supplied target screen proportions.
- `pages/auth/entry.vue` 已恢复为真实 DOM、分层背景与独立按钮;整图视觉层方案已撤销。
- 现有截图分别对应整图方案之前和整图方案本身,均不能作为当前真实 DOM 版本的实现证据。
- `pages/auth/entry.vue` uses real DOM and local background assets; the whole-image page layer remains absent.
- The static contract verifies the calibrated header height, title spacing, divider width, button dimensions and all four vertical anchors.
- The rejected registration side lines and four-corner button brackets are forbidden by the contract.
## Findings
## Remaining runtime evidence
- [P1] Runtime comparison blocked.
- Location: `pages/auth/entry.vue` at `430 × 932`.
- Evidence: no post-change HBuilderX or Android screenshot is available.
- Impact: the真实 DOM 的宽度、间距、按钮比例和已勾选协议状态无法在目标运行时确认。
- Fix: refresh the A-01 page in HBuilderX at `430 × 932`, capture the unchecked state, then compare it with the source visual above.
- [P1] Capture the unchecked A-01 page at `412 × 915` in HBuilderX or Android, without browser chrome, 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.
## Required fidelity surfaces
- Fonts and typography: 真实 DOM 已实现;运行时渲染尚未截图。
- Spacing and layout rhythm: 真实 DOM 已实现;运行时尺寸尚未截图。
- Colors and visual tokens: 分层背景和红金按钮已实现;运行时尚未截图。
- Image quality and asset fidelity: 分层本地资产已使用;运行时清晰度和裁切尚未截图。
- Copy and content: 主入口为 `登录`;运行时渲染尚未截图。
## Implementation Checklist
1. Refresh A-01 in HBuilderX at `430 × 932` with the agreement unchecked.
2. Capture the screen without surrounding browser chrome.
3. Compare the complete source and the runtime capture at the same scale.
4. Tap the agreement circle once and confirm that only then can the login region navigate to A-02.
final result: blocked
final result: runtime evidence pending
@@ -8,7 +8,8 @@
- 文件:[`screens/A01-启动登录引导-效果稿-v1-显式协议.png`](screens/A01-启动登录引导-效果稿-v1-显式协议.png)
- 效果稿 v2[`screens/A01-启动登录引导-效果稿-v2-独立注册.png`](screens/A01-启动登录引导-效果稿-v2-独立注册.png),记录此前“四个独立按钮”的尝试;该入口结构已失效,不作当前方案依据。
- 当前效果稿 v3[`screens/A01-启动登录引导-效果稿-v3-文字注册入口.png`](screens/A01-启动登录引导-效果稿-v3-文字注册入口.png)体现本记录第 2 节的当前入口层级;效果稿 v3 仅作视觉比对依据,`pages/auth/entry.vue` 必须使用真实页面结构还原,不得将整张效果图作为页面内容
- 当前效果稿 v3[`screens/A01-启动登录引导-效果稿-v3-文字注册入口.png`](screens/A01-启动登录引导-效果稿-v3-文字注册入口.png)保留第 2 节的入口层级归档;它不再定义运行时像素坐标
- 当前运行时视觉基准:[`screens/A01-启动登录引导-栅格验收-412x915.png`](screens/A01-启动登录引导-栅格验收-412x915.png),用于 A-01 协议未勾选状态的同尺寸像素比对;`pages/auth/entry.vue` 必须使用真实页面结构还原,不得将整张效果图作为页面内容。
- 用途:保留本轮已确认的“家祠卷轴”欢迎页美术方向,不作为可直接还原的代码布局图,也不作为功能图标资产。
- 画面方向:朱砂家祠红头、暖宣纸主体、古金细线与云纹、墨褐标题、两侧淡墨建筑/竹影与底部山水。登录欢迎页后续必须使用独立的红头/宣纸背景组合,不复用 G01 的列表页大山水底图。
@@ -28,8 +29,19 @@
- A-01 只设计欢迎、入口与协议未勾选提示。账号密码与手机号验证码表单均归 `A-02`,微信授权结果归 `A-03`,注册归 `A-04`,忘记密码归 `A-05`
- A-01 正常态必须展示两个按钮、注册文字入口和未勾选协议;点击任一需要授权的入口但未勾选协议时,仅提示“请先阅读并同意相关协议”,不视为用户已同意。
- 页面根容器宽度必须为 100%,不可写死为 `750rpx` 或使用整张效果图。固定设计画布仍以 `750rpx` 为测量基准,运行时由真实 DOM 按当前屏宽响应式还原。
- 朱砂家祠头图高 244rpx;标题区在头图下方保留 196rpx 起始留白。操作区左右内边距 100rpx,主按钮高度 124rpx,微信按钮与主按钮间距 32rpx,主按钮文案固定为“登录”。
- 注册文字在微信按钮下方 70rpx;协议行在注册入口下方 160rpx,底部内边距包含 `env(safe-area-inset-bottom)`。320 × 568 时页面允许纵向滚动,根容器不得以 `overflow: hidden` 截断协议行或系统安全区。
#### 412 × 915 运行时校准表
| 元素 | 412 × 915 像素基准 | 750rpx 实现基准 |
| --- | --- | --- |
| 朱砂家祠头图 | 高 139px | 高 253rpx |
| 标题区起点 | 红头后约 82px | `padding-top: 150rpx` |
| 标题分隔饰线 | 宽约 234px | 宽 426rpx;上、下间距独立 |
| 两个按钮 | x=60px,宽约 291px,高约 65px | `margin: 95rpx 110rpx 0`,高 118rpx |
| 两按钮间距 | 约 28px | `margin-top: 51rpx` |
| 注册入口 | 微信按钮后约 56px;无左右短线 | `margin-top: 98rpx` |
| 协议行 | 注册入口后约 70px | `margin-top: 128rpx` 加安全区 |
- 上表是 A-01 运行时布局数值的唯一所有者。320 × 568 时页面允许纵向滚动,根容器不得以 `overflow: hidden` 截断协议行或系统安全区;底部内边距包含 `env(safe-area-inset-bottom)`
- 仅作静态设计验证,不代表 uni-app 运行时验收;页面实现后仍须在 Android 320 × 568、360 × 640、360 × 800、412 × 915 上重新验收。
| 状态 | 触发 | A-01 可见结果 | 去向 |
@@ -50,11 +62,12 @@
## 4. 静态设计验收与剩余缺口
- 静态设计验收已覆盖 320 × 568、360 × 640、360 × 800、412 × 915;四个尺寸均保持两个大按钮与单行文字注册入口。A-01 本地页以真实 DOM 还原 v3 的层级和比例,运行时仍须截图对比,不得以整图页面替代。
- 静态设计验收已覆盖 320 × 568、360 × 640、360 × 800、412 × 915;四个尺寸均保持两个大按钮与单行文字注册入口。`412 × 915` 图是 A-01 协议未勾选状态的运行时像素基准;A-01 本地页以真实 DOM 还原层级和比例,运行时仍须截图对比,不得以整图页面替代。
- 归档文件:[320 × 568](screens/A01-启动登录引导-栅格验收-320x568.png)、[360 × 640](screens/A01-启动登录引导-栅格验收-360x640.png)、[360 × 800](screens/A01-启动登录引导-栅格验收-360x800.png)、[412 × 915](screens/A01-启动登录引导-栅格验收-412x915.png)。
- 此结论只验证设计稿与固定栅格,不替代 uni-app 页面实现后的 Android 运行时验收。
- 仍未确定《家谱用户协议》与《隐私政策》的最终页面去向及返回路径;在这两页完成设计前,A-01 不得标记为完整设计完成。
- 页面实现阶段仍须按本记录在 Android 实机或同等运行环境复核四个尺寸的安全区、滚动与文字折行。
- 2026-07-13 已按 412 × 915 参考图重新校准真实 DOM 的标题区、分隔饰线、双按钮、注册入口与协议行;静态合同通过,但仍须由同尺寸 HBuilderX 或 Android 截图叠图确认,未确认前不得标记 A-01 完成。
## 5. 推进约束
@@ -16,7 +16,7 @@
- 使用现有 `static/assets/backgrounds/auth-ancestral-header-v1.png``auth-rice-paper-v1.jpg``auth-ink-scenery-v1.png` 作为独立认证页背景;使用 `login-outline-v1.png``wechat-licensed-v1.png` 作为本地图标。
- 顺序固定为:朱砂家祠头图、标题“家谱”、副标题“为家族留存可传承的记忆”、朱砂主按钮“登录”、描边按钮“微信登录”、单行文字“还没有账号?注册账号”、未勾选协议行。
- 页面遵循 A-01 记录中的 750rpx 栅格、638rpx 内容宽度、108rpx 按钮高和安全区规则
- A-01 的运行时布局唯一遵循 `docs/design/A01_启动登录引导_设计记录.md` 中的“412 × 915 运行时校准表”;本文件不再重复或定义按钮与间距数值
## A-02 双标签登录页
@@ -4,29 +4,15 @@
`docs/design/screens/A01-启动登录引导-栅格验收-412x915.png` 的协议未勾选状态作为唯一视觉基准,把 `pages/auth/entry.vue` 的真实 DOM 校准到同一比例。此次只修正标题区、两条分隔饰线、双按钮、注册入口和协议行;现有认证背景图不在本次视觉校准范围内,接口、路由和 A-02 均不变。
## 基准坐标
## Contract ownership
以下为 412 x 915 设计图的可见边界;实现按 `750rpx / 412px` 换算并保持纵向流式滚动。
| 元素 | 设计图像素 | 750rpx 基准 | 实现约束 |
| --- | --- | --- | --- |
| 朱砂家祠头图 | y=0, h=139 | h≈253rpx | 头图与印章作为独立层,不能用页面留白补高度。 |
| 标题字面 | y≈222286 | y≈404521rpx | 标题区从红头后开始独立校准,不能沿用 196rpx 的未验证留白。 |
| 上分隔饰线 | x≈89323, y≈316 | x≈162588rpx, y≈575rpx | 使用与图一致的小型居中金饰;上、下分隔线分别控制间距。 |
| 副标题 | y≈345366 | y≈628666rpx | 保持单行、居中。 |
| 下分隔饰线 | x≈89323, y≈385 | x≈162588rpx, y≈701rpx | 不能复用上分隔线的通用外边距。 |
| 登录按钮 | x≈60, y≈463, w≈291, h≈65 | x≈109, y≈843, w≈530, h≈118 | 朱砂实底、细金内外框和小角饰均以参考图为准。 |
| 微信登录按钮 | x≈60, y≈555, w≈291, h≈65 | x≈109, y≈1,010, w≈530, h≈118 | 宣纸底、细金框,和主按钮保持相同外框尺寸。 |
| 注册入口 | y≈675 | y≈1,229rpx | 不加左右装饰短线。 |
| 协议行 | y≈767 | y≈1,397rpx | 保留安全区和小屏滚动能力。 |
坐标以图像可见内容为准,边缘抗锯齿可允许约 2px 误差;最终仍以同尺寸运行截图叠图确认。
`docs/design/A01_启动登录引导_设计记录.md` owns the calibrated 412 × 915 coordinate table and acceptance thresholds. This implementation specification records scope and component strategy only; it does not define duplicate layout values.
## 组件策略
- 页面继续使用真实 DOM 与现有本地认证背景,不使用整图作为页面内容。
- 标题两侧云纹和分隔线中心饰物拆成各自的语义元素;不能再把 `create-cloud-v2.png` 同时用作两类饰物
- 两个按钮共享尺寸,不共享未经校准的通用“方括号”角饰直线边框由 CSS 承担;可见角饰必须使用与参考图一致的透明 PNG 资产
- 标题两侧云纹和标题分隔线中心饰物保持独立语义元素;注册链接不得增加设计图中不存在的左右短线
- 两个按钮共享经过校准的外框尺寸,不使用通用“方括号”角饰直线边框由 scoped CSS 承担。
- 登录图标保持白色、微信图标保持其许可的原色;按钮文字按参考图缩小并移除全局通用按钮样式造成的额外字重或圆角干扰。
- 视觉常量只定义在 `pages/auth/entry.vue` 的 A-01 样式中;旧的 A-01 实现合同中互相冲突的 `638rpx/108rpx` 说明不再作为运行时布局依据。
+2 -2
View File
@@ -101,10 +101,10 @@ powershell -ExecutionPolicy Bypass -File tests\vue3-entry.ps1
## 9. 2026-07-13 流程纠正记录
- A-01 的历史效果稿 v1、v2 与当前效果稿 v3 均已归档;当前入口依据为 `docs/design/screens/A01-启动登录引导-效果稿-v3-文字注册入口.png`,对应说明见 `docs/design/A01_启动登录引导_设计记录.md`
- A-01 的历史效果稿 v1、v2、v3 与四尺寸栅格稿均已归档;当前协议未勾选状态的运行时视觉依据为 `docs/design/screens/A01-启动登录引导-栅格验收-412x915.png`,对应说明见 `docs/design/A01_启动登录引导_设计记录.md`
- A-01 的固定栅格、状态、独立背景/图标及 320 × 568、360 × 640、360 × 800、412 × 915 静态效果稿已归档并经审计;它们仍不替代 uni-app 页面实现后的 Android 运行时验收。
- 先前误建的 A-01 规格和“四个独立按钮”执行计划已降为失效历史;2026-07-13 已确认文字注册入口方案,唯一需求所有者为 `docs/design/A01_启动登录引导_设计记录.md`。用户随后授权 A-01 欢迎入口与 A-02 双标签登录页的本地 UI 落地;不得接接口、执行真实登录或替其他未设计页面造功能。
- 所有后续页面效果图必须先保存到 `docs/design/screens/`,并在对应页面设计记录写明用途、状态和验收缺口;未完成归档不得展示为可推进的设计成果。
- G-01 已于 2026-07-13 经用户确认结项;当前进入 D2 / A-01 的设计工作,接口、真实登录和 Android 打包仍暂停。
- A-01 入口页与 A-02 双标签登录页已于 2026-07-13 落地本地 UI:路由入口为 `pages/auth/entry`;只有在 A-01 显式勾选协议后才可进入 A-02。页面不调用接口、不写登录态、不跳转家谱;微信、注册、协议、忘记密码和验证码仅提示待相应页面或能力完成。A-01/A-02 运行时四尺寸验收仍待执行。
- A-01 首次本地预览与 v3 效果稿存在红头高度、按钮宽度和垂直节奏偏差。整图视觉层方案已被用户否决并撤销;现以真实 DOM、分层背景和按钮图标重建页面,下一次 Android 预览必须以 v3 截图作同尺寸对比。
- A-01 首次本地预览与 412 × 915 栅格验收图存在红头高度、按钮宽度和垂直节奏偏差。整图视觉层方案已被用户否决并撤销;现以真实 DOM、分层背景和按钮图标重建页面,下一次 Android 预览必须以图作同尺寸对比。
+69 -69
View File
@@ -11,30 +11,36 @@
<view class="brand-intro">
<view class="title-decoration">
<view class="cloud cloud-left" />
<image class="title-cloud title-cloud-left" src="/static/assets/icons/action/create-cloud-v2.png" mode="aspectFit" />
<text class="brand-title">家谱</text>
<view class="cloud cloud-right" />
<image class="title-cloud title-cloud-right" src="/static/assets/icons/action/create-cloud-v2.png" mode="aspectFit" />
</view>
<view class="brand-divider brand-divider--top">
<view class="brand-divider__line" />
<image class="brand-divider__ornament" src="/static/assets/icons/action/create-cloud-v2.png" mode="aspectFit" />
<view class="brand-divider__line" />
</view>
<view class="gold-divider"><view class="divider-knot"></view></view>
<text class="brand-subtitle">为家族留存可传承的记忆</text>
<view class="gold-divider"><view class="divider-knot"></view></view>
<view class="brand-divider brand-divider--bottom">
<view class="brand-divider__line" />
<image class="brand-divider__ornament" src="/static/assets/icons/action/create-cloud-v2.png" mode="aspectFit" />
<view class="brand-divider__line" />
</view>
</view>
<view class="entry-actions">
<view class="auth-button primary-button" hover-class="button-hover" @click="openLogin">
<image class="button-icon" src="/static/assets/icons/auth/login-outline-v1.png" mode="aspectFit" />
<view class="entry-button entry-button--primary" hover-class="entry-button--pressed" @click="openLogin">
<image class="entry-button__icon" src="/static/assets/icons/auth/login-outline-v1.png" mode="aspectFit" />
<text>登录</text>
</view>
<view class="auth-button secondary-button" hover-class="button-hover" @click="prepareWechatLogin">
<image class="button-icon wechat-icon" src="/static/assets/icons/auth/wechat-licensed-v1.png" mode="aspectFit" />
<view class="entry-button entry-button--secondary" hover-class="entry-button--pressed" @click="prepareWechatLogin">
<image class="entry-button__icon entry-button__icon--wechat" src="/static/assets/icons/auth/wechat-licensed-v1.png" mode="aspectFit" />
<text>微信登录</text>
</view>
<view class="register-link" hover-class="link-hover" @click="prepareRegister">
<view class="link-line" />
<text>还没有账号<text class="register-emphasis">注册账号</text></text>
<view class="link-line" />
</view>
</view>
@@ -118,7 +124,7 @@ const prepareAgreement = () => {
.auth-header {
position: relative;
height: 244rpx;
height: 253rpx;
overflow: hidden;
}
@@ -140,7 +146,7 @@ const prepareAgreement = () => {
display: flex;
flex-direction: column;
align-items: center;
padding: 196rpx 56rpx 0;
padding: 150rpx 56rpx 0;
color: #3f2c1d;
}
@@ -160,47 +166,34 @@ const prepareAgreement = () => {
line-height: 1;
}
.cloud {
position: relative;
width: 54rpx;
height: 24rpx;
border: 3rpx solid #dca34d;
border-top: 0;
border-radius: 0 0 26rpx 26rpx;
.title-cloud {
width: 76rpx;
height: 46rpx;
}
.cloud::before,
.cloud::after {
position: absolute;
bottom: -3rpx;
width: 22rpx;
height: 22rpx;
border: 3rpx solid #dca34d;
border-bottom: 0;
border-radius: 50% 50% 0 0;
content: '';
}
.title-cloud-left { margin-right: 10rpx; }
.title-cloud-right { margin-left: 10rpx; transform: scaleX(-1); }
.cloud::before { left: 5rpx; }
.cloud::after { right: 5rpx; }
.cloud-right { transform: scaleX(-1); }
.gold-divider {
.brand-divider {
display: flex;
align-items: center;
justify-content: center;
width: 430rpx;
width: 426rpx;
}
.brand-divider--top { margin: 47rpx 0 21rpx; }
.brand-divider--bottom { margin: 34rpx 0 30rpx; }
.brand-divider__line {
flex: 1;
height: 1rpx;
margin: 30rpx 0;
background: #d5a34f;
}
.divider-knot {
padding: 0 14rpx;
color: #d5a34f;
background: #f8f2e9;
font-size: 32rpx;
line-height: 1;
.brand-divider__ornament {
width: 44rpx;
height: 24rpx;
margin: 0 14rpx;
}
.brand-subtitle {
@@ -211,51 +204,65 @@ const prepareAgreement = () => {
}
.entry-actions {
margin: 130rpx 100rpx 0;
margin: 95rpx 110rpx 0;
}
.auth-button {
.entry-button {
position: relative;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
width: 100%;
height: 124rpx;
height: 118rpx;
border: 2rpx solid #d8ad63;
border-radius: 8rpx;
border-radius: 6rpx;
font-family: STKaiti, KaiTi, serif;
font-size: 42rpx;
letter-spacing: 5rpx;
font-size: 38rpx;
letter-spacing: 4rpx;
}
.primary-button {
.entry-button::after {
position: absolute;
inset: 10rpx;
border: 1rpx solid rgba(225, 180, 105, 0.92);
border-radius: 2rpx;
content: '';
pointer-events: none;
}
.entry-button--primary {
border-color: #9e170e;
background: #b7170d;
box-shadow: inset 0 0 0 4rpx #d69b5f;
color: #fffaf0;
}
.secondary-button {
margin-top: 32rpx;
.entry-button--primary::after { border-color: #edc67c; }
.entry-button--secondary {
margin-top: 51rpx;
background: rgba(255, 252, 245, 0.82);
box-shadow: inset 0 0 0 3rpx rgba(229, 190, 133, 0.45);
color: #60442f;
}
.button-icon {
width: 52rpx;
height: 52rpx;
margin-right: 24rpx;
.entry-button__icon {
position: relative;
z-index: 1;
width: 46rpx;
height: 46rpx;
margin-right: 18rpx;
}
.wechat-icon { width: 56rpx; }
.button-hover { opacity: 0.84; }
.entry-button__icon--wechat { width: 52rpx; }
.entry-button--primary .entry-button__icon { filter: brightness(0) invert(1); }
.entry-button > text { position: relative; z-index: 1; }
.entry-button--pressed { opacity: 0.84; }
.register-link {
display: flex;
align-items: center;
justify-content: center;
margin-top: 70rpx;
margin-top: 98rpx;
color: #60442f;
font-family: STKaiti, KaiTi, serif;
font-size: 30rpx;
@@ -265,20 +272,13 @@ const prepareAgreement = () => {
.register-emphasis { color: #b7170d; }
.link-line {
width: 58rpx;
height: 1rpx;
margin: 0 18rpx;
background: #d5a34f;
}
.link-hover { opacity: 0.65; }
.agreement-row {
display: flex;
align-items: flex-start;
justify-content: center;
margin-top: 160rpx;
margin-top: 128rpx;
padding: 0 44rpx calc(32rpx + env(safe-area-inset-bottom));
color: #6b5a4a;
font-size: 24rpx;
+23
View File
@@ -51,6 +51,7 @@ $wechatLogin = ConvertFrom-Utf8Base64 '5b6u5L+h55m75b2V'
$registerPrompt = ConvertFrom-Utf8Base64 '6L+Y5rKh5pyJ6LSm5Y+377yf'
$registerEntry = ConvertFrom-Utf8Base64 '5rOo5YaM6LSm5Y+3'
$loginEntry = ConvertFrom-Utf8Base64 '55m75b2V'
$dividerGlyph = ConvertFrom-Utf8Base64 '4oyY'
$agreementRequired = ConvertFrom-Utf8Base64 '6K+35YWI6ZiF6K+75bm25ZCM5oSP55u45YWz5Y2P6K6u'
$wechatPending = ConvertFrom-Utf8Base64 '5b6u5L+h55m75b2V5Yqf6IO95YeG5aSH5Lit'
$registerPending = ConvertFrom-Utf8Base64 '5rOo5YaM6aG16Z2i5YeG5aSH5Lit'
@@ -73,9 +74,31 @@ Assert-Contains -Content $entry -Expected "<text>$loginEntry</text>" -Message 'A
foreach ($requiredClass in @('auth-header', 'brand-intro', 'entry-actions', 'agreement-row')) {
Assert-Contains -Content $entry -Expected $requiredClass -Message "Missing A-01 page structure: $requiredClass"
}
foreach ($requiredVisualAnchor in @(
'brand-divider--top',
'brand-divider--bottom',
'entry-button--primary',
'entry-button--secondary',
'height: 253rpx',
'padding: 150rpx 56rpx 0',
'width: 426rpx',
'margin: 95rpx 110rpx 0',
'height: 118rpx',
'margin-top: 51rpx',
'margin-top: 98rpx',
'margin-top: 128rpx'
)) {
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"')) {
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-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 ($entry -match '(?s)\.auth-page\s*\{[^}]*overflow\s*:\s*hidden') {
throw 'A-01 must allow vertical scrolling on small screens'
}
+10 -6
View File
@@ -6,7 +6,7 @@ function ConvertFrom-Utf8Base64 {
}
$recordPath = ConvertFrom-Utf8Base64 'ZG9jcy9kZXNpZ24vQTAxX+WQr+WKqOeZu+W9leW8leWvvF/orr7orqHorrDlvZUubWQ='
$effect = ConvertFrom-Utf8Base64 'ZG9jcy9kZXNpZ24vc2NyZWVucy9BMDEt5ZCv5Yqo55m75b2V5byV5a+8LeaViOaenOeovy12My3mloflrZfms6jlhozlhaXlj6MucG5n'
$effect = Join-Path (Join-Path (Split-Path -Parent $recordPath) 'screens') (ConvertFrom-Utf8Base64 'QTAxLeWQr+WKqOeZu+W9leW8leWvvC3moIXmoLzpqozmlLYtNDEyeDkxNS5wbmc=')
$record = Get-Content -LiteralPath $recordPath -Raw -Encoding utf8
$rules = @(
(ConvertFrom-Utf8Base64 '55m75b2V'),
@@ -24,12 +24,16 @@ foreach ($rule in $rules) {
$layoutRules = @(
(ConvertFrom-Utf8Base64 '6aG16Z2i5qC55a655Zmo5a695bqm5b+F6aG75Li6IDEwMCU='),
(ConvertFrom-Utf8Base64 '5pyx56CC5a6256Wg5aS05Zu+6auYIDI0NHJweA=='),
(ConvertFrom-Utf8Base64 '5pON5L2c5Yy65bem5Y+z5YaF6L656LedIDEwMHJweA=='),
(ConvertFrom-Utf8Base64 '5Li75oyJ6ZKu6auY5bqmIDEyNHJweA=='),
(ConvertFrom-Utf8Base64 '5Y2P6K6u6KGM5Zyo5rOo5YaM5YWl5Y+j5LiL5pa5IDE2MHJweA=='),
(ConvertFrom-Utf8Base64 'NDEyIMOXIDkxNSDov5DooYzml7bmoKHlh4booag='),
(ConvertFrom-Utf8Base64 '5pyx56CC5a6256Wg5aS05Zu+IHwg6auYIDEzOXB4IHwg6auYIDI1M3JweA=='),
(ConvertFrom-Utf8Base64 'bWFyZ2luOiA5NXJweCAxMTBycHggMA=='),
(ConvertFrom-Utf8Base64 '6auYIDExOHJweA=='),
(ConvertFrom-Utf8Base64 'bWFyZ2luLXRvcDogNTFycHg='),
(ConvertFrom-Utf8Base64 '5peg5bem5Y+z55+t57q/'),
(ConvertFrom-Utf8Base64 'bWFyZ2luLXRvcDogOThycHg='),
(ConvertFrom-Utf8Base64 'bWFyZ2luLXRvcDogMTI4cnB4'),
(ConvertFrom-Utf8Base64 'ZW52KHNhZmUtYXJlYS1pbnNldC1ib3R0b20p'),
(ConvertFrom-Utf8Base64 '5pWI5p6c56i/IHYzIOS7heS9nOinhuinieavlOWvueS+neaNrg==')
(ConvertFrom-Utf8Base64 '5b2T5YmN6L+Q6KGM5pe26KeG6KeJ5Z+65YeG')
)
foreach ($rule in $layoutRules) {