From eced3d1e6ed92648ce353e8dac38c31e04045e8e Mon Sep 17 00:00:00 2001
From: rain <982766701@qq.com>
Date: Wed, 22 Jul 2026 07:41:27 +0800
Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=85=A8=E9=A1=B9=E7=9B=AE?=
=?UTF-8?q?=E5=93=8D=E5=BA=94=E5=BC=8F=E5=AE=A1=E6=A0=B8=E4=B8=8E=E6=8D=A2?=
=?UTF-8?q?=E6=9C=BA=E4=BA=A4=E6=8E=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
App.vue | 1 +
components/AppDialog.vue | 9 +-
components/AppTabbar.vue | 9 +-
components/GenealogyCard.vue | 15 +-
components/PageHeader.vue | 1 +
...ject-wide-audit-and-expert-optimization.md | 252 +++++++++
...whole-product-enrichment-implementation.md | 154 ++++++
...6-07-21-whole-product-enrichment-design.md | 171 ++++++
docs/交接记录.md | 2 +
docs/换机继续任务交接_2026-07-22.md | 304 +++++++++++
pages/auth/a04-register.vue | 7 +-
pages/auth/a05-reset-password.vue | 7 +-
pages/family/f02-publish-feed.vue | 2 +-
pages/family/f06-article-editor.vue | 1 +
pages/family/f09-media-upload.vue | 2 +
pages/family/f10-video-list.vue | 17 +-
pages/genealogy/g01-my-genealogies.vue | 27 +-
pages/genealogy/g03-create-genealogy.vue | 42 +-
pages/genealogy/g06-search-genealogies.vue | 23 +-
pages/genealogy/g10-application-review.vue | 29 +-
pages/genealogy/g11-genealogy-settings.vue | 1 -
pages/genealogy/g12-generation-poems.vue | 1 -
pages/profile/m04-change-password.vue | 13 +-
pages/records/r01-people-list.vue | 27 +-
pages/tree/t01-tree-overview.vue | 78 ++-
pages/tree/t03-member-profile.vue | 2 +-
pages/tree/t04-add-relative.vue | 2 +-
pages/tree/t05-edit-member.vue | 2 +-
pages/tree/t06-edit-relationship.vue | 2 +-
styles/adaptive-frame-profiles.scss | 1 +
styles/global.scss | 5 +
tests/a04-registration-contract.ps1 | 3 +-
tests/a05-reset-password-contract.ps1 | 3 +-
...app-dialog-responsive-content-contract.ps1 | 4 +-
tests/data-driven-layout-contract.ps1 | 1 +
tests/data-driven-layout-risk-allowlist.json | 507 +++++++++++++++++-
tests/document-flow-position-allowlist.json | 320 +++++------
tests/document-flow-position-contract.ps1 | 2 +-
tests/f01-document-flow-contract.ps1 | 15 +-
tests/f01-module-baseline-contract.ps1 | 6 +-
tests/f02-document-flow-contract.ps1 | 9 +-
tests/f06-article-editor-contract.ps1 | 9 +-
tests/f09-media-upload-contract.ps1 | 3 +
tests/f10-video-status-contract.ps1 | 8 +-
.../family-editors-document-flow-contract.ps1 | 7 +-
tests/fixed-navigation-position-contract.ps1 | 3 +
tests/foundation-asset-audit.ps1 | 3 +-
tests/g-series-app-loading-contract.ps1 | 2 +-
tests/g01-empty-state-contract.ps1 | 10 +-
tests/g01-error-state-contract.ps1 | 4 +-
tests/g03-create-flow-contract.ps1 | 4 +-
tests/g03-document-flow-contract.ps1 | 2 +-
tests/g05-all-states-visual-contract.ps1 | 4 +-
tests/g05-document-flow-contract.ps1 | 4 +-
tests/g06-document-flow-contract.ps1 | 6 +-
tests/g08-document-flow-contract.ps1 | 4 +-
tests/g09-document-flow-contract.ps1 | 2 +-
tests/g09-g10-business-state-contract.ps1 | 14 +-
tests/g11-document-flow-contract.ps1 | 10 +-
tests/g12-document-flow-contract.ps1 | 10 +-
tests/m01-module-baseline-contract.ps1 | 19 +-
tests/module-page-visual-contract.ps1 | 2 +-
tests/n01-module-baseline-contract.ps1 | 13 +-
tests/native-route-query-contract.ps1 | 29 +
tests/password-policy-contract.ps1 | 24 +
tests/password-policy-runtime-smoke.js | 19 +
tests/r01-document-flow-contract.ps1 | 18 +-
tests/r01-module-baseline-contract.ps1 | 6 +-
tests/r02-person-detail-contract.ps1 | 15 +-
tests/root-pages-visual-contract.ps1 | 8 +-
...red-interaction-accessibility-contract.ps1 | 12 +-
tests/t01-all-states-visual-contract.ps1 | 13 +-
tests/t01-tree-state-contract.ps1 | 13 +-
tests/t03-document-flow-contract.ps1 | 15 +-
...3-t08-business-specialization-contract.ps1 | 15 +
tests/t07-module-baseline-contract.ps1 | 8 +-
utils/validation.js | 13 +
77 files changed, 2052 insertions(+), 378 deletions(-)
create mode 100644 docs/superpowers/plans/2026-07-21-project-wide-audit-and-expert-optimization.md
create mode 100644 docs/superpowers/plans/2026-07-21-whole-product-enrichment-implementation.md
create mode 100644 docs/superpowers/specs/2026-07-21-whole-product-enrichment-design.md
create mode 100644 docs/换机继续任务交接_2026-07-22.md
create mode 100644 tests/native-route-query-contract.ps1
create mode 100644 tests/password-policy-contract.ps1
create mode 100644 tests/password-policy-runtime-smoke.js
create mode 100644 utils/validation.js
diff --git a/App.vue b/App.vue
index 91156d5..febd78f 100644
--- a/App.vue
+++ b/App.vue
@@ -7,5 +7,6 @@ export default {
diff --git a/components/AppDialog.vue b/components/AppDialog.vue
index be8fa61..d45649c 100644
--- a/components/AppDialog.vue
+++ b/components/AppDialog.vue
@@ -93,18 +93,23 @@ const cancel = () => {
align-items: center;
justify-content: center;
box-sizing: border-box;
- padding: 40rpx;
+ padding: calc(40rpx + env(safe-area-inset-top)) 40rpx calc(40rpx + env(safe-area-inset-bottom));
background: rgba(35, 18, 10, 0.62);
}
.app-dialog {
+ display: flex;
width: 650rpx;
max-width: 100%;
+ max-height: calc(var(--app-viewport-height, 100vh) - 80rpx - env(safe-area-inset-top) - env(safe-area-inset-bottom));
+ flex-direction: column;
+ overflow: hidden;
@include adaptive.adaptive-auth-dialog;
}
.app-dialog__content {
z-index: 1;
display: flex;
- max-height: calc(var(--app-viewport-height, 100vh) - 160rpx);
+ min-height: 0;
+ flex: 1;
flex-direction: column;
align-items: center;
box-sizing: border-box;
diff --git a/components/AppTabbar.vue b/components/AppTabbar.vue
index 639a1a9..5cd1440 100644
--- a/components/AppTabbar.vue
+++ b/components/AppTabbar.vue
@@ -1,10 +1,14 @@
-
+
{
padding: 4rpx 0;
box-sizing: border-box;
}
+.tab-item--pressed {
+ opacity: 0.72;
+}
.tab-icon {
width: 64rpx;
diff --git a/components/GenealogyCard.vue b/components/GenealogyCard.vue
index 6b1959a..ee2d638 100644
--- a/components/GenealogyCard.vue
+++ b/components/GenealogyCard.vue
@@ -3,6 +3,9 @@
')) {
$css = [regex]::Replace($styleMatch.Groups['css'].Value, '(?s)/\*.*?\*/', '')
+ $css = [regex]::Replace($css, '(?m)^\s*@(use|forward|import)\b[^;]+;\s*', '')
foreach ($rule in [regex]::Matches($css, '(?s)(?[^{}]+)\{(?[^{}]*)\}')) {
$selector = (($rule.Groups['selector'].Value -replace '(?s)^.*@media[^\{]*', '') -replace '\s+', ' ').Trim()
$body = $rule.Groups['body'].Value
diff --git a/tests/data-driven-layout-risk-allowlist.json b/tests/data-driven-layout-risk-allowlist.json
index a03caaa..64f706e 100644
--- a/tests/data-driven-layout-risk-allowlist.json
+++ b/tests/data-driven-layout-risk-allowlist.json
@@ -1 +1,506 @@
-[{"file":"components/AppLoading.vue","selector":".app-loading--page .app-loading__knot","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"components/AppLoading.vue","selector":".app-loading--page .app-loading__seal","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"components/AppLoading.vue","selector":".app-loading--section .app-loading__knot","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"components/AppLoading.vue","selector":".app-loading--section .app-loading__seal","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"components/AppTabbar.vue","selector":".app-tabbar","risk":"fixed-content-height","reason":"固定尺寸属于已审核的导航、操作触点或结构化节点视觉边界,不作为正文容量上限"},{"file":"components/AppTabbar.vue","selector":".tab-icon","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"components/GenealogyCard.vue","selector":".card-chevron","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"components/GenealogyCard.vue","selector":".card-meta-icon","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"components/GenealogyCard.vue","selector":".surname-seal","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"components/GenealogyCard.vue","selector":".surname-seal-copy","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"components/GenealogyPageBackground.vue","selector":".genealogy-page-background","risk":"clipping-overflow","reason":"裁切仅用于已审核背景、媒体缩略图或装饰资产的可视边界,不裁切正文数据"},{"file":"components/ModulePageBackground.vue","selector":".module-page-background","risk":"clipping-overflow","reason":"裁切仅用于已审核背景、媒体缩略图或装饰资产的可视边界,不裁切正文数据"},{"file":"components/PageHeader.vue","selector":".header-back","risk":"fixed-content-height","reason":"固定尺寸属于已审核的导航、操作触点或结构化节点视觉边界,不作为正文容量上限"},{"file":"components/PageHeader.vue","selector":".header-back__icon","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"components/PageHeader.vue","selector":".header-hall","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"components/PageHeader.vue","selector":".header-icon-button","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"components/PageHeader.vue","selector":".header-logo","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"components/PageHeader.vue","selector":".header-notice-icon","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"components/PageHeader.vue","selector":".header-title","risk":"clipping-overflow","reason":"裁切仅用于已审核背景、媒体缩略图或装饰资产的可视边界,不裁切正文数据"},{"file":"components/PageHeader.vue","selector":".header-title","risk":"single-line-truncation","reason":"标题来自固定路由文案,导航栏保留单行边界并由完整页面语义补足"},{"file":"components/PageHeader.vue","selector":".notice-dot","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"components/PageHeader.vue","selector":".page-header","risk":"fixed-content-height","reason":"固定尺寸属于已审核的导航、操作触点或结构化节点视觉边界,不作为正文容量上限"},{"file":"components/PageHeader.vue","selector":".page-header--root","risk":"clipping-overflow","reason":"裁切仅用于已审核背景、媒体缩略图或装饰资产的可视边界,不裁切正文数据"},{"file":"components/PageHeader.vue","selector":".page-header--root .header-logo","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"components/PageHeader.vue","selector":".page-header-slot","risk":"fixed-content-height","reason":"固定尺寸属于已审核的导航、操作触点或结构化节点视觉边界,不作为正文容量上限"},{"file":"pages/auth/a01-entry.vue","selector":".agreement-icon","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/auth/a01-entry.vue","selector":".brand-seal","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/auth/a01-entry.vue","selector":".divider-knot","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/auth/a01-entry.vue","selector":".divider-line","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/auth/a01-entry.vue","selector":".input-icon","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/auth/a01-entry.vue","selector":".login-tabs","risk":"fixed-content-height","reason":"固定尺寸属于已审核的导航、操作触点或结构化节点视觉边界,不作为正文容量上限"},{"file":"pages/auth/a01-entry.vue","selector":".other-login-divider","risk":"single-line-truncation","reason":"固定短分隔文案与两侧装饰线共同构成登录页分隔资产"},{"file":"pages/auth/a01-entry.vue","selector":".page-backdrop","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/auth/a01-entry.vue","selector":".password-toggle","risk":"fixed-content-height","reason":"固定尺寸属于已审核的导航、操作触点或结构化节点视觉边界,不作为正文容量上限"},{"file":"pages/auth/a01-entry.vue","selector":".password-toggle__icon","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/auth/a01-entry.vue","selector":".title-divider","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/auth/a01-entry.vue","selector":".wechat-icon","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/auth/a04-register.vue","selector":".agreement-icon","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/auth/a04-register.vue","selector":".back-button","risk":"fixed-content-height","reason":"固定尺寸属于已审核的导航、操作触点或结构化节点视觉边界,不作为正文容量上限"},{"file":"pages/auth/a04-register.vue","selector":".back-button__icon","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/auth/a04-register.vue","selector":".brand-seal","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/auth/a04-register.vue","selector":".page-backdrop","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/auth/a04-register.vue","selector":".register-divider","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/auth/a05-reset-password.vue","selector":".back-button","risk":"fixed-content-height","reason":"固定尺寸属于已审核的导航、操作触点或结构化节点视觉边界,不作为正文容量上限"},{"file":"pages/auth/a05-reset-password.vue","selector":".back-button__icon","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/auth/a05-reset-password.vue","selector":".brand-seal","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/auth/a05-reset-password.vue","selector":".page-backdrop","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/auth/a05-reset-password.vue","selector":".reset-divider","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/auth/a05-reset-password.vue","selector":".success-mark","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/auth/a06-auth-status.vue","selector":".back-button","risk":"fixed-content-height","reason":"固定尺寸属于已审核的导航、操作触点或结构化节点视觉边界,不作为正文容量上限"},{"file":"pages/auth/a06-auth-status.vue","selector":".back-button__icon","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/auth/a06-auth-status.vue","selector":".brand-seal","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/auth/a06-auth-status.vue","selector":".page-backdrop","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/auth/a06-auth-status.vue","selector":".status-divider","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/auth/a06-auth-status.vue","selector":".status-icon","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/family/f01-family-feed.vue","selector":".feed-shortcut","risk":"fixed-content-height","reason":"固定尺寸属于已审核的导航、操作触点或结构化节点视觉边界,不作为正文容量上限"},{"file":"pages/family/f08-album-detail.vue","selector":".album-photo-tile","risk":"clipping-overflow","reason":"裁切仅用于已审核背景、媒体缩略图或装饰资产的可视边界,不裁切正文数据"},{"file":"pages/family/f09-media-upload.vue","selector":".media-album-card__cover","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/family/f09-media-upload.vue","selector":".media-photo-editor__thumb","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/family/f09-media-upload.vue","selector":".media-photo-tile, .media-add-tile","risk":"clipping-overflow","reason":"裁切仅用于已审核背景、媒体缩略图或装饰资产的可视边界,不裁切正文数据"},{"file":"pages/genealogy/g01-my-genealogies.vue","selector":".add-dialog__close","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/genealogy/g01-my-genealogies.vue","selector":".add-dialog__close-icon","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/genealogy/g01-my-genealogies.vue","selector":".application-record__chevron","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/genealogy/g01-my-genealogies.vue","selector":".create-action .create-icon","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/genealogy/g01-my-genealogies.vue","selector":".create-cloud","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/genealogy/g01-my-genealogies.vue","selector":".create-icon","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/genealogy/g01-my-genealogies.vue","selector":".current-info-divider","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/genealogy/g01-my-genealogies.vue","selector":".current-meta-icon","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/genealogy/g01-my-genealogies.vue","selector":".current-seal","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/genealogy/g01-my-genealogies.vue","selector":".empty-divider","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/genealogy/g01-my-genealogies.vue","selector":".empty-seal","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/genealogy/g01-my-genealogies.vue","selector":".error-panel__divider","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/genealogy/g01-my-genealogies.vue","selector":".error-panel__seal","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/genealogy/g01-my-genealogies.vue","selector":".genealogy-index","risk":"clipping-overflow","reason":"该页面壳拥有明确的内部滚动区域,裁切只约束结构化视口而非列表内容容量"},{"file":"pages/genealogy/g01-my-genealogies.vue","selector":".genealogy-switcher__close","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/genealogy/g01-my-genealogies.vue","selector":".genealogy-switcher__close-icon","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/genealogy/g01-my-genealogies.vue","selector":".section-divider","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/genealogy/g01-my-genealogies.vue","selector":".section-heading::before","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/genealogy/g01-my-genealogies.vue","selector":".shortcut-icon","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/genealogy/g03-create-genealogy.vue","selector":".flow-header","risk":"clipping-overflow","reason":"裁切仅用于已审核背景、媒体缩略图或装饰资产的可视边界,不裁切正文数据"},{"file":"pages/genealogy/g03-create-genealogy.vue","selector":".flow-header","risk":"fixed-content-height","reason":"固定尺寸属于已审核的导航、操作触点或结构化节点视觉边界,不作为正文容量上限"},{"file":"pages/genealogy/g03-create-genealogy.vue","selector":".flow-header__back-icon","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/genealogy/g05-genealogy-overview.vue","selector":".overview-state__seal","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/genealogy/g06-search-genealogies.vue","selector":".search-divider","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/genealogy/g06-search-genealogies.vue","selector":".search-status__cloud","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/genealogy/g06-search-genealogies.vue","selector":".search-status__hall","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/genealogy/g06-search-genealogies.vue","selector":".search-title-strip","risk":"fixed-content-height","reason":"固定尺寸属于已审核的导航、操作触点或结构化节点视觉边界,不作为正文容量上限"},{"file":"pages/genealogy/g06-search-genealogies.vue","selector":".search-title-strip__seal","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/profile/m01-profile-home.vue","selector":".profile-hero__cloud","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/profile/m01-profile-home.vue","selector":".profile-hero__hall","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/profile/m01-profile-home.vue","selector":".profile-identity__seal","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/profile/m01-profile-home.vue","selector":".profile-menu__chevron","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/profile/m01-profile-home.vue","selector":".profile-menu__icon","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/profile/m01-profile-home.vue","selector":".profile-section-heading image","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"},{"file":"pages/tree/t01-tree-overview.vue","selector":".generation-band","risk":"fixed-content-height","reason":"固定尺寸属于已审核的导航、操作触点或结构化节点视觉边界,不作为正文容量上限"},{"file":"pages/tree/t01-tree-overview.vue","selector":".member-node","risk":"fixed-content-height","reason":"固定尺寸属于已审核的导航、操作触点或结构化节点视觉边界,不作为正文容量上限"},{"file":"pages/tree/t01-tree-overview.vue","selector":".member-node--selected","risk":"fixed-content-height","reason":"固定尺寸属于已审核的导航、操作触点或结构化节点视觉边界,不作为正文容量上限"},{"file":"pages/tree/t01-tree-overview.vue","selector":".tree-page","risk":"clipping-overflow","reason":"该页面壳拥有明确的内部滚动区域,裁切只约束结构化视口而非列表内容容量"},{"file":"pages/tree/t01-tree-overview.vue","selector":".tree-scroll","risk":"single-line-truncation","reason":"世系画布使用独立横向滚动所有权,nowrap 只维持结构化画布宽度"},{"file":"pages/tree/t03-member-profile.vue","selector":".member-heading__seal","risk":"fixed-content-height","reason":"固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"}]
\ No newline at end of file
+[
+ {
+ "file": "components/AppLoading.vue",
+ "selector": ".app-loading--page .app-loading__knot",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "components/AppLoading.vue",
+ "selector": ".app-loading--page .app-loading__seal",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "components/AppLoading.vue",
+ "selector": ".app-loading--section .app-loading__knot",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "components/AppLoading.vue",
+ "selector": ".app-loading--section .app-loading__seal",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "components/AppTabbar.vue",
+ "selector": ".tab-icon",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "components/GenealogyCard.vue",
+ "selector": ".card-chevron",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "components/GenealogyCard.vue",
+ "selector": ".card-meta-icon",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "components/GenealogyCard.vue",
+ "selector": ".surname-seal",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "components/GenealogyCard.vue",
+ "selector": ".surname-seal-copy",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "components/GenealogyPageBackground.vue",
+ "selector": ".genealogy-page-background",
+ "risk": "clipping-overflow",
+ "reason": "裁切仅用于已审核背景、媒体缩略图或装饰资产的可视边界,不裁切正文数据"
+ },
+ {
+ "file": "components/ModulePageBackground.vue",
+ "selector": ".module-page-background",
+ "risk": "clipping-overflow",
+ "reason": "裁切仅用于已审核背景、媒体缩略图或装饰资产的可视边界,不裁切正文数据"
+ },
+ {
+ "file": "components/PageHeader.vue",
+ "selector": ".header-back",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸属于已审核的导航、操作触点或结构化节点视觉边界,不作为正文容量上限"
+ },
+ {
+ "file": "components/PageHeader.vue",
+ "selector": ".header-back__icon",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "components/PageHeader.vue",
+ "selector": ".header-hall",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "components/PageHeader.vue",
+ "selector": ".header-icon-button",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "components/PageHeader.vue",
+ "selector": ".header-logo",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "components/PageHeader.vue",
+ "selector": ".header-notice-icon",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "components/PageHeader.vue",
+ "selector": ".header-title",
+ "risk": "clipping-overflow",
+ "reason": "裁切仅用于已审核背景、媒体缩略图或装饰资产的可视边界,不裁切正文数据"
+ },
+ {
+ "file": "components/PageHeader.vue",
+ "selector": ".header-title",
+ "risk": "single-line-truncation",
+ "reason": "标题来自固定路由文案,导航栏保留单行边界并由完整页面语义补足"
+ },
+ {
+ "file": "components/PageHeader.vue",
+ "selector": ".notice-dot",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "components/PageHeader.vue",
+ "selector": ".page-header--root",
+ "risk": "clipping-overflow",
+ "reason": "裁切仅用于已审核背景、媒体缩略图或装饰资产的可视边界,不裁切正文数据"
+ },
+ {
+ "file": "components/PageHeader.vue",
+ "selector": ".page-header--root .header-logo",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/auth/a01-entry.vue",
+ "selector": ".agreement-icon",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/auth/a01-entry.vue",
+ "selector": ".divider-knot",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/auth/a01-entry.vue",
+ "selector": ".divider-line",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/auth/a01-entry.vue",
+ "selector": ".input-icon",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/auth/a01-entry.vue",
+ "selector": ".other-login-divider",
+ "risk": "single-line-truncation",
+ "reason": "固定短分隔文案与两侧装饰线共同构成登录页分隔资产"
+ },
+ {
+ "file": "pages/auth/a01-entry.vue",
+ "selector": ".password-toggle__icon",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/auth/a01-entry.vue",
+ "selector": ".title-divider",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/auth/a01-entry.vue",
+ "selector": ".wechat-icon",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/auth/a04-register.vue",
+ "selector": ".agreement-icon",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/auth/a04-register.vue",
+ "selector": ".back-button__icon",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/auth/a04-register.vue",
+ "selector": ".register-divider",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/auth/a05-reset-password.vue",
+ "selector": ".back-button__icon",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/auth/a05-reset-password.vue",
+ "selector": ".reset-divider",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/auth/a05-reset-password.vue",
+ "selector": ".success-mark",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/auth/a06-auth-status.vue",
+ "selector": ".back-button__icon",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/auth/a06-auth-status.vue",
+ "selector": ".status-divider",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/auth/a06-auth-status.vue",
+ "selector": ".status-icon",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/family/f01-family-feed.vue",
+ "selector": ".feed-shortcut",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸属于已审核的导航、操作触点或结构化节点视觉边界,不作为正文容量上限"
+ },
+ {
+ "file": "pages/family/f08-album-detail.vue",
+ "selector": ".album-photo-tile",
+ "risk": "clipping-overflow",
+ "reason": "裁切仅用于已审核背景、媒体缩略图或装饰资产的可视边界,不裁切正文数据"
+ },
+ {
+ "file": "pages/family/f09-media-upload.vue",
+ "selector": ".media-album-card__cover",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/family/f09-media-upload.vue",
+ "selector": ".media-photo-editor__thumb",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/family/f09-media-upload.vue",
+ "selector": ".media-photo-tile, .media-add-tile",
+ "risk": "clipping-overflow",
+ "reason": "裁切仅用于已审核背景、媒体缩略图或装饰资产的可视边界,不裁切正文数据"
+ },
+ {
+ "file": "pages/genealogy/g01-my-genealogies.vue",
+ "selector": ".add-dialog__close",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/genealogy/g01-my-genealogies.vue",
+ "selector": ".add-dialog__close-icon",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/genealogy/g01-my-genealogies.vue",
+ "selector": ".application-record__chevron",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/genealogy/g01-my-genealogies.vue",
+ "selector": ".create-action .create-icon",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/genealogy/g01-my-genealogies.vue",
+ "selector": ".create-cloud",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/genealogy/g01-my-genealogies.vue",
+ "selector": ".create-icon",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/genealogy/g01-my-genealogies.vue",
+ "selector": ".current-info-divider",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/genealogy/g01-my-genealogies.vue",
+ "selector": ".current-meta-icon",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/genealogy/g01-my-genealogies.vue",
+ "selector": ".current-seal",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/genealogy/g01-my-genealogies.vue",
+ "selector": ".empty-divider",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/genealogy/g01-my-genealogies.vue",
+ "selector": ".empty-seal",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/genealogy/g01-my-genealogies.vue",
+ "selector": ".error-panel__divider",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/genealogy/g01-my-genealogies.vue",
+ "selector": ".error-panel__seal",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/genealogy/g01-my-genealogies.vue",
+ "selector": ".genealogy-switcher__close",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/genealogy/g01-my-genealogies.vue",
+ "selector": ".genealogy-switcher__close-icon",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/genealogy/g01-my-genealogies.vue",
+ "selector": ".section-divider",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/genealogy/g01-my-genealogies.vue",
+ "selector": ".section-heading::before",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/genealogy/g01-my-genealogies.vue",
+ "selector": ".shortcut-icon",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/genealogy/g05-genealogy-overview.vue",
+ "selector": ".overview-state__seal",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/genealogy/g06-search-genealogies.vue",
+ "selector": ".search-divider",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/genealogy/g06-search-genealogies.vue",
+ "selector": ".search-status__cloud",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/genealogy/g06-search-genealogies.vue",
+ "selector": ".search-status__hall",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/profile/m01-profile-home.vue",
+ "selector": ".profile-hero__cloud",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/profile/m01-profile-home.vue",
+ "selector": ".profile-hero__hall",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/profile/m01-profile-home.vue",
+ "selector": ".profile-identity__seal",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/profile/m01-profile-home.vue",
+ "selector": ".profile-menu__chevron",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/profile/m01-profile-home.vue",
+ "selector": ".profile-menu__icon",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/profile/m01-profile-home.vue",
+ "selector": ".profile-section-heading image",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "pages/tree/t01-tree-overview.vue",
+ "selector": ".generation-band",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸属于已审核的导航、操作触点或结构化节点视觉边界,不作为正文容量上限"
+ },
+ {
+ "file": "pages/tree/t01-tree-overview.vue",
+ "selector": ".member-node",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸属于已审核的导航、操作触点或结构化节点视觉边界,不作为正文容量上限"
+ },
+ {
+ "file": "pages/tree/t01-tree-overview.vue",
+ "selector": ".member-node--selected",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸属于已审核的导航、操作触点或结构化节点视觉边界,不作为正文容量上限"
+ },
+ {
+ "file": "pages/tree/t01-tree-overview.vue",
+ "selector": ".tree-page",
+ "risk": "clipping-overflow",
+ "reason": "该页面壳拥有明确的内部滚动区域,裁切只约束结构化视口而非列表内容容量"
+ },
+ {
+ "file": "pages/tree/t01-tree-overview.vue",
+ "selector": ".tree-scroll",
+ "risk": "single-line-truncation",
+ "reason": "世系画布使用独立横向滚动所有权,nowrap 只维持结构化画布宽度"
+ },
+ {
+ "file": "pages/tree/t03-member-profile.vue",
+ "selector": ".member-heading__seal",
+ "risk": "fixed-content-height",
+ "reason": "固定尺寸只约束已审核图标或装饰资产的画布,不承载可变正文数据"
+ },
+ {
+ "file": "components/AppButton.vue",
+ "selector": ".app-button--compact .app-button__label",
+ "risk": "single-line-truncation",
+ "reason": "紧凑按钮只承载组件调用方提供的短操作标签,单行约束保护固定操作触点"
+ },
+ {
+ "file": "components/AuthPageShell.vue",
+ "selector": ".auth-shell",
+ "risk": "clipping-overflow",
+ "reason": "登录壳仅裁切横向装饰溢出,纵向正文仍由页面自然增长"
+ },
+ {
+ "file": "components/AuthPageShell.vue",
+ "selector": ".auth-shell__header",
+ "risk": "clipping-overflow",
+ "reason": "顶部品牌区只裁切内部装饰图层,不裁切可变正文"
+ },
+ {
+ "file": "pages/genealogy/g01-my-genealogies.vue",
+ "selector": ".genealogy-index",
+ "risk": "clipping-overflow",
+ "reason": "页面壳拥有独立列表滚动区,裁切只约束结构化视口"
+ },
+ {
+ "file": "pages/genealogy/g09-my-applications.vue",
+ "selector": ".application-card__action",
+ "risk": "single-line-truncation",
+ "reason": "申请卡操作仅使用固定短标签,单行约束保护操作列宽"
+ },
+ {
+ "file": "components/AppDialog.vue",
+ "selector": ".app-dialog",
+ "risk": "clipping-overflow",
+ "reason": "弹窗外框只约束共享九宫格边界,正文容量由内部滚动区域完整承载"
+ }
+]
diff --git a/tests/document-flow-position-allowlist.json b/tests/document-flow-position-allowlist.json
index 578cd02..6f63132 100644
--- a/tests/document-flow-position-allowlist.json
+++ b/tests/document-flow-position-allowlist.json
@@ -1,157 +1,167 @@
[
- {
- "file": "components/AppDialog.vue",
- "selector": ".app-dialog-layer",
- "reason": "全屏弹窗遮罩"
- },
- {
- "file": "components/AppToast.vue",
- "selector": ".app-toast",
- "reason": "跨页面轻提示"
- },
- {
- "file": "components/PageHeader.vue",
- "selector": ".page-header",
- "reason": "用户指定的固定顶部导航栏"
- },
- {
- "file": "components/AppTabbar.vue",
- "selector": ".app-tabbar",
- "reason": "用户指定的固定底部导航栏"
- },
- {
- "file": "components/PageHeader.vue",
- "selector": ".header-texture",
- "reason": "固定顶部栏内部纯装饰纹理层"
- },
- {
- "file": "components/PageHeader.vue",
- "selector": ".header-hall",
- "reason": "固定顶部栏内部纯装饰祠堂层"
- },
- {
- "file": "components/GenealogyPageBackground.vue",
- "selector": ".genealogy-page-background",
- "reason": "不参与排版且覆盖视口的独立家谱背景层"
- },
- {
- "file": "components/GenealogyPageBackground.vue",
- "selector": ".genealogy-page-background__art",
- "reason": "独立家谱背景层内部的底部背景画面"
- },
- {
- "file": "components/ModulePageBackground.vue",
- "selector": ".module-page-background",
- "reason": "不参与排版且覆盖视口的独立模块背景层"
- },
- {
- "file": "components/ModulePageBackground.vue",
- "selector": ".module-page-background__image",
- "reason": "独立模块背景层内部的底部背景画面"
- },
- {
- "file": "pages/family/f08-album-detail.vue",
- "selector": ".album-photo-tile",
- "reason": "仅作为照片裁切层与底部说明叠层的精确局部边界"
- },
- {
- "file": "pages/family/f08-album-detail.vue",
- "selector": ".album-hero-photo, .album-photo-tile__image",
- "reason": "在固定比例照片格内执行裁切的媒体画面层"
- },
- {
- "file": "pages/family/f08-album-detail.vue",
- "selector": ".album-photo-tile__caption",
- "reason": "依附照片格底部的局部说明叠层"
- },
- {
- "file": "pages/family/f08-album-detail.vue",
- "selector": ".album-preview",
- "reason": "用户触发的全屏照片预览层"
- },
- {
- "file": "pages/family/f09-media-upload.vue",
- "selector": ".media-photo-tile",
- "reason": "仅作为照片缩略图角标与删除操作的精确局部边界"
- },
- {
- "file": "pages/family/f09-media-upload.vue",
- "selector": ".media-photo-order, .media-photo-current, .media-photo-status",
- "reason": "依附照片缩略图的顺序与状态角标"
- },
- {
- "file": "pages/family/f09-media-upload.vue",
- "selector": ".media-photo-remove",
- "reason": "依附照片缩略图右上角的删除操作"
- },
- {
- "file": "pages/tree/t01-tree-overview.vue",
- "selector": ".member-sheet",
- "reason": "用户选择节点后显示的固定底部详情抽屉"
- },
- {
- "file": "pages/tree/t01-tree-overview.vue",
- "selector": ".member-sheet__skin",
- "reason": "固定底部详情抽屉内部的装饰框层"
- },
- {
- "file": "pages/auth/a01-entry.vue",
- "selector": ".feedback-toast",
- "reason": "登录页面跨内容轻提示"
- },
- {
- "file": "pages/auth/a01-entry.vue",
- "selector": ".verification-layer",
- "reason": "用户触发的验证码弹窗遮罩"
- },
- {
- "file": "pages/auth/a04-register.vue",
- "selector": ".feedback-toast",
- "reason": "注册页面跨内容轻提示"
- },
- {
- "file": "pages/auth/a05-reset-password.vue",
- "selector": ".feedback-toast",
- "reason": "重置密码页面跨内容轻提示"
- },
- {
- "file": "pages/auth/a05-reset-password.vue",
- "selector": ".success-layer",
- "reason": "用户触发的重置成功弹窗遮罩"
- },
- {
- "file": "pages/auth/a06-auth-status.vue",
- "selector": ".recovery-layer",
- "reason": "用户触发的账号恢复弹窗遮罩"
- },
- {
- "file": "pages/genealogy/g01-my-genealogies.vue",
- "selector": ".add-dialog-layer",
- "reason": "用户触发的固定底部添加家谱弹层"
- },
- {
- "file": "pages/genealogy/g01-my-genealogies.vue",
- "selector": ".genealogy-switcher-layer",
- "reason": "用户触发的固定家谱切换弹窗遮罩"
- },
- {
- "file": "pages/genealogy/g10-application-review.vue",
- "selector": ".review-feedback",
- "reason": "审核操作后跨内容显示的固定轻提示"
- },
- {
- "file": "pages/genealogy/g03-create-genealogy.vue",
- "selector": ".duplicate-reminder-layer, .flow-success-layer",
- "reason": "用户触发的重复提醒与成功弹窗遮罩"
- },
- {
- "file": "pages/genealogy/g11-genealogy-settings.vue",
- "selector": ".settings-feedback",
- "reason": "保存设置后跨内容显示的固定轻提示"
- },
- {
- "file": "pages/genealogy/g12-generation-poems.vue",
- "selector": ".poem-feedback",
- "reason": "保存字辈后跨内容显示的固定轻提示"
- }
+ {
+ "file": "components/PageHeader.vue",
+ "selector": ".page-header",
+ "reason": "用户指定的固定顶部导航栏"
+ },
+ {
+ "file": "components/AppTabbar.vue",
+ "selector": ".app-tabbar",
+ "reason": "用户指定的固定底部导航栏"
+ },
+ {
+ "file": "components/PageHeader.vue",
+ "selector": ".header-texture",
+ "reason": "固定顶部栏内部纯装饰纹理层"
+ },
+ {
+ "file": "components/PageHeader.vue",
+ "selector": ".header-hall",
+ "reason": "固定顶部栏内部纯装饰祠堂层"
+ },
+ {
+ "file": "components/GenealogyPageBackground.vue",
+ "selector": ".genealogy-page-background",
+ "reason": "不参与排版且覆盖视口的独立家谱背景层"
+ },
+ {
+ "file": "components/GenealogyPageBackground.vue",
+ "selector": ".genealogy-page-background__art",
+ "reason": "独立家谱背景层内部的底部背景画面"
+ },
+ {
+ "file": "components/ModulePageBackground.vue",
+ "selector": ".module-page-background",
+ "reason": "不参与排版且覆盖视口的独立模块背景层"
+ },
+ {
+ "file": "components/ModulePageBackground.vue",
+ "selector": ".module-page-background__image",
+ "reason": "独立模块背景层内部的底部背景画面"
+ },
+ {
+ "file": "pages/family/f08-album-detail.vue",
+ "selector": ".album-photo-tile",
+ "reason": "仅作为照片裁切层与底部说明叠层的精确局部边界"
+ },
+ {
+ "file": "pages/family/f08-album-detail.vue",
+ "selector": ".album-hero-photo, .album-photo-tile__image",
+ "reason": "在固定比例照片格内执行裁切的媒体画面层"
+ },
+ {
+ "file": "pages/family/f08-album-detail.vue",
+ "selector": ".album-photo-tile__caption",
+ "reason": "依附照片格底部的局部说明叠层"
+ },
+ {
+ "file": "pages/family/f08-album-detail.vue",
+ "selector": ".album-preview",
+ "reason": "用户触发的全屏照片预览层"
+ },
+ {
+ "file": "pages/family/f09-media-upload.vue",
+ "selector": ".media-photo-tile",
+ "reason": "仅作为照片缩略图角标与删除操作的精确局部边界"
+ },
+ {
+ "file": "pages/family/f09-media-upload.vue",
+ "selector": ".media-photo-order, .media-photo-current, .media-photo-status",
+ "reason": "依附照片缩略图的顺序与状态角标"
+ },
+ {
+ "file": "pages/family/f09-media-upload.vue",
+ "selector": ".media-photo-remove",
+ "reason": "依附照片缩略图右上角的删除操作"
+ },
+ {
+ "file": "pages/tree/t01-tree-overview.vue",
+ "selector": ".member-sheet",
+ "reason": "用户选择节点后显示的固定底部详情抽屉"
+ },
+ {
+ "file": "pages/tree/t01-tree-overview.vue",
+ "selector": ".member-sheet__skin",
+ "reason": "固定底部详情抽屉内部的装饰框层"
+ },
+ {
+ "file": "pages/auth/a01-entry.vue",
+ "selector": ".feedback-toast",
+ "reason": "登录页面跨内容轻提示"
+ },
+ {
+ "file": "pages/auth/a01-entry.vue",
+ "selector": ".verification-layer",
+ "reason": "用户触发的验证码弹窗遮罩"
+ },
+ {
+ "file": "pages/auth/a04-register.vue",
+ "selector": ".feedback-toast",
+ "reason": "注册页面跨内容轻提示"
+ },
+ {
+ "file": "pages/auth/a05-reset-password.vue",
+ "selector": ".feedback-toast",
+ "reason": "重置密码页面跨内容轻提示"
+ },
+ {
+ "file": "pages/auth/a05-reset-password.vue",
+ "selector": ".success-layer",
+ "reason": "用户触发的重置成功弹窗遮罩"
+ },
+ {
+ "file": "pages/auth/a06-auth-status.vue",
+ "selector": ".recovery-layer",
+ "reason": "用户触发的账号恢复弹窗遮罩"
+ },
+ {
+ "file": "pages/genealogy/g01-my-genealogies.vue",
+ "selector": ".add-dialog-layer",
+ "reason": "用户触发的固定底部添加家谱弹层"
+ },
+ {
+ "file": "pages/genealogy/g01-my-genealogies.vue",
+ "selector": ".genealogy-switcher-layer",
+ "reason": "用户触发的固定家谱切换弹窗遮罩"
+ },
+ {
+ "file": "pages/genealogy/g10-application-review.vue",
+ "selector": ".review-feedback",
+ "reason": "审核操作后跨内容显示的固定轻提示"
+ },
+ {
+ "file": "pages/genealogy/g03-create-genealogy.vue",
+ "selector": ".duplicate-reminder-layer, .flow-success-layer",
+ "reason": "用户触发的重复提醒与成功弹窗遮罩"
+ },
+ {
+ "file": "pages/genealogy/g11-genealogy-settings.vue",
+ "selector": ".settings-feedback",
+ "reason": "保存设置后跨内容显示的固定轻提示"
+ },
+ {
+ "file": "pages/genealogy/g12-generation-poems.vue",
+ "selector": ".poem-feedback",
+ "reason": "保存字辈后跨内容显示的固定轻提示"
+ },
+ {
+ "file": "components/AppDialog.vue",
+ "selector": ".app-dialog-layer",
+ "reason": "全屏弹窗遮罩层"
+ },
+ {
+ "file": "components/AppToast.vue",
+ "selector": ".app-toast",
+ "reason": "跨页面轻提示层"
+ },
+ {
+ "file": "components/AuthPageShell.vue",
+ "selector": ".auth-shell__header",
+ "reason": "为顶部品牌装饰建立局部定位上下文"
+ },
+ {
+ "file": "components/AuthPageShell.vue",
+ "selector": ".auth-shell__seal",
+ "reason": "仅定位顶部品牌区内的固定比例印章装饰"
+ }
]
diff --git a/tests/document-flow-position-contract.ps1 b/tests/document-flow-position-contract.ps1
index e6115f6..5a32b79 100644
--- a/tests/document-flow-position-contract.ps1
+++ b/tests/document-flow-position-contract.ps1
@@ -14,7 +14,7 @@ foreach ($file in $files) {
$relative = $file.FullName.Substring($root.Length + 1).Replace('\', '/')
$source = [System.IO.File]::ReadAllText($file.FullName, [System.Text.Encoding]::UTF8)
foreach ($styleMatch in [regex]::Matches($source, '(?s)')) {
- $css = $styleMatch.Groups['css'].Value
+ $css = [regex]::Replace($styleMatch.Groups['css'].Value, '(?m)^\s*@(use|forward|import)\b[^;]+;\s*', '')
foreach ($rule in [regex]::Matches($css, '(?s)(?[^{}]+)\{(?[^{}]*)\}')) {
$body = [regex]::Replace($rule.Groups['body'].Value, '(?s)/\*.*?\*/', '')
$positionMatches = [regex]::Matches($body, '(?im)(?[^;{}]+?)\s*;')
diff --git a/tests/f01-document-flow-contract.ps1 b/tests/f01-document-flow-contract.ps1
index 37d528d..91495e0 100644
--- a/tests/f01-document-flow-contract.ps1
+++ b/tests/f01-document-flow-contract.ps1
@@ -1,16 +1,25 @@
$ErrorActionPreference = 'Stop'
$root = Split-Path $PSScriptRoot -Parent
$page = [System.IO.File]::ReadAllText((Join-Path $root 'pages/family/f01-family-feed.vue'), [System.Text.Encoding]::UTF8)
+$profiles = [System.IO.File]::ReadAllText((Join-Path $root 'styles/adaptive-frame-profiles.scss'), [System.Text.Encoding]::UTF8)
foreach ($expected in @(
'box-sizing: border-box',
'width: 514rpx',
- 'background: url("/static/assets/foundation/transparent/a01-scroll-secondary-v3.png") center / 100% 100% no-repeat',
- 'background: url("/static/assets/modules/family/transparent/f01-family-letter-card.png") center / 100% 100% no-repeat',
- 'background: url("/static/assets/foundation/transparent/a01-scroll-primary-v3.png") center / 100% 100% no-repeat'
+ '@use "../../styles/adaptive-frame-profiles.scss" as adaptive;',
+ '@include adaptive.adaptive-scroll-button(secondary);',
+ '@include adaptive.adaptive-family-letter;',
+ '@include adaptive.adaptive-scroll-button(primary);'
)) {
if (-not $page.Contains($expected)) { throw "F01 document-flow contract missing: $expected" }
}
+foreach ($expected in @(
+ '@mixin adaptive-family-letter',
+ '"/static/assets/modules/family/transparent/f01-family-letter-card.png"'
+)) {
+ if (-not $profiles.Contains($expected)) { throw "Adaptive profile contract missing: $expected" }
+}
+if ($page -match '100%\s+100%\s+no-repeat|border-image-slice\s*:') { throw 'F01 must consume adaptive frame geometry without page-local stretching or slicing' }
if ($page -match ']*\s)?class="(?:feed-shortcuts__skin|feed-card__skin)"|feed-state-card\s*>\s*]*>\s*]*auto-height') { throw 'F02 publish textarea must grow from its content' }
+$style = [regex]::Match($page, '(?s)').Groups[1].Value
+$panelStyle = [regex]::Match($style, '(?ms)^\s*\.publish-panel\s*\{(?.*?)\}').Groups['body'].Value
+if ($panelStyle -match '\bmin-height\s*:') { throw 'F02 publish panel height must be driven by its current content' }
if ($page -match ']*\s)?class="publish-panel__skin"|publish-field[^>]*>\s*',
'const selectPhoto = (index) =>',
@@ -71,6 +73,7 @@ foreach ($requiredPosition in @(
if ($page -notmatch $requiredPosition) { throw "F09 required thumbnail overlay boundary missing: $requiredPosition" }
}
if ([regex]::Matches($page, 'position\s*:').Count -ne 3) { throw 'F09 must keep only thumbnail badges and their local photo boundary positioned' }
+if ([regex]::Matches($page, '