/* ============================================================
   GV营销平台 · Design Tokens
   视觉语言提炼自 设计风格参考/ (Bitget Wallet)

   执行要点（从参考图提炼）：
   1. 页面底不是纯灰，而是上下各一层极淡的青晕，卡片靠底色浮起
   2. 卡片纯白 + 大圆角 + 近乎无阴影；只有「浮层」才投影
   3. 图标是圆角方块（--r-ic），墨底青字，不是圆形
   4. 数字用超大字重 + 等宽，标签用 12px 弱灰，对比拉满
   ============================================================ */
:root {
  /* 底色 / 表面 */
  --bg:          #E8EBED;
  --page:        #F6F8F9;
  --surface:     #FFFFFF;
  /* 白卡片**内部**的填充块。只比卡片沉 8 级（surface-2 沉 14 级，那太深）——
     页面底是 #E8EBED(L234)，用 surface-2 填卡内块会让它离页面底只差 7 级、离卡片却差 14，
     视觉上归到「页面」那一层，白卡被挖成两个洞。卡外的次级面仍用 surface-2。 */
  --surface-1:   #F6F8FB;
  --surface-2:   #EFF2F4;
  --surface-3:   #E4E8EB;

  /* 页面青晕（顶 / 底） */
  --wash-1:      #E6FAFD;
  --wash-2:      #EAF9FB;

  /* 主色：高饱和青 */
  --primary:     #3DD9E9;
  --primary-600: #12C3D8;
  --primary-700: #0A8B9E;
  --primary-ink: #04222A;
  --primary-50:  #E4FAFD;

  /* 深墨 */
  --ink:         #17191C;
  --ink-deep:    #22262A;   /* 深色卡片 / logo 渐变的浅端 */
  --ink-2:       #6A7178;
  --ink-3:       #9BA1A8;
  --ink-4:       #C7CCD1;

  /* 语义色 + 对应浅底 / 深字 */
  --up:          #16C784;
  --up-50:       #E4F7EF;
  --up-700:      #0E9E68;
  --down:        #F6465D;
  --down-50:     #FDE8EB;
  --down-700:    #C42539;
  --warn:        #F5A623;
  --warn-50:     #FFF6E5;
  --warn-700:    #8A6100;
  /* 锁定态：石板蓝灰。不用紫 —— 靛紫是 AI 产品的默认配色，见 CLAUDE.md 2.5 ④ */
  --lock:        #5B7A99;
  --lock-50:     #EDF2F6;
  --lock-700:    #3D5771;

  /* 深底之上的文字 / 图标 */
  --on-dark:     #FFFFFF;

  /* 第三方品牌色：外部既定常量，不属于本设计系统，只允许在分享渠道图标上用 */
  --brand-wechat:    #07C160;
  --brand-qq:        #12B7F5;
  --brand-weibo:     #E6162D;
  --brand-whatsapp:  #25D366;
  --brand-facebook:  #1877F2;
  --brand-instagram: #E4405F;
  --brand-line:      #06C755;
  --brand-kakao:     #FEE500;
  --brand-kakao-ink: #191919;   /* Kakao 是亮黄底，字要用深色 */
  --brand-x:         #0F1419;

  /* 墨底卡片渐变（.card.dark）：青调深墨，比中性的 --ink 更贴主色 */
  --card-dark-1: #0C1F26;   /* 深端 */
  --card-dark-2: #1B4049;   /* 浅端 */

  /* 头像默认渐变（暖橙，与青色主调形成对冲） */
  --avatar-1:    #3A424E;
  --avatar-2:    #232932;

  /* RGB 分量：用于半透明层（遮罩 / 毛玻璃 / 阴影） */
  --ink-rgb:     23,25,28;
  --page-rgb:    246,248,249;
  --surface-rgb: 255,255,255;
  --primary-rgb: 61,217,233;
  /* 语义色的分量：提示条（.notice）的底与描边由同一个色相现算，
     省掉「底色一个 token、描边再一个 token」那种一个组件配两个色号的做法。 */
  --warn-rgb:    245,166,35;
  --down-rgb:    246,70,93;

  /* 形态 */
  --r-card:  20px;
  --r-box:   14px;
  --r-ic:    11px;   /* 圆角方块图标 */
  --r-pill:  999px;

  --sp: 18px;
  --appbar-h: 70px;   /* .appbar 实际高度（头像 40 + 上下 padding 30）。二级吸顶的 top 靠它算 */

  /* 卡片压在底色上，几乎不投影；浮层才投影 */
  --shadow-card: 0 1px 2px rgba(var(--ink-rgb),.04), 0 10px 30px -14px rgba(var(--ink-rgb),.14);
  --shadow-nav:  0 8px 32px -8px rgba(var(--ink-rgb),.18), 0 2px 8px rgba(var(--ink-rgb),.04);

  --font: -apple-system, "PingFang SC", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; padding: 0; }
/* 表单元素默认不继承字体，会掉回 Arial —— 统一收口，别再逐个选择器手写 font-family */
button, input, select, textarea { font-family: inherit; }
body {
  background: var(--bg);
  font-family: var(--font);
  color: var(--ink);
  display: flex;
  justify-content: center;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}

/* 手机容器：桌面上居中成一台机器，移动端全屏 */
#phone {
  width: 100%;
  max-width: 430px;
  min-height: 100vh;
  position: relative;
  /* 必须是 clip，不能是 hidden：overflow-x:hidden 会把 overflow-y 隐式变成 auto，
     于是 #phone 成了「永不滚动的滚动容器」，把子元素的 position:sticky 全部废掉
     （.appbar 的吸顶、.footbar 原来的吸底都是这么坏的）。clip 只裁切、不建滚动容器。 */
  overflow-x: clip;
  box-shadow: 0 0 60px rgba(var(--ink-rgb),.10);

  /* 上下两层青晕，中段留白 —— 卡片靠这层底色浮起来 */
  background:
    radial-gradient(150% 40% at 50% -6%, var(--wash-1) 0%, transparent 55%),
    var(--page);
  background-attachment: fixed, scroll;
}
@media (min-width: 460px) {
  body { padding: 24px 0; align-items: flex-start; }
  #phone { min-height: calc(100vh - 48px); border-radius: 28px; overflow: hidden; }
  /* 桌面上手机居中、上方留了 24px 边距。悬浮顶栏是 position:fixed（相对视口），
     top:0 会顶到手机框外的灰底上，得下移 24px 对齐手机顶部。移动端全屏无此偏移。 */
  .appbar.float { top: 24px; }
}

#view { padding-bottom: 108px; }

/* ---------- 排版 ---------- */
h1,h2,h3,h4 { margin: 0; font-weight: 700; }
.t-xl   { font-size: 30px; font-weight: 800; letter-spacing: -.6px; }
.t-lg   { font-size: 20px; font-weight: 700; letter-spacing: -.2px; }
.t-md   { font-size: 16px; font-weight: 600; }
.t-sm   { font-size: 14px; }
.t-xs   { font-size: 12px; }
.muted  { color: var(--ink-2); }
.dim    { color: var(--ink-3); }
.on-dark-2 { color: var(--on-dark); opacity: .6; }
.on-dark-3 { color: var(--on-dark); opacity: .4; }
.up     { color: var(--up); }
.down   { color: var(--down); }
.strike { text-decoration: line-through; color: var(--ink-3); }
.mono   { font-variant-numeric: tabular-nums; }
/* 大数字的尾巴：本币约等值，跟在 .t-xl/.t-lg 数字后面。
   必须重置 letter-spacing —— 大字号那几个类是负字距（-.6px 起），
   继承下来会把 13px 的小字挤成一坨。 */
.num-fiat { font-size: 13px; font-weight: 600; color: var(--ink-2); letter-spacing: 0; margin-left: 8px; white-space: nowrap; }
.center { text-align: center; }
.right  { text-align: right; }
.grow   { flex: 1; }
.nowrap { white-space: nowrap; }
.ell    { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 两行截断：标题允许换行，第二行放不下就 …。卡片里的商品名用它，
   别用 .ell —— 单行截断会把「Nova Pulse 磁吸充电宝 10000mAh」砍成没信息量的半截。 */
.ell2 {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden; word-break: break-word;
}

.row { display: flex; align-items: center; gap: 10px; }
.col { display: flex; flex-direction: column; }
.between { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.wrap { flex-wrap: wrap; }
.gap4{gap:4px}.gap6{gap:6px}.gap8{gap:8px}.gap12{gap:12px}.gap16{gap:16px}
.mt4{margin-top:4px}.mt6{margin-top:6px}.mt8{margin-top:8px}.mt10{margin-top:10px}.mt12{margin-top:12px}.mt16{margin-top:16px}.mt24{margin-top:24px}
.mb4{margin-bottom:4px}.mb8{margin-bottom:8px}.mb12{margin-bottom:12px}.mb16{margin-bottom:16px}.mb24{margin-bottom:24px}
.link { color: var(--primary-700); cursor: pointer; font-weight: 600; }

/* ---------- 图片占位（U.img / U.thumb 输出的 <img class="ph">） ----------
   picsum 按请求尺寸返回原图，不加约束它就按自身像素铺开，撑破图位、压住旁边的文字。
   所以占位图一律：填满所属图位 + 等比裁切 + 继承容器圆角。
   图位容器（.shop-logo / .prod-img / .mini-img …）负责 overflow:hidden 裁掉溢出部分。 */
.ph {
  display: block; width: 100%; height: 100%;
  object-fit: cover;                 /* 等比填满，不拉伸变形 */
  border-radius: inherit;
  background: var(--surface-2);      /* 图没加载出来时不至于露出空洞 */
}
/* 所有图位容器统一裁切：没有它，占位图会溢出圆角、压到相邻文字上。
   .avatar 故意不在这里 —— 它右上角要挂未读红点，红点落在圆形轮廓之外，
   一裁就没了。头像里的图靠 .ph 自己的 border-radius:inherit 保持圆形，不需要裁。 */
.shop-logo, .shop-thumb .img, .dt-img,
.prod-img, .mini-img, .d-img, .rv-img, .gallery > div, .coin { overflow: hidden; }

/* ---------- 线性图标（icons.js 输出） ---------- */
/* svg 随父级 font-size 缩放、随 currentColor 变色 —— 可无缝顶替 emoji */
.svg-ic { width: 1em; height: 1em; display: inline-block; vertical-align: -0.14em; flex: 0 0 auto; }
/* 实心态（收藏已选中等）。SVG 内联写了 fill="none"，但那是表现属性，CSS 能盖过它 */
.svg-ic.fill { fill: currentColor; }
.iconbtn.faved { color: var(--warn); }
/* 圆形币种 / 内容图标容器：参考图里币种是圆形彩标 */
.coin {
  width: 40px; height: 40px; flex: 0 0 40px; border-radius: var(--r-pill);
  display: flex; align-items: center; justify-content: center;
  font-size: 19px; background: var(--surface-1); color: var(--ink);
}
/* 底色用 --surface-1（= GV 卡「锁定中 / 冻结」那块的底，2026-08-12）：
   币标永远长在白卡 / 白弹层里，和 .cell 是同一个处境 —— --surface-2 是给**卡外**浅底控件的，
   填进白卡会沉到跟页面底色一层。资产页原先两处内联覆盖成 --primary-50（浅青）已删，
   底色统一走这里；**字色**仍由调用处按需覆盖（资产页的币标是 --primary-700 青字）。 */
.coin.sm { width: 34px; height: 34px; flex-basis: 34px; font-size: 16px; }
/* 币种字符标（U.coinMark）：Lucide 没有 USDT / ₮ 字形，用字母顶。
   字重拉满才压得住旁边的线性图标，不然一堆图标里混一个瘦字母会显得掉队。 */
.sym {
  font-weight: 800; font-size: 1.05em; line-height: 1;
  letter-spacing: -.02em; user-select: none;
}

/* ---------- 顶栏 ---------- */
.appbar {
  position: sticky; top: 0; z-index: 20;
  background: rgba(var(--page-rgb),.72);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  padding: 14px var(--sp) 10px;
  display: flex; align-items: center; gap: 12px;
}
.appbar.solid { background: rgba(var(--surface-rgb),.88); }
/* 悬浮顶栏（商品详情）：透明无底，只浮一个返回键在大图上。
   必须 fixed 而不是 absolute —— absolute 会跟着页面滚走，滑到详情中段就没有返回入口；
   也不能让它回到文档流（sticky），否则会把下面的大图顶下去。
   和 #tabbar / .footbar 一样居中约束到手机框宽度。 */
.appbar.float {
  position: fixed; top: 0; left: 50%; transform: translateX(-50%);
  width: 100%; max-width: 430px;
  background: none; backdrop-filter: none; -webkit-backdrop-filter: none;
  padding-top: calc(14px + env(safe-area-inset-top, 0px));
}
.appbar .title { font-size: 17px; font-weight: 700; flex: 1; text-align: center; letter-spacing: -.2px; }
.appbar .title.left { text-align: left; }

.iconbtn {
  width: 40px; height: 40px; flex: 0 0 40px;
  border-radius: var(--r-pill);
  border: none; background: var(--surface);
  color: var(--ink); font-size: 17px;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; box-shadow: var(--shadow-card);
  transition: transform .14s;
}
.iconbtn.ghost { background: transparent; box-shadow: none; }
.iconbtn:active { transform: scale(.94); }

.avatar {
  width: 44px; height: 44px; flex: 0 0 44px; border-radius: var(--r-pill);
  background: linear-gradient(140deg, var(--avatar-1), var(--avatar-2));
  display: flex; align-items: center; justify-content: center; font-size: 20px;
  position: relative; cursor: pointer;
}
/* 默认头像：邮箱首字母（U.letter 生成）。字号由调用方按头像直径给，这里只管字形 */
.avatar .ltr {
  color: var(--on-dark); font-weight: 700; line-height: 1;
  letter-spacing: 0; user-select: none;
}
/* 未读红点：压在头像最上层（头像里可能是图、可能是字母，都不能盖住它）。
   描边用页面底色，把红点从头像上「抠」出来，任何底图上都咬得住。 */
.avatar .dot {
  position: absolute; top: 0; right: 0; z-index: 2;
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--down); border: 2px solid var(--page);
  box-shadow: 0 0 0 1px rgba(var(--ink-rgb), .06);
}

.searchbar {
  flex: 1; height: 46px; border-radius: var(--r-pill);
  background: var(--surface-2);
  display: flex; align-items: center; gap: 8px; padding: 0 16px;
  color: var(--ink-3); font-size: 15px;
}
.searchbar input {
  border: none; background: transparent; outline: none;
  flex: 1; font-size: 15px; font-family: var(--font); color: var(--ink);
}

/* ---------- 页面块 ---------- */
.pad { padding: 0 var(--sp); }
.section { padding: 0 var(--sp); margin-top: 24px; }
.section-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.section-head .t-lg { font-size: 19px; }

.card {
  background: var(--surface);
  border-radius: var(--r-card);
  padding: 16px;
  border: 1px solid rgba(var(--ink-rgb),.05);
  box-shadow: 0 1px 2px rgba(var(--ink-rgb),.03);
}
.card.flat { background: var(--surface-2); }
/* 墨底渐变卡片：资产 hero / 邀请码 / 商家中心 / 返还说明。次级文字用 .on-dark-2 */
.card.dark { background: linear-gradient(150deg, var(--card-dark-1), var(--card-dark-2)); color: var(--on-dark); border-color: transparent; }
.card.dark .shop-logo { background: rgba(var(--surface-rgb), .12); }

/* 商家未传 Logo、后台也没配默认图时的兜底门脸：墨底青字的店铺图标填满图位。
   图标尺寸按容器百分比给（各处 .shop-logo 从 38px 到海报的整格都有），
   不能用 em —— .svg-ic 是 1em，而各图位的字号并不统一，会大小乱跳。 */
.shop-logo-def {
  display: flex; align-items: center; justify-content: center;
  width: 100%; height: 100%;
  background: var(--ink); color: var(--primary);
}
.shop-logo-def .svg-ic { width: 52%; height: 52%; }
/* 墨底卡里再压一层墨会糊成一团，跟着 .shop-logo 同一套深底配色走 */
.card.dark .shop-logo-def { background: rgba(var(--surface-rgb), .12); }
.card.dark .tag { background: rgba(var(--primary-rgb), .18); color: var(--primary); }

/* 墨底卡的点缀：右上角一团光晕（首页可用GV卡、确权详情 hero 用）。
   只是给深底一点方向感，**不是新配色** —— 用的是纯白的透明度，没引入任何新色值。

   🔴 **必须是 radial-gradient，不能是实心圆**（2026-08-13）。
   实心圆（`background: rgba(...)`）铺满整个圆、到边界戛然而止，右上角会看见**一条清晰的圆弧**
   —— 像卡上贴了个圆片，不像光。渐变从中心渐隐到 0，才看不出圆在哪结束。

   🔴 **中性白，不绑品牌色**（2026-08-13 由 `--primary-rgb` 青改过来）。
   青色光晕会跟着主题色变；白色提亮在任何深底上都成立，换主题不用回来调这里。
   ⚠️ 透明度 .07 不是笔误：渐变**中心亮、边缘为 0**，平均下来比实心 .04 还淡，
   照搬 .04 会几乎看不见。改强弱只动这个数。

   `overflow:hidden` 把圆裁在卡的圆角里；内容要压在光晕之上，否则会被盖掉。 */
.card.dark.glow { position: relative; overflow: hidden; }
.card.dark.glow::after {
  content: ''; position: absolute; right: -46px; top: -62px;
  width: 196px; height: 196px; border-radius: 50%;
  background: radial-gradient(circle, rgba(var(--surface-rgb), .07), rgba(var(--surface-rgb), 0) 70%);
  pointer-events: none;
}
.card.dark.glow > * { position: relative; z-index: 1; }
.card + .card { margin-top: 12px; }

/* 列表行 */
.list { background: var(--surface); border-radius: var(--r-card); overflow: hidden; border: 1px solid rgba(var(--ink-rgb),.05); box-shadow: 0 1px 2px rgba(var(--ink-rgb),.03); }
.li {
  display: flex; align-items: center; gap: 12px;
  padding: 16px; cursor: pointer;
  border-bottom: 1px solid var(--surface-2);
  transition: background .12s;
}
.li:last-child { border-bottom: none; }
.li:active { background: var(--surface-2); }
/* 余额为 0 的行整体退一档：币名转次级、数量转弱，币标压透明度。
   资产页一列币里往往大半是 0，不降级的话「一分钱没有的币」和真金白银同等权重，
   用户得逐行读数字才知道自己有什么。
   🔴 判据是 `!(amt > 0)`**不是 `amt < 阈值`**：dust（非零但低于展示精度，显示 `<0.000001`）
   是**有钱**，不能降级 —— 那正是最容易被用户当成「钱没了」的一档，越要显眼。 */
.li.zero .t-md { color: var(--ink-2); font-weight: 500; }
.li.zero .right .t-md { color: var(--ink-3); }
.li.zero .coin { opacity: .6; }
/* 右箭头：列表行之外（如「我的」页头像行）也用它，所以不再限定在 .li 里 */
.chev { color: var(--ink-4); font-size: 18px; }
/* ---------- 消息中心 ---------- */
/* 铃铛未读角标（「我的」页顶栏）。原来是内联 style 手搓的小红点，收成类。 */
.iconbtn.noti-btn { position: relative; overflow: visible; }
/* `.inline` = 把这枚红点从「图标右上角的绝对定位角标」放平成「跟在标题后的行内圆点」。
   商户工作台的「订单审核 ⑦」用它 —— 别另造一套红点，两处红点不同大小/不同红会很显眼。 */
/* ⚠️ `flex: 0 0 auto` + `display:inline-flex` 缺一不可：
   `.noti-badge` 基础是 `display:flex`，放平之后会成为父级 flex 容器的**可伸缩子项** ——
   实测被拉成一条横贯整行的红色长条。`min-width:17px` 只保底不封顶，拦不住拉伸。 */
.noti-badge.inline {
  position: static; border: 0; margin-left: 8px;
  display: inline-flex; flex: 0 0 auto; vertical-align: middle;
}
.noti-badge {
  position: absolute; top: -3px; right: -3px;
  min-width: 17px; height: 17px; padding: 0 4px;
  border-radius: var(--r-pill); background: var(--down); color: var(--on-dark);
  font-size: 10px; font-weight: 800; font-style: normal;
  display: flex; align-items: center; justify-content: center;
  border: 2px solid var(--page);
}

.li.noti { align-items: flex-start; padding: 14px 16px; }
.li.noti .li-ic { margin-top: 2px; }
/* 未读：左侧一道主色竖条 + 极浅底。比在角落点个小红点更容易扫到 */
/* 未读标记只剩右上角这一枚小圆点（2026-08-12）。
   原先是「青底 + 左侧 3px 色条 + 标题加粗」三件套：一屏里未读多的时候整页发蓝，
   已读的反而像被划掉了，而三样都在说同一件事。现在读 / 未读的卡片**完全一样**，
   只差这枚点 —— 点开即已读，点随之消失。
   颜色用 --down：本站的未读一直是红的（`.chip-dot` 的计数、tabbar 的 `.noti-badge`），
   换成青会和"可点/强调"撞语义。 */
.noti-dot {
  display: inline-block; width: 6px; height: 6px; border-radius: 50%;
  background: var(--down); margin-right: 6px; vertical-align: middle; position: relative; top: -1px;
}
.li.noti .chev { align-self: center; }

/* 消息类型图标配色：沿用语义色的「浅底 + 深字」三件套 */
.noti-ic.cyan { background: var(--primary-50); color: var(--primary-700); }
.noti-ic.up   { background: var(--up-50);      color: var(--up-700); }
.noti-ic.warn { background: var(--warn-50);    color: var(--warn-700); }
.noti-ic.lock { background: var(--lock-50);    color: var(--lock-700); }

/* chip 上的未读计数 */
.chip .chip-dot {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 15px; height: 15px; padding: 0 4px; margin-left: 5px;
  border-radius: var(--r-pill); background: var(--down); color: var(--on-dark);
  font-size: 10px; font-weight: 800; font-style: normal;
}
.chip.on .chip-dot { background: var(--on-dark); color: var(--ink); }

/* 列表行系统图标：圆角方块 + 浅底墨字（区别于 .coin 的圆形币标） */
.li-ic {
  width: 36px; height: 36px; flex: 0 0 36px; border-radius: var(--r-ic);
  display: flex; align-items: center; justify-content: center;
  font-size: 18px; background: var(--surface-1); color: var(--ink);
}
/* 底色 --surface-1：.li-ic 只出现在 .li 里，而 .li 只出现在 .list（--surface 白）里 —— 13 处无例外。
   白底上 --surface-2 沉 14 级偏重，--surface-1 沉 7 级正好。与 .coin / .op-grid .ic / .cell 同源。
   ⚠️ 通知行的 .noti-ic 永远带一个 tone（cyan/up/warn/lock），从不落到这个底色，不受影响。 */
/* 列表行尾的删除钮（提现地址簿在用）：比 .iconbtn 收窄一圈，免得 40px 的圆钮
   把 16px padding 的行撑高；常态弱灰不抢视线，按下才转警示色。
   必须写在 .iconbtn 之后 —— 同为单类选择器，靠后来居上盖掉那边的 40px。 */
.li-del { flex: 0 0 34px; width: 34px; height: 34px; color: var(--ink-3); }
.li-del:active { color: var(--down); }

.li.static { cursor: default; }
.li.static:active { background: transparent; }
.li.on { background: var(--primary-50); }        /* 选中行（站点 / 语言选择器） */
.li.on .t-md { color: var(--primary-700); font-weight: 700; }

/* 键值行 */
.kv { display: flex; justify-content: space-between; gap: 12px; padding: 9px 0; font-size: 14px; }
.kv .k { color: var(--ink-2); flex: 0 0 auto; }
/* min-width:0 + overflow-wrap 让长值（外部订单号 / 链接 / 无空格备注）在行内折行，
   而不是被容器 overflow:hidden 裁掉读不全。带 .ell 的单值行不受影响（nowrap 优先）。 */
.kv .v { text-align: right; font-weight: 600; font-variant-numeric: tabular-nums; min-width: 0; overflow-wrap: anywhere; }
/* 键值行的**第二行小字**：主值一行、换算值一行（如「实付 240 ￥」下面的「≈ 33.33 USDT」）。
   ------------------------------------------------------------
   原先换算值是跟在主值后面的内联 span，两个数字挤在一行里争夺右端 ——
   金额一长（六位数 + 币种符号）就把「≈ …」顶到左边，一列订单看下来右端参差不齐。

   `.kv .v` 本身已经是 `text-align:right`，所以这里**只要变成块级**就自然右对齐，
   不需要再写一次 text-align。
   ⚠️ 必须显式 `font-weight:400`：`.kv .v` 是 600，不重置的话小字会跟着变粗，
   和主值抢视线，"次要信息"这层意思就没了。 */
.kv .v .kv-sub { display: block; margin-top: 2px; font-size: 12px; font-weight: 400; color: var(--ink-3); }


/* 键值行里的就地编辑输入：商家审核订单时要能改「实付」那一格，
   又不值得为一个数字把整行拆成表单。贴着 .kv .v 排版——窄、右对齐、等宽数字，
   聚焦描 primary-600 边（同 .input 口径）。配 data-num 用，净化走 ui.js 那套委托。 */
/* 内联可编辑值（审核弹窗里的实付 / 锁定期）。
   底色必须是 --surface：它永远长在 .card.flat 里，而 .card.flat 就是 --surface-2 ——
   两边同色时这个框会整个融进卡片，只剩一道 1.5px 浅边，看着像个灰掉的标签而不是能填的框。 */
.kv-in {
  width: 92px; text-align: right;
  background: var(--surface); border: 1.5px solid var(--ink-4);
  border-radius: 9px; padding: 5px 8px;
  font-size: 14px; font-weight: 600; font-family: var(--font);
  font-variant-numeric: tabular-nums; color: var(--ink); outline: none;
  transition: border-color .14s;
}
.kv-in:focus { border-color: var(--primary-600); }
/* 占位值必须一眼看出「这是默认、我还没填」——.kv-in 是 600 字重，
   placeholder 继承过去会和真填进去的值一样黑，用户分不清默认与已改。
   但也别用 --ink-4：那是**禁用色**，占位符该用 --ink-3（token 表里「弱文字 / 占位」那一档），
   用禁用色会让人以为这个框不能改。 */
.kv-in::placeholder { color: var(--ink-3); font-weight: 400; }

/* ---------- pill 快捷入口 ---------- */
.pills {
  display: flex; gap: 10px; overflow-x: auto; padding: 4px var(--sp) 8px;
  scrollbar-width: none;
}
.pills::-webkit-scrollbar { display: none; }
.pill {
  flex: 0 0 auto; display: flex; align-items: center; gap: 9px;
  height: 44px; padding: 0 18px 0 14px;
  border-radius: var(--r-pill); background: var(--surface-2); border: none;
  font-size: 14px; font-weight: 600; color: var(--ink); font-family: var(--font);
  cursor: pointer; transition: transform .14s, background .14s;
}
.pill:active { transform: scale(.97); background: var(--surface-3); }
.pill .ic {
  display: flex; align-items: center; justify-content: center;
  font-size: 20px; color: var(--ink); background: none;
}

/* 筛选 chip */
.chips { display: flex; gap: 8px; overflow-x: auto; padding: 0 var(--sp); scrollbar-width: none; }
.chips::-webkit-scrollbar { display: none; }
/* 表单 / 卡片里的 chips：去掉自带的页边距（2026-08-13）。
   `.chips` 的 `padding: 0 var(--sp)` 是给**裸铺在页面上**的横滚条准备的；
   装进 .field 或卡片里就会和外层的边距叠成双层，所以原先四处都内联写了 padding:0 ——
   同一个需求内联四遍就是碎片化，收成一个修饰类。 */
.chips.flush { padding: 0; }
.chip {
  flex: 0 0 auto; height: 34px; padding: 0 14px; border-radius: var(--r-pill);
  background: var(--surface); border: 1px solid var(--surface-3); font-size: 13px; font-weight: 600;
  color: var(--ink-2); font-family: var(--font); cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
  transition: background .14s, color .14s;
}
.chip.on { background: var(--ink); color: var(--on-dark); border-color: var(--ink); }
.chip .svg-ic { font-size: 16px; opacity: .9; }
/* 常用联系人 chip（转账页）：三个平分一行、长昵称截断。
   .chip 基础是 flex:0 0 auto（给横滚 .chips 用的），要平分必须显式改写；
   截断三件套缺 min-width:0 就不生效 —— flex 项默认不肯缩到比内容更窄。 */
.chip.payee {
  flex: 1 1 0; min-width: 0; height: 36px; padding: 0 10px;
  font-size: 12px; display: block;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* 广场筛选展开按钮 */
.filter-btn {
  display: inline-flex; align-items: center; gap: 6px;
  height: 32px; padding: 0 12px; border-radius: var(--r-pill);
  background: var(--surface); border: 1px solid var(--surface-3); cursor: pointer;
  font-family: var(--font); font-size: 13px; font-weight: 600; color: var(--ink-2);
}
.filter-btn.on { background: var(--ink); color: var(--on-dark); border-color: var(--ink); }
.filter-btn .fb-dot {
  min-width: 16px; height: 16px; padding: 0 4px; border-radius: var(--r-pill);
  background: var(--primary-600); color: var(--on-dark);
  font-size: 10px; font-weight: 800; font-style: normal;
  display: flex; align-items: center; justify-content: center;
}
.filter-btn.on .fb-dot { background: var(--primary); color: var(--ink); }
.filter-btn .fb-arrow { font-size: 12px; transition: transform .18s; line-height: 1; }
.filter-btn .fb-arrow.up { transform: rotate(180deg); }

/* ---------- 按钮 ---------- */
.btn {
  width: 100%; height: 54px; border: none; border-radius: var(--r-pill);
  /* 字重按「按钮的分量」递减：主 CTA 600 → 次级小按钮 500（见下面 .btn-sm / .btn-xs）。
     卡片里的行内操作（撤销订单 / 删除 / 申请平台介入）是次要动作，
     跟 600 的正文标题一样粗会喧宾夺主 —— 它们只该在需要时被找到，而不是抢眼。 */
  font-size: 16px; font-weight: 600; letter-spacing: -.2px; font-family: var(--font);
  white-space: nowrap;
  cursor: pointer; display: flex; align-items: center; justify-content: center; gap: 8px;
  transition: transform .14s, opacity .14s;
}
.btn:active { transform: scale(.985); }
.btn[disabled] { opacity: .42; pointer-events: none; }
.btn-primary { background: var(--primary); color: var(--primary-ink); }
.btn-dark    { background: var(--ink); color: var(--on-dark); }
/* 浅灰底的次级按钮再降一档：字色退到 ink-2，和主色 CTA 拉开层次 */
.btn-ghost   { background: var(--surface-2); color: var(--ink-2); }
/* `.btn-ghost` 也是**跨两种底**的（查过，2026-08-13）：
     · 白卡里 13 处 —— 商户订单审核的「拒绝」、用户订单卡的「删除 / 取消」等；
     · 页面底上 2 处 —— 「我的」页与建单页的独立按钮。
   同 `.seg` 的处理：不改 `.btn-ghost` 本身，按「在不在白卡里」分流。
   🔴 起因是同一张白卡里出现**两个灰**：让利块 / 明细条是 `--surface-1`(#F6F8FB)，
   而「拒绝」钮是 `--surface-2`(#EFF2F4)，并排看得出深浅不一。
   ⚠️ `.order-card` 也要写进来 —— 商户订单审核的卡片用的是它，不是 `.card`。
   ⚠️ `:not(.dark)` 不能省：墨底卡上压一块浅灰会瞎。 */
.card:not(.dark) .btn-ghost, .order-card .btn-ghost { background: var(--surface-1); }
.btn-line    { background: transparent; color: var(--ink); border: 1px solid var(--surface-3); }
.btn-danger  { background: var(--down-50); color: var(--down); }
.btn-sm { height: 40px; font-size: 13.5px; font-weight: 500; width: auto; padding: 0 18px; }
.btn-xs { height: 32px; font-size: 13px; font-weight: 500; width: auto; padding: 0 14px; border-radius: var(--r-pill); }
/* 行内小按钮配 .grow：只准撑开，不准压缩。
   .grow 是 flex:1（basis 0），会无视内容宽度平分空间，把「申请平台介入」这类长标签挤到
   放不下——按钮高度是写死的，文字一折行就溢出。改成 basis auto + 不收缩，宽度从内容起算。 */
.btn-sm.grow, .btn-xs.grow { flex: 1 0 auto; }
/* 按钮里的图标：icon() 出的是 24×24，塞进 40px 高的 btn-sm 会压过标签。
   .btn 本身已是 flex + gap:8px，图标直接写在标签前面即可，不用再包容器。 */
.btn svg { width: 18px; height: 18px; flex: 0 0 auto; }
.btn-sm svg, .btn-xs svg { width: 16px; height: 16px; }
/* 只有图标、没有文字的按钮：宽度收成与高度相等。
   不收的话 `btn-sm` 的 `padding: 0 18px` 会把一个 16px 的图标撑成 52px 宽的胶囊，
   看着像「按钮的文字没加载出来」。图标同时放大回 18px —— 没有标签分担，
   16px 在一个 40px 的圆里太小，点得中但看不清。
   ⚠️ **必须配 `title` + `aria-label`**：图标按钮没有可读的名字，
   读屏软件念出来是「按钮」，鼠标悬停也没有任何提示。 */
.btn-ico { width: 40px; padding: 0; flex: 0 0 auto; }
.btn-ico svg { width: 18px; height: 18px; }

/* 底部固定操作条 */
/* 底部吸底操作条。
   注意：不能用 position:sticky —— #phone 带 overflow-y:auto 却没有约束高度，
   会成为一个「永不滚动的 sticky 容器」，导致 sticky 永远不触发。
   所以和 #tabbar 一样用 fixed + 居中约束到手机框宽度。 */
.footbar {
  position: fixed; bottom: 0; left: 50%; transform: translateX(-50%);
  width: 100%; max-width: 430px;
  z-index: 15;
  padding: 12px var(--sp) calc(16px + env(safe-area-inset-bottom, 0px));
  background: linear-gradient(to top, var(--page) 62%, rgba(var(--page-rgb),0));
}

/* ---------- 表单 ---------- */
.field { margin-bottom: 16px; }
/* 表单字段紧跟一张卡片时补上间距。`.field` 只有 margin-bottom，字段挨着字段时
   靠上一个的下边距就够了；但卡片没有下边距，于是「卡片 → 字段」是 0 间距 ——
   身份验证器那个字段贴在上面那张卡的边框上，看着像卡的一部分。
   ⚠️ 写成相邻选择器而不是在调用点各包一层 `mt16`：全站只有两处这种相邻
   （提现 / 兑换的验证器），但包一层的写法下一个人未必知道要包，还是会贴上。 */
.card + .field { margin-top: 16px; }
.field > label { display: block; font-size: 13px; color: var(--ink-2); margin-bottom: 8px; font-weight: 600; }
/* 标签行带右侧附注：左边是字段名，右边挂一个跟着输入变的数
   （「转账数量 / 可用 1,975 USDT」、「备注 / 0/30」）。
   ⚠️ 基线对齐不是居中 —— 13px 的标题和 12px 的附注要坐在同一条基线上，
   居中会让小字浮起来半像素，两行标签排在一起时看得出参差。
   ⚠️ 必须写成 `.field > label.between` 才盖得住上面那条的 `display:block`。 */
.field > label.between { display: flex; align-items: baseline; }
.lbl-r { font-size: 12px; font-weight: 400; color: var(--ink-3); font-variant-numeric: tabular-nums; white-space: nowrap; }
.input, .select, .textarea {
  width: 100%; background: var(--surface); border: 1.5px solid transparent;
  border-radius: var(--r-box); padding: 15px 16px;
  font-size: 15px; font-family: var(--font); color: var(--ink); outline: none;
  transition: border-color .14s;
}
.input:focus, .select:focus, .textarea:focus { border-color: var(--primary-600); }
/* 只读字段的统一形态（邮箱、已核定的确权币种…）：浅底 + 弱字。
   原先五处各写各的 —— 四处内联 `style="color:var(--ink-3)"`，一处内联了个
   **根本不存在的** `var(--fill-2)`（全项目唯一未定义的 token，背景是透明的，
   看着和可编辑的输入框一模一样）。禁用态是控件自己的事，不该由调用方每次记得写。 */
.input[disabled], .select[disabled], .textarea[disabled],
.input-amt:has(input[disabled]) { background: var(--surface-2); color: var(--ink-3); }
.input-amt input[disabled] { color: var(--ink-3); }
.input::placeholder, .textarea::placeholder { color: var(--ink-4); }
.textarea { min-height: 90px; resize: vertical; }
/* 自增高文本域：随内容长高，到 max-height 后内部滚动（高度由 U.autoGrow 逐字算）。
   手柄拖拽和自动算高会互相打架，所以关掉 resize。 */
.textarea.auto { resize: none; overflow-y: auto; max-height: 320px; }
.select { appearance: none; background-image: linear-gradient(45deg,transparent 50%,var(--ink-3) 50%),linear-gradient(135deg,var(--ink-3) 50%,transparent 50%); background-position: calc(100% - 20px) 22px, calc(100% - 15px) 22px; background-size: 5px 5px; background-repeat: no-repeat; }
/* 联系方式行（入驻表单专用）：名称 + 值 + 删除，一行放下。
   .ct-value 必须 min-width:0 —— flex 项默认 min-width:auto，不肯缩到比内容窄，
   贴一条长链接进去就会把整行撑破（同 CLAUDE.md 第 4 节那条「等宽卡片的前提」）。 */
.ct-row { display: flex; gap: 8px; align-items: center; margin-bottom: 8px; }
.ct-row .ct-label { flex: 0 0 92px; padding-left: 12px; padding-right: 12px; }
.ct-row .ct-value { flex: 1; min-width: 0; }
.ct-row .ct-del { flex: 0 0 34px; width: 34px; height: 34px; }

/* 提示 / 错误文字。**不限定在 .field 里** —— 键值行、弹窗、卡片里同样要解释和报错。
   限定死了，在 .field 外面用就得每处重写一遍颜色，而且很容易忘：忘了就是一行**灰色的错误提示**，
   混在正文里毫无警示作用（商家审核弹窗的锁定期/倍数越界提示就这么翻过车）。
   `.toast.err` 有自己的规则（选择器更具体），不受影响。 */
.hint { font-size: 12px; color: var(--ink-3); margin-top: 6px; line-height: 1.5; }
.err  { font-size: 12px; color: var(--down); margin-top: 6px; line-height: 1.5; }

/* 格式样本块：给「这一行该长什么样」看的原样文本（批量建单的粘贴格式用的就是它）。
   等宽字体是关键 —— 逗号分隔的裸数据用正文字体排出来像一句话，用户会当说明读过去，
   不会意识到那是要照抄的东西。长行折行不横滚：手机上横滚条根本发现不了。
   ⚠️ 它是**只读样本，不是输入框**。别做成 .input 的样子，用户会去点它然后发现打不了字。 */
.eg   { background: var(--surface-2); border-radius: var(--r-box); padding: 10px 12px; margin-top: 8px; }
.eg-l { font-size: 12px; line-height: 1.9; color: var(--ink-2); overflow-wrap: anywhere;
        font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }

.input-amt { display: flex; align-items: center; background: var(--surface); border-radius: var(--r-box); padding: 0 16px; }
.input-amt input { flex: 1; min-width: 0; border: none; outline: none; background: transparent; font-size: 26px; font-weight: 800; letter-spacing: -.5px; padding: 16px 0; font-family: var(--font); font-variant-numeric: tabular-nums; }
/* 后缀（￥ / USDT / × 实付）永不折行。
   input 是 flex:1 且默认 min-width:auto —— 它拒绝缩到内容宽度以下，
   于是把挤压全转嫁给后缀，「× 实付」这种长后缀就被压成两行。
   解法：input 加 min-width:0 让它肯让位；后缀禁收缩 + 禁折行。 */
.input-amt .suffix {
  font-size: 14px; font-weight: 700; color: var(--ink-2);
  flex: 0 0 auto; white-space: nowrap; margin-left: 10px;
}

/* 上传占位 */
.upload {
  border: 1.5px dashed var(--ink-4); border-radius: var(--r-box);
  background: var(--surface); padding: 22px; text-align: center;
  color: var(--ink-3); font-size: 13px; cursor: pointer;
}
.upload.filled { border-style: solid; border-color: var(--primary-600); color: var(--ink); background: var(--primary-50); }

/* 支付截图九宫格（最多 9 张）：缩略图 + 右上角删除，未满时末尾跟一个「加号」格。
   .ro 只读态（订单详情 / 商家审核）隐藏删除按钮。 */
.shots { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.shot {
  position: relative; aspect-ratio: 1 / 1;
  border-radius: var(--r-box); background: var(--surface-2);
  display: flex; align-items: center; justify-content: center;
  font-size: 26px; overflow: hidden;
}
.shot .x {
  position: absolute; top: 4px; right: 4px;
  width: 20px; height: 20px; border-radius: var(--r-pill);
  background: rgba(var(--ink-rgb), .62); color: var(--on-dark);
  border: none; cursor: pointer; font-size: 10px;
  display: flex; align-items: center; justify-content: center;
}
.shot .n {                      /* 左下角序号：商家核对时好指认「第 3 张」 */
  position: absolute; left: 6px; bottom: 4px;
  font-size: 10px; font-weight: 700; color: var(--ink-3);
}
.shot.add {
  border: 1.5px dashed var(--ink-4); background: var(--surface);
  color: var(--ink-3); cursor: pointer;
  flex-direction: column; gap: 2px; font-size: 20px;
}
.shot.add:active { border-color: var(--primary-600); background: var(--primary-50); }
.shot.add span { font-size: 10px; }
.shots.ro .x { display: none; }

/* 分段选择 */
.seg { display: flex; background: var(--surface-2); border-radius: var(--r-pill); padding: 4px; }
/* .seg 是**跨两种底**的（查过全部 4 处调用，2026-08-12）：
     · 白卡里 3 处 —— 资产页顶部控制台、提交凭证的核销方式、dev 面板的超时处理；
     · 页面底上 1 处 —— 商家入驻表单的「店铺所有权」，那个 .field 直接铺在 .pad 里。
   所以**不能改 .seg 本身**，按「在不在白卡里」分流：白卡里沉 7 级，页面上仍沉 7 级（--surface-2）。
   ⚠️ `:not(.dark)` 不是多余的：.card.dark 是墨底渐变卡，浅底 pill 压上去会瞎。 */
.card:not(.dark) .seg { background: var(--surface-1); }
.seg button {
  flex: 1; height: 38px; border: none; background: transparent; border-radius: var(--r-pill);
  font-size: 14px; font-weight: 600; color: var(--ink-2); font-family: var(--font); cursor: pointer;
  transition: background .16s, color .16s;
}
.seg button.on { background: var(--surface); color: var(--ink); box-shadow: var(--shadow-card); }

/* 单选卡 */
.optcard {
  border: 1.5px solid var(--surface-3); border-radius: var(--r-box);
  padding: 14px 16px; background: var(--surface); cursor: pointer; margin-bottom: 10px;
  transition: border-color .14s, background .14s;
}
.optcard.on { border-color: var(--primary-600); background: var(--primary-50); }

/* 数量步进 */
.stepper { display: flex; align-items: center; gap: 0; background: var(--surface-2); border-radius: var(--r-pill); }
.stepper button { width: 38px; height: 38px; border: none; background: transparent; font-size: 20px; color: var(--ink); cursor: pointer; }
.stepper .n { width: 44px; text-align: center; font-weight: 700; font-variant-numeric: tabular-nums; }

/* ---------- 徽标 ---------- */
.tag {
  display: inline-flex; align-items: center; height: 22px; padding: 0 9px;
  border-radius: 8px; font-size: 11px; font-weight: 700;
  background: var(--surface-2); color: var(--ink-2);
}
.tag.cyan { background: var(--primary-50); color: var(--primary-700); }
.tag.lock { background: var(--lock-50); color: var(--lock-700); }
.tag.up   { background: var(--up-50);   color: var(--up-700); }
.tag.down { background: var(--down-50); color: var(--down); }
.tag.warn { background: var(--warn-50); color: var(--warn-700); }
.tag.dark { background: var(--ink); color: var(--on-dark); }
/* 彩色描边款：底透明、**边框取字色**（currentColor），颜色由后面的修饰符给。
   ⚠️ 必须排在 .tag.cyan / .up / .down 等**之后** —— 那几个带 background，
   靠这条的 `background: transparent` 覆盖掉，顺序反了就变成实底。
   描边比实底轻一档：资质标是次级信息，不该跟币种那枚实底青标同重。 */
.tag.line { background: transparent; box-shadow: inset 0 0 0 1px currentColor; }
.tag.line.cyan { color: var(--primary-700); }
.tag.line.warn { color: var(--warn-700); }
.tag.line.lock { color: var(--lock-700); }
.tag.line.up   { color: var(--up-700); }
.tag.line.down { color: var(--down); }
/* 墨底卡上的描边标：`*-700` 那几个是**给白底用的深色**，压在墨底上跟背景糊成一片
   （邀请页顶部那张 .card.dark 上的身份标就是这么消失的）。
   这里换成各色的**亮端**，描边仍走 currentColor（亮色描边压在墨底上本来就清楚）。
   ⚠️ 不用 `color-mix` 把描边调淡 —— 这个原型要在旧 WebView 里也能跑，
   一个不认识的函数会让整条规则被丢掉，标又变回看不见。 */
.card.dark .tag.line.cyan { color: var(--primary); }
.card.dark .tag.line.warn { color: var(--warn); }
.card.dark .tag.line.lock { color: #9DBBD8; }   /* --lock 在墨底上仍偏暗，单独提亮一档 */
.card.dark .tag.line.up   { color: var(--up); }
.card.dark .tag.line.down { color: var(--down); }
/* 墨底上的实底标同理：.tag.dark 是「墨底 + 白字」，摞在墨底卡上等于隐形。 */
.card.dark .tag.dark { background: rgba(var(--surface-rgb), .16); color: var(--on-dark); }
/* 勾：只给「已缴」用。字号压小、右边留口气，别跟文字黏成一坨。 */
.tag .ck { margin-right: 3px; font-size: 11px; line-height: 1; }
/* 小一号：次级标识（身份 / 保证金）与主标签（币种 / 类目 / 平台）拉开层级。
   ⚠️ 靠**尺寸**分层不是靠颜色 —— 颜色位已经被币种占掉了。 */
.tag.sm { height: 19px; padding: 0 7px; font-size: 10px; border-radius: 6px; }
/* 徽标在 flex 行里**永不压缩**：`.row` 的子项默认可缩，长店名一挤就把标压成
   半个字甚至换行。原先只有个别调用点内联写 `flex:0 0 auto`，写漏的就会塌。 */
.row > .tag, .between > .tag { flex: 0 0 auto; }

/* ---------- 资产 ---------- */
.balance-hero { padding: 4px var(--sp) 0; }
.balance-hero .num { font-size: 44px; font-weight: 800; letter-spacing: -1.8px; font-variant-numeric: tabular-nums; }
/* 字号(.55em)与字重(inherit)由「大数字的小数位」那条统一给，这里只留颜色与字距。 */
.balance-hero .num .dec { color: var(--ink-3); letter-spacing: -.6px; }

.asset-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.asset-box { background: var(--surface); border-radius: var(--r-card); padding: 16px; }
.asset-box .lbl { font-size: 12px; color: var(--ink-2); display: flex; align-items: center; gap: 5px; }
.asset-box .val { font-size: 21px; font-weight: 800; margin-top: 7px; font-variant-numeric: tabular-nums; letter-spacing: -.4px; }
/* 待办格：淡红底 + 红数字。与右边那格（成绩）区分性质 —— 同色等于说两者一样重要。
   ⚠️ 归零时**别挂这个类**（视图里判了 pending > 0）：一个红色的「0」是在为没有的事报警。 */
.asset-box.todo { background: rgba(var(--down-rgb), .06); }
.asset-box.todo .val { color: var(--down); }
.asset-box.hi { background: linear-gradient(150deg, var(--ink), var(--ink-deep)); color: var(--on-dark); }
.asset-box.hi .lbl { color: rgba(var(--surface-rgb),.62); }
.asset-box.hi .val { color: var(--primary); }

.statdot { width: 7px; height: 7px; border-radius: 50%; }
.statdot.lock { background: var(--lock); }
.statdot.rel  { background: var(--primary-600); }
.statdot.avail{ background: var(--up); }

/* 释放进度 */
.bar { height: 6px; border-radius: var(--r-pill); background: var(--surface-3); overflow: hidden; }
.bar > i { display: block; height: 100%; background: var(--primary-600); border-radius: var(--r-pill); }

/* ---------- 商品 / 商家卡片 ---------- */
.shop-card { background: var(--surface); border-radius: var(--r-card); padding: 16px; margin-bottom: 10px; cursor: pointer; }
.shop-logo {
  width: 46px; height: 46px; flex: 0 0 46px; border-radius: 15px;
  display: flex; align-items: center; justify-content: center; font-size: 21px;
}
.shop-thumbs { display: flex; gap: 8px; margin-top: 13px; }
/* min-width:0 是关键：flex 项默认 min-width:auto，不肯缩到比内容更窄，
   于是一个长商品名就能把这一列（连带里面的图）撑宽，两列宽度不再相等。 */
.shop-thumb { flex: 1 1 0; min-width: 0; background: var(--surface-2); border-radius: 13px; padding: 10px; }
.shop-thumb .img { aspect-ratio: 1 / 1; border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 27px; }

/* 商品卡片网格（「好物」页 / 商家详情页共用）：双列，图在上、价格 + 名称在下。
   两页的商品列表以前是左图右文的行（.goods-row），信息密度高但图太小、翻起来像通讯录；
   电商的商品流一律是卡片网格 —— 图是决策主体，得给它整整一列的宽度。 */
/* 瀑布流：两列各自独立流动，卡片不做左右行对齐（名称占一行还是两行，下一张就顶上来）。
   用 CSS columns 而不是 grid —— grid 会把同一行的卡片拉成等高，留一道参差不齐的空白。 */
.grid2 { columns: 2; column-gap: 12px; }
.prod-card {
  background: var(--surface); border-radius: var(--r-card); overflow: hidden;
  cursor: pointer; border: 1px solid rgba(var(--ink-rgb),.05);
  transition: transform .12s;
  break-inside: avoid;           /* 别把一张卡拦腰截断到两列 */
  -webkit-column-break-inside: avoid;
  margin-bottom: 12px;
}
.prod-card:active { transform: scale(.99); }
.prod-body { padding: 12px 12px 14px; }
/* 商品名最多两行，超出省略号 */
.prod-nm {
  font-size: 13px; line-height: 1.45; color: var(--ink-2); margin-top: 5px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; text-overflow: ellipsis;
}

.prod-img { aspect-ratio: 1 / 1; display: flex; align-items: center; justify-content: center; font-size: 56px; }
.price { font-size: 20px; font-weight: 800; letter-spacing: -.4px; }
/* GV徽标：所有商品展示位统一用它（由 UI.price 生成）。
   曾经和 .mini-gift 并存两份几乎一样的定义，已合并到这里。 */
.gift-badge {
  display: inline-flex; align-items: center; gap: 5px;
  background: var(--primary-50); color: var(--primary-700);
  border-radius: 9px; padding: 5px 10px; font-size: 11.5px; font-weight: 600; letter-spacing: .2px;
}
.gift-badge svg.svg-ic { font-size: 13px; opacity: .85; }

/* ---------- 搜索 ---------- */
.searchbar.tappable { cursor: pointer; }
.searchbar .clear {
  width: 20px; height: 20px; border-radius: 50%; border: none;
  background: var(--ink-4); color: var(--on-dark); font-size: 12px; line-height: 1;
  display: flex; align-items: center; justify-content: center; cursor: pointer; flex: 0 0 20px;
}
/* 搜索页的「取消」：它是 .appbar 的**兄弟**，不在 .searchbar 里面 ——
   选择器写成 .searchbar .cancel 会完全不生效，按钮掉回浏览器默认的方框边框。
   形态是纯文字按钮：无边框无底色，靠间距和字重站住，点下去给主色反馈。 */
.cancel {
  flex: 0 0 auto;
  border: none; background: transparent;
  color: var(--ink-2); font-size: 15px; font-weight: 600;
  padding: 0 2px 0 10px; cursor: pointer;
  transition: color .14s, opacity .14s;
}
.cancel:hover  { color: var(--ink); }
.cancel:active { color: var(--primary-700); opacity: .7; }
mark { background: transparent; color: var(--primary-700); font-weight: 800; padding: 0; }

.hist-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.hist-chip {
  height: 32px; padding: 0 13px; border-radius: var(--r-pill);
  background: var(--surface); border: none; font-size: 13px; color: var(--ink-2);
  font-family: var(--font); cursor: pointer; display: flex; align-items: center;
}
.hist-chip:active { background: var(--surface-3); }
.hot-rank {
  width: 20px; height: 20px; border-radius: 6px; flex: 0 0 20px;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 800; background: var(--surface-2); color: var(--ink-3);
}
.hot-rank.top { background: var(--ink); color: var(--primary); }

.res-row {
  display: flex; align-items: center; gap: 12px; padding: 13px 16px;
  cursor: pointer; border-bottom: 1px solid var(--surface-2);
}
.res-row:last-child { border-bottom: none; }
.res-row:active { background: var(--surface-2); }

/* 分类精选 · 横向滚动 */
.hscroll {
  display: flex; gap: 12px; overflow-x: auto;
  padding: 0 var(--sp) 4px; scrollbar-width: none;
  scroll-snap-type: x proximity;
}
.hscroll::-webkit-scrollbar { display: none; }
.mini-card {
  flex: 0 0 152px; scroll-snap-align: start;
  background: var(--surface); border-radius: var(--r-card);
  overflow: hidden; cursor: pointer; transition: transform .14s;
}
.mini-card:active { transform: scale(.98); }
.mini-img {
  aspect-ratio: 1 / 1; display: flex; align-items: center; justify-content: center;
  font-size: 44px; position: relative;
}
.mini-cat {
  position: absolute; left: 8px; top: 8px;
  background: rgba(var(--ink-rgb),.72); color: var(--on-dark);
  border-radius: 8px; padding: 3px 8px; font-size: 10px; font-weight: 700;
}
.mini-body { padding: 11px 12px 13px; }

/* ---------- 商品图文详情 ---------- */
.detail-tabs { display: flex; gap: 20px; border-bottom: 1px solid var(--surface-2); margin-bottom: 4px; }
.detail-tabs button {
  border: none; background: none; padding: 12px 0 11px; cursor: pointer;
  font-family: var(--font); font-size: 15px; font-weight: 600; color: var(--ink-3);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
  transition: color .14s;
}
.detail-tabs button.on { color: var(--ink); border-bottom-color: var(--ink); }

.detail-wrap { position: relative; max-height: 520px; overflow: hidden; }
.detail-wrap.open { max-height: none; }
/* 小号折叠：店铺介绍这类短文本用，限高与渐隐都更矮。
   .sm 和 .open 同优先级（都是两个类），.sm 写在后面会压住 .open，
   所以展开态必须显式写 .sm.open，否则点了展开也不动。 */
.detail-wrap.sm { max-height: 86px; }
.detail-wrap.sm.open { max-height: none; }
.detail-wrap.sm .detail-fade { height: 54px; }
/* 5 行档：入驻须知用。14px(.t-sm) × 1.9 行高 × 5 行 = 133px。
   同 .sm，展开态必须显式写 .l5.open —— 两个类同优先级，写在后面的会压住 .open。 */
.detail-wrap.l5 { max-height: 133px; }
.detail-wrap.l5.open { max-height: none; }
.detail-wrap.l5 .detail-fade { height: 64px; }

/* 墨底卡里的折叠：渐隐与按钮都要换深色，否则是白糊一片压在墨底上。
   渐隐收到 --card-dark-2（卡片渐变的浅端，须知块正落在卡的中下部，对得上）；
   按钮走半透明白，与「口令领取」的磨砂块同一套。 */
.card.dark .detail-fade {
  background: linear-gradient(to top, var(--card-dark-2) 32%, rgba(var(--ink-rgb), 0));
}
.card.dark .detail-more {
  background: rgba(var(--surface-rgb), .14); border-color: rgba(var(--surface-rgb), .2);
  color: var(--on-dark);
}
.card.dark .detail-more:active { background: rgba(var(--surface-rgb), .24); }
.detail-fade {
  position: absolute; left: 0; right: 0; bottom: 0; height: 110px;
  background: linear-gradient(to top, var(--surface) 32%, rgba(var(--surface-rgb),0));
  display: flex; align-items: flex-end; justify-content: center;
}
.detail-wrap.open .detail-fade { display: none; }
.detail-more {
  border: 1.5px solid var(--surface-3); background: var(--surface);
  border-radius: var(--r-pill); height: 38px; padding: 0 20px;
  font-family: var(--font); font-size: 13px; font-weight: 700; color: var(--ink);
  cursor: pointer; display: flex; align-items: center; gap: 6px;
}

.d-h {
  font-size: 15px; font-weight: 700; margin: 20px 0 9px;
  display: flex; align-items: center; gap: 8px;
}
.d-h:first-child { margin-top: 4px; }
.d-h::before { content: ''; width: 3px; height: 15px; border-radius: 2px; background: var(--primary-600); }
.d-p { font-size: 14px; color: var(--ink-2); line-height: 1.85; margin: 0 0 10px; overflow-wrap: anywhere; }
/* 商品详情编辑器（商家发布页）：图文块按顺序混排，每块下面挂一排 ↑ ↓ 🗑 操作 */
.dt-block { padding-bottom: 12px; margin-bottom: 12px; border-bottom: 1px solid var(--surface-2); }
.dt-block:last-child { border-bottom: none; }
.dt-img { border-radius: var(--r-box); aspect-ratio: 4 / 3; background: var(--surface-2); }

/* 详情插图：4:3 框。原来写死 180px 高，等于把商家传的竖向长图裁成一条窄带。 */
.d-img {
  border-radius: var(--r-box); aspect-ratio: 4 / 3; margin: 12px 0 7px;
  display: flex; align-items: center; justify-content: center; font-size: 64px;
}
.d-cap { font-size: 12px; color: var(--ink-3); text-align: center; margin-bottom: 14px; }
.d-list { margin: 4px 0 10px; padding-left: 18px; }
.d-list li { font-size: 14px; color: var(--ink-2); line-height: 1.9; }

/* ---------- 评价 ---------- */
.stars { display: inline-flex; gap: 2px; color: var(--warn); line-height: 1; }
.stars .s { font-size: 13px; }
.stars .s.off { color: var(--ink-4); }
.stars.lg .s { font-size: 17px; }

.rate-hero { display: flex; gap: 20px; align-items: center; padding: 4px 0 14px; }
.rate-score { text-align: center; flex: 0 0 auto; }
.rate-score .n { font-size: 34px; font-weight: 800; letter-spacing: -1px; line-height: 1.1; font-variant-numeric: tabular-nums; }
.rate-bars { flex: 1; min-width: 0; }
.rate-bar-row { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.rate-bar-row .lb { font-size: 11px; color: var(--ink-3); width: 26px; flex: 0 0 26px; }
.rate-bar-row .bar { flex: 1; height: 5px; }
.rate-bar-row .bar > i { background: var(--warn); }
.rate-bar-row .ct { font-size: 11px; color: var(--ink-3); width: 20px; text-align: right; flex: 0 0 20px; }

.rv-card { padding: 16px 0; border-bottom: 1px solid var(--surface-2); }
.rv-card:last-child { border-bottom: none; }
.rv-text { font-size: 14px; color: var(--ink); line-height: 1.75; margin-top: 9px; overflow-wrap: anywhere; }
.rv-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.rv-imgs { display: flex; gap: 8px; margin-top: 11px; }
.rv-img {
  width: 74px; height: 74px; border-radius: 12px; background: var(--surface-2);
  display: flex; align-items: center; justify-content: center; font-size: 30px;
}
.rv-reply {
  background: var(--surface-2); border-radius: 13px;
  padding: 11px 13px; margin-top: 12px;
  font-size: 13px; color: var(--ink-2); line-height: 1.7;
  overflow-wrap: anywhere;
}
.rv-reply b { color: var(--ink); }

.star-pick { display: flex; gap: 10px; justify-content: center; margin: 6px 0 4px; }
.star-pick .s { font-size: 34px; cursor: pointer; color: var(--ink-4); line-height: 1; transition: transform .12s, color .12s; }
.star-pick .s.on { color: var(--warn); }
/* 选中的星要填实 —— pickStar 只切 .on，不重渲染，所以填充态由 CSS 管 */
.star-pick .s.on .svg-ic { fill: currentColor; }
.star-pick .s:active { transform: scale(1.15); }

.tag-pick {
  height: 32px; padding: 0 13px; border-radius: var(--r-pill);
  background: var(--surface-2); border: 1.5px solid transparent;
  font-size: 13px; color: var(--ink-2); font-family: var(--font); cursor: pointer;
  transition: background .14s, border-color .14s;
}
.tag-pick.on { background: var(--primary-50); border-color: var(--primary-600); color: var(--primary-700); font-weight: 600; }

.gallery { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; }
.gallery::-webkit-scrollbar { display: none; }
/* 商品图一律 1:1 —— 上传规格是 1200×1200，好店 / 好物 / 订单 / 商品卡 / 详情轮播
   共用同一张主图，比例不统一就会各裁各的（宽条位只剩中间一条带）。 */
.gallery > div { flex: 0 0 100%; scroll-snap-align: start; aspect-ratio: 1 / 1; display: flex; align-items: center; justify-content: center; font-size: 88px; }
.dots { display: flex; gap: 5px; justify-content: center; margin-top: -22px; position: relative; z-index: 2; }
.dots i { width: 6px; height: 6px; border-radius: var(--r-pill); background: rgba(var(--ink-rgb),.22); transition: width .2s; }
.dots i.on { width: 18px; background: var(--ink); }

/* ---------- 订单 ---------- */
.order-card { background: var(--surface); border-radius: var(--r-card); padding: 17px; margin-bottom: 12px; }

/* 订单卡里的「订单明细」折叠（商户端审核列表）。
   用**原生 `<details>`**：展开态存在 DOM 里，键盘操作与读屏语义由浏览器给，
   不必自己写 toggle、也不必在模块里记「哪张卡是开的」。
   ⚠️ 它挺不过一次 render()（整页 innerHTML 重建）——审完一单全部收起，这是已知取舍。 */
.ord-more > summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 9px; border-radius: var(--r-box);
  background: var(--surface-1); color: var(--ink-2);
  font-size: 13px; font-weight: 600;
}
.ord-more > summary::-webkit-details-marker { display: none; }   /* Safari 那个三角 */
.ord-more > summary .svg-ic { width: 15px; height: 15px; color: var(--ink-3); transition: transform .22s ease; }
.ord-more[open] > summary .svg-ic { transform: rotate(180deg); }

/* 「让利 / 获赠」双值胶囊（商户端订单卡专用，右对齐独占一行）。
   两个数**单位不同**（让利是 USDT、获赠是 GV），所以各带自己的标签和单位，
   中间一道竖线分隔 —— 不加分隔就是一串数字，读的人会把它们当成同一笔钱。
   ⚠️ 不能直接套 `.tag`：那个是 inline-flex，混排的文本节点会各自变成 flex item，
   长内容被挤成一列一行（「让利 / 96 / U · 获赠 / 480 / GV」就是这么来的）。
   这里每一段包在自己的 span 里，gap 只作用在段与段之间。 */
.deal-tag {
  display: inline-flex; align-items: center; gap: 10px;
  height: 28px; padding: 0 13px; border-radius: var(--r-pill);
  background: var(--surface-2); white-space: nowrap;
  font-size: 12px; font-variant-numeric: tabular-nums;
}
.deal-tag > span { display: inline-flex; align-items: baseline; gap: 4px; }
.deal-tag .k { color: var(--ink-3); }
.deal-tag b  { font-weight: 700; font-size: 13px; letter-spacing: -.2px; }
.deal-tag .u { color: var(--ink-3); font-weight: 400; }
.deal-tag i  { width: 1px; height: 12px; background: var(--ink-4); }
.timeline { position: relative; padding-left: 24px; }
.timeline .node { position: relative; padding-bottom: 20px; }
.timeline .node:last-child { padding-bottom: 0; }
.timeline .node::before {
  content: ''; position: absolute; left: -24px; top: 4px;
  width: 10px; height: 10px; border-radius: 50%; background: var(--ink-4);
}
.timeline .node.done::before { background: var(--primary-600); }
.timeline .node::after {
  content: ''; position: absolute; left: -20px; top: 18px; bottom: 2px;
  width: 2px; background: var(--surface-3);
}
.timeline .node:last-child::after { display: none; }

/* ---------- 空态 ---------- */
.empty { text-align: center; padding: 56px 20px; color: var(--ink-3); }
.empty .ic { font-size: 44px; opacity: .5; }
.empty .tx { margin-top: 12px; font-size: 14px; }

/* ---------- 底部导航（悬浮胶囊） ---------- */
#tabbar {
  position: fixed; bottom: 14px; left: 50%; transform: translateX(-50%);
  width: calc(100% - 32px); max-width: 398px;
  height: 66px; border-radius: var(--r-pill);
  background: rgba(var(--surface-rgb),.82);
  backdrop-filter: blur(20px) saturate(160%); -webkit-backdrop-filter: blur(20px) saturate(160%);
  box-shadow: var(--shadow-nav);
  display: flex; align-items: center; justify-content: space-around;
  z-index: 30;
}
#tabbar .tab {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px;
  background: none; border: none; cursor: pointer; font-family: var(--font);
  color: var(--ink-3); font-size: 10.5px; font-weight: 500; letter-spacing: .2px;
  transition: color .14s;
}
/* position:relative 是给 .noti-badge 当定位父级用的（商户端「订单」tab 的待审核角标）。
   少了它，角标会往上找定位祖先，直接飞到 #tabbar 的右上角去。 */
#tabbar .tab .ic {
  position: relative;
  width: 40px; height: 40px; border-radius: var(--r-pill);
  display: flex; align-items: center; justify-content: center;
  font-size: 24px; color: var(--ink-3); background: transparent;
  transition: background .22s, color .16s;
}
/* 导航栏是深色浮层，角标描边要跟着底色走，别用页面底色 --page 描一圈灰边 */
#tabbar .tab .ic .noti-badge { border-color: var(--surface); }
/* 选中态 = **图标底下浮起一个半透明圆圈**（2026-08-13 改，原先只是整体转 --ink + 上移 1px）。
   圆圈比「字变黑」显眼得多，一眼看得出人在哪一栏 —— 上移 1px 那种位移在 66px 的胶囊里
   几乎看不出来，且会让角标跟着抖。
   🔴 配色一律走项目 token，不引 `--brand` 那套：
     · 圆圈底 `--primary-50` —— 第 7 节登记的就是「主色浅底（**选中态背景**）」，本就是干这个的；
     · 圈内图标与下面的标签 `--primary-700` —— 同一节写着它是「**青色浅底之上的可读文字**」。
   ⚠️ 别用 `--primary`(#3DD9E9)：它是高饱和亮青，压在 primary-50 上或近白的导航底上都糊。 */
#tabbar .tab.on { color: var(--primary-700); }
#tabbar .tab.on .ic { background: var(--primary-50); color: var(--primary-700); }
#tabbar.hidden { display: none; }

/* ---------- Sheet / 弹窗 ---------- */
#sheet-root { position: fixed; inset: 0; z-index: 60; pointer-events: none; }
.mask {
  position: absolute; inset: 0; background: rgba(var(--ink-rgb),.45);
  opacity: 0; transition: opacity .22s; pointer-events: auto;
}
.mask.in { opacity: 1; }
.sheet {
  position: absolute; left: 50%; bottom: 0; transform: translate(-50%,100%);
  width: 100%; max-width: 430px;
  background: var(--page); border-radius: 28px 28px 0 0;
  padding: 8px 16px calc(20px + env(safe-area-inset-bottom));
  transition: transform .26s cubic-bezier(.32,.72,0,1); pointer-events: auto;
  max-height: 88vh; overflow-y: auto;
  box-shadow: var(--shadow-nav);
}
.sheet.in { transform: translate(-50%,0); }
.sheet .grab { width: 38px; height: 4px; border-radius: var(--r-pill); background: var(--ink-4); margin: 6px auto 14px; }
.sheet .sheet-title { font-size: 18px; font-weight: 700; text-align: center; margin-bottom: 18px; letter-spacing: -.2px; }

/* 滚动条：桌面预览里的原生粗条收细成移动端 overlay 质感（真机竖滚本就是悬浮细条）。
   横滚容器 .pills / .chips / .hscroll 另有 `::-webkit-scrollbar{display:none}`，class 优先级更高，仍保持完全隐藏。 */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-thumb { background: rgba(var(--ink-rgb),.16); border-radius: var(--r-pill); }
::-webkit-scrollbar-thumb:hover { background: rgba(var(--ink-rgb),.30); }
::-webkit-scrollbar-track { background: transparent; }
.sheet { scrollbar-width: thin; scrollbar-color: rgba(var(--ink-rgb),.16) transparent; }

.dialog {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%,-46%) scale(.96);
  width: calc(100% - 64px); max-width: 340px;
  background: var(--surface); border-radius: var(--r-card); padding: 24px 20px 18px;
  opacity: 0; transition: all .2s; pointer-events: auto; text-align: center;
  box-shadow: var(--shadow-nav);
}
.dialog.in { transform: translate(-50%,-50%) scale(1); opacity: 1; }

/* 弹窗头图：圆角方块 + 线性图标（第 3 条视觉要点）。danger 弹窗转粉红警示配色 */
.dlg-ic {
  width: 52px; height: 52px; margin: 0 auto 14px;
  border-radius: var(--r-box);
  /* 底色 --surface-1：.dlg-ic 的父级恒为 .dialog（--surface 白）。
     这是**不传 tone 时**的中性底；传了 ok/warn/info/danger 走下面四条语义色，不受影响。 */
  background: var(--surface-1); color: var(--ink);
  display: flex; align-items: center; justify-content: center;
  font-size: 26px;
}
.dlg-ic.danger { background: var(--down-50);    color: var(--down); }
.dlg-ic.ok     { background: var(--up-50);      color: var(--up-700); }
.dlg-ic.warn   { background: var(--warn-50);    color: var(--warn-700); }
.dlg-ic.info   { background: var(--primary-50); color: var(--primary-700); }

/* 2FA 输入 */
.otp { display: flex; gap: 8px; justify-content: center; margin: 18px 0; }
.otp input {
  width: 42px; height: 52px; text-align: center; font-size: 22px; font-weight: 700;
  border: 1.5px solid var(--surface-3); border-radius: 13px; outline: none; font-family: var(--font);
  background: var(--surface); color: var(--ink);
  transition: border-color .14s;
}
.otp input:focus { border-color: var(--primary-600); }

/* ---------- Toast ---------- */
#toast-root { position: fixed; top: 22px; left: 0; right: 0; z-index: 90; display: flex; flex-direction: column; align-items: center; gap: 8px; pointer-events: none; }
.toast {
  background: var(--ink); color: var(--on-dark); padding: 12px 20px; border-radius: var(--r-pill);
  font-size: 14px; font-weight: 600; max-width: 84%; text-align: center;
  animation: tin .24s ease; box-shadow: var(--shadow-nav);
}
.toast.err { background: var(--down); }
@keyframes tin { from { opacity: 0; transform: translateY(-14px); } }

/* ---------- 系统模拟按钮 ---------- */
#devbtn {
  position: fixed; right: 16px; bottom: 96px; z-index: 40;
  width: 42px; height: 42px; border-radius: 50%; border: none;
  background: var(--ink); color: var(--primary); font-size: 17px; cursor: pointer;
  box-shadow: var(--shadow-nav); opacity: .82;
}
@media (min-width: 460px) { #devbtn { right: calc(50% - 215px + 16px); } }

/* ---------- 提交凭证浮标（用户端专用，可在「我的」里关） ----------
   位置：⚙ 之上。⚙ 是 42px、bottom:96 → 顶边在 138，这里 bottom:148 留 10px 间距。
   right:13 而不是 16 —— 它比 ⚙ 宽 6px，两者要**圆心对齐**（都落在距右 37px），
   差 3px 在竖直堆叠里一眼就看得出是歪的。 */
#subfab {
  position: fixed; right: 13px; bottom: 148px; z-index: 40;
  width: 48px; height: 48px; border-radius: 50%; border: none;
  background: var(--primary); color: var(--primary-ink); cursor: pointer;
  box-shadow: var(--shadow-nav);
  display: grid; place-items: center;
  transition: transform .14s;
}
#subfab:active { transform: scale(.93); }
#subfab svg { width: 22px; height: 22px; stroke-width: 2.2; }
@media (min-width: 460px) { #subfab { right: calc(50% - 215px + 13px); } }

/* ---------- 开关（.li 里的设置项，如「我的 → 提交凭证浮标」） ----------
   放在 .li 的最右侧，替代 .chev —— 那一行是「就地切换」不是「跳转」，
   给它一个箭头会让人以为点进去还有二级页。 */
.sw {
  position: relative; flex: 0 0 46px; width: 46px; height: 27px;
  border-radius: var(--r-pill); border: none; padding: 0; cursor: pointer;
  background: var(--surface-3); transition: background .18s;
}
.sw::after {
  content: ''; position: absolute; top: 3px; left: 3px;
  width: 21px; height: 21px; border-radius: 50%;
  background: var(--surface); box-shadow: 0 1px 3px rgba(var(--ink-rgb), .28);
  transition: transform .18s;
}
.sw.on { background: var(--primary-600); }
.sw.on::after { transform: translateX(19px); }

/* ---------- FEAT-A01 登录 / 注册 ---------- */
.auth { padding: 0 var(--sp) 32px; }
.auth-brand { text-align: center; padding: 56px 0 36px; }
/* 品牌字标。原来是 76×76 的墨色圆角方块 + 里面一枚白色单色 mark；
   换成 WDEO 横向字标后那个深色底必须去掉 —— 字标本身就是黑字 + 红点，
   压在墨色方块上会糊成一团，红点也会失真。
   图是抠过白底的透明 PNG，**靠高度定尺寸、宽度自适应**，别写死 width。 */
.auth-logo {
  height: 52px;
  /* 只居中，别写 `margin: 0 auto` —— 那会把上下外边距一并归零，
     挂在它身上的 .mb24 / .mt16 全部失效（注册页的字标就会直接顶着「创建账号」）。 */
  margin-left: auto; margin-right: auto;
  display: flex; align-items: center; justify-content: center;
}
.auth-logo.sm { height: 34px; }        /* 注册页：已经有顶栏标题，字标收小一档 */
.auth-logo img { height: 100%; width: auto; display: block; }
/* 勾选项（登录页「记住我」）。
   用原生 checkbox + accent-color 上主色，不自绘方框 ——
   自绘要把点击热区、键盘焦点、无障碍语义全部重做一遍，为一个勾不值当。
   包一层 <label> 让文字也可点。 */
.cbx {
  display: flex; align-items: center; gap: 10px;
  cursor: pointer; user-select: none;
}
.cbx input {
  width: 18px; height: 18px; flex: none; margin: 0;
  accent-color: var(--primary-600);
}

.auth-or {
  position: relative; text-align: center; margin: 20px 0 14px;
}
.auth-or::before {
  content: ''; position: absolute; left: 0; right: 0; top: 50%;
  height: 1px; background: var(--surface-3);
}
.auth-or span {
  position: relative; background: var(--page); padding: 0 12px;
  font-size: 12px; color: var(--ink-3);
}

/* 风险提示条 */
/* 提示条：**浅底 + 同色相描边**（2026-08-12 改，原来是纯 `-50` 实底、无边框）。
   实底在白卡片旁边是一整块色，比它要提示的那句话还抢眼；退成淡底之后
   靠一条描边把边界立住 —— 块还是块，但不再和内容抢。
   底与描边由同一个 `-rgb` 现算，一个组件不配两个色号。 */
.notice {
  background: rgba(var(--warn-rgb), .07); border: 1px solid rgba(var(--warn-rgb), .22);
  border-radius: var(--r-box); padding: 12px 14px;
  font-size: 12px; line-height: 1.6; color: var(--warn-700); overflow-wrap: anywhere;
}
.notice.danger { background: rgba(var(--down-rgb), .06); border-color: rgba(var(--down-rgb), .22); color: var(--down-700); }
.notice.info { background: rgba(var(--primary-rgb), .08); border-color: rgba(var(--primary-rgb), .30); color: var(--primary-700); }

/* ---------- 降低动效（无障碍） ---------- */
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* ==== 构建追加：Bitget 布局组件 ==== */
/* 资产页的动作宫格：4 列，条目不足 4 的整数倍时最后一行自然靠左。
   `.op-row`（单行 flex 版）已删（2026-08-07）—— 资产页七个动作全平铺后再没人用它。 */
/* ⚠️ 左右**不留页边距**：这块现在长在资产页顶部那张 .card 里（2026-08-12），
   卡自己有 16px padding，再带 var(--sp) 就是双层。两个类都只在 views-asset.js 用。 */
.op-grid { display: grid; grid-template-columns: repeat(4,1fr); gap: 16px 2px; padding: 18px 0 14px; }
.op { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 9px; background: none; border: none; cursor: pointer; font-family: var(--font); padding: 0; }
.op .ic { width: 50px; height: 50px; border-radius: var(--r-pill); background: var(--surface-2); color: var(--ink); display: flex; align-items: center; justify-content: center; font-size: 23px; transition: transform .14s, background .14s; }
.op:active .ic { transform: scale(.92); background: var(--surface-3); }
/* 资产页顶部那 6 个操作图标：底色跟 GV 卡「锁定中 / 冻结」(.cell) 对齐（2026-08-12）。
   🔴 **只作用在 .op-grid 里**（该类仅资产页在用），别提到 `.op .ic` 去改全局 ——
   分享面板的 .op 长在 .sheet 里，而 .sheet 的底是 --page(L246)，
   --surface-1(L247) 压上去几乎隐形，「复制链接 / 生成二维码」那两个没配品牌色的会直接糊掉。
   同一个值在白卡上是「轻轻凹一下」，在 --page 上就是「没有」。 */
.op-grid .ic { background: var(--surface-1); }
.op .lbl { font-size: 12px; color: var(--ink-2); font-weight: 500; }

/* 分享海报：商品图 + 介绍 + 二维码。二维码是真码，扫了直达详情页 */
.poster {
  background: var(--surface); border-radius: var(--r-card);
  border: 1px solid var(--surface-3); overflow: hidden; text-align: left;
}
.poster-img { aspect-ratio: 1 / 1; overflow: hidden; background: var(--surface-2); }
.poster-body { padding: 14px; }
.poster-intro { font-size: 12px; color: var(--ink-2); line-height: 1.6; margin-top: 8px; }
.poster-foot {
  display: flex; align-items: center; gap: 10px;
  margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--surface-2);
}
/* 二维码容器：白底 + 内边距，扫码识别率靠这圈白边 */
.qr {
  width: 64px; height: 64px; flex: 0 0 64px;
  border-radius: var(--r-ic); background: var(--on-dark);
  border: 1px solid var(--surface-3); padding: 3px; overflow: hidden;
}
.qr .qr-img { width: 100%; height: 100%; display: block; }
/* 收款页的主二维码：大尺寸 + 更厚的白边（扫码距离越远，白边越吃紧） */
.qr.lg {
  width: 208px; height: 208px; flex-basis: 208px;
  border-radius: var(--r-box); padding: 12px;
  /* ⚠️ 只能写左右，不许写 `margin: 0 auto` —— 那会把 margin-top 一并归零，
     而 `.qr.lg`(0,2,0) 特异性高于 `.mt16`(0,1,0)，工具类**静默失效**：
     收款页写着 `class="qr lg mt16"` 却和上面的用户名贴死，看代码完全看不出问题。 */
  margin-left: auto; margin-right: auto;
}

/* 分享面板：四列宫格，格子复用 .op（圆形图标 + 下方文字） */
.share-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px 6px; }
.op .ic.wechat    { background: var(--brand-wechat);    color: var(--on-dark); }
.op .ic.moments   { background: var(--brand-wechat);    color: var(--on-dark); }
.op .ic.qq        { background: var(--brand-qq);        color: var(--on-dark); }
.op .ic.weibo     { background: var(--brand-weibo);     color: var(--on-dark); }
.op .ic.whatsapp  { background: var(--brand-whatsapp);  color: var(--on-dark); }
.op .ic.facebook  { background: var(--brand-facebook);  color: var(--on-dark); }
.op .ic.instagram { background: var(--brand-instagram); color: var(--on-dark); }
.op .ic.line      { background: var(--brand-line);      color: var(--on-dark); }
.op .ic.x         { background: var(--brand-x);         color: var(--on-dark); }
.op .ic.kakao     { background: var(--brand-kakao);     color: var(--brand-kakao-ink); }
/* 举报是反向操作：粉红底红字，和上面几个分享操作明确区分开 */
.op .ic.report    { background: var(--down-50);         color: var(--down); }
/* 行内提示图标：跟在标签后面的小问号，点开说明弹窗。
   负 margin 是为了让 24px 的点击区不把行高撑开 —— 视觉是 15px，热区仍够手指点。 */
.hint-ic { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; margin: -6px 0 -6px 1px; padding: 0; border: 0; background: none; color: var(--ink-3); cursor: pointer; vertical-align: middle; }
.hint-ic svg { width: 15px; height: 15px; }
.hint-ic:active { color: var(--ink-2); }
.bal-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; padding: 0; }
.bal-head .num { font-size: 40px; font-weight: 800; letter-spacing: -1.6px; font-variant-numeric: tabular-nums; line-height: 1.05; }
.bal-head .num .cur { font-size: 26px; font-weight: 700; margin-right: 2px; }
/* 字号(.55em)与字重(inherit)由「大数字的小数位」那条统一给，这里只留颜色。 */
.bal-head .num .dec { color: var(--ink-3); }
/* `.fcards` / `.fcard`（资产页那两张横滚功能卡：兑换 / 折价兑现）已删（2026-08-07）——
   两个动作平铺进 .op-grid 了，同一层级的入口不再有第二种形态。 */
.op .ic svg, #tabbar .tab .ic svg { stroke-width: 2; }
.shop-card { border: 1px solid rgba(var(--ink-rgb),.05); box-shadow: 0 1px 2px rgba(var(--ink-rgb),.03); }
.shop-card > .row { gap: 12px; align-items: flex-start; }
.shop-card .shop-logo { margin-top: 1px; }
.order-card { border: 1px solid rgba(var(--ink-rgb),.05); box-shadow: 0 1px 2px rgba(var(--ink-rgb),.03); }

/* 「按钮体系精修」那一段已合并回各自的基础定义（2026-08-13）。
   它原本以**覆盖层**的形式存在：读第 500~570 行拿到一套值（17/700、border:none），
   实际渲染是另一套（16/600、1px 描边），CLAUDE.md 记的又是第三套 —— 三份不一致。
   ⚠️ 以后调按钮 / chip 的字号字重描边，**改原处**，别再在文件末尾堆覆盖层。
   `.seg button { font-weight: 600 }` 与基础定义同值，一并删。 */

/* 吸顶头：把顶栏和它下面那条控件栏当一个整体粘在顶部
   （好物页 = 搜索栏 + 品类栏。确权记录页原来也用它包「标题栏 + 订单/交易分段」，
   2026-08-12 交易 tab 撤掉后那页只剩裸顶栏，不再是这个类的调用者）。
   整体粘比两个各自 sticky 更稳 —— 不用手算第二层的 top 偏移。 */
.stickhead {
  position: sticky; top: 0; z-index: 20;
  background: rgba(var(--page-rgb), .82);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  padding-bottom: 10px;
}
.stickhead .appbar {                 /* 里层不再单独粘，也不重复毛玻璃 */
  position: static; background: none;
  backdrop-filter: none; -webkit-backdrop-filter: none;
}

/* 二级吸顶（好店页）：顶栏粘在 0，类目栏粘在顶栏底下。
   顶栏是 sticky 而非同一个容器（中间隔着快捷入口、GV卡、分类精选），
   所以类目栏得自己算 top —— 用 --appbar-h，别写死数字。 */
.chipbar.substick {
  position: sticky; top: var(--appbar-h); z-index: 19;
  padding-top: 10px; padding-bottom: 10px;
  background: rgba(var(--page-rgb), .82);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
}

/* 品类横滚 + 右侧常驻筛选按钮。
   关键：按钮不盖在 chips 上 —— chips 在一个更窄的容器里滚，右侧给按钮留出空位。
   容器右缘用 mask 做透明→不透明渐变，边界上的 chip 被裁切并淡出，
   用户一眼就知道右边还有东西可滚（盖死它反而什么提示都没有）。 */
.chipbar { position: relative; display: flex; align-items: center; }
.chipbar .chips {
  flex: 1; min-width: 0;
  padding-right: 44px;                       /* 滚到底时最后一个 chip 能完全走出渐隐区 */
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 44px), transparent 100%);
          mask-image: linear-gradient(to right, #000 calc(100% - 44px), transparent 100%);
}
/* chip 间距与内边距收紧：让第 6 个品类的边界落在容器中段，而不是正好卡在边缘上，
   保证初始视图里下一个品类稳定露出 ~40%，用户看得出还能往右滚。 */
.chipbar .chips { gap: 6px; }
.chipbar .chip { padding: 0 13px; }
.chipbar .chipbar-fade {
  flex: 0 0 auto; display: flex; align-items: center;
  padding-right: var(--sp);
}

/* 「收/转」FAB 已移除（收款 / 转账 归到资产页操作行，提交凭证在好店页快捷入口）。
   overflow 留着：商户端「订单」tab 上的待审核红点 .noti-badge 是负偏移定位的，
   裁掉就看不见了 —— 它不是 FAB 的遗留。 */
#tabbar { overflow: visible; }

/* ==== GV结构化分解 ==== */
.gift-bar { display: flex; height: 8px; border-radius: var(--r-pill); overflow: hidden; gap: 2px; background: var(--surface-2); }
.gift-bar > i { display: block; height: 100%; min-width: 4px; border-radius: 2px; }
/* 资产页的 GV 卡（每个确权币种一张）。原先三态平铺三等分（.gift-stat，已删）——
   三个数一样大，读不出「哪个是我现在能动的」。改成两层：
   锁定 / 冻结并列压小（现在动不了的钱），可用整行 + 绿底放大（现在能动的钱）。
   三态圆点复用既有的 .statdot（.lock / .rel / .avail），不另配一套颜色。 */
.gv-head { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.gv-sym { min-width: 0; }
.gv-sym .t { font-size: 14px; font-weight: 600; color: var(--ink-2); }
.gv-sym .s { display: block; font-size: 11px; color: var(--ink-3); margin-top: 1px; }
/* 变现价值靠右上、顶格对齐：它是这张卡的结论，但比总额轻一档，别和主数字抢。 */
.gv-fiat { margin-left: auto; align-self: flex-start; font-size: 15px; font-weight: 600;
           color: var(--ink-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* 副行里那枚「价格未更新」标：跟在锚定资产后面，别把行高撑起来 */
.gv-sym .s .tag { margin-left: 4px; padding: 1px 5px; font-size: 10px; }
.gv-total { font-size: 30px; font-weight: 800; color: var(--ink); letter-spacing: -.6px;
            line-height: 1.1; font-variant-numeric: tabular-nums; margin-bottom: 16px; }
/* .gv-total 的单位后缀：30px 主数字上 `.72em` 会长到 21px，压回固定 13px。
   字距也要归零 —— .gv-total 是负字距，继承下来会把 GV 两个字母挤在一起。
   ⚠️ **代币行余额仍然不挂单位**（2026-08-12 试过又撤回：左边已经写着币名）。
   通用 `.unit` 现在服务的是商户端订单卡那三格「让利 / 用户获得 / 您获得」。 */
.gv-total .unit { font-size: 13px; color: var(--ink-3); margin-left: 4px; }

.dual { display: flex; gap: 12px; margin-bottom: 10px; }
.cell { flex: 1; min-width: 0; background: var(--surface-1); border-radius: var(--r-box); padding: 11px 13px; }
.cell .top { display: flex; align-items: center; gap: 6px; }
.cell .name { font-size: 13px; color: var(--ink-2); }
.cell .pct { margin-left: auto; font-size: 11px; color: var(--ink-3); font-variant-numeric: tabular-nums; }
/* 数值缩进 14px 与圆点+间距对齐，让标签和数字左边成一条线 */
.cell .amt { margin-top: 8px; padding-left: 14px; font-size: 17px; font-weight: 700;
             color: var(--ink); font-variant-numeric: tabular-nums; letter-spacing: -.2px; }

.avail-row { display: flex; align-items: center; justify-content: space-between;
             background: var(--up-50); border-radius: var(--r-box); padding: 12px 13px; }
.avail-row .lhs { display: flex; align-items: center; gap: 8px; min-width: 0; }
.avail-row .name { font-size: 13px; color: var(--ink-2); }
.avail-row .pct { font-size: 11px; color: var(--ink-3); font-variant-numeric: tabular-nums; margin-top: 1px; }
.avail-row .val { font-size: 18px; font-weight: 700; color: var(--up-700);
                  font-variant-numeric: tabular-nums; letter-spacing: -.2px; }
/* 绿数字里的小数跟着绿走（压透明度），落回灰会像两个不相干的数拼在一起 */
.avail-row .val .dec { color: var(--up-700); opacity: .5; }

/* 小数点后压一档：整数是量级、小数是精度。一律由 U.decDim() 生成，别自己拆字符串。 */
.dec { color: var(--ink-4); font-size: .72em; font-weight: 500; }
/* 单位后缀与小数位**同一档**（2026-08-13 产品定）：`96.00 U` 里的 `.00` 和 `U`
   一样大、一样浅，整数部分自己跳出来。规格照抄上面那条 `.dec`，别另调一档。
   ⚠️ `.gv-total`（30px 主数字）另有覆盖：`.72em` 在那个尺度上会长到 21px。 */
.unit { color: var(--ink-4); font-size: .72em; font-weight: 500; margin-left: 2px; letter-spacing: 0; }
/* 🔴 **大数字的小数位另有一档 ≈.55em**（2026-08-13 补齐，同日收口成这一条）。
   `.72em` 是给列表里那些 12~17px 小数字调的 —— 那个尺度上小数再压就看不清了。
   压到 30px 以上的主数字上，小数会长到 21px+，和整数抢，一串数字读起来糊成一团。
   ⚠️ 新增任何 ≥30px 的主数字，都要挂进下面这个选择器列表。

   两件事都在这里定死，**别再回到各处各写一份**：
   ① **字号按 em 不按 px。** `.bal-head .num .dec`(22/40=.550) 与
      `.balance-hero .num .dec`(24/44=.545) 原先按 px 写死 —— 比例其实同一档，
      但一套 px 一套 em，新加主数字时照着谁抄全看运气（GV 卡总额与首页余额卡就这么漏了）。
      折算差 ≤0.2px，肉眼无别。
   ② **字重一律 `inherit`。** 小数位不自己定字重，跟着它所属的那个数字走（四处主数字都是 800）。
      原先四处各写各的：`.bal-head` 800、`.balance-hero` 800、`.gv-total` 落到全局 500、
      墨底那条 600 —— 同一件东西四个值。`inherit` 之后，改主数字字重小数位自动跟上，
      也不必再在每条规则上写「⚠️ 必须显式写 font-weight」。
   ⚠️ 本条比 `.card.dark .dec`(0,3,0) 更具体(0,4,0)，墨底卡上的**大**数字走这里的 inherit，
      墨底卡上其余小数字仍是那条的 600。颜色不归本条管，各自保留。 */
.bal-head .num .dec,
.balance-hero .num .dec,
.card.dark .t-xl .dec,
.gv-total .dec { font-size: .55em; font-weight: inherit; }

/* ---------- 收款方回显（转账页）----------
   转账实时到账、**不可撤销**，「转给谁」是这一页风险最高的一个字段。
   原来是一行 `.hint` 淡灰字，比旁边「常用联系人」那个标题还轻 —— 用户扫过去就过去了。
   做成整条带底色的胶囊：对了绿、错了红，不读字也知道状态。
   ⚠️ 只用在这一处，别拿它当通用提示条 —— 通用的是 `.hint` / `.err` / `.notice`。 */
.echo { display: flex; align-items: center; gap: 8px; margin-top: 8px;
        padding: 8px 12px; border-radius: var(--r-box); font-size: 12.5px; }
.echo .av { width: 20px; height: 20px; border-radius: 50%; flex: 0 0 auto;
            display: flex; align-items: center; justify-content: center;
            font-size: 11px; font-weight: 700; color: var(--on-dark); }
.echo b { font-weight: 700; }
.echo .muid { color: var(--ink-3); margin-left: 4px; }
.echo.ok  { background: var(--up-50);   color: var(--up-700); }
.echo.ok  .av { background: var(--up); }
.echo.bad { background: var(--down-50); color: var(--down-700); }
.echo.bad .av { background: var(--down); }

/* 金额输入的错误态：**框本身**变红，不只是下面那行字。
   钱输错了先看到的是框，回头才读字；只标字的话，一屏几个输入框时找不到是哪个错了。
   ⚠️ 用 inset 阴影画边、不用 border：`.input-amt` 基础样式没有边框，
   出错时才加一条会把框撑高 3px，输入过程中跳一下比不标还烦。 */
.input-amt.err { box-shadow: inset 0 0 0 1.5px var(--down); background: var(--down-50); }
/* 可点的单位后缀（提交凭证页选支付币种）。与静态 `.suffix` 同字号同色，
   靠一个下拉箭头表示「这里能点」—— 换成按钮配色会让它比旁边那个大金额还抢眼。
   ⚠️ 热区要够：`.suffix` 本身只有文字宽，加左右内边距把点击区撑到 44px 量级。 */
.suffix-pick {
  display: inline-flex; align-items: center; gap: 2px;
  border: 0; background: none; cursor: pointer; font-family: var(--font);
  margin-right: -6px; padding: 8px 6px 8px 10px;
}
.suffix-pick svg { width: 14px; height: 14px; color: var(--ink-3); }

/* 普通 `.input` 右侧的单位后缀（商户端建单的实付栏）。
   ⚠️ 和 `.input-amt .suffix` 不是一回事：那个是**大额输入**的一部分（26px 数字、flex 布局），
   这里的 `.input` 是整宽单行框，后缀只能**叠在框内右侧**，并给 input 留出右内边距，
   否则长金额会从后缀底下穿过去。 */
.input-sfx { position: relative; }
.input-sfx .input { padding-right: 46px; }
/* 后缀默认是**死文字**：`pointer-events: none` 让点击穿过去落到输入框上 ——
   它压在输入框右侧，不穿透的话点到它就等于点了个不聚焦的空当。 */
.input-sfx .sfx-tx {
  position: absolute; right: 14px; top: 50%; transform: translateY(-50%);
  font-size: 14px; font-weight: 700; color: var(--ink-2); pointer-events: none;
}
/* 🔴 但后缀**挂了 onclick 时必须收回事件**（2026-08-14）：商户建单的金额后缀是
   计价币种选择器，继承上面那条 `pointer-events: none` 的话点了毫无反应 ——
   而它长得像个可点的下拉（带箭头 + 主色），是最难查的那种「按钮没坏但点不动」。
   选择器写成 `[onclick]`，谁把后缀做成可点的都自动生效，不用记得来改这里。 */
.input-sfx .sfx-tx[onclick] {
  pointer-events: auto; cursor: pointer;
  display: inline-flex; align-items: center; gap: 2px;
  padding: 4px 0 4px 8px;                  /* 左侧留出热区，别贴着数字 */
}
.input-sfx .sfx-tx[onclick] .svg-ic { width: 14px; height: 14px; }

/* ==== 全局币种下拉选择器 ==== */
.select-trigger {
  width: 100%; height: 54px; border: 1px solid var(--surface-3); background: var(--surface);
  border-radius: var(--r-box); padding: 0 12px 0 10px; display: flex; align-items: center; gap: 10px;
  font-family: var(--font); cursor: pointer; transition: border-color .14s;
}
.select-trigger:active { border-color: var(--primary-600); }
.select-trigger .t-md { text-align: left; }
.select-trigger .sel-chev { color: var(--ink-3); font-size: 18px; display: flex; flex: 0 0 auto; }

/* ==== 筛选弹层（分组 chip，主流筛选面板）==== */
.fgroup { margin-bottom: 22px; }
.fgroup-t { font-size: 13px; font-weight: 600; color: var(--ink-2); margin-bottom: 12px; }
.fchips { display: flex; flex-wrap: wrap; gap: 10px; }
.fchip { height: 38px; padding: 0 16px; border-radius: var(--r-pill); background: var(--surface-2); border: 1px solid transparent; font-size: 13px; font-weight: 500; color: var(--ink); font-family: var(--font); cursor: pointer; transition: background .14s, border-color .14s, color .14s; }
.fchip.on { background: var(--primary-50); border-color: var(--primary-600); color: var(--primary-700); font-weight: 600; }
/* 平台子项：隶属于「第三方平台店铺」，不是平级维度。
   左侧竖线 + 缩进，让层级一眼可见；选了别的经营类型就整块收起。 */
.plat-sub {
  margin: 12px 0 0 4px; padding: 12px 0 2px 14px;
  border-left: 2px solid var(--primary-50);
}

/* ---------- 金额隐藏（眼睛，2026-08-13）---------- */
/* 遮罩本身：等宽 + 字距撑开，六个星号占的宽度接近它遮掉的数字，
   切换时卡片不会忽宽忽窄。字号继承所在位置，所以大数字和小数字都能用同一个类。 */
.masked { font-family: var(--font); letter-spacing: .12em; opacity: .72; }
/* 眼睛：跟在标签后面的小钮，不撑行高（负 margin 同 .hint-ic 的做法）。
   热区 24px、视觉 14px —— 视觉尺寸不决定可点性。 */
.eye-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; margin: -5px 0; padding: 0;
  border: none; background: none; cursor: pointer;
  color: inherit; opacity: .72; font-size: 14px; transition: opacity .14s;
}
.eye-btn:active { opacity: 1; }

/* ---------- 首页余额卡的「口令领取」入口（2026-08-13）----------
   原先这个位置是个纯装饰的礼物图标（没有 onclick）。现在是真入口，
   所以要有按钮的样子：半透明白底方块 + 一行说明文字。
   长在 .card.dark 上，用 --surface-rgb 兑半透明，别写死 rgba(255,255,255,…)。 */
/* ---------- 首页余额卡的「口令领取」入口（2026-08-13，按产品给的规格实现）----------
   浮在卡右上角，上下两层：磨砂圆角图标块 + 一行浅金文字。
   🔴 **背后是两层**，缺一层就没有层次：
     ① 卡片右上角那团青色光晕 —— 走既有的 `.card.dark.glow`（`--primary-rgb` 的透明度，
        不是新色值），让这个角比卡其余部分亮一点；
     ② 这个 46×46 的**磨砂半透明**块压在光晕上。
   🔴 **图标块不能是深色实底** —— 实块压在墨底卡上是一块死黑，把卡挖了个洞；
   半透明白 + backdrop-filter 才会「浮着发光」。
   配色用主色青（同这张卡上的大数字），不引第二套色。 */
/* 可用GV 卡右上角的装饰图标块（2026-08-13 起**只是图标，不可点**）。
   `pointer-events: none` 是关键：它让点击**穿过去**落到卡片上 ——
   卡片整块点了去资产页，图标区域也一样，不会出现一块「点了没反应」的死区。
   ⚠️ 别改成 `stopPropagation`：那才会造成死区（卡上有个洞点不动）。
   ⚠️ `cursor` 与 hover 态都已去掉 —— 留着会暗示它有自己的动作。 */
.redeem-btn {
  position: absolute; right: 16px; top: 16px;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 0; border: none; background: none; font-family: var(--font);
  pointer-events: none;
}
.redeem-btn .rc {
  width: 46px; height: 46px; border-radius: 14px;
  background: rgba(var(--surface-rgb), .14);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center;
  font-size: 24px; color: var(--primary);
  transition: background .15s;
}
/* hover / active 态已撤（2026-08-13）：这块现在是**卡片的装饰层**、不是独立按钮
   （见 views-market.js 那段注释）。留着按下变色会暗示它有自己的动作，
   而它点了只是跟着卡片去资产页。 */
/* icon() 的 svg 写死 stroke-width=2，这里按规格压到 1.7；线帽本来就是 round。 */
.redeem-btn .rc svg { stroke-width: 1.7; }
.redeem-btn .rt { font-size: 11px; font-weight: 700; color: var(--primary); white-space: nowrap; }

/* ---------- 快捷入口三等分（2026-08-13）----------
   .pills 默认是横滚胶囊条。首页那三个正好占满、从来滚不起来，而胶囊的形状
   暗示「这里可以横滑」。.even 让它们等分成方按钮：点击目标更大，也更像入口。
   ⚠️ 只加在需要的地方，别改 .pills 本身 —— 别处的快捷入口条项目更多，仍要横滚。 */
.pills.even { overflow-x: visible; }
.pills.even .pill { flex: 1 1 0; min-width: 0; justify-content: center; border-radius: var(--r-box); }

/* 可点的标（商家卡上那个「+3 / 收起」）：形状随 .tag，但要有可按的反馈。
   ⚠️ 它是 <button> 不是 <span> —— 键盘可达、语义正确；.tag 本身不带这些。 */
.tag-btn { border: none; cursor: pointer; font-family: var(--font); color: var(--ink-2);
           transition: background .14s, transform .1s; }
.tag-btn:active { background: var(--surface-3); transform: scale(.94); }
/* 收起态是个图标（chevron-up）。给它固定宽度并居中：不定宽的话，
   「+3」和一个 ▲ 宽度差一截，展开/收起时整排标会左右跳一下。 */
.tag-btn.ic { display: inline-flex; align-items: center; justify-content: center;
              min-width: 30px; padding: 3px 6px; font-size: 13px; }

/* 深色卡上的小数位：全局 .dec 是 --ink-4（给白底用的浅灰），压在墨底上会脏。
   这里换成半透明白，与 .on-dark-3 同一档。⚠️ 必须显式写 font-weight ——
   全局 .dec 带 500，不写会把大数字的小数位悄悄压轻（同 .bal-head .num .dec 那条）。 */
.card.dark .dec { color: rgba(var(--surface-rgb), .45); font-weight: 600; }

/* ---------- 步进器里的手输框（2026-08-13）----------
   `.stepper` 原本中间是个只读的 `.n`。审核页的两个比例**必须能手输**：
   让利比例是 1%～100%，从 30 调到 80 纯靠点 + 要点 50 下。
   所以中间换成 input，两侧的 ± 只是快捷微调。
   ⚠️ 这是 `.stepper` 第一次真正被用上 —— 它在 CSS 里躺了很久、零调用者。 */
.stepper input.n {
  border: none; background: none; font-family: var(--font); font-size: 15px;
  color: var(--ink); padding: 0; min-width: 0;
}
.stepper input.n::placeholder { color: var(--ink-3); font-weight: 700; }
.stepper .u { font-size: 12px; color: var(--ink-2); padding-right: 4px; }
.stepper button:disabled { opacity: .3; cursor: default; }

/* 审核页「结算预览」里那条**你要掏多少钱**：淡红底 + 大号红字。
   它和上面两行（用户获得 / 商户获得）不是同一类 —— 那两个是发出去的 GV，
   这个是从店铺钱包真扣的 USDT，同底色摆一起会被读成一组三个并列的数。 */
.pay-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  background: var(--down-50); border-radius: var(--r-box); padding: 12px 14px; margin-top: 10px;
}
.pay-row .amt { font-size: 22px; font-weight: 800; color: var(--down);
                font-variant-numeric: tabular-nums; letter-spacing: -.4px; }
.pay-row .amt .u { font-size: 12px; font-weight: 600; color: var(--down); margin-left: 3px; }

/* ---------- 商家卡：资质行（店号 · 凭证数 + 身份 / 保证金标） ----------
   店号那串是弱信息（对号用），标是强信息（判断用）—— 一左一右分开，
   眼睛扫列表时走的是右边那一列标，不用逐张读店号。 */
.sid-row { display: flex; align-items: center; gap: 6px; }
.sid-row > .grow { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------- 抵用券（CR-017 · #/vouchers） ----------
   列表里每行左侧的金额块：它是这一行的主语（用户找券是按金额找的），
   所以给它固定宽度自成一列，而不是塞进正文里当一段文字。 */
.vc-face {
  flex: 0 0 62px; text-align: center;
  font-size: 19px; font-weight: 800; letter-spacing: -.6px;
  color: var(--primary-700); font-variant-numeric: tabular-nums;
}
.vc-face.done { color: var(--ink-3); text-decoration: line-through; }

/* 出示弹层里的大金额与券码。￥ 压到 .5em —— 金额才是要一眼读到的数。 */
.vc-amt { font-size: 38px; font-weight: 800; letter-spacing: -1.4px; color: var(--primary-700); font-variant-numeric: tabular-nums; }
.vc-amt.lg { font-size: 46px; }
.vc-amt i { font-size: .5em; font-style: normal; font-weight: 700; margin-right: 2px; }
.vc-qr { margin: 0 auto; }
/* 券码字距拉开：隔着柜台念给店员听，或者他照着手输 */
.vc-code { margin-top: 12px; font-size: 20px; font-weight: 700; letter-spacing: 3px; color: var(--ink); }
/* 复制钮在 20px 的券码旁边太小，放大一档；左边留口气，别贴着最后一位字符
   （券码的 letter-spacing 只作用在字符之间，最后一位右边是没有间距的）。 */
.vc-code .iconbtn.ghost { width: 24px !important; height: 24px !important; font-size: 16px !important; margin-left: 6px; }

/* 列表行右侧的统计数字（邀请页「团队数量 / 团队昨日GV」）。
   比 .t-md 小一档：它是一行里的**值**，不是标题 —— 和左边的行标题同量级就够了，
   再大就成了这一屏的主角，而这一屏的主角是邀请码。 */
.stat-num { font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -.2px; }

/* 支付渠道图标（CR-032）。品牌色实底 —— 微信绿、支付宝蓝是这两个渠道最强的识别符，
   用中性灰的话用户得读字才知道点的是哪个。 */
.pay-ic.wechat { background: #07C160; color: #fff; }
.pay-ic.alipay { background: #1677FF; color: #fff; }

/* 顶栏右侧的范围下拉（商户端订单审核的店铺切换）。
   宽度给上限而不是固定值：店名长短不一，固定宽会让短名字后面拖一截空白，
   而长名字被 .ell 截得只剩两个字。 */
.scope-btn {
  display: inline-flex; align-items: center; gap: 2px;
  max-width: 132px; height: 30px; padding: 0 8px 0 10px;
  border: 0; border-radius: var(--r-pill);
  background: var(--surface-2); color: var(--ink);
  font-family: var(--font); font-size: 13px; font-weight: 600;
  cursor: pointer; white-space: nowrap;
}
.scope-btn .ell { overflow: hidden; text-overflow: ellipsis; }
.scope-btn svg.svg-ic { font-size: 15px; color: var(--ink-3); flex: 0 0 auto; }
.scope-btn:active { background: var(--surface-3); }
