feat: 拍摄流程对齐 Figma(正→左→右顺序/描摹轮廓蒙版/正脸只提示回正) + 报告页按 Figma 08 重排

- 拍照顺序 正脸→左脸→右脸:步骤文案/语音文件(step2-leftface/step3-rightface)/payload 归属对齐
- 蒙版轮廓由 Figma 拍照示意位图 alpha 镂空区逐像素描摹生成(0 正脸含耳/1 左脸鼻朝左/2 右脸鼻朝右),框外纯黑
- 侧脸步预览与抓帧不镜像(左右不再迷惑),HeadPose 侧脸自校准阈值 30 帧防误翻转
- 语音:「保持不动」播完再进倒计时(afterCurrent 接续,不再拦腰切断)
- 正脸步角度不合格只提示「请正对屏幕」,阈值放宽 |yaw|≤15°/|pitch|≤18°;转头提示仅侧脸步
- 抓帧改完整帧(修 Face++ INVALID_IMAGE_FACE)
- 报告页按 Figma 08:内联白底顶栏(返回+标题)、总分双独立白卡(30px 大数字+15px 单位后缀)、
  维度短竖分隔线+最低分标红、Tab 黄条、免责左对齐、护理建议去 tag 加粗+收尾句、
  产品大标题移出白卡、COREⅡ 换 Figma 导出 SVG 字标、产品图 151×174、卡圆角 10px
- 精华卡判据措辞用户化(均分档→综合均分/最差项约束→最低分维度/年龄组档→年龄段,引擎值不动)
- 修报告页滚动 P0(去 position:relative 覆写),文档同步(语音文档/README)
This commit is contained in:
Ubuntu
2026-09-28 00:57:28 +08:00
parent 0e00f3e938
commit 4e3d915b7d
16 changed files with 250 additions and 207 deletions
+92 -109
View File
@@ -212,8 +212,8 @@ button { font-family: inherit; border: 0; background: none; cursor: pointer; }
}
#s-cam.cam-live #cam-video { display: block; }
#s-cam.cam-live .cam-bg { display: none; }
/* 15% 黑遮罩,压住画面保证白色文案可读(静态示意图与实时画面共用) */
#s-cam::before { content: ""; position: absolute; inset: 0; background: rgba(0,0,0,.15); z-index: 1; }
/* 设计稿(Figma 05-07):取景框外全黑,仅轮廓镂空区显示实时画面,不再整屏压暗 */
#s-cam::before { content: none; }
#s-cam .nav { position: fixed; left: 0; right: 0; }
.cam-step {
position: absolute; left: 0; right: 0; top: 16.5%;
@@ -266,7 +266,7 @@ button { font-family: inherit; border: 0; background: none; cursor: pointer; }
text-align: center; font-size: 8px; line-height: 10px; color: #fff;
}
/* 取景蒙版:SVG mask 镂空压暗(58%) + 轮廓线框,按 data-step 切换轮廓 */
/* 取景蒙版:SVG mask 镂空 + 轮廓线框,按 data-step 切换轮廓;框外纯黑不透明(对齐 Figma:只有轮廓内显示画面) */
.cam-mask {
position: absolute; inset: 0;
width: 100%; height: 100%;
@@ -276,7 +276,7 @@ button { font-family: inherit; border: 0; background: none; cursor: pointer; }
.cam-mask[data-step="0"] [data-shape="0"],
.cam-mask[data-step="1"] [data-shape="1"],
.cam-mask[data-step="2"] [data-shape="2"] { display: block; }
.cam-dim-rect { fill: rgba(0,0,0,.58); }
.cam-dim-rect { fill: #000; } /* 框外全黑(Figma 设计):摄像头画面只在轮廓镂空区可见 */
.cam-line path { fill: none; stroke: rgba(255,255,255,.85); stroke-width: 2.5; }
/* 未检测到人脸:轮廓呼吸动画(~1.8s);姿态 ok:品牌绿定格 */
@keyframes maskBreath { 0%,100% { stroke-opacity: .3; } 50% { stroke-opacity: .95; } }
@@ -331,88 +331,114 @@ button { font-family: inherit; border: 0; background: none; cursor: pointer; }
}
.cam-nudge.show { opacity: 1; transform: translateX(-50%); }
/* ═══════════ 08 报告页 ═══════════ */
.report-body { padding: 12px 38px 34px; }
/* ═══════════ 08 报告页(Figma 2:9 严格还原:设计稿 1080 基准 ÷2.88) ═══════════ */
.report-body { padding: 0 38px 20px; }
/* 顶栏:白底通栏横带,左返回圆钮 + 居中黑标题(设计 255px 高通栏含手机状态栏,H5 只保留标题栏) */
.report-nav {
position: relative;
margin: 0 -38px; /* 通栏:抵消 body 侧 padding */
height: calc(44px + env(safe-area-inset-top));
padding-top: env(safe-area-inset-top);
background: #fff;
display: flex; align-items: center; justify-content: center;
}
.report-nav .nav-back {
position: absolute; left: 8px;
top: calc(50% + env(safe-area-inset-top) / 2); transform: translateY(-50%);
}
.report-nav-title { font-size: 14px; font-weight: 500; color: #000; letter-spacing: .5px; }
.report-title {
font-size: 20px; font-weight: 700; color: var(--ink);
text-align: center; margin: 10px 0 16px;
font-size: 20.6px; font-weight: 700; color: var(--ink);
text-align: center; margin: 20px 0 13px;
letter-spacing: .5px;
}
.card {
background: #fff; border-radius: 6px;
padding: 14px 15px;
margin-bottom: 9px;
background: #fff; border-radius: 10px;
padding: 14px 18px;
margin-bottom: 10px;
}
/* 总分 */
.card-stats { display: flex; padding: 11px 15px; }
.stat { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 2px; }
.stat-label { font-size: 9px; font-weight: 500; color: var(--grey); }
/* label 下短横线(34×1 居中) */
/* 总分:两张独立白卡(设计 420+420,间距 17px→6px) */
.stats-row { display: flex; gap: 6px; margin-bottom: 10px; }
.stats-row .card-stat { flex: 1; margin-bottom: 0; }
.card-stat {
display: flex; flex-direction: column; align-items: center;
padding: 12px 10px 13px;
}
.stat-label { font-size: 8.7px; font-weight: 500; color: var(--grey); }
/* label 下短横线(设计 99px→34px 居中) */
.stat-label::after {
content: ""; display: block;
width: 34px; height: 1px; background: #EFEFEF;
margin: 4px auto 0;
}
.stat-value { font-size: 29px; font-weight: 400; color: var(--ink); letter-spacing: 1px; line-height: 34px; }
/* 维度(灰底独立文字,置于总分卡与维度卡之间) */
.dims-intro { font-size: 10px; font-weight: 500; color: #464646; line-height: 1.6; margin: 0 2px 9px; }
/* 大数字 30px/400 + 单位 15px/500(设计 87px 与 43.7px) */
.stat-value { margin-top: 2px; line-height: 40px; color: var(--ink); }
.stat-value b { font-size: 30px; font-weight: 400; letter-spacing: 1px; }
.stat-value i { font-style: normal; font-size: 15px; font-weight: 500; }
/* 三维度卡(设计:标签 8.7px 灰 / 分数 28.9px lh50 / 竖向短分隔线 21px / 最低分标红) */
.card-dims { padding: 17px 19px 15px; }
.dims-row { display: flex; }
.dim { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 2px; }
.dim + .dim { border-left: 1px solid #EFEFEF; }
.dim-name { font-size: 9px; font-weight: 500; color: var(--grey); }
.dim-score { font-size: 29px; font-weight: 500; color: var(--ink); line-height: 1.1; }
.dim-lv { font-size: 9px; font-weight: 500; min-height: 11px; }
.dims-note { font-size: 9px; font-weight: 500; color: var(--grey); line-height: 1.55; margin-top: 9px; text-align: center; }
.dims-disclaimer { font-size: 7px; font-weight: 400; color: var(--grey-3); margin: 0 2px 9px; line-height: 1.5; }
/* 具体描述 */
.detail-tabs {
display: flex;
border-bottom: 1px solid #F0F0F0;
margin-bottom: 12px;
}
.dtab {
flex: 1; padding: 8px 0 9px;
font-size: 10px; font-weight: 500; color: var(--ink);
position: relative;
.dim { flex: 1; position: relative; display: flex; flex-direction: column; align-items: center; }
.dim + .dim::before {
content: ""; position: absolute; left: 0; top: 37px;
width: 1px; height: 21px; margin-top: -10.5px; background: #EFEFEF;
}
.dim-name { font-size: 8.7px; font-weight: 500; color: var(--grey); }
.dim-score { font-size: 28.9px; font-weight: 500; color: var(--ink); line-height: 50px; }
.dim-score.dim-bad { color: var(--bad); } /* 最低分标红 */
/* 关注行(设计 fs25→8.7px:前缀灰 + 维度名深色大一号;下行深色口号) */
.dims-note { margin-top: 2px; text-align: center; line-height: 1.5; }
.dims-note-l1 { font-size: 8.7px; font-weight: 500; color: #858585; }
.dims-note-l1 b { font-size: 10.1px; font-weight: 500; color: var(--ink); }
.dims-note-l2 { font-size: 8.7px; font-weight: 500; color: var(--ink); }
/* 具体描述(Tab 10.1px,选中 700 + 78×7 黄条;竖排条目标题在图左;图文垂直居中) */
.card-detail { padding: 0 19px 19px; }
.detail-tabs { display: flex; border-bottom: 1px solid #F0F0F0; }
.dtab { flex: 1; padding: 13px 0 0; font-weight: 500; color: var(--ink); }
.dtab-tx { position: relative; display: inline-block; font-size: 10.1px; padding: 0 5px 7px; }
.dtab.active { font-weight: 700; }
.dtab.active::after {
content: ""; position: absolute;
left: 50%; transform: translateX(-50%); bottom: -1px;
width: 78px; height: 7px; border-radius: 3.5px;
background: var(--yellow);
.dtab.active .dtab-tx::after {
content: ""; position: absolute; left: 50%; transform: translateX(-50%); bottom: -1px;
width: 78px; height: 7px; border-radius: 3.5px; background: var(--yellow);
}
.dpanel { display: none; }
.dpanel.active { display: block; animation: fade .25s ease; }
.dpanel.active { display: block; animation: fade .25s ease; padding-top: 19px; }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
.ditem { display: flex; gap: 11px; align-items: flex-start; }
.ditem + .ditem { margin-top: 13px; padding-top: 13px; border-top: 1px solid #F0F0F0; }
.ditem-img { width: 92px; height: 96px; object-fit: cover; border-radius: 4px; flex-shrink: 0; }
.ditem-text { flex: 1; }
.ditem { display: flex; gap: 9px; align-items: center; }
.ditem + .ditem { margin-top: 18px; padding-top: 18px; border-top: 1px solid #F0F0F0; }
.ditem-img { width: 92px; height: 96px; object-fit: cover; border-radius: 6px; flex-shrink: 0; }
.ditem-text { flex: 1; min-width: 0; }
/* 检测条目标题:竖排,位于图左(设计稿如此) */
.ditem-title {
writing-mode: vertical-rl;
letter-spacing: 4px;
font-size: 11.5px; font-weight: 500; color: var(--ink);
margin-right: 12px; flex-shrink: 0;
margin-right: 3.5px; flex-shrink: 0;
}
.ditem-para { font-size: 10.1px; font-weight: 400; color: var(--para); line-height: 1.41; overflow-wrap: anywhere; }
/* 护理建议(标题 13px/700/#000;条目 10.1px #4A4A4A lh1.43;收尾句 11.1px/500/#000) */
.card-care, .card-essence { padding: 18px 20px 16px 19px; }
.card-heading { font-size: 13px; font-weight: 700; color: #000; margin-bottom: 4px; }
.care-item { font-size: 10.1px; color: var(--para); line-height: 1.43; margin-bottom: 7px; overflow-wrap: anywhere; }
.care-summary { font-size: 11.1px; font-weight: 500; color: #000; margin-top: 5px; }
/* 精华推荐(Figma 无此卡,按业务文档 V2.3 §6.4 保留,样式沿用护理建议卡) */
.essence-name { font-size: 12px; font-weight: 700; color: var(--ink); margin-bottom: 5px; }
.essence-triggers { font-size: 7px; color: var(--grey-3); margin-top: 6px; }
/* 产品推荐:大标题独立落在灰底;白卡左文案右图(图 151×174 撑满卡高,COREⅡ 为 Figma 导出字标 SVG) */
.prod-title {
font-size: 21.6px; font-weight: 700; color: var(--ink);
line-height: 1.5; text-align: center; margin: 15px 0 16px;
}
.ditem-para { font-size: 10px; font-weight: 400; color: var(--para); line-height: 1.45; overflow-wrap: anywhere; }
/* 护理建议 */
.card-heading { font-size: 13px; font-weight: 700; color: #000; margin-bottom: 8px; }
.care-item { font-size: 10px; color: var(--para); line-height: 1.6; margin-bottom: 8px; overflow-wrap: anywhere; }
.care-summary { font-size: 11px; font-weight: 500; color: #000; margin-top: 10px; }
/* 产品推荐:白底圆角卡,左侧文案 + 右侧单图(图高撑卡) */
.prod-title { font-size: 21px; font-weight: 700; color: var(--ink); line-height: 1.45; text-align: center; margin: 4px 0 12px; }
.card-product { padding: 0; overflow: hidden; }
.prod-card { display: flex; align-items: stretch; }
.prod-info {
flex: 1; min-width: 0;
padding: 18px 12px 18px 16px;
display: flex; flex-direction: column; justify-content: center; gap: 7px;
padding: 44px 10px 16px 16px;
display: flex; flex-direction: column; align-items: flex-start;
}
.prod-badge { font-size: 8px; font-weight: 500; letter-spacing: 3px; color: #B9B9B9; }
.prod-name { font-size: 13px; font-weight: 700; color: var(--ink); line-height: 1.4; overflow-wrap: anywhere; }
.prod-sub { font-size: 7.5px; font-weight: 500; color: var(--grey-3); }
.prod-badge { width: 39px; height: auto; }
.prod-name { font-size: 13px; font-weight: 700; color: var(--ink); line-height: 1.34; margin-top: 9px; overflow-wrap: anywhere; }
.prod-sub { font-size: 7.3px; font-weight: 500; color: var(--grey-3); margin-top: auto; padding-top: 10px; }
.prod-scroll {
flex-shrink: 0; margin: 0; padding: 0;
display: flex; overflow: hidden;
@@ -420,15 +446,15 @@ button { font-family: inherit; border: 0; background: none; cursor: pointer; }
}
.prod-scroll::-webkit-scrollbar { display: none; }
.prod-scroll img {
width: 168px; height: 225px;
width: 151px; height: 174px;
object-fit: cover; flex-shrink: 0;
border-radius: 0 6px 6px 0;
}
.btn-more { margin: 16px auto 0; }
.btn-more { margin: 20px auto 0; }
/* 免责小字:灰底独立文字,左对齐到卡片文案位(设计 x=166→57.6px;fw300 #000) */
.report-disclaimer {
font-size: 7px; font-weight: 300; color: var(--grey-3);
line-height: 1.7; text-align: center;
margin: 5px 2px 9px; /* 灰底独立文字,位于描述卡与护理建议卡之间 */
font-size: 7.3px; font-weight: 300; color: #000;
line-height: 1.44; text-align: left;
margin: 13px 19px 11px;
}
/* ═══════════ 弹窗 ═══════════ */
@@ -636,23 +662,6 @@ button { font-family: inherit; border: 0; background: none; cursor: pointer; }
}
.overlay-policy .policy-page { position: relative; }
/* #8 维度卡关注行:灰小字 + 深色口号(对齐设计稿) */
.dims-note { margin-top: 12px; }
.dims-note-l1 { font-size: 10px; font-weight: 400; color: var(--grey); }
.dims-note-l2 { font-size: 11.5px; font-weight: 500; color: var(--ink); line-height: 1.8; }
/* #9 Tab 黄色指示条:宽度跟随文字(原固定 78px 过宽) */
.dtab { padding: 8px 0 0; }
.dtab.active::after { content: none; }
.dtab-tx { position: relative; display: inline-block; padding: 0 5px 9px; }
.dtab.active .dtab-tx::after {
content: ""; position: absolute; left: 0; right: 0; bottom: -1px;
height: 7px; border-radius: 3.5px; background: var(--yellow);
}
/* #13 分类卡图片对齐设计稿(约 100px 见方、圆角 10) */
.ditem-img { width: 100px; height: 100px; border-radius: 10px; }
/* ═══════════ 第7轮:用户测试 agent 反馈 ═══════════ */
/* P1-1 隐私页标题被悬浮返回键遮挡:正文上留返回键位 */
#p-policy .policy-body { padding-top: 52px; }
@@ -665,27 +674,7 @@ button { font-family: inherit; border: 0; background: none; cursor: pointer; }
.rs-list { z-index: 50; }
/* #4 无进展提示再上移(取景/拍摄区下方,引导 chips 上方) */
.cam-nudge { bottom: 24%; }
/* #6 报告页顶栏移除,返回/历史改悬浮 */
#s-report { position: relative; }
.report-float-back {
position: absolute; top: 12px; left: 12px; z-index: 21;
background: #fff; box-shadow: 0 1px 6px rgba(0,0,0,.10);
}
.report-float-history {
position: absolute; top: 12px; right: 12px; z-index: 21;
font-size: 12px; color: var(--grey-2); padding: 7px 10px;
background: #fff; border-radius: 15px; box-shadow: 0 1px 6px rgba(0,0,0,.10);
}
#s-report .report-body { padding-top: 44px; }
/* #8 关注行:前缀灰 + 维度名深色 500 */
.dims-note-l1 b { font-weight: 500; color: var(--ink); }
/* #9 维度分:最低分标红(替代原档位徽章) */
.dim-score.dim-bad { color: var(--bad); }
/* #11 护理建议(设计稿样式:标题 + 编号条目) */
#care-list .care-item { margin-bottom: 10px; }
#care-list .care-item b { font-weight: 600; color: var(--ink); }
/* 护理建议/精华推荐卡标题对齐设计稿(≈16px) */
.card-care .card-heading, .card-essence .card-heading { font-size: 16px; }
/* #6 报告页头部:按 Figma 08 还原为内联白底顶栏(见报告页主区块),不再悬浮 */
/* ═══════════ 第9轮:真机反馈 ═══════════ */
/* #1 城市下拉浮层再提级,并加实体阴影边界(部分端 stacking 表现不同) */
@@ -697,12 +686,6 @@ button { font-family: inherit; border: 0; background: none; cursor: pointer; }
font-size: 15px; font-weight: 500; text-shadow: 0 1px 8px rgba(0,0,0,.65);
}
.cam-hint.ok { background: none; color: #34C759; }
/* #6 Tab 条对齐设计稿:文字 11px、选中 700,黄色指示条恢复设计宽度 78px */
.dtab-tx { font-size: 11px; padding: 0 5px 10px; }
.dtab.active .dtab-tx::after { left: 50%; right: auto; transform: translateX(-50%); width: 78px; }
/* #7 关注行:维度名加粗 700,两行收紧 */
.dims-note-l1 b { font-weight: 700; }
.dims-note-l2 { line-height: 1.6; }
/* #9 档案页顶栏移除,返回键悬浮(白圆带影,压暗背景上可读) */
.profile-float-back {
position: fixed; top: 12px; left: 12px; z-index: 21;