Files
juzi/h5/css/style.css
T
xslandCursor 531a7ddd14 fix: 拍照页对齐 Figma(正→右→左/镜像预览/WebView 口径定位/85%遮罩) + 语音调度重写 + 正脸照不镜像
- 拍照顺序改为正脸→右脸→左脸(对齐 Figma),左右以用户本人为准;送检前按 target 重排为 [正,左,右]
- 三步预览均镜像(Figma 侧脸轮廓按镜像绘制),后置镜头侧脸轮廓自动翻转;抓帧恒为原始视角
- 蒙版 viewBox 取 Figma 帧 y86–812(扣除微信导航栏)+ meet 缩放,文案/引导/提示按 726 高定位;框外 85% 黑,静态态白底
- 语音:流程音排队不截断、姿态提示挂起补播、倒计时等播报收尾、拍摄完成打断过时引导、出报告/退出清队列;去重仅限姿态提示
- 语音文件改名 step2-rightface / step3-leftface,同步清单、生成脚本与设计文档
- 精华卡去重复正文、推荐依据写明具体原因;年龄仅数字;toast 按字数延时;备注去内部质量码
- 新增无头浏览器冒烟测试 h5/test/e2e-browser.mjs

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-28 02:22:37 +08:00

697 lines
30 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ═══════════════════════════════════════════
巨子测肤 · 1'me 在线肌肤测试 — H5 样式
设计稿 1080px 基准 → 此处 375px(÷2.88)
主色 #F5F078 · 文字 #282828 · 底 #EFEFEF
═══════════════════════════════════════════ */
:root {
--yellow: #F5F078;
--ink: #282828;
--ink-2: #2C2C2C;
--grey: #868686;
--grey-2: #757575;
--grey-3: #707070;
--para: #4A4A4A;
--bg: #EFEFEF;
--line: #E5E5E5;
--dry: #EAE6E1;
--neutral: #DBF6D6;
--bad: #D30C0C;
--nav-h: 44px;
--font: "Noto Sans SC","PingFang SC","Hiragino Sans GB","Microsoft YaHei",system-ui,sans-serif;
}
* { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { height: 100%; }
body {
font-family: var(--font);
color: var(--ink);
background: #000;
overflow: hidden;
-webkit-font-smoothing: antialiased;
user-select: none;
max-width: 480px; /* 桌面预览时居中显示 */
margin: 0 auto;
position: relative;
}
img { display: block; }
button { font-family: inherit; border: 0; background: none; cursor: pointer; }
/* ─── 屏幕容器 ─── */
.screen {
position: absolute; inset: 0;
display: none;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
background: var(--bg);
}
.screen.active { display: block; animation: screenIn .35s ease both; }
@keyframes screenIn { from { opacity: 0; transform: translateX(14px); } to { opacity: 1; transform: none; } }
/* ─── 通用按钮 ─── */
.btn-primary {
display: block;
width: 182px; height: 39px;
line-height: 39px;
background: var(--yellow);
border-radius: 20px;
color: var(--ink);
font-size: 14px; font-weight: 500;
text-align: center;
transition: transform .12s ease;
}
.btn-primary:active { transform: scale(.96); }
/* ─── 折线箭头(返回/下拉) ─── */
.chev {
width: 9px; height: 9px;
border: solid var(--ink-2); border-width: 0 2px 2px 0;
display: inline-block; padding: 2px;
}
.chev.left { transform: rotate(135deg); }
.chev.down { transform: rotate(45deg); }
/* ═══════════ 01 启动页 ═══════════ */
#s-splash { background: #101823; }
.splash-bg {
position: absolute; inset: 0;
background: url(../assets/img/bg-splash.jpg) center/cover no-repeat;
}
.splash-slogan {
position: absolute; left: 0; right: 0; top: 20%;
text-align: center;
color: #fff; font-size: 23px; font-weight: 500;
line-height: 1.38;
letter-spacing: 1px;
text-shadow: 0 1px 8px rgba(0,0,0,.18);
}
.splash-bottom {
position: absolute; left: 0; right: 0; bottom: 11%;
display: flex; flex-direction: column; align-items: center; gap: 18px;
padding-bottom: env(safe-area-inset-bottom);
}
.brand-row { display: flex; align-items: center; gap: 7px; }
.brand-logo { width: 46px; height: auto; filter: brightness(0) invert(1); }
.brand-text { color: #fff; font-size: 21px; font-weight: 500; letter-spacing: 1px; }
/* ═══════════ 通用导航 ═══════════ */
.nav {
position: sticky; top: 0; z-index: 20;
height: var(--nav-h);
display: flex; align-items: center;
padding: 0 6px;
background: rgba(255,255,255,.94);
-webkit-backdrop-filter: blur(8px); /* iOS<15.4 需要前缀 */
backdrop-filter: blur(8px);
}
.nav-dark { background: rgba(20,20,20,.55); }
.nav-dark .nav-title { color: #fff; }
.nav-dark .chev { border-color: #fff; }
.nav-back {
width: 27px; height: 27px;
display: flex; align-items: center; justify-content: center;
border: 1px solid #E5E5E5; border-radius: 50%;
background: #fff;
}
/* 深色导航(拍照页):半透明白底盘 + 浅白描边 */
.nav-dark .nav-back { background: rgba(255,255,255,.18); border-color: rgba(255,255,255,.4); }
.nav-title {
position: absolute; left: 50%; transform: translateX(-50%);
font-size: 14px; font-weight: 500; color: #000;
max-width: 55%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* ═══════════ 03 档案填写 ═══════════ */
#s-profile { background: #0e0f18; }
.profile-bg {
position: absolute; inset: 0;
/* 设计稿:启动页照片 + 50% 正片叠底黑遮罩(矩形3) */
background:
linear-gradient(rgba(0,0,0,.55), rgba(0,0,0,.55)),
url(../assets/img/bg-splash.jpg) center/cover no-repeat;
}
#s-profile .nav { position: fixed; left: 0; right: 0; }
.profile-body {
position: relative; z-index: 1;
min-height: 100%;
/* 设计:标题在导航下 23px;按钮随内容流(卡底→按钮间距按设计节奏约 22px) */
padding: calc(var(--nav-h) + 23px) 64px clamp(48px, 8vh, 121px);
display: flex; flex-direction: column; justify-content: flex-start;
gap: 16px;
}
.page-title {
color: #fff; font-size: 21px; font-weight: 700;
letter-spacing: 1px; margin-bottom: 2px;
}
.field-label {
display: block;
color: #fff; font-size: 14px; font-weight: 400;
margin-bottom: 6px; letter-spacing: .5px;
}
.form-row.two { display: flex; gap: 22px; }
.form-row.two .field { flex: 1; }
.field-input {
display: block; width: 100%; height: 38px;
background: #fff; border-radius: 6px; border: 0; outline: none;
padding: 0 12px;
font-family: inherit; font-size: 13px; color: var(--ink);
appearance: none; -webkit-appearance: none;
}
.field-input::placeholder { color: #bbb; }
.field-select-wrap { position: relative; }
.field-select-wrap .chev { position: absolute; right: 12px; top: 15px; width: 7px; height: 7px; pointer-events: none; }
/* 肤质卡片 */
.skin-card {
background: #fff; border-radius: 6px;
padding: 24px 10px 26px;
}
.skin-axis {
display: flex; justify-content: center; gap: 8px;
margin: 0 0 14px;
}
.axis-item {
display: inline-flex; align-items: center; gap: 4px;
font-size: 9px; color: var(--ink);
}
.chip { width: 8px; height: 8px; border-radius: 2px; display: inline-block; }
.skin-carousel { overflow: hidden; touch-action: pan-y; /* 纵向滚动交给浏览器,横向留给拖拽 */ }
.skin-track { display: flex; transition: transform .32s cubic-bezier(.22,.61,.36,1); }
.skin-item {
flex: 0 0 100%;
display: flex; flex-direction: column; align-items: center;
}
.skin-item img { width: 109px; height: 109px; }
.skin-name { font-size: 13px; font-weight: 500; color: #000; margin-top: 12px; }
.skin-desc {
font-size: 10px; color: var(--ink); font-weight: 400;
line-height: 1.5; text-align: center;
margin-top: 5px; padding: 0 26px;
}
.skin-dots { display: flex; justify-content: center; gap: 7px; margin-top: 16px; }
.skin-dots i {
width: 8px; height: 8px; border-radius: 50%;
background: #D6D6D6; transition: background .25s;
}
.skin-dots i.on { background: #000; }
/* 按钮随内容流:卡底→按钮间距 22px(= flex gap 16 + 此处 6),两侧 auto 居中 */
.btn-submit { margin: 6px auto 0; }
/* ═══════════ 05-07 拍照页 ═══════════ */
#s-cam { background: #000; }
/* 相机未就绪/降级时的静态态:白底经蒙版 85% 压暗 → 框外深灰、轮廓内白,即 Figma 05-07 静态稿 */
.cam-bg { position: absolute; inset: 0; background: #fff; }
/* 实时相机画面(getUserMedia 成功后显示,盖住静态示意图) */
#cam-video {
position: absolute; inset: 0;
width: 100%; height: 100%;
object-fit: cover;
transform: scaleX(-1); /* 自拍镜面预览 */
display: none; z-index: 0;
}
#s-cam.cam-live #cam-video { display: block; }
#s-cam.cam-live .cam-bg { display: none; }
/* 设计稿(Figma 05-07):压暗只在取景蒙版框外(.cam-dim-rect),不再整屏压暗 */
#s-cam::before { content: none; }
#s-cam .nav { position: fixed; left: 0; right: 0; }
/* 拍照页纵向定位按 WebView 口径:Figma 帧 812 高扣掉顶部 86px 微信导航栏 = 726 高视口,百分比均以 726 为基准 */
.cam-step {
position: absolute; left: 0; right: 0; top: 6.4%;
text-align: center;
color: #fff; font-size: 21px; font-weight: 500;
line-height: 1.5; letter-spacing: 1px;
text-shadow: 0 1px 10px rgba(0,0,0,.4);
z-index: 2;
}
.cam-guide {
position: absolute; left: 0; right: 0; bottom: 22.4%;
display: flex; justify-content: center; align-items: center; gap: 18px;
z-index: 2;
}
.cam-guide span { color: #fff; font-size: 14px; font-weight: 400; opacity: .92; }
.cam-guide i { width: 0; height: 15px; border-left: 1px solid #fff; }
.cam-controls {
position: absolute; left: 0; right: 0; bottom: 5.2%;
display: flex; align-items: center; justify-content: space-between;
padding: 0 55px;
padding-bottom: env(safe-area-inset-bottom);
z-index: 2;
}
.cam-side img { width: 31px; height: 31px; }
.cam-shutter img { width: 62px; height: 62px; }
.cam-shutter:active { transform: scale(.92); }
/* 白屏补光:瞬间点亮(.on 无过渡),移除后淡出(总时长 600–900ms) */
.cam-fill {
position: absolute; inset: 0; background: #fff;
opacity: 0; pointer-events: none; z-index: 30; /* 盖住导航(z 20) */
transition: opacity .25s ease;
}
.cam-fill.on { opacity: 1; transition: none; }
/* 步骤圆点:当前步高亮、完成步绿色打勾(Figma 无此元素,放在步骤文案与取景轮廓之间的空隙) */
.cam-dots {
position: absolute; top: 16.2%; left: 0; right: 0;
display: flex; justify-content: center; gap: 12px;
z-index: 2;
}
.cam-dots i {
width: 9px; height: 9px; border-radius: 50%;
background: rgba(255,255,255,.35);
position: relative; transition: background .25s;
}
.cam-dots i.on { background: #fff; box-shadow: 0 0 0 3px rgba(255,255,255,.25); }
.cam-dots i.done { background: #34C759; }
.cam-dots i.done::after {
content: "✓"; position: absolute; left: 0; right: 0; top: -1px;
text-align: center; font-size: 8px; line-height: 10px; color: #fff;
}
/* 取景蒙版:SVG mask 镂空 + 轮廓线框,按 data-step 切换轮廓;框外 85% 黑 */
.cam-mask {
position: absolute; inset: 0;
width: 100%; height: 100%;
z-index: 1; pointer-events: none;
}
.cam-mask [data-shape] { display: none; }
.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-mask.flip { transform: scaleX(-1); } /* 后置镜头预览不镜像:侧脸轮廓随之翻转 */
.cam-dim-rect { fill: #000; fill-opacity: .85; } /* Figma 05-07 框外为 85% 黑(alpha 217):环境隐约可见,人脸只在轮廓内清晰 */
.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; } }
.cam-mask.no-face .cam-line path { animation: maskBreath 1.8s ease-in-out infinite; }
.cam-mask.ok .cam-line path { stroke: #34C759; stroke-opacity: 1; animation: none; }
/* 检测引擎加载状态(小字胶囊) */
.cam-status {
position: absolute; top: 17px; left: 50%; /* 与悬浮返回键同一行,不压步骤文案 */
transform: translateX(-50%);
font-size: 10px; color: rgba(255,255,255,.85);
background: rgba(0,0,0,.35);
padding: 4px 12px; border-radius: 11px;
z-index: 2; opacity: 0; transition: opacity .25s; white-space: nowrap;
}
.cam-status.show { opacity: 1; }
/* 引导提示:一次只显示一条,触发式出现/消失 */
.cam-hint {
position: absolute; left: 50%; bottom: 29%;
transform: translateX(-50%) translateY(6px);
font-size: 13px; color: #fff;
background: rgba(0,0,0,.45);
padding: 7px 16px; border-radius: 17px;
z-index: 2; opacity: 0; pointer-events: none;
transition: opacity .2s ease, transform .2s ease;
white-space: nowrap;
}
.cam-hint.show { opacity: 1; transform: translateX(-50%); }
.cam-hint.ok { background: rgba(52,199,89,.82); }
/* 倒计时大数字(取景中央 3→2→1) */
.cam-count {
position: absolute; left: 0; right: 0; top: 40%;
text-align: center;
font-size: 76px; font-weight: 600; color: #fff;
text-shadow: 0 2px 18px rgba(0,0,0,.55);
z-index: 3; opacity: 0; transition: opacity .15s; pointer-events: none;
}
.cam-count.show { opacity: 1; }
/* 长时间无进展轻提示(不阻塞流程) */
.cam-nudge {
position: absolute; left: 50%; bottom: 13%;
transform: translateX(-50%) translateY(6px);
font-size: 10px; color: #fff;
background: rgba(0,0,0,.55);
padding: 6px 14px; border-radius: 14px;
z-index: 2; opacity: 0; pointer-events: none;
transition: opacity .25s ease, transform .25s ease;
white-space: nowrap;
}
.cam-nudge.show { opacity: 1; transform: translateX(-50%); }
/* ═══════════ 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: 20.6px; font-weight: 700; color: var(--ink);
text-align: center; margin: 20px 0 13px;
letter-spacing: .5px;
}
.card {
background: #fff; border-radius: 10px;
padding: 14px 18px;
margin-bottom: 10px;
}
/* 总分:两张独立白卡(设计 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;
}
/* 大数字 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; 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 .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; padding-top: 19px; }
@keyframes fade { from { opacity: 0; } to { opacity: 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: 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;
}
.card-product { padding: 0; overflow: hidden; }
.prod-card { display: flex; align-items: stretch; }
.prod-info {
flex: 1; min-width: 0;
padding: 44px 10px 16px 16px;
display: flex; flex-direction: column; align-items: flex-start;
}
.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;
scrollbar-width: none;
}
.prod-scroll::-webkit-scrollbar { display: none; }
.prod-scroll img {
width: 151px; height: 174px;
object-fit: cover; flex-shrink: 0;
}
.btn-more { margin: 20px auto 0; }
/* 免责小字:灰底独立文字,左对齐到卡片文案位(设计 x=166→57.6px;fw300 #000) */
.report-disclaimer {
font-size: 7.3px; font-weight: 300; color: #000;
line-height: 1.44; text-align: left;
margin: 13px 19px 11px;
}
/* ═══════════ 弹窗 ═══════════ */
.overlay {
position: absolute; inset: 0; z-index: 50;
display: none;
align-items: center; justify-content: center;
background: rgba(0,0,0,.5);
}
.overlay.show { display: flex; }
.overlay .popup { animation: popIn .3s cubic-bezier(.34,1.4,.64,1) both; }
@keyframes popIn { from { opacity: 0; transform: translateY(26px) scale(.96); } to { opacity: 1; transform: none; } }
.popup {
position: relative;
width: 307px;
background: #fff; border-radius: 10px;
padding: 34px 26px 33px;
text-align: left;
}
.popup-close {
position: absolute; top: 12px; right: 12px;
width: 31px; height: 31px;
display: flex; align-items: center; justify-content: center;
}
.popup-close img { width: 17px; height: 17px; opacity: .8; }
.popup-title {
font-size: 23px; font-weight: 500; color: var(--ink);
line-height: 1.35; letter-spacing: .5px;
margin-bottom: 15px;
}
.popup-title-center { text-align: center; margin: 18px 0 24px; }
/* 拍照引导弹窗:近方形比例,标题垂直居中偏上,按钮贴底 */
#p-photoguide .popup {
min-height: 312px;
display: flex; flex-direction: column;
padding: 34px 26px 52px;
}
#p-photoguide .popup-title-center { margin: 56px 0 auto; }
.popup-body { font-size: 11.5px; color: var(--ink); line-height: 1.55; margin-bottom: 20px; }
.privacy-row { display: flex; align-items: center; gap: 8px; margin-bottom: 40px; cursor: pointer; }
.checkbox {
width: 11px; height: 11px; border-radius: 50%;
border: 1px solid #282828; background: #fff;
flex-shrink: 0; position: relative;
}
.checkbox.checked::after {
content: ""; position: absolute;
inset: 2px; border-radius: 50%;
background: var(--ink-2);
}
.privacy-text { font-size: 10px; color: var(--grey-2); }
.popup-btn { margin: 0 auto; }
/* 分析中 */
.overlay-dark { background: rgba(16,16,16,.82); }
.analyzing {
color: #fff; text-align: center;
font-size: 13px; letter-spacing: 1px;
display: flex; flex-direction: column; align-items: center; gap: 16px;
}
.analyzing-tip { font-size: 10px; color: rgba(255,255,255,.45); letter-spacing: 0; }
.spinner {
width: 34px; height: 34px;
border: 3px solid rgba(255,255,255,.25);
border-top-color: var(--yellow);
border-radius: 50%;
animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
/* Toast */
.toast {
position: absolute; left: 50%; bottom: 15%;
transform: translateX(-50%) translateY(8px);
background: rgba(20,20,20,.85); color: #fff;
font-size: 12px;
padding: 9px 18px; border-radius: 18px;
opacity: 0; pointer-events: none;
transition: all .25s ease;
z-index: 99; white-space: nowrap;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
/* ═══════════ 第3轮上线打磨新增(以下均为新增规则,不动以上已验收样式) ═══════════ */
/* 隐私协议链接:下划线、色值不变,点击开占位弹层 */
.privacy-link { color: var(--grey-2); text-decoration: underline; cursor: pointer; }
.privacy-link:active { opacity: .7; }
/* 隐私协议占位弹层(轻量,复用 .overlay/.popup 骨架) */
#p-policy .popup { padding: 30px 26px 34px; }
.popup-title-policy { font-size: 18px; margin-bottom: 12px; }
/* ═══════════ 第4轮:引导式自动三连拍 + SkinScore 报告接入(新增,不动以上已验收样式) ═══════════ */
/* 档位配色:良好=绿 / 改善=琥珀 / 预警=红(文字场景直接上色) */
.lv-good { color: #2FA84F; }
.lv-warn { color: #E8A13D; }
.lv-bad { color: var(--bad); }
/* 肤龄钳制留痕(小字灰) */
.stat-sub { font-size: 8px; color: var(--grey-3); min-height: 10px; line-height: 10px; }
/* 分类条目:S 值 + 档位徽章 */
.cat-head { display: flex; align-items: center; gap: 6px; margin-bottom: 4px; }
.cat-s { font-size: 15px; font-weight: 600; color: var(--ink); }
.cat-s.cat-na { font-size: 9px; font-weight: 400; color: var(--grey-2); }
.cat-badge { font-style: normal; font-size: 8px; font-weight: 500; color: #fff; padding: 2px 7px; border-radius: 8px; }
.cat-badge.lv-good { background: #2FA84F; color: #fff; }
.cat-badge.lv-warn { background: #E8A13D; color: #fff; }
.cat-badge.lv-bad { background: var(--bad); color: #fff; }
/* 降级标注(下颌线未参与评分等,小字灰) */
.vm-notes { font-size: 7px; font-weight: 400; color: var(--grey-3); line-height: 1.7; margin: 0 2px 9px; }
/* 精华推荐卡 */
.essence-name { font-size: 15px; font-weight: 700; color: var(--ink); margin-bottom: 6px; }
.essence-triggers { font-size: 8.7px; color: var(--grey-3); margin-top: 6px; } /* 设计规范 Caption 级:验收要求展示命中判据,需可读 */
/* ═══════════ 第5轮:报告页检测可视化(face_maps 图层 / marks 叠加,新增,不动以上已验收样式) ═══════════ */
/* 分类卡检测图复用 .ditem-img(左图右文、92×96 裁切);无检测图时(hidden)卡片退回文字占位 */
.ditem-img[hidden] { display: none; }
/* ═══════════ 隐私政策与服务协议(全文页) ═══════════ */
.overlay-policy { background: #F5F5F5; }
.policy-page { width: 100%; height: 100%; display: flex; flex-direction: column; background: #fff; }
.policy-header {
position: relative; flex: none; height: var(--nav-h);
display: flex; align-items: center; justify-content: center;
background: #fff; border-bottom: 1px solid var(--line);
}
.policy-header .nav-back { position: absolute; left: 4px; top: 0; width: 40px; height: 100%; display: flex; align-items: center; justify-content: center; }
.policy-header-title { font-size: 14px; font-weight: 500; color: #000; }
.policy-body { flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 22px 20px 48px; }
.policy-title { font-size: 19px; font-weight: 700; color: var(--ink); line-height: 1.4; margin-bottom: 16px; }
.policy-h2 {
font-size: 15px; font-weight: 600; color: var(--ink);
margin: 26px 0 10px; padding-left: 9px;
border-left: 4px solid var(--yellow); line-height: 1.3;
}
.policy-h3 { font-size: 13.5px; font-weight: 600; color: var(--ink); margin: 16px 0 6px; }
.policy-body p { font-size: 12.5px; color: var(--para); line-height: 1.9; margin-bottom: 10px; text-align: justify; }
.policy-body strong { color: var(--ink); }
.policy-body ul, .policy-body ol { padding-left: 1.5em; margin: 0 0 10px; }
.policy-body li { font-size: 12.5px; color: var(--para); line-height: 1.9; margin-bottom: 5px; text-align: justify; }
.policy-body li::marker { color: var(--grey); }
.policy-toc { color: var(--grey-2); }
.policy-end { text-align: center; color: var(--grey); margin-top: 28px; }
/* ═══════════ 历史报告 ═══════════ */
.nav-history {
position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
font-size: 12px; color: var(--grey-2); padding: 4px 8px;
}
.policy-header .history-clear {
position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
font-size: 12px; color: var(--grey-2); padding: 4px 8px;
}
.history-empty { text-align: center; color: var(--grey); font-size: 12.5px; padding: 60px 0; }
.his-item {
display: flex; align-items: center; gap: 12px;
background: #fff; border: 1px solid var(--line); border-radius: 10px;
padding: 14px 14px; margin-bottom: 10px; cursor: pointer;
}
.his-thumb { width: 44px; height: 56px; border-radius: 6px; object-fit: cover; flex: none; background: var(--bg); }
.his-main { flex: 1; min-width: 0; }
.his-main b { display: block; font-size: 13px; font-weight: 600; color: var(--ink); margin-bottom: 3px; }
.his-main span { display: block; font-size: 11px; color: var(--grey); }
.his-score { flex: none; text-align: right; }
.his-score b { font-size: 22px; font-weight: 500; color: var(--ink); }
.his-score span { font-size: 11px; color: var(--grey); margin-left: 2px; }
.his-del { flex: none; font-size: 11px; color: var(--grey-2); padding: 6px 4px; }
/* ═══════════ 第6轮:真机反馈 13 项 ═══════════ */
/* #2 姿态提示浮层:移到取景框下方(原 29% 与脸部轮廓/下巴重叠) */
.cam-hint { bottom: 21%; }
/* #10 无进展提示与快门重叠:上移 */
.cam-nudge { bottom: 16%; }
/* #4/#10 拍照页顶栏取消,返回键改悬浮白圆(对齐设计稿) */
.cam-back-float {
position: absolute; top: 12px; left: 12px; z-index: 3;
background: rgba(255,255,255,.9); border-color: transparent;
}
/* #12 预览镜像改为类切换(前置镜像/后置不镜像) */
#cam-video { transform: none; }
#cam-video.mirror { transform: scaleX(-1); }
/* #1 城市自定义下拉(替代原生 select) */
.rs { position: relative; }
.rs-current {
width: 100%; display: flex; align-items: center; justify-content: space-between;
background: #fff; border: 1px solid var(--line); border-radius: 8px;
padding: 12px 14px; font-size: 13px; color: var(--ink); text-align: left;
}
.rs-current .chev { transition: transform .2s; }
.rs.open .rs-current .chev { transform: rotate(225deg); }
.rs-value.rs-placeholder { color: #B3B3B3; }
.rs-list {
position: absolute; left: 0; right: 0; top: calc(100% + 6px); z-index: 30;
max-height: 264px; overflow-y: auto; -webkit-overflow-scrolling: touch;
background: #fff; border: 1px solid var(--line); border-radius: 8px;
box-shadow: 0 8px 24px rgba(0,0,0,.08);
}
.rs-list li { padding: 12px 14px; font-size: 13px; color: var(--ink); }
.rs-list li + li { border-top: 1px solid #F3F3F3; }
.rs-list li:active { background: #F7F7F7; }
/* #5 隐私页去头部条,返回键悬浮 */
.policy-float-back {
position: absolute; top: 12px; left: 12px; z-index: 2;
background: #fff; box-shadow: 0 1px 6px rgba(0,0,0,.12);
}
.overlay-policy .policy-page { position: relative; }
/* ═══════════ 第7轮:用户测试 agent 反馈 ═══════════ */
/* P1-1 隐私页标题被悬浮返回键遮挡:正文上留返回键位 */
#p-policy .policy-body { padding-top: 52px; }
/* P1-2 姿态提示气泡压住底部引导文字:改到步骤文案下方、取景框上方 */
.cam-hint { bottom: auto; top: 26%; }
/* ═══════════ 第8轮:真机反馈 11 项 ═══════════ */
/* #1 城市下拉浮层层级高于肤质轮播圆点 */
.rs { z-index: 50; }
.rs-list { z-index: 50; }
/* #4 无进展提示再上移(取景/拍摄区下方,引导 chips 上方) */
.cam-nudge { bottom: 17.5%; } /* 引导 chips(bottom 22.4%) 与快门之间 */
/* #6 报告页头部:按 Figma 08 还原为内联白底顶栏(见报告页主区块),不再悬浮 */
/* ═══════════ 第9轮:真机反馈 ═══════════ */
/* #1 城市下拉浮层再提级,并加实体阴影边界(部分端 stacking 表现不同) */
.rs, .rs-list { z-index: 999; }
/* #3 姿态提示浮层改设计语言:无气泡底,纯白文字+投影,置于引导 chips 上方 */
.cam-hint {
top: auto; bottom: 26%;
background: none; padding: 0; border-radius: 0;
font-size: 15px; font-weight: 500; text-shadow: 0 1px 8px rgba(0,0,0,.65);
}
.cam-hint.ok { background: none; color: #34C759; }
/* #9 档案页顶栏移除,返回键悬浮(白圆带影,压暗背景上可读) */
.profile-float-back {
position: fixed; top: 12px; left: 12px; z-index: 21;
background: rgba(255,255,255,.92); border-color: transparent;
box-shadow: 0 1px 6px rgba(0,0,0,.18);
}
/* 下拉浮层与肤质圆点之间留明确间隙 */
.rs-list { max-height: 236px; }