/* 品源 · 商家手机端版式（`web/app/`）· 2026-10-07 · **只服务手机端**
   （电脑端是 `web/pinyuan.css`，两份文件、两个入口）。三条纪律，都是踩出来的：
     ① 类名一律 `pv-` 前缀、页面根 `.pv` —— `pinyuan.css` 里 `.btn` / `.row` / `.card`
        这些通用名**都带着电脑端几何**；两边一旦交叉引用，同权重就靠"谁后加载"
        决定胜负，那是本仓最恨的一类静默不一致。
     ② 颜色/间距/圆角/阴影**只读 `:root` 令牌**，规则体里不写裸色值。令牌的唯一事实源
        仍是 `pinyuan.css` 的 `:root`，这一份是**镜像**，`core/test_app_contract.py`
        逐值比对两边（对不上就红）。
     ③ **触摸目标 ≥44、输入框字号 ≥16**（16 是 iOS 的硬线：小于它聚焦会放大整页）
        —— `tools/cdp-verify-app.py` 逐元素量这两条。
   几何分工：`.pv` 固定外壳（100dvh + 安全区，**页面整体不滚**）· `.pv-body` 唯一滚动
     容器 · `.pv-tab` 常驻底栏（4 格 + 凸起拍照键）· `.pv-sheet` 底部弹层。
   ⚠️ **这个文件的注释算首屏字节**（`tools/bytes.py`）。2026-10-11 起为腾预算收过
      长版，细节见 git 历史（对应的判据都还在：D2/B1/K）。 */

/* ── 令牌镜像（唯一事实源：`web/pinyuan.css` 的 `:root`；判据见文件头 ②）────── */
:root{
  /* ★ 2026-10-31 主题：浅色是默认。`color-scheme` 管的是**浏览器自己画的那部分**
     （滚动条、输入框、自动填充、表单控件）—— 不写它，深色下滚动条仍是白的。
     深色令牌在文件末尾的 `:root[data-theme="dark"]`，只覆盖颜色，不动几何。 */
  color-scheme:light;
  /* 镜像块：`--tx3` 改深的账写在 `web/pinyuan.css` 那一行上面。**两端逐值相同。** */
  --tx:#1F2329; --tx2:#646A73; --tx3:#697077;
  --brand:#2E6BF0; --brand-soft:#E9F0FE;
  /* ★ `--bg` = 页面底，`--card` = 浮在上面的面（卡片/栏）。
     浅色下两者都是 #fff（所以拆开这件事**一个像素都没改**）；
     深色下必须分开：底 #111418 比面 #1A1E24 深，否则整页是一块平板、层次全平。 */
  --line:#DEE0E3; --content:#F2F3F5; --card:#fff; --bg:#fff;
  /* ★ 2026-11-10（P3 样板）补三个"压在实色/照片上的字与遮罩"令牌。
     它们**在电脑端一直有**（`pinyuan.css` 的 `--on-solid`/`--on-photo`/`--scrim-img`），
     手机端这份镜像却漏了 —— 于是 `/platstudio` 写 `color:var(--on-solid)` 时
     `var()` 取不到值 → **整条声明失效** → 颜色退回继承（= --tx），
     浅色下按钮字变成深灰、深色下变成浅灰，而且不报错。
     这不是"顺手补的"：样板文件 plat.css 正是靠它把最后 3 个裸色值换掉的。
     ⚠️ 值必须与 `pinyuan.css` 逐值相同（判据：core/test_app_contract 令牌镜像）；
        深色那三行同理（判据：core/test_theme 令牌同构）。 */
  --on-solid:#fff; --on-photo:#fff; --scrim-img:rgb(31 35 41/72%);
  --ok:#1A7F37; --ok-soft:#E6F4EA;
  --warn:#B26A00; --warn-soft:#FFF4E5;
  --danger:#C5221F; --danger-soft:#FDECEA;
  --info:#175CD3; --info-soft:#EFF8FF;
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:20px; --s6:24px; --s8:32px;
  --r-sm:6px; --r-md:10px;
  /* 字号档位：**镜像**自 `web/pinyuan.css` 的 `--fs-*`（逐值比对见 core/test_app_contract.py）。
     手机端自己直接用（`/platstudio` 也引本文件当令牌源），所以必须在这儿真有一份，
     不能只在电脑端定义 —— `var()` 取不到值时 font-size 整条声明失效，字号会退回继承，
     而那种坏法**不报错**、只是字变大变小。 */
  --fs-2xs:10px; --fs-xs:11px; --fs-sm:12px; --fs-md:13px;
  --fs-lg:14px;  --fs-xl:15px; --fs-3xl:18px;  --fs-4xl:22px;
  --sh2:0 4px 12px rgb(16 24 40/8%),0 1px 2px rgb(16 24 40/4%);
  --dur-2:180ms; --ease-out:cubic-bezier(.2,.8,.2,1);

  /* ── 手机端自己的语义令牌（`--pv-` 前缀 = 电脑端没有对应物）──────────────
     上面那份是**电脑端令牌的镜像**（逐值比对见 `core/test_app_contract.py`）；而底栏角标
     的红、登录页那层渐变、热/迟两档的浅底，电脑端根本不需要。它们**只能**放在 `:root`：
     规则体里写裸色值就等于作废"颜色只有一处来源"这条规矩。
     判据只认前缀 —— 加了 `--pv-` 就是"手机端专属"，不加就是"必须与电脑端逐值相同"。 */
  --pv-badge:#e5484d;
  --pv-off-bg:#EFF0F1;
  --pv-note-bg:#EEF3FF; --pv-note-line:#D3E0FB;
  --pv-soft:#FAFBFC;
  --pv-checkbox-line:#C6C9CE;
  --pv-login-bg:#EAF1FF;
  --pv-login-warn-bg:#FFF6E9;
  --pv-brand-2:#4B84F5;
  --pv-brand-3:#5B8DF7;
  --pv-warn-2:#F0A93C;
  --pv-warn-3:#D98314;
  --pv-hot-bg:#FFF1F0;
  --pv-hot-line:#F6C9C6;
  --pv-hot-tx:#A5382F;
  --pv-late-bg:#FFF6F5;
  --pv-late-line:#F3B7B2;
  --pv-ai-tx:#17418F;
  --pv-miss-bg:#FFFCF5;
  --pv-miss-line:#F3D9A8;
  --pv-done-bg:#F7FCF8;
  --pv-done-line:#BFE0C6;
}
*,*::before,*::after{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{height:100%;margin:0}
body{
  background:var(--bg); color:var(--tx);
  font:15px/1.55 -apple-system,BlinkMacSystemFont,"PingFang SC","Hiragino Sans GB",
       "Microsoft YaHei",sans-serif;
  /* 后台是"外壳固定、内容区自己滚"：页面整体不滚，才谈得上"底栏永远在" */
  overflow:hidden;
  -webkit-text-size-adjust:100%;
  -webkit-font-smoothing:antialiased;
}
[hidden]{display:none !important}
a{color:var(--brand);text-decoration:none}
:focus-visible{outline:2px solid var(--brand);outline-offset:2px}

/* ══ 外壳 ══════════════════════════════════════════════════════════════════ */
/* `100dvh` 而不是 `100vh`：移动浏览器的地址栏收起/展开会改视口高度，
   用 vh 会让底栏在滚动时"跳一下"。安全区两向都留 —— 刘海与手势条。 */
.pv{height:100dvh;display:flex;flex-direction:column;
  padding-top:env(safe-area-inset-top);padding-bottom:env(safe-area-inset-bottom);
  background:var(--bg)}

.pv-head{flex:none;min-height:52px;display:flex;align-items:center;gap:8px;
  padding:0 var(--s4);background:var(--card);border-bottom:1px solid var(--line);
  position:relative;z-index:20}
.pv-head .pv-t{flex:1;min-width:0;font-size:17px;font-weight:600;line-height:1.25;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pv-head .pv-t small{display:block;font-size:12px;color:var(--tx3);font-weight:400;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* ★ 2026-10-11：48 → **52**（设计规格《上货-冻结版》§1.1；`plainHead` 全端只有
   上货这一页用，见 `app.js:1383`）。`border-bottom:0` 保留：设计稿顶栏无下边框。 */
.pv-head.pv-head--plain{border-bottom:0;min-height:52px}

.pv-body{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;
  -webkit-overflow-scrolling:touch;background:var(--bg)}
.pv-body.pv-grey{background:var(--content)}
/* 内容区底部**永远**给凸起拍照键让位：34 = 它高出底栏的 26 + 呼吸。
   ⚠️ 这必须归**外壳**，不能归每一页 —— 第一版做成"哪一页有底栏就自己加一个类"，
      结果「加载中」「读不到」那两屏没跑到加类那一行，留白是 0，上货页的「从相册选」
      当场被那个圆压掉一半（`cdp-verify-app.py` 的 A4 判据红出来的）。 */
.pv-body{padding-bottom:34px}
.pv.pv-notab .pv-body{padding-bottom:0}     /* 聊天页没有底栏，也就没有凸起键 */
/* ★ 2026-10-11 晚（用户「拍照三页都显示底部导航」）：上货①②回执改成**有底栏**，
   于是也要"内容不被凸起键盖住"（A4）。⚠️ 24 与那三屏底部块自己的 5 是一组：
   一起决定"主按钮离屏幕底 85"（门换算成"与底栏顶线 29±3"）。 */
.pv-body--flow{padding-bottom:24px}
.pv-body.pv-pad{padding-left:var(--s4);padding-right:var(--s4)}

/* 图标：`.pv-ic` 必须自带尺寸 —— 不给的话 SVG 按默认 300×150 渲染 */
.pv-ic{width:24px;height:24px;flex:none;display:block}
.pv-ib{width:44px;height:44px;flex:none;display:flex;align-items:center;
  justify-content:center;border:0;background:none;padding:0;margin:-10px 0;
  color:var(--tx);cursor:pointer;border-radius:50%;font:inherit}
.pv-ib:active{background:var(--content)}
/* 上货②右上那颗动作键：实心胶囊（原来是一行 15px 蓝字，真机上和标题一个分量 ——
   用户原话「拍完后也没成完成的下一步」）。`width:auto;margin:0` 不能省：
   `--go` 没覆盖 `.pv-ib` 的 `width:44px`，只挂 `--go` 实测掉到 44 宽、文字折三行。 */
.pv-ib--go{padding:0 14px;border-radius:22px;background:var(--brand);
  color:var(--card);font-weight:600;width:auto;margin:0}
.pv-ib--go:active{background:var(--brand);opacity:.88}

/* ══ 底栏：4 格 + 中间凸起拍照 ═════════════════════════════════════════════ */
.pv-tab{flex:none;display:flex;align-items:flex-start;height:56px;padding-top:6px;
  background:var(--card);border-top:1px solid var(--line);position:relative;z-index:30}
/* 底栏：标签 12px、图标 24px（相机键 26px），触摸目标 47 ≥ 44。
   ⚠️ `line-height:1.2` 必须显式写：不然吃 body 的 1.55，24+2+12×1.55=44.6，离 47 只剩 2.4px。 */
.pv-tab .pv-tb{flex:1;height:47px;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:2px;font-size:12px;line-height:1.2;color:var(--tx3);
  background:none;border:0;padding:0;font-family:inherit;cursor:pointer;position:relative}
.pv-tab .pv-tb .pv-ic{width:24px;height:24px}
.pv-tab .pv-tb.on{color:var(--brand);font-weight:600}
.pv-tab .pv-tb .pv-dot{position:absolute;top:1px;left:50%;margin-left:3px;min-width:17px;
  height:17px;padding:0 5px;border-radius:9px;background:var(--pv-badge);color:var(--card);
  font-size:12px;line-height:17px;font-weight:600;text-align:center;
  box-shadow:0 0 0 2px var(--card)}
/* ★ 2026-10-29：凸起拍照键（`.pv-tcam`）跟着「上货」一起迁出老板端 ——
   底栏现在只有「数据 / 我的」两格，这颗键和它的选中态规则都已删除。
   拍照入口在独立工作台 `/studio`（底部第一格「拍摄」）。 */

/* ══ 通用零件 ══════════════════════════════════════════════════════════════ */
.pv-sec{padding:14px 0 2px}
.pv-sec > h2{display:flex;align-items:center;min-height:44px;margin:0 0 6px;
  font-size:13px;font-weight:600;color:var(--tx2)}

.pv-card{background:var(--card);border:1px solid var(--line);border-radius:var(--r-md);
  overflow:hidden}
/* 一行 ≥56px（比 44 的下限还高：列表行要能"一指戳中"，不是"勉强够到"） */
.pv-row{display:flex;align-items:center;gap:10px;min-height:56px;padding:10px 14px;
  border-bottom:1px solid var(--line);background:var(--card);cursor:pointer;
  width:100%;text-align:left;font:inherit;color:inherit;border-left:0;border-right:0;border-top:0}
.pv-row:last-child{border-bottom:0}
.pv-row:active{background:var(--content)}
.pv-row .pv-g{flex:1;min-width:0}
.pv-row .pv-g > b{display:block;font-size:15px;font-weight:500;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pv-row .pv-g span{display:block;font-size:12px;color:var(--tx3);margin-top:2px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pv-row .pv-v{flex:none;font-size:14px;color:var(--tx2)}

.pv-btn{display:flex;align-items:center;justify-content:center;gap:6px;width:100%;
  height:48px;min-height:48px;padding:0 16px;border:1px solid var(--line);border-radius:var(--r-md);
  background:var(--card);color:var(--tx);font:inherit;font-size:16px;font-weight:500;
  cursor:pointer}
.pv-btn:active{background:var(--content)}
.pv-btn--p{background:var(--brand);border-color:var(--brand);color:var(--card)}
.pv-btn--p:active{opacity:.9}
.pv-btn--g{background:none;border:0;color:var(--brand);font-weight:400}
.pv-btn--sm{height:44px;width:auto;padding:0 20px;font-size:14px}
.pv-btn[disabled]{opacity:.45;cursor:default}
.pv-btn--busy{position:relative;color:transparent !important}
.pv-btn--busy::after{content:"";position:absolute;width:18px;height:18px;border-radius:50%;
  border:2px solid currentColor;border-color:var(--card) var(--card) var(--card) transparent;
  animation:pvspin .7s linear infinite}
.pv-btn:not(.pv-btn--p).pv-btn--busy::after{border-color:var(--brand) var(--brand) var(--brand) transparent}
@keyframes pvspin{to{transform:rotate(360deg)}}

/* ★ 2026-10-08 真机第三轮：「**输入框变小**」—— 根因是**布局**不是样式：键盘一弹起来
   视口变矮，`.pv-body--col` 是纵向 flex，子项默认 `flex-shrink:1` 就把 `height:48px`
   的输入框和按钮一起压成 40。`min-height` 是钉住它最直接的一处（它是属性，不与别的
   flex 规则打架）。键盘弹起时的尺寸由 `cdp-verify-app.py` 那两条判据量着。 */
.pv-inp{width:100%;height:48px;min-height:48px;padding:0 14px;border:1px solid var(--line);
  border-radius:var(--r-md);background:var(--card);color:var(--tx);
  /* 16px 是 iOS 的硬线：小于它聚焦时 Safari 会放大整页 */
  font:inherit;font-size:16px;outline:none}
.pv-inp:focus{border-color:var(--brand);box-shadow:0 0 0 3px rgb(46 107 240/15%)}
.pv-inp::placeholder{color:var(--tx3)}
.pv-lab{display:block;font-size:13px;color:var(--tx2);margin:16px 0 6px}
.pv-lab i{color:var(--danger);font-style:normal}

.pv-tag{display:inline-block;flex:none;font-size:12px;line-height:18px;padding:0 8px;
  border-radius:4px}
.pv-tag--ok{color:var(--ok);background:var(--ok-soft)}
.pv-tag--warn{color:var(--warn);background:var(--warn-soft)}
.pv-tag--off{color:var(--tx2);background:var(--pv-off-bg)}
.pv-tag--red{color:var(--danger);background:var(--danger-soft)}

/* 横滑页签 / 快捷回复 —— 44px 高是触摸下限，不是审美 */
.pv-find{display:flex;gap:8px;align-items:center;padding:4px var(--s4) 10px}
.pv-find .pv-inp{flex:1;min-width:0;height:40px;font-size:16px}
.pv-find .pv-btn{flex:none}
.pv-chips{display:flex;gap:8px;overflow-x:auto;padding:10px var(--s4);flex:none;
  border-bottom:1px solid var(--line);background:var(--card);
  scrollbar-width:none;-webkit-overflow-scrolling:touch}
.pv-chips::-webkit-scrollbar{display:none}
.pv-chip{flex:none;height:44px;padding:0 18px;border-radius:22px;border:1px solid var(--line);
  background:var(--card);color:var(--tx2);font:inherit;font-size:14px;
  display:flex;align-items:center;cursor:pointer}
.pv-chip.on{background:var(--brand-soft);border-color:var(--brand);color:var(--brand);
  font-weight:600}
.pv-chips--flat{border-bottom:0;padding:0 0 10px;background:none}
/* 主题三档（「我的 › 外观」，2026-10-31）：等分三格。高度沿用 `.pv-chip` 的 44
   —— 那是触摸下限，判据 `cdp-verify-app.py` 逐元素量，不是为了好看。 */
.pv-seg{display:flex;gap:6px;padding:0 10px 12px}
.pv-seg .pv-chip{flex:1 1 0;padding:0 4px;justify-content:center;font-size:13px}

/* 三态：读到 / 读不到并说出口 / 真的是空 —— **三种样子必须能分辨** */
.pv-state{padding:22px var(--s4);text-align:center;font-size:14px;color:var(--tx2);
  line-height:1.75}
.pv-state b{display:block;font-size:15px;color:var(--tx);margin-bottom:6px;font-weight:600}
.pv-state--err b{color:var(--warn)}
.pv-state .pv-btn{margin-top:14px}
.pv-sk{padding:14px var(--s4)}
.pv-sk i{display:block;height:14px;border-radius:7px;background:var(--content);
  margin-bottom:10px;animation:pvsk 1.2s ease-in-out infinite}
@keyframes pvsk{0%,100%{opacity:1}50%{opacity:.5}}

/* ══ 登录（整屏覆盖：无头、无底栏）════════════════════════════════════════ */
.pv-login{position:fixed;inset:0;z-index:100;display:flex;flex-direction:column;
  overflow-y:auto;background:
    radial-gradient(120% 52% at 50% 0%,var(--pv-login-bg) 0%,var(--card) 62%) var(--card);
  padding:calc(env(safe-area-inset-top) + 44px) 28px
          calc(env(safe-area-inset-bottom) + 20px)}
.pv-login--warn{background:
  radial-gradient(120% 52% at 50% 0%,var(--pv-login-warn-bg) 0%,var(--card) 62%) var(--card)}
.pv-login .pv-brand{text-align:center;margin-bottom:26px;flex:none}
.pv-login .pv-logo{width:76px;height:76px;border-radius:20px;margin:0 auto 14px;
  background:linear-gradient(140deg,var(--pv-brand-2),var(--brand));color:var(--card);
  display:flex;align-items:center;justify-content:center;font-size:30px;font-weight:700;
  box-shadow:0 10px 24px rgb(46 107 240/28%)}
.pv-login .pv-logo--warn{background:linear-gradient(140deg,var(--pv-warn-2),var(--pv-warn-3));
  box-shadow:0 10px 24px rgb(217 131 20/28%)}
.pv-login h1{font-size:24px;margin:0 0 6px;letter-spacing:1px}
.pv-login .pv-sub{font-size:13px;color:var(--tx2)}
.pv-login form{display:flex;flex-direction:column;gap:12px;margin-top:24px;flex:none}
.pv-eye{position:absolute;right:4px;top:2px}
.pv-field{position:relative}
.pv-agree{display:flex;gap:8px;align-items:flex-start;margin-top:16px;flex:none;
  font-size:12px;color:var(--tx2);line-height:1.65;cursor:pointer;
  min-height:44px;padding:2px 0}
/* ⚠️ 协议链接的可点面积（审计 C1）：原来只有 72×15。现在 15 → 31px，**行高不动**。
   ⚠️ 必须**真行内**：只有真行内的纵向 `padding` 才不撑行高 —— 第一版写成
      `inline-block`，勾选行当场从 44 涨到 **60**（验收判据红出来的）。
   做不到 44 是有意的（这一行是两段文字，撑到 44 会把段落撕开；B1 对此有豁免）。 */
.pv-agree a{padding:8px 0}
.pv-agree .pv-bx{width:20px;height:20px;flex:none;margin-top:1px;border-radius:5px;
  border:1.5px solid var(--pv-checkbox-line);background:var(--card);display:flex;align-items:center;
  justify-content:center;color:var(--card)}
.pv-agree.on .pv-bx{background:var(--brand);border-color:var(--brand)}
.pv-agree .pv-bx .pv-ic{width:14px;height:14px}
.pv-agree.err{color:var(--danger)}
.pv-agree.err .pv-bx{border-color:var(--danger);animation:pvshake .4s}
@keyframes pvshake{0%,100%{transform:translateX(0)}25%{transform:translateX(-5px)}
  75%{transform:translateX(5px)}}
.pv-err{margin-top:12px;padding:10px 12px;border-radius:8px;font-size:13px;
  color:var(--danger);background:var(--danger-soft);flex:none}
.pv-login .pv-go{margin-top:16px;flex:none}
.pv-login .pv-alt{display:flex;align-items:center;justify-content:center;min-height:48px;
  font-size:14px;color:var(--brand);cursor:pointer;flex:none}
/* ⚠️ `.pv-foot` 原来**只在登录页有规则** → 看板上那两处静默继承 body 的 15px
   （同一个类名一处 12px 一处 15px，而 15px 那份没人声明过 · 审计 B5）。 */
.pv-foot{font-size:12px;color:var(--tx3)}
.pv-login .pv-foot{margin-top:auto;padding-top:24px;flex:none;text-align:center;
  line-height:1.9}
.pv-login .pv-foot a{color:var(--tx3)}

/* ══ 首页 ══════════════════════════════════════════════════════════════════
   ★ 2026-10-08 首页清空（用户「首页的内容都不要，以后要换成数据看板」）：
   原来那套数字卡的规则跟着一起删了（留着就是没人用的规则，D2 本来防这个）。 */

/* ══ 商品 ══════════════════════════════════════════════════════════════════ */
.pv-plist{padding:12px var(--s4) 4px;display:flex;flex-direction:column;gap:10px}
.pv-pc{display:flex;align-items:center;gap:12px;padding:10px;background:var(--card);
  border:1px solid var(--line);border-radius:var(--r-md);cursor:pointer;
  font:inherit;color:inherit;text-align:left;width:100%}
.pv-pc:active{background:var(--content)}
.pv-pc .pv-im{width:72px;height:72px;flex:none;border-radius:var(--r-sm);
  background:var(--content);object-fit:cover;display:flex;align-items:center;
  justify-content:center;font-size:26px;color:var(--tx3);overflow:hidden}
.pv-pc .pv-g{flex:1;min-width:0}
.pv-pc .pv-g > b{display:block;font-size:15px;font-weight:600;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pv-pc .pv-g .pv-pr{font-size:15px;font-weight:600;color:var(--danger);margin-top:3px;
  font-variant-numeric:tabular-nums}
.pv-pc .pv-g .pv-mt{font-size:12px;color:var(--tx3);margin-top:3px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pv-pc .pv-r{flex:none;align-self:flex-start}
/* 详情图：多张时**横向滑动**（scroll-snap），首张仍是整幅宽；
   圆点跟着滚动位置亮 —— 原来只画第一张却画出 N 颗点，点哪张都不变。 */
.pv-gallery{position:relative;background:var(--content);display:flex;overflow-x:auto;
  scroll-snap-type:x mandatory;scrollbar-width:none;-webkit-overflow-scrolling:touch}
.pv-gallery::-webkit-scrollbar{display:none}
.pv-gallery .pv-shot{display:block;flex:none;width:100%;aspect-ratio:1/1;object-fit:cover;
  scroll-snap-align:start;scroll-snap-stop:always}
.pv-gallery .pv-shot--ph{display:flex;align-items:center;justify-content:center;
  font-size:64px;color:var(--tx3)}
.pv-dots{display:flex;gap:6px;justify-content:center;padding:10px 0}
.pv-dots i{width:6px;height:6px;border-radius:50%;background:var(--line);font-style:normal}
.pv-dots i.on{background:var(--brand)}

/* ══ 上货（拍照）══════════════════════════════════════════════════════════
   ★ 2026-10-07 真机返工：**三步进度条删掉了**（用户口径「上面三个条只显示一个上货
   意义不大」—— 三个里只有一个是真实状态，"我在第几步"从屏幕内容本身就看得出）。 */
/* 底部 34px 是给**凸起拍照键**让位的：它比底栏高出 16px，
   不让位的话最后一屏的「从相册选」正好被那个圆压住（实拍到的）。 */
.pv-shoot{padding:18px var(--s4) 34px;display:flex;flex-direction:column;flex:1;min-height:0}
.pv-shot{position:relative;width:100px;height:100px;flex:none;border-radius:var(--r-md);
  background:var(--content);border:1px solid var(--line);overflow:hidden;
  display:flex;align-items:center;justify-content:center;font-size:32px;color:var(--tx3)}
.pv-shot img{width:100%;height:100%;object-fit:cover;display:block}
/* ★ 2026-10-29：`.pv-shot .pv-del`（拍照缩略图右上角删除）与 `.pv-shot--add`
   只服务旧「上货」屏；新工作台用 `.st-*` 自己的缩略图与失败态，这两条已删除。 */
/*: 拍满 5 张后那一格（`shoot.js` 的 `.pv-shot--ph`）：白底 + 实描边。
   ⚠️ 尺寸不在这条里：方与填满归 `.pv-tl`（写 `height:100%` 会塌成细长条）。 */
.pv-shot--ph{background:var(--card);box-shadow:inset 0 0 0 1px var(--line);cursor:default}
/* ★ 2026-10-29：`.pv-shot--fail` 迁到工作台的 `.st-tag--bad`（见 `web/studio/studio.css`）。 */
.pv-shot .pv-retry{position:absolute;inset:0;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:4px;border:0;cursor:pointer;
  background:rgb(255 255 255/88%);color:var(--danger);font:inherit;font-size:12px}
.pv-shot .pv-retry b{display:block;width:26px;height:26px;border-radius:50%;
  background:var(--danger);color:var(--card);font-size:16px;line-height:26px;text-align:center}
/* 待编辑 / 待审核的草稿行：一行一件事，每行给三样能认人的东西（图 / 编号 / 名字） */
.pv-dlist{padding:12px var(--s4) 4px}
/* 左滑露出「丢弃」。⚠️ 88px 与 `goods.js::bindSwipe` 里的 -88 必须同改。 */
.pv-drow{position:relative;overflow:hidden;border-radius:var(--r-md);margin-bottom:10px}
.pv-drow .pv-dc{margin-bottom:0;position:relative;z-index:1}
.pv-drow--open .pv-dc{box-shadow:-2px 0 8px rgb(0 0 0/6%)}
.pv-ddrop{position:absolute;top:0;right:0;bottom:0;width:88px;border:0;cursor:pointer;
  background:var(--danger);color:var(--card);font:inherit;font-size:14px;font-weight:600}
.pv-dc{display:flex;align-items:center;gap:12px;width:100%;text-align:left;
  padding:10px;margin-bottom:10px;background:var(--card);border:1px solid var(--line);
  border-radius:var(--r-md);font:inherit;color:inherit;cursor:pointer}
.pv-dc:active{background:var(--content)}
.pv-dc .pv-im{width:64px;height:64px;flex:none;border-radius:var(--r-sm);
  background:var(--content);overflow:hidden;display:flex;align-items:center;
  justify-content:center;font-size:24px;color:var(--tx3)}
.pv-dc .pv-im img{width:100%;height:100%;object-fit:cover;display:block}
.pv-dc .pv-g{flex:1;min-width:0}
.pv-dc .pv-g > b{display:block;font-size:15px;font-weight:600;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pv-dc .pv-g > b.non{color:var(--tx3);font-weight:400}
.pv-dc .pv-g span{display:block;margin-top:3px;font-size:12px;color:var(--tx3);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* 破坏性动作的字色。⚠️ 这个类**此前用了却没定义**（`me.js` 的「退出登录」一直是普通色）
   —— D2 只查"定义了没人用"，查不出"用了没定义"。 */
.pv-danger{color:var(--danger)}
.pv-hint{text-align:center;font-size:12px;color:var(--tx3);margin-top:10px;line-height:1.6}
/* ★ 2026-10-29：`.pv-picked`（旧上货 ② 的身份行）迁到工作台的 `.st-h`。 */

/* 需要"撑满剩余高度"的页（拍照三步、回执）：内容区自己变纵向 flex，
   里面的 `margin-top:auto` 才推得动主按钮 —— 否则它会贴在内容后面而不是底部。 */
.pv-body--col{display:flex;flex-direction:column}
/* 提交回执：一整屏，不是 toast。
   "还缺 N 项"必须留在屏幕上等他看完 —— 一闪而过的提示等于没说。 */
.pv-done{flex:1;display:flex;flex-direction:column;align-items:center;
  justify-content:center;padding:24px 28px;text-align:center}
/* ★ 2026-10-29：`.pv-tick`（旧上货回执的对勾）没有使用方了 —— 删除。 */
.pv-done h2{margin:0 0 6px;font-size:20px}
.pv-done p{margin:0 0 22px;font-size:14px;color:var(--tx2);line-height:1.75}

/* ══ 客服（工作台）════════════════════════════════════════════════════════
   ★ 2026-10-12 用户原话「**统一叫客服…我要真实的客服页你咋就听不懂老是出个空页**」：
   从"会话列表页"改成工作台，老的两族规则整个删了（要捞回来看 git 历史）。
   ⚠️ **这段注释里故意不写带点的类名**：D2 是纯文本扫的，注释里带点的类名照样算
      "定义了没人用"（这一版我自己就踩了一次）。 */
/* 导购通不通那颗灯（`msg.js::led()`，三态与"认码不认文案"的账都在那儿：那半边不计费）。 */
.pv-led{display:inline-block;width:9px;height:9px;border-radius:50%;margin-right:6px;
  background:var(--ok);animation:pvsk 2.4s ease-in-out infinite}
.pv-led--off{background:var(--warn);animation:none}
.pv-led--err{background:var(--danger);animation:none}

.pv-ctx{margin:10px var(--s4) 0;padding:10px 14px;background:var(--pv-soft);flex:none;
  border:1px solid var(--line);border-radius:var(--r-md);font-size:12px;color:var(--tx2)}
.pv-ctx b{display:block;font-size:13px;color:var(--tx);margin-bottom:4px}
.pv-ctx .pv-kv{display:flex;gap:6px;line-height:1.9}
.pv-ctx .pv-kv i{flex:none;font-style:normal;color:var(--tx3)}
/* ★ 2026-10-12：容器必须是 **flex 竖列** —— `.pv-bub--*` 那三条 `align-self` 否则一直空转
   （真会话里三类气泡全贴左、"你一句我一句"看不出来）。账与实测见 `msg.js::skel`。 */
.pv-chat{padding:14px var(--s4);display:flex;flex-direction:column}
.pv-bub{max-width:78%;margin-bottom:8px;padding:9px 13px;border-radius:16px;
  font-size:15px;line-height:1.5;word-break:break-word}
.pv-bub .pv-who{display:block;font-size:12px;opacity:.65;margin-bottom:2px}
.pv-bub--them{align-self:flex-start;background:var(--content);border-bottom-left-radius:5px}
.pv-bub--me{align-self:flex-end;background:var(--brand);color:var(--card);border-bottom-right-radius:5px}
.pv-bub--ai{align-self:flex-start;background:var(--brand-soft);color:var(--pv-ai-tx);
  border-bottom-left-radius:5px}
.pv-sys{align-self:center;margin:6px 0;padding:3px 12px;border-radius:10px;
  background:var(--content);font-size:12px;color:var(--tx3)}
.pv-composer{flex:none;padding:10px var(--s4) 12px;background:var(--card);
  border-top:1px solid var(--line)}
.pv-composer .pv-line{display:flex;gap:8px;align-items:flex-end}
.pv-composer .pv-inp{height:44px;border-radius:22px;padding:0 16px}
.pv-composer .pv-send{flex:none;width:64px;height:44px;border-radius:22px;border:0;
  background:var(--brand);color:var(--card);font:inherit;font-size:15px;font-weight:600;
  cursor:pointer}
.pv-composer .pv-send[disabled]{opacity:.45}
/* ★ 2026-10-12：线不删，1px 边框盒子留着、只把颜色变透明，线由背景画在 16..宽−16；
   `.pv-desk` 把底部那 34px 留白收成 0。账与判据见 `msg.js::drawChat`。 */
.pv-sep--b,.pv-sep--t{border-color:transparent;background-origin:border-box;background-repeat:no-repeat;
  background-image:linear-gradient(var(--line),var(--line));
  background-size:calc(100% - var(--s8)) 1px}
.pv-sep--b{background-position:var(--s4) 100%}
.pv-sep--t{background-position:var(--s4) 0}
.pv-body.pv-desk{padding-bottom:0}

/* ══ 我的 ══════════════════════════════════════════════════════════════════ */
.pv-id{margin-top:4px;padding:16px;border-radius:var(--r-md);color:var(--card);
  background:linear-gradient(140deg,var(--brand),var(--pv-brand-3));display:flex;gap:14px;align-items:center}
/* ⚠️ `.pv-lg` 是**同名不同页的两块**：`.pv-id .pv-lg` = 身份卡的 LOGO 格子（56×56 圆角
   方块），`.pv-lg li / .pv-lg i` = 健康六档（已改名 `.pv-lg2`）。删任何一边之前先确认另一边
   —— 2026-10-09 健康改版把这一族规则一起删了，真机上 LOGO 塌成 15×23 的一行字。
   判据：`cdp-verify-app.py` 的 K 组（LOGO 格子必须是 44+ 的圆角方块、背景不透明）。 */
.pv-id .pv-lg{width:56px;height:56px;flex:none;border-radius:14px;overflow:hidden;
  background:rgb(255 255 255/22%);display:flex;align-items:center;justify-content:center;
  font-size:24px;font-weight:600}
.pv-id .pv-lg img{width:100%;height:100%;object-fit:cover}
.pv-id b{display:block;font-size:17px}
.pv-id span{display:block;margin-top:3px;font-size:12px;opacity:.85}
/* ★ 2026-10-08 真机第五轮：「**上方虚线框离图片太近且不明显**」—— 原来是 1px 灰虚线 +
   浅灰底，摆在照片旁边等于看不见。现在**品牌色淡底 + 左侧一道实心竖条**（一眼看出
   "这是一句提示"），外距也拉到 18。 */
.pv-note{margin-top:18px;padding:12px 14px 12px 16px;border:1px solid var(--pv-note-line);
  border-left:4px solid var(--brand);border-radius:var(--r-md);
  background:var(--pv-note-bg);font-size:13px;color:var(--tx2);line-height:1.7}
/* ⚠️ 块级 `<b>` 用显式 `.pv-lead` 标，**不写 `b{display:block}`**（审计 A3/A4）：后者会把
   句子中间用于强调的 `<b>` 也撑成整行；`:first-child` 判不了（它忽略文本节点）。 */
.pv-lead{display:block;margin-bottom:4px;font-size:13px;font-weight:600;color:var(--tx)}
/* 「全部 N 件 ›」那一行（首页商品明细的收口）：与普通行同高、可点。 */
.pv-row--more .pv-g b{color:var(--brand)}
.pv-tiny{text-align:center;font-size:12px;color:var(--tx3);line-height:1.9;padding:22px 0 4px}

/* ══ 底部弹层（手机上"确认/选择"唯一正确的形状）═══════════════════════════ */
.pv-scrim{position:fixed;inset:0;z-index:200;background:rgb(0 0 0/32%);
  animation:pvfade var(--dur-2) var(--ease-out)}
@keyframes pvfade{from{opacity:0}to{opacity:1}}
/* `--pv-kb` 由 app.js 的 visualViewport 监听写入（iOS 键盘不改布局视口）；
   没有键盘时是 0，位置与原来逐像素相同。 */
.pv-sheet{position:fixed;left:0;right:0;bottom:var(--pv-kb,0px);z-index:210;
  background:var(--card);border-radius:14px 14px 0 0;padding:14px var(--s4)
  calc(env(safe-area-inset-bottom) + 14px);box-shadow:0 -8px 28px rgb(16 24 40/14%);
  max-height:calc(82dvh - var(--pv-kb,0px));overflow-y:auto;
  animation:pvup var(--dur-2) var(--ease-out)}
@keyframes pvup{from{transform:translateY(100%)}to{transform:translateY(0)}}
.pv-sheet .pv-bar{width:36px;height:4px;border-radius:2px;background:var(--line);
  margin:0 auto 12px}
.pv-sheet h3{margin:0 0 6px;font-size:17px;font-weight:600}
.pv-sheet .pv-desc{margin:0 0 14px;font-size:13px;color:var(--tx3);line-height:1.7}
.pv-opt{display:flex;align-items:center;min-height:52px;font-size:15px;
  border-bottom:1px solid var(--line);cursor:pointer;width:100%;background:none;
  border-left:0;border-right:0;border-top:0;font-family:inherit;color:var(--tx);
  text-align:left;padding:0}
.pv-opt:last-child{border-bottom:0}
.pv-opt--danger{color:var(--danger)}
/* 弹层里的**主作用**（「保存」这类）给实心分量（用户口径「保存太小气」）。
   ⚠️ **不复用**实心主按钮那个类：它被"一屏只有一个实心主按钮"数着，而弹层是另一层。 */
.pv-opt--primary{justify-content:center;height:48px;min-height:48px;margin:6px 0 10px;
  border-bottom:0;border-radius:var(--r-md);background:var(--brand);color:var(--card);
  font-weight:600}
.pv-opt--primary.pv-opt--danger{background:var(--danger);color:var(--card)}

/* 看板设置（`me.js` 的弹层）：一行 = 勾 + 名字 + 上移/下移。
   ⚠️ `.pv-bx` 不是可点元素 —— 可点的是整行 `.pv-bst`（52px）；
      做成 24px 的 button 会撞上"目标 ≥44"那条判据。 */
.pv-bsr{display:flex;align-items:center;border-bottom:1px solid var(--line)}
.pv-bsr:last-child{border-bottom:0}
.pv-bst{flex:1;min-width:0;display:flex;align-items:center;gap:10px;min-height:52px;
  background:none;border:0;padding:0;font:inherit;color:inherit;text-align:left;cursor:pointer}
.pv-bx{width:24px;height:24px;flex:none;border:1.5px solid var(--pv-checkbox-line);
  border-radius:6px;background:var(--card);display:flex;align-items:center;
  justify-content:center;color:var(--card);font-style:normal}
.pv-bx.on{background:var(--brand);border-color:var(--brand)}
.pv-bx .pv-ic{width:16px;height:16px}
.pv-bsl{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pv-bsg{font-size:13px;font-weight:600;color:var(--tx2);padding:12px 0 2px}
.pv-bi--up svg{transform:rotate(-90deg)}

/* LOGO 裁剪（`crop.js`）：整屏覆盖 · 深底 · 整图可见 + 中间 1:1 框 · 底部取消/旋转/确定。
   ⚠️ 底色用 `rgb()`（规则体不许裸色值）且必须**不透明**（原来 4% 透明会透出「我的」）。
   ⚠️ 压暗与三分格画在 canvas 上；`touch-action:none` 不能省；「确定」挂 `.pv-ok`。 */
.pv-crop{position:fixed;inset:0;z-index:220;display:flex;flex-direction:column;
  background:rgb(0 0 0);color:var(--card)}
.pv-crop canvas{display:block;width:100%;flex:1;min-height:0;touch-action:none}
.pv-crop .pv-tip{position:absolute;left:0;right:0;margin:0;text-align:center;
  top:calc(env(safe-area-inset-top) + 12px);
  font-size:12px;line-height:1.5;opacity:.75;pointer-events:none}
.pv-crop .pv-cbar{flex:none;display:flex;align-items:center;gap:10px;padding:12px 16px
  calc(env(safe-area-inset-bottom) + 12px)}
.pv-crop .pv-btn{width:auto;flex:1}
.pv-crop .pv-btn--g{border:1px solid rgb(255 255 255/28%);color:var(--card)}
.pv-crop .pv-ok{background:var(--brand);border-color:var(--brand);color:var(--card);
  font-weight:600}
.pv-bi--down svg{transform:rotate(90deg)}

/* ══ 轻提示（不用电脑端那种居中弹窗 —— 手机上它会盖住键盘）═══════════════ */
.pv-toast{position:fixed;left:50%;bottom:calc(env(safe-area-inset-bottom) + 88px + var(--pv-kb,0px));
  transform:translateX(-50%);z-index:300;max-width:calc(100vw - 48px);
  padding:10px 16px;border-radius:20px;background:rgb(31 35 41/92%);color:var(--card);
  font-size:14px;line-height:1.5;text-align:center;
  animation:pvfade var(--dur-2) var(--ease-out)}
.pv-toast--err{background:rgb(197 34 31/94%)}

/* ══ 键盘弹起时底栏退场（2026-10-07 真机返工）════════════════════════════
   用户口径：「点击输入名称后输入框变窄，导航上移这个不正常」—— iOS 弹键盘把视口压小，
   底栏（`.pv` 纵向 flex 最后一项）就被顶到键盘上面去。口径：有焦点 = 键盘在，
   底栏整条收起来（用 `:has()` 不用 js）。⚠️ 底部留白同时归零（那 34px 否则是白边）。 */
.pv:has(input:focus) .pv-tab{display:none}
.pv:has(input:focus) .pv-body{padding-bottom:0}
/* ★ 2026-10-11 晚（用户「第一页的主按钮点搜索框会跳位置」）：键盘弹起时底栏退场
   （少 56），这三屏要把那 56 补回来 —— 24 + 56 = 80，内容区下边界不动，主按钮不跳
   （不补时实测 705 → 785）。别的页照旧清零。 */
.pv:has(input:focus) .pv-body--flow{padding-bottom:80px}


/* ══ 数据看板（B8）· 与 pc.css 的看板段同一套语言 ══════════════════════
   ⚠️ 只写新增的类；图形一律 data-* 分档。`.pv-kpis`/`.pv-kpi`/`.u` 原本**不存在**
      （真机"整宽竖排"）—— D2 只查"定义了没人用"，不查"用了没定义"。
   ⚠️ 列必须 `minmax(0,1fr)`：`1fr` 的最小宽度=内容最小宽度 → 两列顶到 458px。 */
.pv-kpis{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;padding:0 16px}
/* 看板的版心（16px）：看板没套 `.pv-pad`，卡片与小节标题会贴到屏幕边、和上面自带 16px
   的 KPI 卡对不齐。⚠️ 只改这一屏，**不改共用的那几个类**（会波及「我的」）。 */
.pv-board > .pv-sec{padding-left:var(--s4);padding-right:var(--s4)}
.pv-board > .pv-card{margin-left:var(--s4);margin-right:var(--s4)}
.pv-board > .pv-note{margin-left:var(--s4);margin-right:var(--s4)}
.pv-board > .pv-foot{padding-left:var(--s4);padding-right:var(--s4)}
/* ⚠️ 详情页版心（审计 A1/A2）：这页 body 没套 `pv-pad`（商品图要整幅宽），代价是卡片/说明
   贴屏幕边（实测 `.pv-card` 是 `x=0 / right=390`，边框压边、圆角被切一半）。
   ⚠️ 只认**直接**子元素 —— `.pv-sec` 里那个 `.pv-card` 不能再加一遍（会变 32px）。 */
.pv-body--detail > .pv-card,
.pv-body--detail > .pv-note,
.pv-body--detail > .pv-sec{margin-left:var(--s4);margin-right:var(--s4)}
.pv-kpi{background:var(--card);border-radius:var(--r-md);box-shadow:var(--sh2);padding:12px}
.pv-kpi .hd{display:flex;align-items:center;gap:8px;margin-bottom:8px}
.pv-kpi .k,.pv-kpi .d{font-size:12px;color:var(--tx3);overflow:hidden}
/* ⚠️ 审计 A5：`.d`（"为什么这一格是—"）**最多两行，不许 nowrap+省略号** ——
   卡片只有 174px 宽，实测那句话（17 字/184px）被切成「没有一行能配上成本，毛…」，
   而它正是 ADR-10（读不到 ≠ 0）在界面上唯一的落点。`.k`（标签）保持单行省略。 */
.pv-kpi .k{min-width:0;text-overflow:ellipsis;white-space:nowrap}
.pv-kpi .d{margin-top:6px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.pv-kpi .v{font-size:24px;font-weight:700;letter-spacing:-.5px;line-height:1.05;
  font-variant-numeric:tabular-nums}
.pv-kpi .v .u{font-size:12px;font-weight:500;color:var(--tx3);margin-left:3px;font-style:normal}
.pv-kpi .v--none{color:var(--tx3)}
/* 看板原先自带的第二份胶囊样式已撤，四段改用全端同一份 chip 组件。
   ⚠️ 这里**故意不写那两个已删的类名**：D2 是正则纯文本扫 CSS，注释里出现带点的类名
      照样算"定义了没人用"（与"用了没定义"合起来才是完整的一对）。 */
/* ⚠️ 高度 **≥44**（触摸目标契约）。第一版写 30px，门报红「今天」54×30。 */

/* ⚠️ 品牌底上的字用 `var(--card)`（本仓既有的"其上色"写法，同 `.pv-btn--p`）：
   **不许写裸色值** —— 色值只有 `:root` 一处来源，`test_app_contract` 会判红。 */
.pv-kico{width:26px;height:26px;border-radius:9px;flex:none;display:grid;place-items:center}
.pv-kico .pv-ic{width:15px;height:15px}
.pv-kico--b{background:var(--brand-soft);color:var(--brand)}
.pv-kico--g{background:var(--ok-soft);color:var(--ok)}
.pv-kico--w{background:var(--warn-soft);color:var(--warn)}
.pv-kico--i{background:var(--info-soft);color:var(--info)}
.pv-kico--n{background:var(--content);color:var(--tx2)}
.pv-cmp{display:grid;grid-template-columns:1fr 1fr;gap:2px 8px;margin-top:6px;font-size:12px;color:var(--tx3)}
.pv-cmp b{font-weight:700;margin-left:2px}
.pv-cmp .up b{color:var(--ok)}.pv-cmp .down b{color:var(--danger)}
.pv-cmp .nil b{color:var(--tx3);font-weight:400}
.pv-stack{display:flex;gap:2px;height:9px}
.pv-stack i{display:block;border-radius:3px;min-width:2px}
.pv-stack i[data-w="1"]{width:10%}
.pv-stack i[data-w="2"]{width:20%}
.pv-stack i[data-w="3"]{width:30%}
.pv-stack i[data-w="4"]{width:40%}
.pv-stack i[data-w="5"]{width:50%}
.pv-stack i[data-w="6"]{width:60%}
.pv-stack i[data-w="7"]{width:70%}
.pv-stack i[data-w="8"]{width:80%}
.pv-stack i[data-w="9"]{width:90%}
.pv-stack i[data-w="10"]{width:100%}
/* ⚠️ 健康那块叫 `.pv-lg2`（改名时这六条漏改了 → 色块透明；门里 F5 量它） */
.pv-stack i.s-ok,.pv-lg2 i.s-ok{background:var(--ok)}
.pv-stack i.s-near,.pv-lg2 i.s-near{background:var(--warn)}
.pv-stack i.s-slow,.pv-lg2 i.s-slow{background:var(--danger)}
.pv-stack i.s-low,.pv-lg2 i.s-low{background:var(--brand)}
.pv-stack i.s-none,.pv-lg2 i.s-none{background:var(--line)}
.pv-stack i.s-nc,.pv-lg2 i.s-nc{background:var(--tx3);opacity:.45}
.pv-con{display:flex;align-items:center;gap:10px;padding:12px 14px;border-bottom:1px solid var(--line)}
.pv-con:last-child{border-bottom:0}
.pv-con .g{flex:1;min-width:0}
.pv-con .nm{font-size:13px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pv-con .sub{font-size:12px;color:var(--tx3);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pv-con .n{flex:none;font-size:15px;font-weight:700}
.pv-con--probe .nm{color:var(--tx3);font-weight:500}


/* ══ B8.5（2026-10-09）· 老板六条 ═══════════════════════════════════════ */

/* ★ 数据条（替代原来那块大色块 hero —— 老板嫌它占地方）*/
.pv-bar{margin:0 16px 12px;padding:9px 12px;border-radius:var(--r-md);
  background:var(--content);display:flex;align-items:center;gap:8px;
  font-size:12px;color:var(--tx2)}
.pv-bar b{color:var(--tx);font-weight:600}
.pv-bar .r{margin-left:auto;color:var(--tx3);font-size:12px}

/* ④ 四张 KPI 卡：**单色描边**（用户口径「四个板块的描边改成单色」）——
   原来四条 `--a/--b/--c/--d` 淡色渐变已全撤。判据：全端 `.pv-kpi` 的 `borderColor`
   只允许一个取值，且只写 `var(--line)`。 */
.pv-kpi{border:1px solid var(--line);box-shadow:0 1px 3px rgb(16 24 40/5%)}

/* ★ ⑤ **库存健康：去掉左边的环**，只留堆叠条 + 六档（整宽两列）*/
.pv-flow{padding:14px}
.pv-lg2{display:grid;grid-template-columns:1fr 1fr;gap:7px 14px;margin-top:11px;
  list-style:none;padding:0}
.pv-lg2 li{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--tx2);
  min-width:0}
.pv-lg2 i{width:8px;height:8px;border-radius:2px;flex:none}
.pv-lg2 .v{margin-left:auto;color:var(--tx);font-weight:600;white-space:nowrap;
  font-variant-numeric:tabular-nums}
.pv-lg2 .n{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* ⑥ **没数据时六档照常显示**（数字 0，行不能少）—— 靠淡色区分"这是 0" */
.pv-lg2 .v--zero{color:var(--tx3);font-weight:400}

/* ★ ① **对比 + 环比图**（上面一张图，下面四个按钮点一下整块换）*/
.cmpcard{margin:0 16px 12px;background:var(--card);border-radius:var(--r-md);
  box-shadow:var(--sh2);padding:14px}
.cmpcard .lb{font-size:12px;color:var(--tx3)}
.cmpcard .big{font-size:28px;font-weight:700;letter-spacing:-.8px;line-height:1.15;
  margin-top:2px;font-variant-numeric:tabular-nums}
.cmpcard .big i{font-style:normal;font-size:13px;font-weight:500;color:var(--tx3);
  margin-left:3px}
.cmpcard .dl{display:flex;align-items:baseline;gap:6px;margin-top:7px;font-size:13px;
  flex-wrap:wrap}
.cmpcard .dl b{font-weight:700;font-variant-numeric:tabular-nums}
.cmpcard .dl .up b{color:var(--ok)}
.cmpcard .dl .down b{color:var(--danger)}
.cmpcard .dl .nil b{color:var(--tx3)}
.cmpcard .dl .sub{color:var(--tx3);font-size:12px}
.cmpchart{display:flex;align-items:flex-end;height:112px;margin-top:18px}
.cmpday{flex:1;min-width:0;display:flex;align-items:flex-end;justify-content:center;
  gap:2px;height:100%}
.cmpday i{display:block;border-radius:2px 2px 0 0;width:42%}
.cmpday i.now{background:var(--brand)}
.cmpday i.base{background:var(--line)}
.cmpday i[data-h="1"]{height:10%}.cmpday i[data-h="2"]{height:20%}
.cmpday i[data-h="3"]{height:30%}.cmpday i[data-h="4"]{height:40%}
.cmpday i[data-h="5"]{height:50%}.cmpday i[data-h="6"]{height:60%}
.cmpday i[data-h="7"]{height:70%}.cmpday i[data-h="8"]{height:80%}
.cmpday i[data-h="9"]{height:90%}.cmpday i[data-h="10"]{height:100%}
.cmpday i.empty{height:2px;background:var(--content)}
.cmpaxis{display:flex;margin-top:6px}
.cmpaxis span{flex:1;min-width:0;text-align:center;font-size:12px;color:var(--tx3);
  overflow:hidden;white-space:nowrap}
.cmplegend{display:flex;align-items:center;gap:10px;margin-top:12px;padding-top:11px;
  border-top:1px solid var(--line);font-size:12px;color:var(--tx2);flex-wrap:wrap}
.cmplegend > span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  max-width:52%}
.cmplegend i{width:9px;height:9px;border-radius:2px;display:inline-block;margin-right:5px;
  vertical-align:-1px}
.cmplegend .now i{background:var(--brand)}
.cmplegend .base i{background:var(--line)}
.cmplegend .r{margin-left:auto;color:var(--tx3);max-width:none}
.cmpbtns{display:flex;gap:6px;margin:0 16px}
/* ⚠️ `min-width:0` 不能省：flex 子项默认 `min-width:auto`，**长文本不肯收缩**，
   整页会横向溢出（真图上是"右边被切掉"）。 */
.cmpbtn{flex:1;min-width:0;height:44px;border:0;border-radius:var(--r-md);
  background:var(--content);color:var(--tx2);font:inherit;font-size:14px;
  font-weight:500;cursor:pointer}
.cmpbtn.on{background:var(--brand);color:var(--card);font-weight:600}

/* ══ B8.5b 落点（§5.3 接成代码）═════════════════════════════════════════
   老板「看板数据里怎么都点不开」—— KPI 卡/六档/平台可见性原来是死元素。
   ⚠️ **能点的必须看得出能点；不能点的什么都不加**（与其点了没反应，不如看起来就不能点）。 */
.pv-lg2 li[data-k]{cursor:pointer}
.pv-lg2 li[data-k] .n{color:var(--brand)}
.pv-lg2 li[data-k]::after{content:'›';margin-left:4px;color:var(--tx3);font-size:14px;
  line-height:1}
.pv-lg2 li.on{background:var(--brand-soft);border-radius:var(--r-sm);margin:-3px -5px;
  padding:3px 5px}
.pv-lg2 li.on::after{content:'⌄';color:var(--brand)}
/* 展开的商品清单（用响应里已有的 `lists`，不再发请求）*/
.pv-exp{margin-top:10px;padding-top:10px;border-top:1px solid var(--line)}
.pv-exp .hd{font-size:12px;color:var(--tx3);margin-bottom:8px}
.pv-exp .pv-row{padding:9px 0}

/* 宽视口（用电脑打开）把手机端装进一个 420px 居中框（原话「解决电脑打开就是手机页面」）
   ⚠️ 那几个 `position:fixed` 的层（登录/遮罩/弹层/裁剪）按**视口**定位、不跟 `.pv` 走，
      必须一起收窄，否则横铺满屏从框里露出来（登录层就是 `inset:0`）。 */
@media (min-width:560px){
  body{background:var(--content)}
  .pv{width:420px;margin:0 auto;overflow:hidden;box-shadow:var(--sh2)}
  .pv-login,.pv-scrim,.pv-crop,.pv-sheet{
    left:50%;right:auto;width:420px;margin-left:-210px}
  .pv-toast{max-width:396px}
}

/* ══ 深色主题（2026-10-31）════════════════════════════════════════════════
   开关在「我的 › 外观」，三档：跟随系统 / 浅色 / 深色（`web/theme.js`）。
   为什么可以只写这一块：这个文件的规则体里**没有任何裸色值**（判据
   `test_规则体与内联样式里都不写裸色值` 守着），所有颜色都从上面那组
   令牌来 —— 换主题 = 重定义令牌，不碰任何一条规则。
   ⚠️ 这里的值全部按 WCAG 算过（`--tx3` 在 card 上 5.40，浅色基线 5.02）：
      **改之前先算，别用眼睛调**。深色下 `--brand` 比浅色亮一档，
      于是 `.pv-btn--p` 那种 `color:var(--card)` 的按钮自动从
      "蓝底白字"变成"亮蓝底深字"，两套都过线 —— 这是 token 化的红利，别去写死 #fff。 */
:root[data-theme="dark"]{
  color-scheme:dark;
  --tx:#E6E9EE; --tx2:#A3ABB7; --tx3:#8B93A0;
  --brand:#6E9BFF; --brand-soft:#1B2A46;
  --line:#2A303A; --content:#0D1013; --card:#1A1E24; --bg:#111418;
  /* 与 `pinyuan.css` 深色块逐值相同：实心底变亮 → 字要翻成深色；
     照片上的东西不跟主题走（照片不会因为换了主题就变亮），只把遮罩压深一档。 */
  --on-solid:#0D1013; --on-photo:#fff; --scrim-img:rgb(0 0 0/65%);
  --ok:#4ED08A; --ok-soft:#14301F;
  --warn:#E2A93F; --warn-soft:#332711;
  --danger:#F07A7E; --danger-soft:#3A1D20;
  --info:#7FB3FF; --info-soft:#16243A;
  --sh2:0 4px 12px rgb(0 0 0/45%),0 1px 2px rgb(0 0 0/35%);
  /* 手机端专属那组（浅底块）：深色下不能沿用浅色，否则整片整片的白 */
  --pv-badge:#F0605F;
  --pv-off-bg:#22272F;
  --pv-note-bg:#16203A; --pv-note-line:#2A3A5C;
  --pv-soft:#15191F;
  --pv-checkbox-line:#3A414C;
  --pv-login-bg:#101A2C;
  --pv-login-warn-bg:#2C2415;
  --pv-brand-2:#5B87E8;
  --pv-brand-3:#6E9BFF;
  --pv-warn-2:#D99B33;
  --pv-warn-3:#C4831A;
  --pv-hot-bg:#2E1F1E; --pv-hot-line:#4A2C29; --pv-hot-tx:#F0A79E;
  --pv-late-bg:#2C1E1D; --pv-late-line:#4A2A27;
  --pv-ai-tx:#BBD1FF;
  --pv-miss-bg:#2A2418; --pv-miss-line:#4A3D24;
  --pv-done-bg:#14261A; --pv-done-line:#26452F;
}
