/* ============ 全局样式 ============ */
.pv .screen {
  --brand: #185FA5;
  --brand-dark: #0C447C;
  --brand-soft: #E6F1FB;
  --brand-line: #85B7EB;

  /* 涨跌色按中国市场惯例：涨=红、跌=绿（与欧美相反，别改） */
  --up: #C0392B;
  --up-soft: #FCEBEB;
  --down: #1D9E75;
  --down-soft: #E1F5EE;
  --flat: #888780;

  --warn: #BA7517;
  --warn-soft: #FAEEDA;

  --ink-1: #1d2129;
  --ink-2: #4e5969;
  --ink-3: #86909c;
  --line: #eef0f4;
  --line-2: #f5f4ef;
  --bg: #f4f6f8;
  --card: #ffffff;
  --head: #FAFAF7;

  background: var(--bg);
  color: var(--ink-1);
  font-size: 28px;
  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Helvetica Neue", Helvetica, sans-serif;
  line-height: 1.5;
}

.pv view, .pv text, .pv scroll-view, .pv button, .pv input, .pv canvas {
  box-sizing: border-box;
}

/* ---------- 容器 ---------- */
.pv .page-wrap {
  padding: 20px 24px 40px;
}

.pv .card {
  background: var(--card);
  border-radius: 20px;
  padding: 24px;
  margin-bottom: 20px;
  box-shadow: 0 2px 16px rgba(20, 40, 60, 0.05);
}

.pv .card-title {
  font-size: 29px;
  font-weight: 600;
  display: flex;
  align-items: center;
}

.pv .card-title::before {
  content: '';
  width: 8px;
  height: 28px;
  border-radius: 4px;
  background: var(--brand);
  margin-right: 12px;
}

.pv .card-sub {
  font-size: 23px;
  color: var(--ink-3);
}

/* ---------- 上市首发价（结果页机型标题卡右侧） ----------
   靠右贴着卡片内边距，与左侧「品牌 型号 / 规格容量」同一行。
   数字用等宽数字，逐台对照时不会左右跳。 */
.pv .launch {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  flex-shrink: 0;
  margin-left: 16px;
}

.pv .launch .launch-lbl {
  font-size: 22px;
  color: var(--ink-3);
}

.pv .launch .launch-pr {
  font-size: 30px;
  font-weight: 600;
  color: var(--ink-1);
  font-variant-numeric: tabular-nums;
}

/* ---------- 文本 ---------- */
.pv .t-1 { color: var(--ink-1); }
.pv .t-2 { color: var(--ink-2); }
.pv .t-3 { color: var(--ink-3); }
.pv .t-brand { color: var(--brand); }
.pv .t-warn { color: var(--warn); }
.pv .fz-22 { font-size: 22px; }
.pv .fz-24 { font-size: 24px; }
.pv .fz-26 { font-size: 26px; }
.pv .fz-30 { font-size: 30px; }
.pv .fw-6 { font-weight: 600; }
.pv .mono { font-variant-numeric: tabular-nums; }

/* ---------- 布局 ---------- */
.pv .row { display: flex; align-items: center; }
.pv .row-between { display: flex; align-items: center; justify-content: space-between; }
.pv .col { display: flex; flex-direction: column; }
.pv .flex-1 { flex: 1; min-width: 0; }
.pv .wrap { flex-wrap: wrap; }
.pv .gap-8 { gap: 8px; }
.pv .gap-12 { gap: 12px; }
.pv .gap-16 { gap: 16px; }
.pv .mt-8 { margin-top: 8px; }
.pv .mt-12 { margin-top: 12px; }
.pv .mt-16 { margin-top: 16px; }

.pv .ellipsis {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* ---------- 数据来源条 ----------
   靠右显示：这块只回答一个问题「这份价是哪天的」，属于页面的落款而不是标题，
   左边留白反而更像正文的开头。首页与结果页共用这一处样式，两页自然一致。 */
.pv .databar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding: 18px 24px;
  background: var(--brand-soft);
  border-radius: 16px;
  margin-bottom: 20px;
}

/* 「数据最后更新日期」与日期上下两行都贴右边线 */
.pv .databar .col {
  align-items: flex-end;
}

.pv .databar .lbl {
  font-size: 24px;
  color: var(--brand-dark);
}

.pv .databar .date {
  font-size: 28px;
  font-weight: 600;
  color: var(--brand-dark);
  font-variant-numeric: tabular-nums;
}

.pv .databar.stale {
  background: var(--warn-soft);
}

.pv .databar.stale .lbl,
.pv .databar.stale .date { color: #633806; }

/* ---------- 步骤标题 ---------- */
.pv .step-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
}

.pv .step-no {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--brand-soft);
  color: var(--brand);
  font-size: 22px;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}

.pv .step-txt {
  font-size: 27px;
  font-weight: 500;
}

/* 步骤标题右侧的附着信息：占据剩余空间、推到最右 */
.pv .step-meta {
  margin-left: auto;
  font-size: 22px;
  color: var(--ink-3);
}

/* 可点击的那种（「更多 6 / 收起」），用品牌色区分于普通说明文字 */
.pv .step-more {
  margin-left: auto;
  font-size: 24px;
  color: var(--brand);
  padding: 6px 4px 6px 16px;
}

/* ---------- 品牌 / 规格 胶囊 ---------- */
/**
 * 品牌网格：3 列 × 2 行 = 6 格，正好放下收起状态下常显的 6 个品牌（BRAND_TOP_N）。
 * 想改列数就得同步改 utils/brands.js 的 BRAND_TOP_N，否则末行会留空格子
 * —— 自检里有一条断言在盯「列数 × 2 == BRAND_TOP_N」。
 */
.pv .grid-brand {
  display: grid;
  /* 3 列 × 2 行 = 6 格，与 utils/brands.js 的 BRAND_TOP_N 是同一个契约（自检在盯 列数 × 2 == TOP_N）：
     收起时正好铺满两排、不留空格子。改列数必须连 BRAND_TOP_N 一起改 */
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}

.pv .chip {
  border: 1px solid #E5E3DC;
  border-radius: 14px;
  padding: 16px 8px;
  text-align: center;
  background: #fff;
}

.pv .chip.on {
  border-color: var(--brand);
  background: var(--brand-soft);
}

.pv .chip .nm {
  font-size: 26px;
  font-weight: 500;
}

.pv .chip.on .nm { color: var(--brand-dark); }

.pv .chip .ct {
  font-size: 21px;
  color: var(--ink-3);
  margin-top: 2px;
}

.pv .chip.on .ct { color: var(--brand); }

/* ---------- 搜索框 ---------- */
.pv .search {
  width: 100%;
  height: 72px;
  padding: 0 22px;
  border: 1px solid #E5E3DC;
  border-radius: 14px;
  font-size: 26px;
  background: #fff;
  color: var(--ink-1);
  margin-bottom: 16px;
}

.pv .search-ph {
  color: var(--ink-3);
  font-size: 26px;
}

/* ---------- 型号列表 ---------- */
/**
 * 高度定成「整 4 行」，让筛选区紧凑但够看：
 *   行高 .mrow = 80px  →  .mlist max-height = 4 × 80 = 320px
 * 用 max-height 而不是 height：型号少于 4 个（搜索命中少）时盒子自己收窄，
 * 不会留一片空白。改行高的话，这两个数要一起改（自检里有一条断言在盯这个倍数）。
 */
.pv .mlist {
  max-height: 320px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: #fff;
}

.pv .mrow {
  height: 80px;
  padding: 0 22px;
  border-bottom: 1px solid var(--line-2);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
}

.pv .mrow:last-child { border-bottom: none; }
.pv .mrow.on { background: var(--brand-soft); }
.pv .mrow .m { font-size: 27px; }
.pv .mrow.on .m { color: var(--brand-dark); font-weight: 500; }
.pv .mrow .c { font-size: 22px; color: var(--ink-3); white-space: nowrap; }

/* ---------- 规格 ---------- */
.pv .specs {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
}

.pv .spec {
  border: 1px solid #E5E3DC;
  border-radius: 30px;
  padding: 10px 24px;
  font-size: 25px;
  background: #fff;
}

.pv .spec.on {
  border-color: var(--brand);
  background: var(--brand-soft);
  color: var(--brand-dark);
  font-weight: 500;
}

/* ---------- 面包屑 ---------- */
/**
 * 常驻一行：没选品牌时显示「全部品牌」（.here，灰），选了才长成「全部品牌 › 华为」（.link，蓝）。
 * 见 pages/index/index.wxml —— 这一行**不能加 wx:if**，否则点第一个品牌时下面的卡片会整体下移。
 */
.pv .crumb {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  font-size: 23px;
  color: var(--ink-2);
  padding: 0 0 16px;
}

.pv .crumb .link { color: var(--brand); }
.pv .crumb .sep { color: #B4B2A9; }
/* 当前所在层级：不染色 —— 蓝色在这个页面里只代表「能点」，点了没变化的就不该是蓝的 */
.pv .crumb .here { color: var(--ink-2); }

/* ---------- 当日报价 ---------- */
.pv .grp {
  border: 1px solid var(--line);
  border-radius: 16px;
  margin-bottom: 16px;
  overflow: hidden;
  background: #fff;
}

.pv .gh {
  padding: 16px 22px;
  background: var(--head);
  font-size: 26px;
  font-weight: 500;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.pv .gh .no {
  font-size: 22px;
  color: var(--ink-3);
  font-weight: 400;
}

.pv .gr {
  border-top: 1px solid var(--line-2);
  padding: 18px 22px;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 16px;
}

/**
 * justify-content 用 flex-end 而不是 space-between：
 * 一行可能一个角标都没有（只有价格），那时 .rt 是唯一子元素，
 * space-between 会把它顶到左边。有角标时靠 .tags 的 margin-right:auto 把价格推到右边。
 */
.pv .gr .tags { margin-right: auto; }

.pv .gr.bad { background: #FEFAF8; }

.pv .badge {
  font-size: 20px;
  color: var(--up);
  background: var(--up-soft);
  border-radius: 6px;
  padding: 0 10px;
  font-weight: 500;
}

/**
 * 报价行角标 —— 样式按 **语义** 分色，四类互相不撞：
 *   cond  机况（已开封 / 已激活）  琥珀 = 注意，这台机器不是全新原封
 *   limit 交易范围（省渠/市渠/国补） 蓝 = 信息，能不能卖给这个客户
 *   ok    全网渠                    绿 = 放行，与「省渠」正好正反对照
 *   info  配置（4G / 折叠 / 非卫星）  灰 = 中性
 * 「全网渠」与涨跌的「跌」同为绿色系：两者一个在行首、一个紧贴价格，
 * 位置隔得远，且语义都是「正向」，不会读混。
 * 具体某个备注出哪种角标、什么时候出，见 utils/format.js 的 TAG_RULES。
 */
.pv .tg {
  font-size: 20px;
  border-radius: 6px;
  padding: 0 10px;
  font-weight: 500;
  white-space: nowrap;
}

.pv .tg.cond { color: var(--warn); background: var(--warn-soft); }
.pv .tg.limit { color: var(--brand-dark); background: var(--brand-soft); }
.pv .tg.ok { color: var(--down); background: var(--down-soft); }
.pv .tg.info { color: var(--ink-2); background: #EEF1F5; }

/* 角标行：机况/限制/配置 + 价格异常并排；都没有时整个容器不渲染（wx:if 在 wxml 里） */
.pv .tags {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.pv .gr .rt {
  display: flex;
  align-items: center;
  gap: 10px;
  white-space: nowrap;
}

.pv .gr .pr {
  font-size: 32px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.pv .gr.bad .pr { color: var(--up); }

/* 涨跌标记 */
.pv .dl {
  font-size: 21px;
  font-weight: 500;
  padding: 2px 10px;
  border-radius: 6px;
  font-variant-numeric: tabular-nums;
}

.pv .dl.up { color: var(--up); background: var(--up-soft); }
.pv .dl.down { color: var(--down); background: var(--down-soft); }
.pv .dl.flat { color: var(--flat); background: #F1EFE8; }

/* ---------- 档位 / 货源 ---------- */
.pv .tabs {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}

.pv .tab {
  border: 1px solid #E5E3DC;
  border-radius: 28px;
  padding: 8px 22px;
  font-size: 24px;
  background: #fff;
  color: var(--ink-2);
}

.pv .tab.on {
  background: var(--brand);
  border-color: var(--brand);
  color: #fff;
  font-weight: 500;
}

.pv .srcline {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 12px;
  font-size: 22px;
  color: var(--ink-3);
}

.pv .srcchip {
  border: 1px solid #E5E3DC;
  border-radius: 24px;
  padding: 6px 18px;
  font-size: 22px;
  background: #fff;
  color: var(--ink-2);
}

.pv .srcchip.on {
  background: var(--down-soft);
  border-color: var(--down);
  color: #0F6E56;
  font-weight: 500;
}

/* ---------- 图表 ---------- */
.pv .chartbox {
  position: relative;
}

.pv .chart {
  width: 100%;
  height: 400px;
  display: block;
}

/* 颜色图例：**整行居中**（2026-10-08 确认）。
   它是「图的读法说明」，不属于某一侧的内容，贴左会显得像列表里的一行。
   注意别改成 `space-between` —— 颜色多时会把最后一个顶到最右边，比贴左更乱。 */
.pv .legend {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 18px;
  margin-top: 12px;
  font-size: 23px;
}

.pv .lgi {
  display: flex;
  align-items: center;
  gap: 8px;
}

.pv .lgi.off { opacity: .32; }

.pv .dot {
  width: 16px;
  height: 16px;
  border-radius: 50%;
}

/* 图例正下方的「点长什么样 = 什么意思」说明（chart.summarize 的 markNote）。
   与图例挨近一点（它俩是一组），与再下面的元信息行拉开。 */
.pv .marknote {
  margin-top: 14px;
}

.pv .chinfo {
  font-size: 22px;
  color: var(--ink-3);
  margin-top: 10px;
  line-height: 1.6;
}

.pv .warnbox {
  margin-top: 12px;
  padding: 18px 20px;
  background: var(--warn-soft);
  border-radius: 14px;
  font-size: 23px;
  color: #633806;
  line-height: 1.65;
}

.pv .warnbox.error {
  background: var(--up-soft);
  color: #7A1F1F;
}

/* ---------- 触摸读数条 ---------- */
.pv .tipbar {
  margin-top: 12px;
  padding: 16px 20px;
  background: #2C2C2A;
  border-radius: 14px;
  color: #fff;
  font-size: 23px;
  line-height: 1.7;
  font-variant-numeric: tabular-nums;
}

.pv .tipbar .k { color: #C7C6BE; }

/* ---------- 正文段落 ---------- */
.pv .para {
  font-size: 25px;
  color: var(--ink-2);
  line-height: 1.8;
}

/* ---------- 键值行（关于页） ---------- */
.pv .kv {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 18px 0;
  border-bottom: 1px solid var(--line);
}

.pv .kv:last-child { border-bottom: none; }

.pv .kv-label {
  color: var(--ink-2);
  font-size: 25px;
  flex: none;
}

.pv .kv-value {
  font-size: 26px;
  font-weight: 600;
  color: var(--ink-1);
  font-variant-numeric: tabular-nums;
  word-break: break-all;
  text-align: right;
}

/* ---------- 按钮 ---------- */
.pv .btn {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 84px;
  border-radius: 42px;
  font-size: 28px;
  font-weight: 600;
  border: none;
}

.pv .btn::after { border: none; }

.pv .btn-ghost {
  background: #fff;
  color: var(--ink-1);
  border: 1px solid var(--line);
}

/* 主按钮：品牌色底 + 白字。
   ⚠️ 这个类此前**根本没有定义** —— 结果页「生成分享图片」与弹层「保存到相册」
   写了 `class="btn btn-primary"`，却只吃到 .btn 的骨架（没有底色、没有字色），
   于是屏幕上就是一行孤零零的字，谁也看不出能点（2026-10-08 用户反馈才发现：
   此前项目里只有 .btn-ghost，从来没用过主按钮）。
   补类是这两处唯一的修法 —— 别去改页面上的类名。 */
.pv .btn-primary {
  background: var(--brand);
  color: #fff;
}

/* 按下态：稍深一档，给出「点到了」的反馈（小程序 view 支持 :active） */
.pv .btn-primary:active {
  background: var(--brand-dark);
}

.pv .btn-block { width: 100%; }

/* ---------- 底部入口 ---------- */
.pv .footlink {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px 0 0;
  font-size: 24px;
  color: var(--brand);
}

/* ---------- 版本水印 ---------- */
.pv .watermark {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 32px 0 12px;
  font-size: 21px;
  color: var(--ink-3);
}

/* ---------- 空 / 错误 ---------- */
.pv .empty {
  padding: 100px 40px;
  text-align: center;
  color: var(--ink-3);
  font-size: 26px;
}

.pv .empty-icon {
  font-size: 72px;
  display: block;
  margin-bottom: 18px;
}

/* ---------- 上一页/下一页 ---------- */
.pv .hide { display: none; }

/* ---------- 分享图预览弹层（结果页用，**只此一份**；样式抄自混动能耗小程序的 app.wxss，
   那边经过三个页面验证过的弹层布局：弹层限高、图片区可滚动、按钮固定在底部） ---------- */

/* 离屏画布：不能 display:none（否则取不到 canvas 节点），移出可视区即可。
   高度给足即可 —— 实际画布尺寸在 JS 里按内容动态设置（poster.measure()） */
.pv .share-canvas {
  position: fixed;
  left: -9999px;
  top: 0;
  width: 750px;
  height: 2400px;
  pointer-events: none;
}

.pv .share-mask {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  background: rgba(16, 22, 30, 0.62);
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px;
  box-sizing: border-box;
}

/* 弹层必须限高：分享图很长，不限高会把底部的按钮挤出屏幕 */
.pv .share-sheet {
  width: 100%;
  max-width: 640px;
  max-height: 82vh;
  background: #fff;
  border-radius: 24px;
  padding: 32px 28px 24px;
  display: flex;
  flex-direction: column;
  align-items: center;
  box-sizing: border-box;
}

.pv .share-title {
  flex: none;
  font-size: 30px;
  font-weight: 600;
  color: var(--ink-1);
  margin-bottom: 20px;
}

/* 图片区可上下滚动，占用剩余空间；按钮固定在弹层底部始终可见 */
.pv .share-body {
  flex: 1;
  width: 100%;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  border-radius: 16px;
  background: var(--bg);
}

.pv .share-preview {
  width: 100%;
  display: block;
  border-radius: 16px;
}

.pv .share-hint {
  flex: none;
  font-size: 21px;
  color: var(--ink-3);
  margin: 16px 0 22px;
}

.pv .share-actions {
  flex: none;
  display: flex;
  gap: 20px;
  width: 100%;
}

.pv .share-close {
  flex: none;
  font-size: 24px;
  color: var(--ink-3);
  margin-top: 22px;
  padding: 8px 20px;
}

/* 首页（级联筛选）的页面级样式
 *
 * 品牌胶囊 / 型号列表 / 规格胶囊的样式都放在 app.wxss 里（三个页面共用同名类），
 * 这里只放首页独有的微调。目前没有 —— 保留文件是因为 app.json 会引用它，
 * 且后续首页要做单独调整时有个明确的落点。
 *
 * 型号列表的「整 4 行」高度契约在 app.wxss 的 .mlist / .mrow 上：
 *   行高 80px × 4 = max-height 320px，改一个要连另一个一起改。
 * 品牌网格同理：3 列 × 2 行 = 6 格，与 utils/brands.js 的 BRAND_TOP_N 必须相等。
 */

/* 结果页：骨架类都在 app.wxss 里，这里只放这一页独有的微调 */

.pv .chartbox {
  padding: 4px 0;
}

.pv .srcline .srcchip {
  margin-right: 4px;
}

/* ---------- 生成分享图卡片（弹层样式在 app.wxss，勿在此重复） ---------- */
.pv .share-tip {
  font-size: 24px;
  color: var(--ink-2);
  line-height: 1.6;
  margin-top: 14px;
}

.pv .share-btn {
  margin-top: 18px;
}

.pv .share-hint2 {
  font-size: 21px;
  color: var(--ink-3);
  margin-top: 10px;
  line-height: 1.5;
}

/* 关于页：复用 app.wxss 的 .kv 行样式，这里只补底色 */


.pv, .pv *{box-sizing:border-box}
.pv{margin:0;background:#e9edf2;color:#1d2129;font-family:-apple-system,BlinkMacSystemFont,"PingFang SC","Microsoft YaHei",sans-serif}
.pv-head{padding:30px 40px 0;max-width:1700px;margin:0 auto}
.pv-head h1{margin:0;font-size:22px;font-weight:600}
.pv-head p{margin:10px 0 0;font-size:14px;color:#4e5969;line-height:1.8;max-width:1100px}
.pv-head code{background:#fff;border:1px solid #d8dfe7;border-radius:4px;padding:1px 6px;font-size:13px}
.pv .grid-wrap{display:flex;flex-wrap:wrap;gap:26px;padding:26px 40px 80px;align-items:flex-start;max-width:1700px;margin:0 auto}
.pv .frame{width:375px}
.pv .cap{font-size:13px;color:#4e5969;margin-bottom:8px;line-height:1.5;min-height:40px}
.pv .cap b{color:#185FA5}
.pv .phone{width:375px;height:667px;overflow-y:auto;border-radius:32px;background:#fff;
  box-shadow:0 10px 30px rgba(20,40,60,.16);border:1px solid #d8dfe7}
.pv .screen{width:750px;zoom:.5;min-height:1334px}
.pv .nav{height:88px;display:flex;align-items:center;justify-content:center;background:#fff;
  font-size:32px;font-weight:600;border-bottom:1px solid #eef0f4;position:sticky;top:0;z-index:3}
.pv .body{position:relative;min-height:1246px}
.pv .chart svg{display:block}
/* 分享图第 ⑬ 屏：poster 的 SVG 直接嵌进来，白底衬托出图片边界 */
.pv .posterbox{background:#fff;border-radius:20px;box-shadow:0 2px 16px rgba(20,40,60,.08);overflow:hidden}
.pv .posterbox svg{display:block}
/* 小程序里 .mlist 是 scroll-view；预览用 div，必须自己裁剪，否则内容会溢出压住下面的卡片 */
.pv .mlist{overflow-y:auto}
.pv .scrollhint{position:fixed;right:18px;bottom:18px;background:#2c2c2a;color:#fff;font-size:12px;
  padding:8px 14px;border-radius:20px;opacity:.85;z-index:99}
