:root {
  --bg: #f4f5fb;
  --panel: #ffffff;
  --border: #eaecf2;
  --text: #1a1d29;
  --muted: #8b90a0;
  --primary: #5b5bd6;
  --primary-dark: #4a4ac0;
  --primary-soft: #eeeefb;
  --pending: #e08a1e;
  --recharged: #5b5bd6;
  --sold: #16a34a;
  --grad: linear-gradient(135deg, #6d6df0, #5b5bd6);
  --shadow: 0 1px 2px rgba(20,23,40,.04), 0 6px 20px rgba(20,23,40,.06);
  --shadow-sm: 0 1px 3px rgba(20,23,40,.06);

  /* ---------- 卡片/面板：全站唯一一套 ----------
     背景现在是整屏的照片或视频（而且管理员随时能换成任意一张图），
     所以「浮在背景上的面板」必须自带一层足够深的底 + 白字 —— 浅色半透明面板
     压在一张亮图上会被洗白，小字直接看不见。

     为什么要收敛成变量：之前是各页面自己在模板里写内联 <style> 打补丁，
     orders.html 和 kiro_monitor.html 是同一段 `!important` 复制粘贴，
     而 users / my / balance / cards / products / settings 等页面压根没打，
     于是同一个 .stat-card 在不同页面上一个深色白字、一个浅色灰字。
     现在只有这一处定义，加页面不用再抄那段补丁。

     做号台（.mintboard）另有一套 --mb-* 变量，是刻意的特例（电视墙要更高对比），
     它的选择器更具体所以照旧生效，不受这里影响。 */
  --card-bg: rgba(20,23,44,.58);
  --card-bg-hi: rgba(28,32,58,.72);      /* 悬停/强调态 */
  --card-border: rgba(255,255,255,.18);
  --card-border-hi: rgba(255,255,255,.3);
  --card-radius: 14px;
  --card-shadow: 0 8px 28px rgba(0,0,0,.22);
  --card-blur: blur(20px) saturate(160%);
  /* 三级文字：主数字/正文、次要说明、最弱的口径小字。
     都带一点投影 —— 背景可能是任意亮度的照片，纯色白字在浅色区域会糊掉。 */
  --card-txt: #fff;
  --card-txt-dim: rgba(255,255,255,.78);
  --card-txt-mute: rgba(255,255,255,.58);
  --card-txt-shadow: 0 1px 3px rgba(0,0,0,.55);

  /* ---------- 数据表格：刻意走浅底深字，和上面的深色面板是两个家族 ----------
     密集表格（几十行 × 十几列）在浅底上读得明显更快，所以这里不跟卡片统一成深色。
     要统一的是**同一个家族内部别有两套值**：base 原来是 .62 的半透明，
     而 cards.html / vcc.html 各自内联改成 .96 —— 同一张表在不同页面深浅不一。
     .62 压在照片上本来就偏薄，所以取 .96 当全站默认，那两处内联删掉。 */
  --table-bg: rgba(255,255,255,.96);
  --table-txt: #1a1d29;
  --table-head-bg: #f7f8fc;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

[hidden] { display: none !important; }

body {
  font-family: -apple-system, "Segoe UI", "Microsoft YaHei", system-ui, sans-serif;
  /* 只给一层中性深色底，**不要**在这儿放照片。
     原来这里是 url("/static/bg-poster.jpg")，也就是那段旧背景视频的封面帧。
     它写在 CSS 里 → 浏览器第一帧就画它 → JS 之后才把真正配置的背景盖上去，
     于是每次刷新都会先闪一下**旧背景**。背景现在是管理员可换的，
     把上一版背景的静帧钉死在样式里正好是反的。
     首帧改由 common.js 用 localStorage 里缓存的配置直接铺（见 bgInit）。 */
  background: #11141f;
  color: var(--text);
  font-size: 14px;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  position: relative;
  overflow-x: hidden;
}

/* ===== 动态极光背景（已改用视频封面/视频背景，默认停用，仅保留定义）===== */
body::before,
body::after {
  content: "";
  position: fixed;
  z-index: -1;
  pointer-events: none;
  border-radius: 50%;
  filter: blur(90px);
  will-change: transform;
  display: none;
}
body::before {
  width: 62vw; height: 62vw;
  top: -18vw; right: -12vw;
  background: radial-gradient(circle at 30% 30%, rgba(139,123,255,.55), rgba(185,139,255,.32) 45%, transparent 72%);
  opacity: .5;
  animation: auroraA 24s ease-in-out infinite alternate;
}
body::after {
  width: 58vw; height: 58vw;
  bottom: -22vw; left: -14vw;
  background: radial-gradient(circle at 60% 40%, rgba(110,231,240,.45), rgba(124,155,255,.34) 45%, transparent 72%);
  opacity: .45;
  animation: auroraB 30s ease-in-out infinite alternate;
}
/* 第三团光斑（浮层，中部偏移）*/
.aurora-blob {
  position: fixed; z-index: -1; pointer-events: none;
  width: 46vw; height: 46vw; left: 30vw; top: 20vh;
  border-radius: 50%; filter: blur(100px); opacity: .32;
  background: radial-gradient(circle at 50% 50%, rgba(255,139,197,.5), rgba(255,183,139,.28) 50%, transparent 72%);
  animation: auroraC 36s ease-in-out infinite alternate;
  will-change: transform;
  display: none;
}
@keyframes auroraA {
  0%   { transform: translate(0, 0) scale(1) rotate(0deg); }
  100% { transform: translate(-7vw, 9vw) scale(1.18) rotate(25deg); }
}
@keyframes auroraB {
  0%   { transform: translate(0, 0) scale(1) rotate(0deg); }
  100% { transform: translate(9vw, -7vw) scale(1.22) rotate(-20deg); }
}
@keyframes auroraC {
  0%   { transform: translate(0, 0) scale(1); }
  50%  { transform: translate(-8vw, 4vw) scale(1.15); }
  100% { transform: translate(6vw, -6vw) scale(.92); }
}
@media (prefers-reduced-motion: reduce) {
  body::before, body::after, .aurora-blob { animation: none; }
}

/* ===== 全屏循环背景视频 ===== */
.bg-video {
  position: fixed; inset: 0; z-index: -3;
  width: 100%; height: 100%; object-fit: cover;
  pointer-events: none;
}
/* ===== 静态背景图 / 多图轮播 =====
   两层叠着交叉淡入（common.js 的 bgSlideshow 用）：一层显示当前图，
   另一层在底下预载下一张再换透明度。只用一层的话换图那一瞬间会白闪 ——
   backgroundImage 一改就先变空。
   淡入时长由 JS 按配置写在 style.transitionDuration 上，这里只给个兜底值。 */
.bg-img {
  position: fixed; inset: 0; z-index: -3;
  background-size: cover; background-position: center; background-repeat: no-repeat;
  opacity: 0;
  transition: opacity 1.2s ease;
  pointer-events: none;
}
.bg-img.on { opacity: 1; }

/* 压暗层：背景太亮时压不住正文，比让管理员自己去 P 图省事 */
.bg-dim {
  position: fixed; inset: 0; z-index: -2;
  background: #0b0e1a; opacity: 0; pointer-events: none;
}

/* 有视频或图片时隐藏极光光斑，避免叠加杂乱 */
body.has-bg-video::before,
body.has-bg-video::after,
body.has-bg-video .aurora-blob,
body.has-bg-img::before,
body.has-bg-img::after,
body.has-bg-img .aurora-blob { display: none; }

.app { max-width: none; width: 100%; margin: 0 auto; padding: 0 30px 24px; }

/* 顶部栏：悬浮玻璃态胶囊 + 滚动吸顶 */
.topbar {
  display: flex; align-items: center; gap: 18px;
  flex-wrap: wrap;                 /* 导航项多时整体可换行，避免挤出看不见 */
  position: sticky; top: 12px; z-index: 30;
  margin: 12px 0 22px; padding: 11px 20px;
  background: linear-gradient(135deg, rgba(255,255,255,.20), rgba(255,255,255,.08));
  -webkit-backdrop-filter: blur(26px) saturate(190%);
  backdrop-filter: blur(26px) saturate(190%);
  border: 1px solid rgba(255,255,255,.32);
  border-radius: 22px;
  box-shadow: 0 12px 40px rgba(20,24,60,.20), inset 0 1px 0 rgba(255,255,255,.35);
}

/* ---------- 左侧竖排导航 ----------
   原来是横向顶栏，管理员十来个入口会 flex-wrap 折成两行，顶栏变高把内容往下压。
   改成固定在左侧的竖排玻璃面板：入口再多也是一列，还能按「货源/经营/其它」分段。

   由 common.js 的 renderNav() 生成（<aside class="sidebar" id="sidebar">），
   页面模板里只放 <div id="nav"></div> 占位。遗留模板里手写的 .topbar 不受影响。 */
:root { --sb-w: 208px; }

body.has-sidebar { padding-left: var(--sb-w); }

.sidebar {
  position: fixed; left: 0; top: 0; bottom: 0; z-index: 40;
  width: var(--sb-w);
  display: flex; flex-direction: column; gap: 4px;
  padding: 16px 12px 12px;
  overflow-y: auto; overscroll-behavior: contain;
  background: linear-gradient(170deg, rgba(255,255,255,.22), rgba(255,255,255,.09));
  -webkit-backdrop-filter: blur(26px) saturate(190%);
  backdrop-filter: blur(26px) saturate(190%);
  border-right: 1px solid rgba(255,255,255,.28);
  box-shadow: 4px 0 32px rgba(20,24,60,.20), inset -1px 0 0 rgba(255,255,255,.22);
}
/* 细滚动条：入口多到需要滚时，别弹出系统那条粗的把宽度吃掉 */
.sidebar::-webkit-scrollbar { width: 6px; }
.sidebar::-webkit-scrollbar-thumb {
  background: rgba(255,255,255,.28); border-radius: 3px;
}
.sidebar::-webkit-scrollbar-track { background: transparent; }

/* 顶部一行：品牌 + 收起按钮。分隔线挂在这一行上（不是挂在 .sb-brand 上），
   否则按钮会跑到线的外面去。 */
.sb-head {
  display: flex; align-items: center; gap: 6px;
  padding: 4px 4px 12px; margin-bottom: 4px;
  border-bottom: 1px solid rgba(255,255,255,.18);
}
.sb-brand {
  flex: 1; min-width: 0;
  display: flex; align-items: center; gap: 10px;
  text-decoration: none; white-space: nowrap; overflow: hidden;
}
.sb-brand-name {
  font-size: 17px; font-weight: 700; letter-spacing: .4px;
  color: #fff; text-shadow: 0 1px 3px rgba(0,0,0,.35);
  overflow: hidden; text-overflow: ellipsis;
}

.sb-nav { display: flex; flex-direction: column; gap: 2px; }
.sb-group {
  margin: 12px 8px 4px; font-size: 11px; font-weight: 600;
  letter-spacing: 1.4px; text-transform: none;
  color: rgba(255,255,255,.55); text-shadow: 0 1px 2px rgba(0,0,0,.3);
}
.sb-nav .sb-group:first-child { margin-top: 2px; }
.sb-link {
  position: relative;
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; border-radius: 10px;
  color: rgba(255,255,255,.86); text-decoration: none;
  font-size: 14px; white-space: nowrap;
  transition: background .15s, color .15s;
}
/* 图标固定宽度、居中。收起时整条侧栏缩窄，但图标的中心位置几乎不动 ——
   这是「收起不突兀」的关键：只有文字淡出，不需要重新找每一项在哪。
   线性 SVG 走 currentColor，所以选中/悬停时会跟文字一起变色。 */
.sb-ico {
  flex: 0 0 20px; width: 20px; height: 20px;
  display: grid; place-items: center;
}
.sb-ico svg {
  width: 18px; height: 18px; display: block;
  /* 细描边在深背景上容易糊成一团，给一点点透明度层次 */
  opacity: .92;
}
.sb-link:hover .sb-ico svg,
.sb-link.active .sb-ico svg { opacity: 1; }
.sb-tx { overflow: hidden; text-overflow: ellipsis; }
.sb-link:hover { background: rgba(255,255,255,.18); color: #fff; }
.sb-link.active {
  background: linear-gradient(135deg, rgba(255,255,255,.44), rgba(255,255,255,.26));
  color: var(--primary); font-weight: 600;
}
/* 当前页左侧一道竖条：竖排列表里光靠底色不够一眼看出选中的是哪个 */
.sb-link.active::before {
  content: ""; position: absolute; left: -12px; top: 50%;
  transform: translateY(-50%);
  width: 3px; height: 20px; border-radius: 0 3px 3px 0;
  background: var(--grad);
}

/* ---- 「兑换」入口动效 ----
   三个都很克制：扫光每 3.6 秒掠过一次、礼物图标每 4 秒轻晃一下、右侧小圆点呼吸。
   目的是让买家一眼找到入口，不是闪瞎眼。 */
.sb-hot .sb-shine {
  position: absolute; inset: 0; border-radius: inherit;
  overflow: hidden; pointer-events: none;
}
.sb-hot .sb-shine::after {
  content: ""; position: absolute; top: 0; bottom: 0; left: -60%;
  width: 45%;
  background: linear-gradient(100deg, transparent 0%, rgba(255,255,255,.55) 50%, transparent 100%);
  transform: skewX(-18deg);
  animation: sbShine 3.6s ease-in-out infinite;
}
@keyframes sbShine {
  0%   { left: -60%; }
  45%  { left: 130%; }
  100% { left: 130%; }
}
.sb-hot .sb-ico svg { transform-origin: 50% 80%; animation: sbWiggle 4s ease-in-out infinite; }
@keyframes sbWiggle {
  0%, 82%, 100% { transform: rotate(0) scale(1); }
  86% { transform: rotate(-12deg) scale(1.12); }
  90% { transform: rotate(10deg) scale(1.12); }
  94% { transform: rotate(-6deg) scale(1.06); }
  97% { transform: rotate(3deg) scale(1.02); }
}
.sb-hot .sb-hot-dot {
  margin-left: auto; flex: 0 0 auto;
  width: 7px; height: 7px; border-radius: 50%;
  background: #ff5b7f;
  box-shadow: 0 0 0 0 rgba(255,91,127,.6);
  animation: sbPulse 1.8s ease-out infinite;
}
@keyframes sbPulse {
  0%   { box-shadow: 0 0 0 0 rgba(255,91,127,.6); }
  70%  { box-shadow: 0 0 0 7px rgba(255,91,127,0); }
  100% { box-shadow: 0 0 0 0 rgba(255,91,127,0); }
}
/* 收起成窄轨时文字隐藏了，圆点挪到图标右上角 */
body.sb-mini .sb-hot .sb-hot-dot { position: absolute; top: 6px; right: 14px; margin: 0; }
/* 系统开了「减少动态效果」就全部停掉（无障碍：前庭敏感的人看动画会不适） */
@media (prefers-reduced-motion: reduce) {
  .sb-hot .sb-shine::after, .sb-hot .sb-ico svg, .sb-hot .sb-hot-dot { animation: none; }
}

/* 用户区钉在底部：入口列表长短不一，跟着列表浮动会到处乱跑 */
.sb-foot {
  margin-top: auto; padding-top: 12px;
  border-top: 1px solid rgba(255,255,255,.18);
  display: flex; flex-direction: column; align-items: stretch; gap: 8px;
}
.sb-foot .user-chip { padding: 0 4px; }
.sb-foot .btn, .sb-foot .btn-recharge { width: 100%; justify-content: center; }
.sb-foot .nav-balance { text-align: center; }
.sb-foot .btn-logout { color: #fff; text-shadow: 0 1px 3px rgba(0,0,0,.35); }

/* ---- 收起/展开按钮 ----
   就放在品牌行右端，扁平图标按钮：没有边框、没有底色、只有一个箭头。
   跟页面里其它次要图标操作同一个调性，所以它读起来是「导航的头部操作」，
   而不是一个贴在界面上的小组件。

   上一版做成悬浮在侧栏右边缘正中的小圆点（半压在边框线上），无论把透明度
   调到多低都还是突兀 —— 圆形描边 + 阴影在一条直边上本身就是异物。
   挪进品牌行之后顺带省掉一堆麻烦：不用再绕 overflow-y:auto 的裁剪，
   也不用管 backdrop-filter 给 fixed 后代建立包含块的问题。 */
.sb-collapse {
  flex: 0 0 26px;
  width: 26px; height: 26px; padding: 0;
  display: grid; place-items: center;
  border: 0; border-radius: 8px;
  background: transparent;
  color: rgba(255,255,255,.55);
  cursor: pointer;
  transition: background .15s, color .15s;
}
.sb-collapse svg { width: 15px; height: 15px; display: block; }
.sb-collapse:hover { background: rgba(255,255,255,.18); color: #fff; }
.sb-collapse:focus-visible {
  color: #fff; outline: 2px solid rgba(255,255,255,.55); outline-offset: 1px;
}
/* 收起后箭头掉头。只转图形，不换图标。 */
.sb-collapse svg { transition: transform .22s ease; }
body.sb-mini .sb-collapse svg { transform: rotate(180deg); }

/* ---- 收起态：缩成一条图标窄轨 ----
   刻意不做成「整条滑走」：那样一收起来导航就彻底没了，想换页得先展开。
   缩成窄轨的话入口全都还点得到，鼠标悬停有原生 tooltip 看全名。 */
body.sb-mini { --sb-w: 64px; }
body.sb-mini .sidebar { padding-left: 8px; padding-right: 8px; }
body.sb-mini .sb-tx,
body.sb-mini .sb-brand-name,
body.sb-mini .sb-group-tx,
body.sb-mini .sb-foot .user-meta,
body.sb-mini .sb-foot .nav-balance { display: none; }
body.sb-mini .sb-link { justify-content: center; padding: 10px 0; gap: 0; }
/* 收起后品牌行竖过来：logo 在上、收起按钮在下，都居中。
   64px 宽塞不下「logo + 按钮」并排，而按钮必须还留在界面上 ——
   不然收起来就没有任何地方能再展开了。 */
body.sb-mini .sb-head {
  flex-direction: column; gap: 8px;
  padding-left: 0; padding-right: 0;
}
body.sb-mini .sb-brand { flex: none; justify-content: center; }
/* 分组标题收起后变成一条短横线：分段感还在，又不占一行字 */
body.sb-mini .sb-group {
  margin: 10px 10px 6px; height: 1px;
  background: rgba(255,255,255,.22);
}
body.sb-mini .sb-foot { align-items: center; }
body.sb-mini .sb-foot .user-chip { justify-content: center; }
body.sb-mini .sb-foot .btn,
body.sb-mini .sb-foot .btn-recharge {
  width: 34px; min-width: 0; padding: 7px 0; overflow: hidden;
  white-space: nowrap; font-size: 0;
}
/* 退出按钮收起后只留一个图标，否则「退出」两个字会被挤成一团 */
body.sb-mini .sb-foot .btn-logout::before { content: "⏏"; font-size: 14px; }
body.sb-mini .sb-foot .btn-recharge::before { content: "＋"; font-size: 14px; }
/* 选中项那道竖条：窄轨里内边距变了，位置要跟着挪 */
body.sb-mini .sb-link.active::before { left: -8px; }

/* 宽度变化走过渡，内容区的让位也跟着动，不会「啪」地跳一下 */
.sidebar { transition: width .22s ease, padding .22s ease; }
body.has-sidebar { transition: padding-left .22s ease; }

/* 窄屏抽屉的开合按钮，宽屏不需要 */
.sb-toggle { display: none; }

@media (max-width: 900px) {
  body.has-sidebar { padding-left: 0; }
  /* 窄屏用抽屉，收起态没有意义（整条本来就是滑进滑出的）。
     这里把 --sb-w 和相关规则还原，否则抽屉滑出来会是一条 64px 的窄轨。 */
  body.sb-mini { --sb-w: 208px; }
  body.sb-mini .sb-tx,
  body.sb-mini .sb-brand-name,
  body.sb-mini .sb-group-tx,
  body.sb-mini .sb-foot .user-meta,
  body.sb-mini .sb-foot .nav-balance { display: revert; }
  body.sb-mini .sb-link { justify-content: flex-start; padding: 9px 12px; gap: 10px; }
  body.sb-mini .sb-head { flex-direction: row; padding: 4px 4px 12px; }
  body.sb-mini .sb-brand { flex: 1; justify-content: flex-start; }
  body.sb-mini .sb-group { height: auto; background: none; margin: 12px 8px 4px; }
  body.sb-mini .sb-foot .btn,
  body.sb-mini .sb-foot .btn-recharge { width: 100%; padding: 8px 14px; font-size: 14px; }
  body.sb-mini .sb-foot .btn-logout::before,
  body.sb-mini .sb-foot .btn-recharge::before { content: none; }
  /* 边缘那个收起按钮在抽屉模式下会浮在内容上，收掉 */
  .sb-collapse { display: none; }
  .sidebar {
    transform: translateX(-100%);
    transition: transform .22s ease;
    box-shadow: 4px 0 40px rgba(10,12,30,.45);
  }
  body.sb-open .sidebar { transform: translateX(0); }
  .sb-toggle {
    display: grid; place-items: center;
    position: fixed; left: 10px; top: 10px; z-index: 45;
    width: 40px; height: 40px; border: 1px solid rgba(255,255,255,.34);
    border-radius: 12px; cursor: pointer;
    background: rgba(20,23,44,.55);
    -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
    color: #fff; font-size: 17px; line-height: 1;
  }
  /* 按钮压在页面左上角，给内容让出一点位置，别盖住标题 */
  body.has-sidebar .app,
  body.has-sidebar .wrap { padding-top: 8px; }
  body.has-sidebar .page-head,
  body.has-sidebar .stock-cards { margin-top: 44px; }
}

@media (prefers-reduced-motion: reduce) {
  .sidebar, .sb-collapse, .sb-collapse::before,
  body.has-sidebar { transition: none; }
}

.brand {
  display: flex; align-items: center; gap: 10px;
  font-size: 18px; font-weight: 700; white-space: nowrap; letter-spacing: .5px;
  color: #fff; text-shadow: 0 1px 3px rgba(0,0,0,.35);
}
.logo {
  width: 34px; height: 34px; border-radius: 10px;
  background: var(--grad);
  color: #fff; display: grid; place-items: center;
  font-weight: 800; font-size: 19px;
  box-shadow: 0 4px 12px rgba(91,91,214,.35);
}
.search-box { flex: 1; }
.search-box input {
  width: 100%; padding: 10px 14px;
  border: 1px solid rgba(255,255,255,.5); border-radius: 10px;
  background: rgba(255,255,255,.45);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  font-size: 14px; outline: none; color: var(--text);
  transition: border-color .15s, box-shadow .15s;
}
.search-box input:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(26,115,232,.12);
}
.actions { display: flex; gap: 8px; }

/* 按钮 */
.btn {
  padding: 9px 16px; border: 1px solid transparent; border-radius: 9px;
  font-size: 14px; cursor: pointer; white-space: nowrap;
  transition: background .15s, border-color .15s, transform .05s;
}
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--grad); color: #fff; box-shadow: 0 3px 10px rgba(91,91,214,.28); }
.btn-primary:hover { filter: brightness(1.05); }
.btn-ghost {
  background: rgba(255,255,255,.45); border-color: rgba(255,255,255,.5); color: var(--text);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
}
.btn-ghost:hover { background: rgba(255,255,255,.7); }
/* 不可逆动作（批量删除这类）：必须和旁边的普通按钮一眼能区分开，
   否则「删除选中」和「选中改为 1 次」长得一样，很容易点错。 */
.btn.danger { color: #d92d20; border-color: rgba(217,45,32,.45); }
.btn.danger:hover:not(:disabled) { background: #fde8e8; border-color: #d92d20; }
.btn.danger:disabled { color: rgba(217,45,32,.45); border-color: var(--border); }
/* 直接浮在视频/玻璃条上的次要按钮：文字用白色，与顶部导航一致 */
.topbar .actions .btn-ghost,
.page-head .btn-ghost {
  background: rgba(255,255,255,.16); border-color: rgba(255,255,255,.3);
  color: #fff; text-shadow: 0 1px 3px rgba(0,0,0,.35);
}
.topbar .actions .btn-ghost:hover,
.page-head .btn-ghost:hover {
  background: rgba(255,255,255,.3); color: #fff;
}
/* 顶部退出按钮同样浮在玻璃条上，文字提亮 */
.topbar .actions .btn-logout { color: #fff; text-shadow: 0 1px 3px rgba(0,0,0,.35); }
.btn-danger { background: #fde8e8; color: #d92d20; }
.btn-danger:hover { background: #fbd5d5; }
.btn-text { background: none; color: var(--muted); }
.btn-text:hover { color: var(--text); }

/* 批量操作栏 */
.bulkbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 5px 14px; margin-bottom: 10px;
  background: #eef3fe; border: 1px solid #cfe0fd; border-radius: 10px;
  animation: pop .12s ease;
}
.bulk-info { font-size: 13px; color: var(--text); white-space: nowrap; }
.bulk-info b { color: var(--primary); font-size: 15px; }
/* 分组 + 可换行。原来是一行 17 个按钮、不换行，窗口一窄就溢出。
   min-width:0 让 flex 子项能收缩，否则整行会把父容器撑破。 */
.bulkbar { align-items: flex-start; flex-wrap: wrap; padding: 8px 14px; }
.bulkbar .bulk-info { padding-top: 5px; }
.bulk-actions {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 8px 14px; flex: 1 1 0; min-width: 0; justify-content: flex-end;
}
.bulk-group {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  padding: 3px 8px 3px 6px; border-radius: 8px;
  background: rgba(255,255,255,.55); border: 1px solid #dbe6fb;
}
.bulk-gl {
  font-size: 11px; font-weight: 600; color: #6b7a99;
  padding: 0 4px 0 2px; white-space: nowrap;
}
.bulk-group.bulk-danger { background: #fff5f5; border-color: #fbd5d5; }
.bulk-group.bulk-danger .bulk-gl { color: #b42318; }
.bulkbar .btn { padding: 5px 11px; font-size: 13px; white-space: nowrap; }

/* 页面工具条按钮分组：组与组之间一道淡分隔线 */
.page-toolbar .act-group { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.page-toolbar .act-group + .act-group {
  padding-left: 10px; border-left: 1px solid rgba(255,255,255,.35);
}
/* 快速提货：这一页最常用的动作，做成主按钮突出 */
.btn-hero {
  position: relative; overflow: hidden;
  padding: 9px 18px; font-weight: 700; font-size: 14px; letter-spacing: .5px;
  color: #fff; border: none;
  background: linear-gradient(135deg, #ff7a45 0%, #ff4d88 55%, #8b5cf6 100%);
  box-shadow: 0 6px 18px rgba(255,77,136,.45), inset 0 1px 0 rgba(255,255,255,.35);
  transition: transform .12s, box-shadow .12s;
}
.btn-hero:hover { transform: translateY(-1px); box-shadow: 0 10px 24px rgba(255,77,136,.55); color: #fff; }
.btn-hero:active { transform: translateY(0); }
.btn-hero::after {           /* 一道扫光，和侧栏「兑换」同一种语言 */
  content: ""; position: absolute; top: 0; bottom: 0; left: -60%; width: 40%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.5), transparent);
  transform: skewX(-18deg); animation: sbShine 3.6s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) { .btn-hero::after { animation: none; } }
@media (max-width: 768px) {
  .page-toolbar .act-group + .act-group { border-left: 0; padding-left: 0; }
  .bulk-actions { justify-content: flex-start; }
}

/* 选择框列 */
.col-check { width: 42px; text-align: center; }
/* 默认隐藏勾选列，点「多选」后显示 */
.grid.hide-check .col-check { display: none; }
.col-check input { width: 16px; height: 16px; cursor: pointer; }
.grid tbody tr.row-selected { background: #eef3fe; }
.grid tbody tr.row-selected:hover { background: #e4edfd; }

/* 分类标签行：左侧 tabs + 右侧云端联动数据 */
.tabs-bar { display: flex; align-items: center; justify-content: space-between;
  gap: 16px; margin-bottom: 16px; flex-wrap: wrap; }
.tabs-bar .tabs { margin-bottom: 0; }
.kiro-dash { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.kd-item { display: inline-flex; align-items: baseline; gap: 5px; font-size: 13px; color: rgba(255,255,255,.8); white-space: nowrap; text-shadow: 0 1px 3px rgba(0,0,0,.45); }
.kd-val { font-size: 18px; font-weight: 800; color: #fff; text-shadow: 0 1px 4px rgba(0,0,0,.5); }
.kd-val.ok { color: #6ee7a0; }
.kd-val.warn { color: #ffc247; }
.kd-val.bad { color: #ff8080; }
.kd-label { font-size: 12px; }

/* 分类标签 */
.tabs { display: flex; gap: 6px; margin-bottom: 16px; flex-wrap: wrap; }
.tab {
  padding: 7px 16px; border-radius: 20px; cursor: pointer;
  background: rgba(255,255,255,.14); border: 1px solid rgba(255,255,255,.28);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  color: #fff; text-shadow: 0 1px 3px rgba(0,0,0,.35);
  font-size: 13px; transition: all .15s;
}
.tab:hover { background: rgba(255,255,255,.26); color: #fff; }
.tab.active {
  background: var(--primary); border-color: var(--primary);
  color: #fff; font-weight: 500;
}
.tab .count { opacity: .75; margin-left: 4px; }

/* 表格 */
.table-wrap {
  background: var(--table-bg);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  backdrop-filter: blur(20px) saturate(150%);
  border: 1px solid rgba(255,255,255,.45);
  border-radius: var(--card-radius);
  box-shadow: var(--card-shadow); overflow-x: auto;
}

/* 账号列表页：整页占满视口，表格区域填满剩余高度，
   横向滚动条随之固定在窗口底部，无需滚到数据末尾 */
html, body.page-accounts { height: 100%; }
body.page-accounts { overflow: hidden; }
body.page-accounts .app {
  height: 100vh; display: flex; flex-direction: column;
}
body.page-accounts .table-wrap {
  flex: 1; min-height: 0; overflow: auto;
}
/* 纵向滚动时表头保持吸顶 */
body.page-accounts .grid thead th {
  position: sticky; top: 0; z-index: 2;
}
.grid { width: 100%; border-collapse: collapse; color: var(--table-txt); }
.grid th {
  text-align: left; padding: 14px 16px; font-weight: 600;
  color: #5b6070; font-size: 12px; letter-spacing: .04em;
  border-bottom: 1px solid var(--border); background: var(--table-head-bg);
}
.grid td {
  padding: 8px 16px; border-bottom: 1px solid #f0f1f3;
  vertical-align: middle; white-space: nowrap;
}
.grid tr:last-child td { border-bottom: none; }
.grid tbody tr:hover { background: #f8f9fb; }

.mono { font-family: "SF Mono", Consolas, monospace; }
.kiro-linked { margin-left: 6px; cursor: help; font-size: 13px; }

/* 配额进度条 */
.quota { display: flex; align-items: center; gap: 8px; min-width: 120px; }
.quota-bar { flex: 1; height: 8px; background: #eef0f5; border-radius: 6px; overflow: hidden; }
.quota-fill { height: 100%; width: 0; background: #16a34a; border-radius: 6px; transition: width .3s; }
.quota-fill.mid { background: #e08a1e; }
.quota-fill.hi { background: #d92d20; }
.quota-txt { font-size: 12px; color: var(--muted); font-family: Consolas, monospace; white-space: nowrap; }
.email-cell { font-weight: 500; }
.muted { color: var(--muted); }

/* 验证码 */
.totp {
  display: inline-flex; align-items: center; gap: 8px;
}
.totp-code {
  font-family: "SF Mono", Consolas, monospace; font-size: 16px;
  font-weight: 700; color: var(--primary); letter-spacing: 1px;
  cursor: pointer; user-select: none;
}
.totp-code:hover { text-decoration: underline; }
.totp-ring {
  width: 18px; height: 18px; border-radius: 50%;
  background: conic-gradient(var(--primary) var(--deg, 0deg), #e6e8eb 0deg);
  flex-shrink: 0;
}

/* 状态 / 标签 徽章 */
.badge {
  display: inline-block; padding: 4px 12px; border-radius: 14px;
  font-size: 12px; font-weight: 500; cursor: pointer; user-select: none;
  border: 1px solid transparent; transition: filter .15s; white-space: nowrap;
}
.badge:hover { filter: brightness(.96); }
.badge.pending { background: #fef3e2; color: var(--pending); }
.badge.recharged { background: var(--primary-soft); color: var(--recharged); }
.badge.sold { background: #e7f6ec; color: var(--sold); }
.badge.abnormal { background: #fdecec; color: #dc2626; }
/* 已付款待确认：钱付了、订阅还没确认。紫色，和待充值（橙）/ 已充值（蓝）都分得开 */
.badge.paidpend { background: #f4f3ff; color: #5925dc; font-weight: 700; }
.tag {
  display: inline-block; padding: 3px 10px; border-radius: 6px;
  font-size: 12px; cursor: pointer; user-select: none;
  background: #f0f1f3; color: #555; white-space: nowrap;
}
.tag:hover { background: #e6e8eb; }
.tag.lb-empty { color: #bbb; }
.tag.lb-pro { background: #ede9fe; color: #7c3aed; }
.tag.lb-proplus { background: #e0e7ff; color: #4338ca; }
.tag.lb-power { background: #fce7f3; color: #db2777; }
.tag.lb-free { background: #ecfdf5; color: #059669; }

/* 行内操作 */
.col-actions { width: 120px; }
.row-actions { display: flex; gap: 6px; }
.icon-btn {
  border: none; background: none; cursor: pointer; padding: 5px 8px;
  border-radius: 6px; color: var(--muted); font-size: 13px;
}
.icon-btn:hover { background: #f0f1f3; color: var(--text); }
.icon-btn.danger:hover { background: #fde8e8; color: #d92d20; }

.copy-btn {
  border: none; background: none; cursor: pointer; color: var(--muted);
  font-size: 12px; padding: 2px 6px; border-radius: 5px;
}
.copy-btn:hover { background: #f0f1f3; color: var(--primary); }

.clickable { cursor: pointer; border-radius: 4px; padding: 2px 4px; transition: background .12s; }
.clickable:hover { background: #eef3fe; color: var(--primary); }

/* 链接列：过长时省略显示，悬停查看完整地址 */
.link-cell a, .link-cell span {
  display: inline-block; max-width: 200px; vertical-align: middle;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--primary); text-decoration: none;
}
.link-cell a:hover { text-decoration: underline; }
/* 备注列限宽，避免长文本撑开表格 */
.note-cell > span { display: inline-block; max-width: 160px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; vertical-align: middle; }

.note-input {
  width: 140px; padding: 5px 8px; border: 1px solid var(--primary);
  border-radius: 6px; font-size: 13px; outline: none;
  box-shadow: 0 0 0 3px rgba(26,115,232,.12);
}

.empty { padding: 60px 20px; text-align: center; color: var(--muted); }

/* 弹窗 */
.modal-mask {
  position: fixed; inset: 0; background: rgba(15,20,30,.45);
  display: grid; place-items: center; z-index: 50;
  backdrop-filter: blur(2px);
}
.modal-mask[hidden] { display: none; }
.modal {
  background: rgba(255,255,255,.82);
  -webkit-backdrop-filter: blur(28px) saturate(165%);
  backdrop-filter: blur(28px) saturate(165%);
  border: 1px solid rgba(255,255,255,.5);
  border-radius: 16px; padding: 24px;
  width: 480px; max-width: 92vw; box-shadow: 0 24px 60px rgba(0,0,0,.3);
  animation: pop .15s ease;
}
@keyframes pop { from { transform: scale(.96); opacity: 0; } to { transform: scale(1); opacity: 1; } }
.modal h3 { margin-bottom: 16px; font-size: 18px; }
.form { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.form label {
  display: flex; flex-direction: column; gap: 5px;
  font-size: 13px; color: var(--muted);
}
.form label.full { grid-column: 1 / -1; }
.form input, .form select, .form textarea {
  padding: 9px 11px; border: 1px solid var(--border); border-radius: 9px;
  font-size: 14px; color: var(--text); outline: none; background: #fff;
}
.form textarea {
  width: 100%; box-sizing: border-box; resize: vertical;
  font-family: inherit; line-height: 1.5; min-height: 68px;
}
.form input:focus, .form select:focus, .form textarea:focus {
  border-color: var(--primary); box-shadow: 0 0 0 3px rgba(26,115,232,.12);
}
.modal-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px; }
.hint { color: var(--muted); font-size: 13px; line-height: 1.7; margin-bottom: 12px; }
.hint code { background: #f0f1f3; padding: 1px 6px; border-radius: 4px; }
textarea {
  width: 100%; padding: 12px; border: 1px solid var(--border);
  border-radius: 10px; font-family: Consolas, monospace; font-size: 13px;
  resize: vertical; outline: none;
}
textarea:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(26,115,232,.12); }

/* 提示条 */
.toast {
  position: fixed; top: 20px; left: 50%; transform: translateX(-50%);
  background: #1f2329; color: #fff; padding: 11px 22px; border-radius: 10px;
  font-size: 14px; box-shadow: 0 8px 24px rgba(0,0,0,.25); z-index: 3000;
  animation: toastIn .2s ease;
}
@keyframes toastIn { from { opacity: 0; transform: translate(-50%, -10px); } to { opacity: 1; transform: translate(-50%, 0); } }

/* 行内下拉菜单 */
.popmenu {
  position: absolute; background: #fff; border: 1px solid var(--border);
  border-radius: 10px; box-shadow: 0 6px 24px rgba(0,0,0,.14);
  padding: 5px; z-index: 60; min-width: 110px;
}
.popmenu div {
  padding: 8px 12px; border-radius: 7px; cursor: pointer; font-size: 13px;
}
.popmenu div:hover { background: #f0f1f3; }

/* ---------- 统计卡（全站共用：库存/订单/代理/我的/封号监控/做号台…）----------
   走 :root 里那套 --card-* 变量。原来这里是浅色半透明 + 灰字，压在照片背景上
   看不清，于是各页面自己在模板里写内联 !important 补丁，最后同一个类在不同页面
   长得不一样。现在只有这一处定义。 */
.stock-cards { display: flex; gap: 16px; margin-bottom: 20px; }
.stat-card {
  flex: 1;
  background: var(--card-bg);
  -webkit-backdrop-filter: var(--card-blur);
  backdrop-filter: var(--card-blur);
  border: 1px solid var(--card-border);
  border-radius: var(--card-radius);
  padding: 18px 20px;
  box-shadow: var(--card-shadow);
  position: relative; overflow: hidden;
  color: var(--card-txt);
}
.stat-card::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--grad);
}
.stat-label {
  color: var(--card-txt-dim); font-size: 13px; margin-bottom: 8px;
  text-shadow: var(--card-txt-shadow);
}
.stat-value {
  font-size: 30px; font-weight: 800; color: var(--card-txt);
  letter-spacing: .5px; text-shadow: var(--card-txt-shadow);
  /* 等宽数字：这些数字会随刷新跳动，比例字宽会让卡片宽度跟着抖 */
  font-variant-numeric: tabular-nums;
}
/* 卡片底部的一行补充口径（做号看板：号池/已售出明细、今日累计…）。
   放在主数字下面而不是挤进标签里：主数字要一眼能读，口径是第二眼的事。 */
.stat-sub {
  font-size: 12px; margin-top: 6px; line-height: 1.5;
  color: var(--card-txt-mute); text-shadow: var(--card-txt-shadow);
}
/* 做号看板一排卡片。原来固定 flex 一行放 3 张，多了会把每张压到读不清 ——
   改成允许换行 + 最小宽度，窄屏自动折成两行，不用改 HTML 结构。 */
.stock-cards { flex-wrap: wrap; }
.stock-cards .stat-card { flex: 1 1 190px; min-width: 170px; }

/* ============================================================
   做号看板（只作用于 .mintboard 之内）

   为什么整页换成**深色玻璃**而不是继续用站里那套白色半透明：
   这个页面背后是一张亮度很高的大图，白色半透明面板压在云和草地上会被"洗白"，
   浅灰小字直接消失（改之前就是这个毛病）。深色面板反过来把背景压住，
   白字和数字的对比度由面板自己保证，跟背景图亮不亮无关 —— 这是结构上的解决，
   不是把颜色调深一档那种权宜。

   另外 .card 这个类**原来在 CSS 里根本不存在**（只有 .card-doc / .stat-card），
   launcher.html 却一直在用它包内容，所以那几段是裸贴在背景图上的。
   所有规则都挂在 .mintboard 下面，别的页面一行都不受影响。
   ============================================================ */
.mintboard {
  --mb-line: rgba(255,255,255,.14);
  --mb-txt: #f2f5ff;
  --mb-dim: rgba(233,238,255,.66);
  --mb-dim2: rgba(233,238,255,.45);
  --mb-ok: #34d399;
  --mb-warn: #fbbf24;
  --mb-bad: #fb7185;
}

/* ---- 顶部工具条 ---- */
.mintboard .mb-tools {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: 12px; flex-wrap: wrap;
}
.mintboard .mb-brand {
  display: flex; align-items: center; gap: 9px;
  color: #fff; font-size: 17px; font-weight: 700; letter-spacing: .5px;
  text-shadow: 0 2px 14px rgba(0,0,0,.6);
}
/* 标题旁边那颗一直在跳的心跳点：告诉你这页是活的，不是一张截图 */
.mintboard .mb-live-dot {
  width: 9px; height: 9px; border-radius: 50%; background: #5eead4;
  box-shadow: 0 0 12px #5eead4; animation: mb-beat 1.6s ease-in-out infinite;
}
@keyframes mb-beat {
  0%,100% { transform: scale(1); opacity: .95; }
  50%     { transform: scale(1.5); opacity: .55; }
}
.mintboard .mb-tools-r { display: flex; gap: 8px; }
.mintboard .mb-tbtn {
  background: rgba(14,18,32,.62); color: var(--mb-txt);
  border: 1px solid var(--mb-line); border-radius: 11px;
  padding: 7px 13px; font-size: 13px; cursor: pointer;
  -webkit-backdrop-filter: blur(18px); backdrop-filter: blur(18px);
  transition: background .2s, transform .15s, border-color .2s;
}
.mintboard .mb-tbtn:hover { background: rgba(30,38,60,.8); transform: translateY(-1px); }
.mintboard .mb-tbtn.on { border-color: #5eead4; color: #5eead4; }

/* ---- 告警条 ---- */
.mintboard .mb-alerts { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; }
.mintboard .mb-alert {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px; border-radius: 12px; font-size: 13.5px; color: #fff;
  border: 1px solid transparent;
  -webkit-backdrop-filter: blur(18px); backdrop-filter: blur(18px);
  animation: mb-in .38s ease-out;
}
.mintboard .mb-alert .ai {
  width: 8px; height: 8px; border-radius: 50%; flex: none;
  animation: mb-ping 1.8s infinite;
}
.mintboard .mb-alert.warn { background: rgba(251,191,36,.16); border-color: rgba(251,191,36,.42); }
.mintboard .mb-alert.warn .ai { background: var(--mb-warn); }
.mintboard .mb-alert.bad  { background: rgba(251,113,133,.18); border-color: rgba(251,113,133,.5); }
.mintboard .mb-alert.bad .ai { background: var(--mb-bad); }

/* ---- 两栏（热力图 + 失败分布） ---- */
.mintboard .mb-grid2 {
  display: grid; grid-template-columns: 1.35fr 1fr; gap: 14px; margin-top: 14px;
}
@media (max-width: 1100px) { .mintboard .mb-grid2 { grid-template-columns: 1fr; } }

/* ---- 24 小时热力图 ---- */
.mintboard .heat { display: grid; grid-template-columns: repeat(24, 1fr); gap: 4px; }
.mintboard .hc {
  position: relative; border-radius: 6px; height: 54px;
  display: flex; flex-direction: column; justify-content: space-between;
  align-items: center; padding: 4px 0 3px;
  background: rgba(255,255,255,.06);
  border: 1px solid rgba(255,255,255,.06);
  animation: mb-in .4s ease-out both;
  transition: background .5s, box-shadow .3s, transform .15s;
}
.mintboard .hc:hover { transform: translateY(-3px) scale(1.06); z-index: 2; }
.mintboard .hc i { font-size: 9px; color: var(--mb-dim2); font-style: normal; }
.mintboard .hc b { font-size: 12px; font-weight: 700; color: #fff; }
/* 5 档离散色：连续渐变在 24 个小格上人眼分不出来，分档之后高产段一眼可见 */
.mintboard .hc.lv1 { background: rgba(94,234,212,.20); }
.mintboard .hc.lv2 { background: rgba(94,234,212,.38); }
.mintboard .hc.lv3 { background: rgba(56,189,248,.55); }
.mintboard .hc.lv4 { background: linear-gradient(180deg, #38bdf8, #6366f1); box-shadow: 0 0 18px rgba(99,102,241,.55); }
/* 当前这一小时：描边 + 呼吸，免得看错列 */
.mintboard .hc.now { border-color: #5eead4; box-shadow: 0 0 0 1px #5eead4 inset, 0 0 16px rgba(94,234,212,.4); }

/* ---- 失败原因横条 ---- */
.mintboard .fbars { display: flex; flex-direction: column; gap: 9px; }
.mintboard .fbar {
  display: grid; grid-template-columns: 96px 1fr 34px; align-items: center; gap: 10px;
  animation: mb-in .4s ease-out both;
}
.mintboard .fbar .fw { font-size: 12.5px; color: var(--mb-dim); }
.mintboard .fbar .ft {
  height: 9px; border-radius: 5px; background: rgba(255,255,255,.08); overflow: hidden;
}
.mintboard .fbar .ft i {
  display: block; height: 100%; border-radius: 5px;
  background: linear-gradient(90deg, #fb7185, #f59e0b);
  /* 条子是"长"出来的，不是一上来就在那 */
  animation: mb-grow .6s cubic-bezier(.2,.8,.2,1) both;
  transition: width .5s cubic-bezier(.2,.8,.2,1);
}
@keyframes mb-grow { from { transform: scaleX(0); transform-origin: left; } to { transform: scaleX(1); } }
.mintboard .fbar .fn {
  font-size: 13px; font-weight: 700; color: #fff; text-align: right;
  font-variant-numeric: tabular-nums;
}

/* ---- 昨天同时段的影子线（热力格里一条水平虚线） ---- */
.mintboard .hc { position: relative; overflow: hidden; }
.mintboard .hc .sh {
  position: absolute; left: 3px; right: 3px; height: 0;
  border-top: 1px dashed rgba(255,255,255,.75);
  transition: bottom .5s cubic-bezier(.2,.8,.2,1), opacity .4s;
  pointer-events: none;
}

/* ---- 出号流水 ----
   放在登录器表格**下面、整宽**。侧栏那版把表格挤窄了（表格有 13 列，
   本来就吃宽度），而流水本身是一行一条、横向有大量空白 —— 整宽反而能多放
   两列信息（谁跑的、哪台机器）。 */
.mintboard .feed-card { max-height: 340px; display: flex; flex-direction: column; }
.mintboard .feed {
  overflow-y: auto; display: flex; flex-direction: column; gap: 1px;
  /* 顶部淡出：流水滚到上边缘时渐隐，比硬切一刀干净 */
  mask-image: linear-gradient(180deg, transparent 0, #000 14px);
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 14px);
}
.mintboard .fd {
  display: grid;
  grid-template-columns: 62px 16px 90px 92px minmax(0,1fr) 190px;
  align-items: center; gap: 10px;
  padding: 6px 10px; border-radius: 8px; font-size: 12.5px;
  border-left: 2px solid transparent;
  font-variant-numeric: tabular-nums;
}
.mintboard .fd .fd-o { color: var(--mb-txt); }
.mintboard .fd .fd-n code {
  background: rgba(255,255,255,.07); padding: 1px 5px; border-radius: 4px; font-size: 11px;
}
@media (max-width: 900px) {
  /* 窄屏收掉「谁跑的」和实例两列，剩下时间/结果/邮箱/结论四项 */
  .mintboard .fd { grid-template-columns: 56px 14px minmax(0,1fr) auto; }
  .mintboard .fd .fd-o, .mintboard .fd .fd-n { display: none; }
}
.mintboard .fd:hover { background: rgba(255,255,255,.05); }
.mintboard .fd.ok  { border-left-color: rgba(52,211,153,.75); }
.mintboard .fd.bad { border-left-color: rgba(251,113,133,.75); }
.mintboard .fd .fd-t { color: var(--mb-dim2); font-size: 11px; }
.mintboard .fd .fd-i { font-weight: 700; }
.mintboard .fd.ok  .fd-i { color: var(--mb-ok); }
.mintboard .fd.bad .fd-i { color: var(--mb-bad); }
.mintboard .fd .fd-m {
  color: var(--mb-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mintboard .fd .fd-r { color: #fff; font-size: 11.5px; }
.mintboard .fd .fd-w { color: var(--mb-warn); font-size: 11.5px; }
/* 新进来的那条：从上方滑入 + 高亮一下，眼睛能跟上"刚刚发生了什么" */
.mintboard .fd.new { animation: mb-feedin .55s cubic-bezier(.2,.9,.2,1); }
@keyframes mb-feedin {
  0%   { opacity: 0; transform: translateY(-10px); background: rgba(94,234,212,.22); }
  100% { opacity: 1; transform: translateY(0); background: transparent; }
}

/* ---- 环形仪表（成功率） ---- */
.mintboard .ring-card { display: flex; flex-direction: column; }
.mintboard .ring-wrap { position: relative; width: 116px; height: 116px; margin: 2px auto 0; }
.mintboard .ring { width: 100%; height: 100%; transform: rotate(-90deg); }
.mintboard .ring circle { fill: none; stroke-width: 9; stroke-linecap: round; }
.mintboard .ring .ring-bg { stroke: rgba(255,255,255,.10); }
.mintboard .ring .ring-fg {
  /* 描边长度变化走过渡，环就是"转"过去的 */
  transition: stroke-dashoffset .7s cubic-bezier(.2,.8,.2,1), stroke .4s;
  filter: drop-shadow(0 0 8px rgba(94,234,212,.45));
}
.mintboard .ring-txt {
  position: absolute; inset: 0; display: flex; align-items: center;
  justify-content: center; gap: 1px;
}
.mintboard .ring-txt .stat-value { font-size: 30px; }
.mintboard .ring-txt i { font-style: normal; font-size: 13px; color: var(--mb-dim); margin-top: 8px; }

/* ---- 行展开：失败原文明细 ---- */
.mintboard table.grid tbody tr.can-open { cursor: pointer; }
.mintboard .twist {
  display: inline-block; width: 12px; color: var(--mb-dim2);
  transition: transform .2s; margin-right: 2px;
}
.mintboard table.grid tbody tr.detail-row:hover { background: transparent; }
.mintboard table.grid tbody tr.detail-row td { padding: 0 10px 10px; border-bottom: 0; }
.mintboard .dbox {
  background: rgba(0,0,0,.28); border: 1px solid var(--mb-line);
  border-radius: 10px; padding: 10px 12px;
  animation: mb-in .3s ease-out;
}
.mintboard .dhd { color: var(--mb-dim2); font-size: 11.5px; margin-bottom: 6px; }
.mintboard .drow {
  display: grid; grid-template-columns: 62px 150px minmax(0,1fr); gap: 10px;
  font-size: 12px; padding: 4px 0; border-top: 1px solid rgba(255,255,255,.05);
}
.mintboard .drow .dt { color: var(--mb-dim2); font-variant-numeric: tabular-nums; }
.mintboard .drow .dm { color: var(--mb-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mintboard .drow .dd { color: #fde68a; }

/* ---- 鼠标跟随高光 ----
   在卡片上叠一层随鼠标走的径向高光。用 CSS 变量传坐标：改 background 每次都要
   重新解析渐变，改变量只触发合成层更新，7×24 挂着也不烧 CPU。 */
.mintboard .stat-card, .mintboard .card { --mx: 50%; --my: -20%; }
.mintboard .stat-card::after, .mintboard .card::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(420px circle at var(--mx) var(--my),
              rgba(255,255,255,.10), transparent 45%);
  opacity: 0; transition: opacity .35s;
}
.mintboard .stat-card:hover::after, .mintboard .card:hover::after { opacity: 1; }

/* ---- 首屏进场：从下方依次浮入 ----
   第一眼的印象基本由这 0.6 秒决定，而原来是"啪"一下全出来。
   只跑一次（both + 不在刷新时重放），不会变成每 5 秒抖一下。 */
.mintboard .stat-card, .mintboard .card {
  animation: mb-rise .55s cubic-bezier(.2,.8,.2,1) both;
}
@keyframes mb-rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}
.mintboard .stock-cards .stat-card:nth-child(1) { animation-delay: .04s; }
.mintboard .stock-cards .stat-card:nth-child(2) { animation-delay: .10s; }
.mintboard .stock-cards .stat-card:nth-child(3) { animation-delay: .16s; }
.mintboard .stock-cards .stat-card:nth-child(4) { animation-delay: .22s; }
.mintboard .mb-grid2 > .card:nth-child(1) { animation-delay: .28s; }
.mintboard .mb-grid2 > .card:nth-child(2) { animation-delay: .34s; }
.mintboard .card:nth-of-type(3) { animation-delay: .40s; }
.mintboard .feed-card { animation-delay: .46s; }
/* hover 上浮要盖过进场动画的 transform，所以进场结束后由 transition 接管 */
.mintboard .stat-card:hover { animation: none; }

/* ---- 告警旋转光边 ----
   出问题的卡片绕一圈缓慢旋转的渐变光。比静态红框醒目得多，又不像闪烁那么烦。
   用 ::before 放在卡片下层、加一圈 padding 露出边，纯 CSS 无 JS。 */
.mintboard .stat-card.bad { position: relative; }
.mintboard .stat-card.bad::before {
  content: ""; position: absolute; inset: -1px; border-radius: 19px; z-index: -1;
  background: conic-gradient(from 0deg, transparent 0 60%,
              var(--mb-bad) 78%, #fda4af 88%, transparent 100%);
  animation: mb-spin 3.2s linear infinite;
  height: auto; width: auto; opacity: .9;
}
@keyframes mb-spin { to { transform: rotate(1turn); } }
.mintboard table.grid tbody tr.alert td:last-child { position: relative; }

/* 表格里「卡在哪一步」的小胶囊 */
.mintboard .chip {
  display: inline-flex; align-items: center; gap: 5px;
  background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.1);
  border-radius: 999px; padding: 2px 9px; margin: 2px 4px 2px 0;
  font-size: 11.5px; color: var(--mb-dim);
}
.mintboard .chip b { color: #fff; font-size: 11.5px; }
.mintboard .tag-bad { color: var(--mb-bad); }

/* 卡片的异常态：整张卡换色 + 描边，不用去读小字就知道哪项出事了 */
.mintboard .stat-card.warn { border-color: rgba(251,191,36,.5); }
.mintboard .stat-card.warn .stat-value { color: var(--mb-warn); text-shadow: 0 2px 18px rgba(251,191,36,.35); }
.mintboard .stat-card.bad  { border-color: rgba(251,113,133,.55); }
.mintboard .stat-card.bad .stat-value { color: var(--mb-bad); text-shadow: 0 2px 20px rgba(251,113,133,.45); }
.mintboard .stat-card.bad::before { background: linear-gradient(90deg, var(--mb-bad), transparent 70%); }

/* 告警行：左边一道呼吸的红边。排序已经把它顶到最前，这里只给视觉锚点 */
.mintboard table.grid tbody tr.alert { background: rgba(251,113,133,.10); }
.mintboard table.grid tbody tr.alert td:first-child { box-shadow: inset 3px 0 0 var(--mb-bad); }
.mintboard table.grid tbody tr.alert { animation: mb-alertbreath 2.4s ease-in-out infinite; }
@keyframes mb-alertbreath {
  0%,100% { background: rgba(251,113,133,.08); }
  50%     { background: rgba(251,113,133,.18); }
}

/* ---- 全屏电视墙 ----
   挂在第二块屏上看的模式：把导航、下载说明、操作步骤这些"只在动手时才用"的东西
   全收起来，只留数字和表格，字号整体放大。
   用 body 上的 class 控制，而不是只依赖 Fullscreen API —— 有些浏览器/系统组合
   会拒绝全屏请求，那时至少版式能切过去，不会点了没反应。 */
/* 隐藏的是 renderNav() **真正生成的那个节点**，而不是 #nav ——
   common.js 最后一步是 `mount.replaceWith(bar)`，把模板里的
   <div id="nav"> 占位符整个换掉。所以运行时页面上压根没有 #nav 这个节点，
   按 id 写的规则永远命不中（第一版就是这么写的，结果全屏了导航还在）。
   导航现在是左侧竖排 <aside class="sidebar">，所以这里收的是 .sidebar；
   .topbar 一并留着，几个遗留模板里还有手写的那种，全屏时同样不该出现。
   窄屏那个抽屉开关 .sb-toggle 也要收 —— 它是 fixed 的，会浮在数字上面。
   同时收掉两条公告：顶部滚动公告 #ann-bar 和代理公告卡 .agent-notice ——
   电视墙是挂在旁边屏上远远看数字的，任何滚动的字都在抢注意力。 */
body.mb-tv .sidebar,
body.mb-tv .sb-toggle,
body.mb-tv .sb-collapse,
body.mb-tv .topbar,
body.mb-tv #ann-bar,
body.mb-tv .agent-notice,
body.mb-tv .mintboard .card.mb-hide-tv { display: none !important; }
/* 导航收起来之后左边那条内边距也要还回去，否则电视墙左边空一大块 */
body.mb-tv.has-sidebar { padding-left: 0 !important; }
body.mb-tv { overflow: auto; }
body.mb-tv .wrap { max-width: none; padding: 18px 26px; }
body.mb-tv .mintboard .stat-value { font-size: 54px; }
body.mb-tv .mintboard .stat-label { font-size: 15px; }
body.mb-tv .mintboard .stat-sub { font-size: 13.5px; }
body.mb-tv .mintboard .mb-brand { font-size: 22px; }
body.mb-tv .mintboard table.grid tbody td { font-size: 15.5px; padding: 13px 12px; }
body.mb-tv .mintboard table.grid thead th { font-size: 13px; padding: 11px 12px; }
body.mb-tv .mintboard .hc { height: 76px; }
body.mb-tv .mintboard .spark { height: 40px; }

/* ---- 顶部指标卡 ---- */
.mintboard .stock-cards { display: flex; flex-wrap: wrap; gap: 14px; margin-bottom: 16px; }
.mintboard .stat-card {
  flex: 1 1 210px; min-width: 190px;
  background:
    radial-gradient(120% 140% at 0% 0%, rgba(255,255,255,.10) 0%, rgba(255,255,255,0) 55%),
    rgba(14,18,32,.62);
  -webkit-backdrop-filter: blur(26px) saturate(150%);
  backdrop-filter: blur(26px) saturate(150%);
  border: 1px solid var(--mb-line);
  border-radius: 18px; padding: 16px 18px 14px;
  box-shadow: 0 18px 44px -18px rgba(0,0,0,.65), inset 0 1px 0 rgba(255,255,255,.07);
  overflow: hidden;
  transition: transform .28s cubic-bezier(.2,.8,.2,1), box-shadow .28s;
}
.mintboard .stat-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 26px 56px -20px rgba(0,0,0,.72), inset 0 1px 0 rgba(255,255,255,.1);
}
/* 左侧那道竖条改成顶部一条发光线：竖条在深色卡上显得又土又挤 */
.mintboard .stat-card::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; bottom: auto;
  height: 2px; width: auto;
  background: linear-gradient(90deg, var(--mb-a, #6ea8ff), transparent 70%);
  opacity: .9;
}
/* 每张卡一个色相，扫一眼就能分清是哪一项 */
.mintboard .stat-card:nth-child(1) { --mb-a: #5eead4; }
.mintboard .stat-card:nth-child(2) { --mb-a: #7dd3fc; }
.mintboard .stat-card:nth-child(3) { --mb-a: #c4b5fd; }
.mintboard .stat-card:nth-child(4) { --mb-a: #fcd34d; }
.mintboard .stat-label {
  color: var(--mb-dim); font-size: 12px; letter-spacing: .3px;
  margin-bottom: 6px; font-weight: 500;
}
.mintboard .stat-value {
  color: var(--mb-txt); font-size: 36px; font-weight: 800; line-height: 1.1;
  /* 等宽数字：数字在跳动时宽度不变，卡片不会跟着抖 —— 动效好不好看，
     一半取决于有没有做这件事 */
  font-variant-numeric: tabular-nums; font-feature-settings: "tnum";
  text-shadow: 0 2px 18px rgba(110,168,255,.28);
}
.mintboard .stat-sub {
  color: var(--mb-dim2); font-size: 11.5px; margin-top: 5px; line-height: 1.55;
  font-variant-numeric: tabular-nums;
}
/* 数字变化时轻轻弹一下。只在真的变了才加这个类（见页面 JS） */
.mintboard .stat-value.bump { animation: mb-bump .5s cubic-bezier(.2,.9,.2,1); }
@keyframes mb-bump {
  0% { transform: scale(1); }
  35% { transform: scale(1.13); text-shadow: 0 2px 26px rgba(120,220,190,.6); }
  100% { transform: scale(1); }
}

/* ---- 走势条（近 30 分钟，每分钟一根） ---- */
.mintboard .spark { display: flex; align-items: flex-end; gap: 2px; height: 26px; margin-top: 10px; }
.mintboard .spark i {
  flex: 1; min-width: 0; border-radius: 2px 2px 0 0;
  background: linear-gradient(180deg, var(--mb-a, #6ea8ff), rgba(110,168,255,.18));
  /* 高度用 transition 过渡：每 5 秒刷新时柱子是"长"上去的，不是硬跳 */
  transition: height .45s cubic-bezier(.2,.8,.2,1), opacity .45s;
  opacity: .85;
}
.mintboard .spark i.zero { background: rgba(255,255,255,.10); opacity: 1; }

/* ---- 面板 ---- */
.mintboard .card {
  position: relative;
  background: rgba(12,16,28,.58);
  -webkit-backdrop-filter: blur(26px) saturate(150%);
  backdrop-filter: blur(26px) saturate(150%);
  border: 1px solid var(--mb-line);
  border-radius: 18px; padding: 16px 18px;
  box-shadow: 0 18px 44px -20px rgba(0,0,0,.6);
  overflow: hidden;
}
.mintboard .card h3 {
  font-size: 15px; margin: 0 0 10px; color: var(--mb-txt); font-weight: 650;
}
.mintboard .card .muted, .mintboard .card .hint,
.mintboard .card p.muted, .mintboard .card ol.muted li { color: var(--mb-dim); }
.mintboard .card .muted, .mintboard .card .hint { font-size: 12.5px; line-height: 1.75; }
.mintboard .card code {
  background: rgba(255,255,255,.08); color: #d8e3ff;
  padding: 1px 6px; border-radius: 5px; font-size: 12px;
}

/* 面板顶部那条「还活着」的扫描线：每次刷新重跑一遍 5 秒的动画。
   比在角上放个转圈的 spinner 好 —— 它同时告诉你"在刷"和"距下次还有多久"。 */
.mintboard .live-bar {
  position: absolute; left: 0; top: 0; height: 2px; width: 100%;
  background: linear-gradient(90deg, #5eead4, #7dd3fc, #c4b5fd);
  transform-origin: left center;
}
.mintboard .live-bar.run { animation: mb-sweep 5s linear; }
@keyframes mb-sweep { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* ---- 表格 ---- */
.mintboard .table-wrap { background: transparent; box-shadow: none; border: 0; padding: 0; }
.mintboard table.grid { background: transparent; border-collapse: separate; border-spacing: 0; }
.mintboard table.grid thead th {
  background: rgba(255,255,255,.05); color: var(--mb-dim);
  font-size: 11.5px; font-weight: 600; letter-spacing: .3px;
  border: 0; border-bottom: 1px solid var(--mb-line); padding: 9px 10px;
  position: sticky; top: 0; z-index: 1;
}
.mintboard table.grid tbody td {
  color: var(--mb-txt); font-size: 13px; padding: 10px;
  border: 0; border-bottom: 1px solid rgba(255,255,255,.07);
  font-variant-numeric: tabular-nums;
}
.mintboard table.grid tbody tr { transition: background .25s; }
.mintboard table.grid tbody tr:hover { background: rgba(255,255,255,.055); }
.mintboard table.grid tbody td.dim { color: var(--mb-dim2); }
.mintboard table.grid tbody td.big { font-size: 15px; font-weight: 700; }

/* 刚出号的那一行闪一下绿。这是整块看板最有用的动效：
   眼睛不用盯着数字，余光就知道"刚才是哪台机器出了货"。 */
.mintboard table.grid tbody tr.hit { animation: mb-hit 1.6s ease-out; }
@keyframes mb-hit {
  0%   { background: rgba(94,234,212,.30); box-shadow: inset 3px 0 0 #5eead4; }
  100% { background: transparent; box-shadow: inset 3px 0 0 transparent; }
}
/* 新出现的行淡入，不要"啪"地插进来 */
.mintboard table.grid tbody tr.fresh { animation: mb-in .45s ease-out; }
@keyframes mb-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; } }

/* 在线小圆点：呼吸。离线就是个静止的空心点，一眼分得开 */
.mintboard .dot {
  display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  margin-right: 6px; vertical-align: middle;
}
.mintboard .dot.on { background: #34d399; box-shadow: 0 0 0 0 rgba(52,211,153,.7); animation: mb-ping 2s infinite; }
.mintboard .dot.off { background: transparent; border: 1px solid var(--mb-dim2); }
@keyframes mb-ping {
  0%   { box-shadow: 0 0 0 0 rgba(52,211,153,.55); }
  70%  { box-shadow: 0 0 0 7px rgba(52,211,153,0); }
  100% { box-shadow: 0 0 0 0 rgba(52,211,153,0); }
}
.mintboard .tag-on { color: #34d399; }
.mintboard .tag-off { color: var(--mb-dim2); }
.mintboard .tag-warn { color: #fbbf24; }

/* 每行末尾一条迷你走势，让"这台机器的节奏"直接可见 */
.mintboard .rowspark { display: flex; align-items: flex-end; gap: 1px; height: 18px; width: 92px; }
.mintboard .rowspark i {
  flex: 1; border-radius: 1px 1px 0 0; background: rgba(125,211,252,.85);
  transition: height .45s cubic-bezier(.2,.8,.2,1);
}
.mintboard .rowspark i.zero { background: rgba(255,255,255,.09); }

.mintboard .btn-primary { box-shadow: 0 8px 24px -10px rgba(99,102,241,.8); }

/* 动效一律尊重系统的「减少动态效果」设置。做看板容易忘这一条，
   而对晕动敏感的人来说，一屏会呼吸会闪的东西是真的难受。 */
@media (prefers-reduced-motion: reduce) {
  .mintboard * { animation: none !important; transition: none !important; }
}
@media (max-width: 900px) {
  .mintboard .stat-card { flex: 1 1 46%; min-width: 0; }
  .mintboard .stat-value { font-size: 28px; }
}

.panel {
  background: rgba(255,255,255,.55);
  -webkit-backdrop-filter: blur(24px) saturate(165%);
  backdrop-filter: blur(24px) saturate(165%);
  border: 1px solid rgba(255,255,255,.42);
  border-radius: 14px; padding: 20px; margin-bottom: 18px; box-shadow: 0 10px 30px rgba(20,24,60,.14);
}
.panel-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.panel-head h3 { font-size: 16px; }
.withdraw-controls { display: flex; align-items: flex-end; gap: 12px; }
.withdraw-controls label { display: flex; flex-direction: column; gap: 5px; font-size: 13px; color: var(--muted); }
.withdraw-controls input {
  width: 120px; padding: 9px 11px; border: 1px solid var(--border);
  border-radius: 9px; font-size: 15px; outline: none;
}
.withdraw-controls input:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(26,115,232,.12); }

.record {
  border: 1px solid var(--border); border-radius: 12px;
  padding: 14px 16px; margin-bottom: 12px; background: #fafbfc;
}
.record-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; }
.record-head-right { display: flex; align-items: center; gap: 10px; }
.record-time { color: var(--text); font-size: 14px; font-weight: 500; }
.record-count { color: var(--sold); font-size: 13px; font-weight: 600;
  background: #e7f6ec; padding: 3px 12px; border-radius: 12px; }
.btn-sm { padding: 4px 12px; font-size: 12px; }
.record-rows { display: flex; flex-direction: column; gap: 5px; }
.record-row { display: flex; }
.record-text {
  font-family: Consolas, monospace; font-size: 13px; color: #333;
  background: #fff; border: 1px solid var(--border); border-radius: 7px;
  padding: 7px 11px; cursor: pointer; word-break: break-all;
  transition: background .12s, border-color .12s; width: 100%;
}
.record-text:hover { background: #eef3fe; border-color: var(--primary); }

/* ---------- 导入记录页面 ---------- */
.pill {
  font-size: 12px; padding: 3px 11px; border-radius: 12px;
  background: #f0f1f3; color: #555; font-weight: 500;
}
.pill-ok { background: #e7f6ec; color: #16a34a; }
.pill-dup { background: #fef3e2; color: #d97706; }
.pill-err { background: #fdecec; color: #dc2626; }

.imp-row {
  display: flex; align-items: center; gap: 10px; padding: 4px 0;
}
.imp-tag {
  flex-shrink: 0; width: 64px; text-align: center;
  font-size: 11px; padding: 3px 0; border-radius: 6px; font-weight: 600;
}
.imp-tag-ok { background: #e7f6ec; color: #16a34a; }
.imp-tag-dup { background: #fef3e2; color: #d97706; }
.imp-tag-err { background: #fdecec; color: #dc2626; }

/* 重复/错误行的文本弱化显示，带删除线提示被剔除 */
.imp-dup .record-text { color: #999; background: #fafafa; text-decoration: line-through; text-decoration-color: #d9770680; }
.imp-err .record-text { color: #c0392b; background: #fff5f5; }

/* ---------- 登录页 ---------- */
.login-body {
  display: grid; place-items: center; min-height: 100vh; position: relative;
  overflow: hidden;
  background-color: #eef0f8;
  background-image:
    radial-gradient(48rem 48rem at 12% 8%, rgba(109,109,240,.22), transparent 45%),
    radial-gradient(42rem 42rem at 92% 18%, rgba(91,91,214,.18), transparent 46%),
    radial-gradient(46rem 46rem at 50% 115%, rgba(124,124,236,.20), transparent 48%);
}
/* 背景细腻网格纹理，增加质感 */
.login-body::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image:
    linear-gradient(rgba(91,91,214,.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(91,91,214,.05) 1px, transparent 1px);
  background-size: 46px 46px;
  mask-image: radial-gradient(circle at 50% 42%, #000 0%, transparent 72%);
}
/* 背景题字 */
.login-motto {
  position: absolute; top: 8%; left: 0; right: 0; z-index: 0;
  text-align: center; pointer-events: none;
  font-family: "STKaiti", "KaiTi", "Songti SC", "SimSun", serif;
  font-size: clamp(24px, 4vw, 44px); font-weight: 600;
  letter-spacing: .35em; text-indent: .35em;
  color: rgba(74, 74, 160, .28);
}
.login-card {
  position: relative; z-index: 1;
  background: rgba(255,255,255,.96);
  border: 1px solid rgba(255,255,255,.8);
  border-radius: 22px;
  box-shadow: 0 24px 60px rgba(40,42,90,.16), 0 2px 8px rgba(40,42,90,.06);
  padding: 44px 40px; width: 400px; max-width: 92vw;
  backdrop-filter: blur(6px);
}
.login-card .logo { width: 54px; height: 54px; border-radius: 15px; font-size: 28px; }
.login-brand {
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  font-size: 22px; font-weight: 800; letter-spacing: 1px;
}
.login-sub { text-align: center; color: var(--muted); margin: 8px 0 26px; font-size: 13px; }
.login-alt { text-align: center; margin: 18px 0 0; font-size: 13px; color: var(--muted); }
.login-alt a { color: var(--primary); font-weight: 600; text-decoration: none; }
.login-alt a:hover { text-decoration: underline; }
.login-form { display: flex; flex-direction: column; gap: 16px; }
.login-form label { display: flex; flex-direction: column; gap: 7px; font-size: 13px; color: var(--muted); font-weight: 500; }
.login-form input {
  padding: 13px 15px; border: 1px solid var(--border); border-radius: 12px;
  font-size: 15px; outline: none; background: #f7f8fc;
  transition: border-color .15s, box-shadow .15s, background .15s;
}
.login-form input:focus {
  border-color: var(--primary); background: #fff;
  box-shadow: 0 0 0 4px rgba(91,91,214,.14);
}
.login-form .btn {
  margin-top: 10px; padding: 14px; font-size: 16px; font-weight: 600;
  border-radius: 12px; letter-spacing: 3px;
}
.login-err {
  background: #fdecec; color: #d92d20; padding: 10px 12px;
  border-radius: 9px; font-size: 13px; text-align: center;
}
.user-info { color: var(--muted); font-size: 13px; margin-right: 4px; white-space: nowrap; }

/* 订单账号行里的「售后退款」按钮：胶囊描边，低调但清晰 */
.refund-btn {
  margin-left: 8px; flex: none; padding: 5px 14px; border-radius: 999px;
  border: 1px solid rgba(217,45,32,.4); background: rgba(255,245,245,.9);
  color: #d92d20; font-size: 12.5px; font-weight: 600; cursor: pointer;
  white-space: nowrap; transition: all .15s;
}
.refund-btn:hover { background: #d92d20; color: #fff; border-color: #d92d20; }

/* ---------- 多页面导航 & 通用 ---------- */
/* 导航项较多(管理员13项)时允许换行，宽屏仍单行、窄屏折行，保证每个入口都可见 */
.topnav { display: flex; gap: 4px; flex-wrap: wrap; min-width: 0; }
.navlink {
  position: relative;
  padding: 8px 16px; border-radius: 11px; color: rgba(255,255,255,.85);
  text-shadow: 0 1px 3px rgba(0,0,0,.35);
  text-decoration: none; font-size: 14px; transition: all .15s; white-space: nowrap;
}
.navlink:hover { background: rgba(255,255,255,.22); color: #fff; }
.navlink.active {
  background: linear-gradient(135deg, rgba(255,255,255,.42), rgba(255,255,255,.24));
  color: var(--primary); font-weight: 600;
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  box-shadow: 0 3px 12px rgba(91,91,214,.22), inset 0 0 0 1px rgba(255,255,255,.5);
}
.nav-balance {
  font-weight: 700; color: var(--sold); background: #e7f6ec;
  padding: 6px 14px; border-radius: 20px; font-size: 14px;
}
.clickable-balance { cursor: pointer; transition: filter .12s; }
.clickable-balance:hover { filter: brightness(.95); }

/* 充值按钮：渐变 + 呼吸光晕动效 */
.btn-recharge {
  border: none; cursor: pointer; color: #fff; font-size: 13px; font-weight: 700;
  padding: 7px 16px; border-radius: 20px; white-space: nowrap;
  background: linear-gradient(135deg, #22c55e, #16a34a);
  box-shadow: 0 0 0 0 rgba(34,197,94,.5);
  animation: rechargePulse 1.8s ease-in-out infinite;
  transition: transform .1s;
}
.btn-recharge:hover { filter: brightness(1.06); }
.btn-recharge:active { transform: translateY(1px); }
@keyframes rechargePulse {
  0%   { box-shadow: 0 0 0 0 rgba(34,197,94,.5); }
  70%  { box-shadow: 0 0 0 10px rgba(34,197,94,0); }
  100% { box-shadow: 0 0 0 0 rgba(34,197,94,0); }
}

/* 充值弹窗 */
.recharge-modal { width: 360px; max-width: 92vw; text-align: center; }
.recharge-sub { color: var(--muted); font-size: 13px; margin: 4px 0 16px; }
.recharge-qr { display: flex; justify-content: center; }
.recharge-qr img {
  width: 260px; max-width: 80vw; border-radius: 12px; border: 1px solid var(--border);
}
.recharge-tip {
  margin-top: 16px; padding: 10px; border-radius: 10px;
  background: #e7f6ec; color: #16a34a; font-weight: 600; font-size: 14px;
}
/* 顶栏右侧用户区：推到最右 */
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 14px; }
.topbar-userbox { display: flex; align-items: center; gap: 12px; margin-left: 6px;
  padding-left: 14px; border-left: 1px solid var(--border); }
.user-chip { display: flex; align-items: center; gap: 9px; }
.avatar {
  width: 34px; height: 34px; border-radius: 50%; flex-shrink: 0;
  background: var(--grad); color: #fff; display: grid; place-items: center;
  font-weight: 700; font-size: 15px; box-shadow: 0 3px 8px rgba(91,91,214,.3);
}
.user-meta { display: flex; flex-direction: column; line-height: 1.25; }
.user-name { font-weight: 600; font-size: 13px; color: #fff; text-shadow: 0 1px 3px rgba(0,0,0,.35); }
.user-role { font-size: 11px; color: rgba(255,255,255,.85); text-shadow: 0 1px 3px rgba(0,0,0,.35); }
.btn-logout {
  background: rgba(255,255,255,.5); border: 1px solid rgba(255,255,255,.7); color: var(--muted);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.btn-logout:hover { background: #fdecec; border-color: #fbd5d5; color: #d92d20; }
.page-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
.page-head h2 { font-size: 20px; color: #fff; text-shadow: 0 2px 8px rgba(0,0,0,.45); }
/* 直接浮在视频背景上的提示文字/空状态 → 浅色可读 */
.app > .hint, .app > .empty {
  color: rgba(255,255,255,.85); text-shadow: 0 1px 4px rgba(0,0,0,.5);
}
.app > .hint code { background: rgba(255,255,255,.18); color: #fff; }
.check-line { flex-direction: row !important; align-items: center; gap: 8px !important; }
.check-line input { width: auto; }
/* 商品分级固定价输入网格 */
.level-prices-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.level-price-cell input { min-width: 0; }
.level-price-cell { display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: var(--muted, #667085); }
.level-price-cell input { width: 100%; }
.level-inline-select { padding: 4px 6px; border: 1px solid var(--primary); border-radius: 6px; font-size: 13px; background: #fff; }
/* 多标签块输入 */
.tag-input {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  padding: 6px 8px; border: 1px solid var(--border); border-radius: 9px;
  background: #fff; min-height: 40px; box-sizing: border-box; cursor: text;
}
.tag-input:focus-within { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(26,115,232,.12); }
.tag-input input {
  border: none !important; outline: none; box-shadow: none !important;
  padding: 2px 4px !important; flex: 1; min-width: 80px; width: auto !important;
  font-size: 13px;
}
.tag-input .tag { cursor: default; display: inline-flex; align-items: center; gap: 4px; }
.tag-chip-x { cursor: pointer; font-weight: 700; opacity: .6; }
.tag-chip-x:hover { opacity: 1; }
.tag-list { display: flex; flex-wrap: wrap; gap: 4px; }
.tag-list .tag { cursor: default; }
.shop-tags { display: flex; flex-wrap: wrap; gap: 6px; align-self: flex-start; margin-top: 2px; }
.price-tag { font-weight: 700; color: var(--primary); }
.amt-plus { color: var(--sold); font-weight: 600; }
.amt-minus { color: #d92d20; font-weight: 600; }

/* 专属价弹窗 */
.price-add { display: flex; gap: 8px; margin-bottom: 12px; }
.price-add select, .price-add input {
  padding: 8px 10px; border: 1px solid var(--border); border-radius: 8px; font-size: 14px;
}
.price-add select { flex: 1; }
.price-list { display: flex; flex-direction: column; gap: 6px; max-height: 240px; overflow: auto; }
.price-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 8px 12px; background: #fafbfc;
  border: 1px solid var(--border); border-radius: 8px;
}

/* ---------- 商城 ---------- */
.shop-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  align-items: stretch; gap: 20px;
}
.shop-card {
  width: 100%;
  background: linear-gradient(135deg, rgba(20,23,44,.72), rgba(20,23,44,.58));
  -webkit-backdrop-filter: blur(24px) saturate(160%);
  backdrop-filter: blur(24px) saturate(160%);
  border: 1px solid rgba(255,255,255,.16); border-radius: 18px;
  padding: 16px; box-shadow: 0 16px 44px rgba(0,0,0,.38), inset 0 1px 0 rgba(255,255,255,.14);
  display: flex; flex-direction: column; align-items: stretch; gap: 14px;
  transition: transform .15s, box-shadow .15s, border-color .15s;
}
/* 顶部图片区（竖版卡片） */
.shop-img-wrap { position: relative; width: 100%; height: 184px; display: flex; overflow: hidden; border-radius: 14px; }
.shop-img-empty {
  align-items: center; justify-content: center;
  background: linear-gradient(135deg, rgba(238,241,255,.45), rgba(246,232,255,.4));
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  border-radius: 14px; border: 1px solid rgba(255,255,255,.4);
}
.shop-img-ph { font-size: 30px; font-weight: 800; color: #b9a7e6; letter-spacing: 1px; }
/* 右侧内容区 */
.shop-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 11px; }
.shop-card { overflow: hidden; }
.shop-card:hover {
  transform: translateY(-6px) scale(1.012);
  box-shadow: 0 28px 64px rgba(0,0,0,.5), 0 0 26px rgba(124,108,245,.35), inset 0 1px 0 rgba(255,255,255,.25);
  border-color: rgba(183,179,255,.55);
}
/* 悬停：图片缓慢放大 */
.shop-img { transition: transform .5s cubic-bezier(.2,.7,.2,1); }
.shop-card:hover .shop-img { transform: scale(1.09); }
/* 悬停：一道高光斜扫过卡片 */
.shop-card::after {
  content: ""; position: absolute; top: 0; left: -70%;
  width: 45%; height: 100%; pointer-events: none; z-index: 3;
  background: linear-gradient(115deg, transparent, rgba(255,255,255,.28), transparent);
  transform: skewX(-20deg); opacity: 0;
}
.shop-card:hover::after { animation: cardSheen .85s ease; }
@keyframes cardSheen {
  0%   { left: -70%; opacity: 0; }
  15%  { opacity: 1; }
  100% { left: 130%; opacity: 0; }
}
/* 售罄标记 */
.shop-soldout { color: #ff7a7a; font-weight: 700; }
/* 售罄卡片：整体降权 + 图片置灰 + 盖「已售罄」罩 */
.shop-card.is-soldout { opacity: .85; }
.shop-card.is-soldout .shop-img { filter: grayscale(.7) brightness(.72); }
.shop-card.is-soldout .shop-img-wrap::after {
  content: "已售罄"; position: absolute; inset: 0; z-index: 2;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,.42); color: #fff; font-weight: 700;
  font-size: 18px; letter-spacing: 3px; border-radius: 14px;
}
/* 热销角标（销量最高的在售商品，右上角） */
.shop-hot-badge {
  position: absolute; top: 12px; right: 12px; z-index: 4; pointer-events: none;
  padding: 3px 11px; border-radius: 999px; font-size: 12px; font-weight: 700; color: #fff;
  background: linear-gradient(135deg, #ff8a4c, #ff4d4f);
  box-shadow: 0 4px 14px rgba(255,77,79,.42);
}
.shop-card:hover .shop-hot-badge { animation: hotPulse 1s ease infinite; }
@keyframes hotPulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.09); } }
/* hover 细节增强：价格提亮 + 购买按钮上浮 */
.shop-card:hover .shop-price { color: #e4dfff; }
.shop-buy { transition: filter .15s, box-shadow .2s, transform .2s; }
.shop-card:hover .shop-buy:not(:disabled) { box-shadow: 0 12px 28px rgba(91,91,214,.55); transform: translateY(-1px); }
/* 微信扫码支付弹窗 */
.wxpay-qr { display: flex; justify-content: center; margin: 8px 0 12px; }
.wxpay-qr img { width: 220px; height: 220px; border-radius: 12px; border: 1px solid var(--border); background: #fff; padding: 6px; }
.wxpay-status { font-size: 13px; color: #07c160; font-weight: 600; }
/* 出货记录列表 */
.records-list { max-height: 60vh; overflow: auto; display: flex; flex-direction: column; gap: 10px; }
/* 账号详情 Tab 切换 */
.acct-tabs { display: flex; gap: 6px; margin: 4px 0 14px; border-bottom: 1px solid var(--border); }
.acct-tab { appearance: none; border: none; background: none; cursor: pointer;
  font-size: 14px; font-weight: 600; color: var(--muted); padding: 8px 14px;
  border-bottom: 2px solid transparent; margin-bottom: -1px; transition: color .15s, border-color .15s; }
.acct-tab:hover { color: var(--text); }
.acct-tab.active { color: var(--primary); border-bottom-color: var(--primary); }
.acct-pane { min-height: 120px; }

/* 使用记录时间线（售后依据）*/
.usage-timeline { display: flex; flex-direction: column; gap: 10px; max-height: 52vh; overflow: auto; padding: 2px; }
.utl-loading, .utl-empty { color: var(--muted); font-size: 13px; text-align: center; padding: 28px 0; }
.utl-item { position: relative; display: flex; gap: 12px; padding: 11px 14px 11px 12px;
  background: #fafbfe; border: 1px solid var(--border); border-radius: 10px;
  border-left: 3px solid var(--border); }
.utl-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--muted); margin-top: 5px; flex-shrink: 0; }
.utl-body { flex: 1; min-width: 0; }
.utl-top { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.utl-status { font-size: 13px; font-weight: 700; color: var(--text); }
.utl-sub { font-size: 11px; font-weight: 600; color: #4a5568; background: #eef0f5;
  padding: 1px 8px; border-radius: 999px; }
.utl-src { font-size: 11px; color: var(--muted); background: #f1f3f7; padding: 1px 8px; border-radius: 999px; }
.utl-src-report { color: #2b6cb0; background: #e6f0fb; }
.utl-src-switch { color: #b7791f; background: #fef3d7; }
.utl-time { margin-left: auto; font-size: 12px; color: var(--muted); white-space: nowrap; }
.utl-usage { display: flex; align-items: center; gap: 10px; margin-top: 8px; }
.utl-bar { flex: 1; height: 6px; background: #e7eaf1; border-radius: 999px; overflow: hidden; }
.utl-bar i { display: block; height: 100%; background: var(--primary); border-radius: 999px; transition: width .3s; }
.utl-bar i.full { background: #e53e3e; }
.utl-qtext { font-size: 12px; color: #4a5568; white-space: nowrap; font-variant-numeric: tabular-nums; }
.utl-detail { margin-top: 6px; font-size: 12.5px; color: #4a5568; line-height: 1.5; word-break: break-word; }
/* 按状态给左边框 + 圆点着色 */
.utl-active { border-left-color: #38a169; } .utl-active .utl-dot { background: #38a169; }
.utl-item.utl-quota { border-left-color: #dd6b20; }
.utl-item.utl-quota .utl-dot { background: #dd6b20; }
.utl-banned { border-left-color: #e53e3e; } .utl-banned .utl-dot { background: #e53e3e; }
.utl-expired { border-left-color: #a0aec0; } .utl-expired .utl-dot { background: #a0aec0; }
.utl-switch { border-left-color: #9f7aea; background: #faf5ff; } .utl-switch .utl-dot { background: #9f7aea; }

/* 顶栏右侧原有的两条徽标（推广条与联系方式条）及其动画已随功能下线一起删除，
   renderNav 不再渲染它们。 */

/* 兑换页：玻璃翻转卡片，页面居中 */
.redeem-app { min-height: calc(100vh - 92px); display: grid; place-items: center; padding: 20px; }
.flip-card { width: 640px; max-width: 94vw; perspective: 1800px; }
/* 兑换正面：无卡片、居中、高透明输入条 */
.redeem-front { text-align: center; padding: 6px; }
.redeem-title { font-size: 36px; font-weight: 800; color: #fff; letter-spacing: 1px;
  text-shadow: 0 2px 14px rgba(0,0,0,.5); margin-bottom: 10px; }
/* .redeem-sub2 目前无使用者，留着备用：兑换页要加副标题可直接复用。
   （.redeem-sub 是另一个类，付款返回页在用，别混。） */
.redeem-sub2 { font-size: 14.5px; color: rgba(255,255,255,.9);
  text-shadow: 0 1px 6px rgba(0,0,0,.5); margin-bottom: 22px; }
.redeem-bar { display: flex; width: 100%; max-width: 620px; margin: 0 auto;
  border-radius: 14px; overflow: hidden; box-shadow: 0 12px 34px rgba(0,0,0,.3);
  border: 1px solid rgba(255,255,255,.35); }
.redeem-bar input {
  flex: 1; min-width: 0; border: none; outline: none;
  background: rgba(255,255,255,.14);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
  color: #fff; font-size: 15px; padding: 15px 18px;
}
.redeem-bar input::placeholder { color: rgba(255,255,255,.72); }
.redeem-go {
  border: none; cursor: pointer; padding: 0 34px; font-size: 15px; font-weight: 800; color: #fff;
  white-space: nowrap; background: linear-gradient(135deg, #22c1c3, #1a73e8);
  transition: filter .15s;
}
.redeem-go:hover { filter: brightness(1.08); }
.flip-inner { position: relative; min-height: 210px; transform-style: preserve-3d;
  transition: transform .7s cubic-bezier(.2,.7,.2,1), height .35s ease; }
.flip-card.flipped .flip-inner { transform: rotateY(180deg); }
.flip-face { position: absolute; top: 0; left: 0; width: 100%; box-sizing: border-box;
  -webkit-backface-visibility: hidden; backface-visibility: hidden; }
.flip-back { transform: rotateY(180deg); max-height: 80vh; overflow: auto; }
.glass-card {
  background: linear-gradient(135deg, rgba(255,255,255,.42), rgba(255,255,255,.24));
  -webkit-backdrop-filter: blur(30px) saturate(185%);
  backdrop-filter: blur(30px) saturate(185%);
  border: 1px solid rgba(255,255,255,.6); border-radius: 20px;
  box-shadow: 0 22px 60px rgba(20,24,60,.34), inset 0 1px 0 rgba(255,255,255,.65);
  padding: 30px 28px;
}
/* 翻转卡片各面本身也承载玻璃，确保 3D 变换下仍有模糊 */
.flip-face.glass-card { -webkit-backdrop-filter: blur(30px) saturate(185%); backdrop-filter: blur(30px) saturate(185%); }
/* 兑换卡片文字在半透明玻璃上加强可读性 */
.flip-front .redeem-brand, .flip-front .redeem-sub { color: #1a1d29; }
.flip-front .redeem-brand span:not(.logo) { text-shadow: 0 1px 2px rgba(255,255,255,.5); }
.redeem-again { width: 100%; margin-top: 14px; }
/* 兑换结果卡片：字段标题用白色（与顶部导航一致），半透明玻璃上才看得清 */
.flip-back .acct-label { color: #fff; text-shadow: 0 1px 3px rgba(0,0,0,.45); font-weight: 600; }
.flip-back .detail-h { color: #fff; text-shadow: 0 1px 3px rgba(0,0,0,.45); }
.shop-name {
  font-size: 24px; font-weight: 800; letter-spacing: .3px;
  color: #fff; line-height: 1.25; margin-top: 2px;
}
.shop-desc { color: rgba(255,255,255,.72); font-size: 13.5px; line-height: 1.6; white-space: pre-wrap; overflow-wrap: anywhere; word-break: break-word; }
.shop-meta { display: flex; align-items: flex-end; justify-content: space-between; margin-top: auto; }
.shop-price { font-size: 31px; font-weight: 800; color: #cbc6ff; letter-spacing: .2px; line-height: 1; text-shadow: 0 2px 10px rgba(124,108,245,.35); }
.shop-stat { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; font-size: 13px; }
.shop-stat .muted { color: rgba(255,255,255,.6) !important; }
.shop-sold { color: #ff9a5b; font-weight: 700; }
.shop-buy {
  margin-top: 10px; padding: 13px; font-size: 16px; font-weight: 600; border-radius: 12px;
  background: linear-gradient(135deg, rgba(109,109,240,.82), rgba(91,91,214,.78));
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  border: 1px solid rgba(255,255,255,.3);
  box-shadow: 0 6px 18px rgba(91,91,214,.3), inset 0 1px 0 rgba(255,255,255,.3);
}
.shop-buy:hover:not(:disabled) { filter: brightness(1.06); }
.shop-buy:disabled {
  background: linear-gradient(135deg, rgba(150,150,170,.5), rgba(130,130,150,.45));
  box-shadow: none; cursor: not-allowed;
}
/* 商城标签 chip：统一胶囊形、深色玻璃底、彩色文字+描边 */
.shop-tags .tag {
  align-self: flex-start; cursor: default; white-space: nowrap;
  padding: 3px 11px; border-radius: 999px; font-size: 12px; font-weight: 600;
  line-height: 1.5; background: rgba(255,255,255,.08);
  border: 1px solid rgba(255,255,255,.18); color: rgba(255,255,255,.88);
}
.shop-tags .tag:hover { background: rgba(255,255,255,.08); }
.shop-tags .tag.lb-pro    { color: #c9b8ff; background: rgba(124,58,237,.20); border-color: rgba(167,139,250,.55); }
.shop-tags .tag.lb-proplus{ color: #b3bcff; background: rgba(67,56,202,.24); border-color: rgba(129,140,248,.55); }
.shop-tags .tag.lb-power  { color: #f9a8d4; background: rgba(219,39,119,.20); border-color: rgba(244,114,182,.55); }
.shop-tags .tag.lb-free   { color: #6ee7b7; background: rgba(5,150,105,.22); border-color: rgba(52,211,153,.55); }
/* 管理端销量 */
.sold-count { color: #d4380d; font-weight: 700; }

/* 订单内账号展示 */
.order-accounts { margin-top: 10px; display: flex; flex-direction: column; gap: 8px; }
.order-accounts textarea {
  width: 100%; font-family: Consolas, monospace; font-size: 13px;
  padding: 10px; border: 1px solid var(--border); border-radius: 8px; resize: vertical;
}

/* ---------- 商品图片 & 质保 ---------- */
.prod-name-cell { display: flex; align-items: center; gap: 10px; }
.prod-thumb {
  width: 40px; height: 40px; border-radius: 8px; object-fit: cover;
  border: 1px solid var(--border); flex-shrink: 0;
}
.warranty-hint { font-size: 11px; margin-top: 2px; }
/* 宽弹窗（商品编辑，两列布局） */
.modal.modal-wide { width: 680px; }
/* 顶部图片上传：加号 / 预览 */
.img-uploader { display: flex; justify-content: center; margin-bottom: 18px; }
.img-uploader-empty {
  width: 120px; height: 120px; border: 2px dashed var(--border);
  border-radius: 12px; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 6px; cursor: pointer; color: var(--muted);
  transition: border-color .15s, color .15s, background .15s;
}
.img-uploader-empty:hover { border-color: var(--primary); color: var(--primary); background: rgba(26,115,232,.05); }
.img-plus { font-size: 34px; line-height: 1; font-weight: 300; }
.img-uploader-tip { font-size: 12px; }
.img-uploader-preview { position: relative; width: 120px; height: 120px; }
.img-uploader-preview img {
  width: 120px; height: 120px; object-fit: cover;
  border-radius: 12px; border: 1px solid var(--border); display: block;
}
.img-remove {
  position: absolute; top: -8px; right: -8px; width: 24px; height: 24px;
  border-radius: 50%; border: none; background: #d92d20; color: #fff;
  font-size: 16px; line-height: 1; cursor: pointer; box-shadow: 0 2px 6px rgba(0,0,0,.2);
}
.img-remove:hover { background: #b42318; }
.product-img-preview {
  max-width: 120px; max-height: 120px; border-radius: 8px;
  border: 1px solid var(--border); display: block; margin-bottom: 6px;
}
.shop-img {
  width: 100%; height: 184px; object-fit: cover; border-radius: 14px;
  border: 1px solid var(--border);
}
.shop-warranty { color: #5fe0a0; font-size: 13px; font-weight: 500; }
.warranty-badge {
  font-size: 12px; font-weight: 600; color: #16a34a;
  background: #e7f6ec; padding: 3px 10px; border-radius: 12px; white-space: nowrap;
}
.warranty-badge.expired { color: #d92d20; background: #fdecec; }

/* ---------- 自定义确认/输入弹窗 ---------- */
.modal.modal-sm { width: 380px; }
.confirm-msg { font-size: 14px; line-height: 1.7; color: var(--text); margin: 4px 0 6px; white-space: pre-line; }
.prompt-input {
  width: 100%; padding: 10px 12px; margin-top: 10px;
  border: 1px solid var(--border); border-radius: 9px; font-size: 14px; outline: none;
}
.prompt-input:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(26,115,232,.12); }

/* 订单展开的账号明细行 */
.order-detail-row td { background: #fafbfc; padding: 10px 16px; }
.order-detail-row .order-accounts { margin: 0; }

/* ---------- 筛选栏 & 分段按钮 ---------- */
.filter-bar { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }
.filter-bar input {
  padding: 9px 13px; border: 1px solid rgba(255,255,255,.5); border-radius: 10px;
  font-size: 14px; outline: none; min-width: 240px; color: var(--text);
  background: rgba(255,255,255,.45);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
}
.filter-bar input:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(91,91,214,.12); }
.seg { display: inline-flex; background: rgba(255,255,255,.40); border: 1px solid rgba(255,255,255,.42);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border-radius: 10px; overflow: hidden; }
.seg-btn { border: none; background: none; padding: 8px 14px; cursor: pointer;
  font-size: 13px; color: #3a3f52; }
.seg-btn:hover { background: rgba(255,255,255,.5); }
.seg-btn.active { background: var(--primary-soft); color: var(--primary); font-weight: 600; }

/* 可点击的行 */
.clickable-row { cursor: pointer; }
.clickable-row:hover { background: var(--primary-soft) !important; }

/* ---------- 详情抽屉 ---------- */
.drawer-mask { position: fixed; inset: 0; background: rgba(15,20,30,.4); z-index: 80;
  display: flex; justify-content: flex-end; backdrop-filter: blur(2px); }
.drawer-mask[hidden] { display: none; }
.drawer { width: 520px; max-width: 94vw; height: 100%;
  background: rgba(255,255,255,.82);
  -webkit-backdrop-filter: blur(28px) saturate(165%);
  backdrop-filter: blur(28px) saturate(165%);
  box-shadow: -8px 0 40px rgba(0,0,0,.28); display: flex; flex-direction: column;
  animation: slideIn .18s ease; }
@keyframes slideIn { from { transform: translateX(30px); opacity: .6; } to { transform: translateX(0); opacity: 1; } }
.drawer-head { display: flex; align-items: center; justify-content: space-between;
  padding: 18px 22px; border-bottom: 1px solid var(--border); }
.drawer-head h3 { font-size: 17px; }
.drawer-body { padding: 18px 22px; overflow-y: auto; flex: 1; }
.detail-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-bottom: 8px; }
.detail-stat { background: #fafbfe; border: 1px solid var(--border); border-radius: 10px; padding: 12px; }
.detail-stat-label { font-size: 12px; color: var(--muted); margin-bottom: 6px; }
.detail-stat-value { font-size: 17px; font-weight: 700; color: var(--text); }
.detail-h { margin: 20px 0 8px; font-size: 14px; color: var(--text); }
.detail-row { display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 9px 12px; border: 1px solid var(--border); border-radius: 8px;
  margin-bottom: 6px; font-size: 13px; background: #fff; }
.detail-empty { padding: 8px 0; }

/* ---------- 整单兑换码（提货结果里最该被看到的一行）---------- */
.order-code-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin: 8px 0 12px; padding: 10px 12px; border-radius: 10px;
  background: #f4f3ff; border: 1px solid #ddd9ff; }
.order-code-bar code { font-size: 13px; font-weight: 700; color: #4b3fd8;
  word-break: break-all; }
/* 码本身可点：只复制码（不带单号/网址/说明），省一个按钮 */
.order-code-bar .order-code-val { cursor: pointer;
  text-decoration: underline dotted rgba(75,63,216,.5); text-underline-offset: 3px; }
.order-code-bar .order-code-val:hover { background: #e8e5ff; border-radius: 5px; }
.order-code-bar .order-code-hint { width: 100%; font-size: 12px; color: var(--muted); }
.btn-sm { padding: 5px 12px; font-size: 12.5px; }

/* ---------- JSON 文件 ---------- */
.json-links { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 10px; }
.json-links-title { font-size: 13px; color: var(--muted); width: 100%; }
.json-cur { display: flex; align-items: center; gap: 8px; font-size: 13px;
  color: var(--sold); background: #e7f6ec; padding: 8px 12px; border-radius: 8px; }
.form-hint { font-size: 12px; color: var(--muted); background: #f4f5fb;
  border: 1px dashed #d8dbe6; border-radius: 8px; padding: 8px 10px; margin: 4px 0; line-height: 1.5; }
.json-badge {
  display: inline-block; margin-left: 8px; padding: 1px 7px; border-radius: 6px;
  background: #fff7e6; color: #d97706; border: 1px solid #f5d99a;
  font-family: Consolas, monospace; font-size: 11px; font-weight: 700;
  cursor: pointer; vertical-align: middle;
}
.json-badge:hover { background: #ffefc7; }

/* 需先注册 GitHub 的标记 */
.reg-badge {
  display: inline-block; margin-left: 8px; padding: 1px 7px; border-radius: 6px;
  background: #eef2ff; color: #4f46e5; border: 1px solid #c7d2fe;
  font-size: 11px; font-weight: 700; vertical-align: middle;
}
/* 结账链接徽章：金额 + 剩余有效期直接摆在行上。
   屯链接的用法是「等首期价压到几毛钱时一次取一批、24 小时内付完」，
   所以价格和剩余时间是操作员唯一需要的两个数字，不该藏在详情里。
   可点：点开走 Reveal 取完整链接（服务端写审计）。 */
.link-badge {
  display: inline-block; margin-left: 8px; padding: 1px 7px; border-radius: 6px;
  font-size: 12px; cursor: pointer; white-space: nowrap;
  background: #fff7ed; color: #c2410c; border: 1px solid #fed7aa;
}
.link-badge:hover { filter: brightness(0.97); text-decoration: underline; }
/* 已提交付款、等对账 —— 钱可能已经出去了，用中性蓝，别和「可付」混 */
.link-badge.link-paid { background: #eff6ff; color: #1d4ed8; border-color: #bfdbfe; }
/* 已入库 */
.link-badge.link-settled { background: #e7f6ec; color: #15803d; border-color: #a7e0bb; }
/* 过期 / 作废：灰掉，一眼看出它不是可付的 */
.link-badge.link-expired,
.link-badge.link-void { background: #f3f4f6; color: #6b7280; border-color: #e5e7eb; }

/* GitHub 已注册（正向标记）——与「待注册」的蓝紫区分开，用绿色 */
.reg-badge.reg-done {
  background: #e7f6ec; color: #15803d; border-color: #a7e0bb;
}

/* ---------- 订单卡片（我的订单）---------- */
.order-card {
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 12px; margin-bottom: 12px; overflow: hidden;
  transition: box-shadow .15s, border-color .15s;
}
.order-card:hover { box-shadow: var(--shadow); border-color: #d9dce4; }
.order-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 18px; cursor: pointer; gap: 14px;
}
.order-head:hover { background: #fafbfe; }
.order-left { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.order-title { font-size: 15px; font-weight: 600; color: var(--text); }
.order-time { font-size: 12px; color: var(--muted); }
.order-right { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
.order-right .price-tag { font-size: 16px; }
.warranty-badge.nowarranty { color: var(--muted); background: #f0f1f3; }
.order-toggle {
  display: inline-grid; place-items: center; width: 26px; height: 26px;
  border-radius: 50%; background: var(--primary-soft); color: var(--primary);
  transition: transform .2s; user-select: none;
}
.order-toggle svg { display: block; }
.order-toggle.open { transform: rotate(180deg); }
.order-card .order-accounts { margin: 0 18px 16px; }
.order-foot { display: flex; justify-content: flex-end; padding-top: 4px; }

/* ---------- 账号行（点击弹窗）---------- */
.acct-row {
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  padding: 10px 14px; border: 1px solid var(--border); border-radius: 9px;
  margin-bottom: 8px; background: #fff; transition: background .12s, border-color .12s;
}
.acct-row:hover { background: var(--primary-soft); border-color: var(--primary); }
.acct-row-email { font-family: Consolas, monospace; font-size: 13px; color: var(--text); flex: 1; word-break: break-all; }
.acct-row-arrow { color: var(--muted); font-size: 18px; font-weight: 700; }
/* 账号行里的订阅类型徽标：不许被邮箱挤掉（邮箱是 flex:1，会一直抢空间） */
.acct-row .acct-sub { flex-shrink: 0; }
/* 订单账号行内的 Kiro 订阅/配额/状态 */
.acct-kiro { display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0; }
.acct-kiro-q { font-family: Consolas, monospace; font-size: 12px; color: var(--muted); }

/* ---------- 账号详情弹窗字段 ---------- */
.acct-modal { width: 460px; max-width: 94vw; }
/* 账号详情两列布局 */
.acct-detail-2col { width: 760px; max-width: 95vw; }
/* 固定弹窗内容区高度：切换 tab（账号详情/使用记录/日志）时大小不变，内容多则内部滚动 */
.acct-detail-2col .acct-pane { min-height: 480px; max-height: 62vh; overflow: auto; }
.acct-detail-2col .acct-fields {
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px 18px;
}
.acct-detail-2col .acct-fields .full,
.acct-detail-2col .acct-fields .detail-h,
.acct-detail-2col .acct-fields .sms-status { grid-column: 1 / -1; }
.acct-detail-2col .detail-h { margin: 8px 0 2px; }
/* 验证码双栏（2FA + 短信）*/
.acct-dual { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.dual-item { display: flex; align-items: center; gap: 8px;
  background: #fafbfe; border: 1px solid var(--border); border-radius: 8px; padding: 8px 12px; }
.dual-tag { font-size: 11px; font-weight: 700; color: var(--muted);
  background: #eef0f5; padding: 2px 8px; border-radius: 6px; flex-shrink: 0; }
.dual-item .totp-code { font-size: 20px; }
.dual-item .icon-btn { margin-left: auto; flex-shrink: 0; }
@media (max-width: 640px) { .acct-dual { grid-template-columns: 1fr; } }
.acct-fields { display: flex; flex-direction: column; gap: 12px; margin: 6px 0; }
.acct-field { display: flex; flex-direction: column; gap: 4px; }
.acct-label { font-size: 12px; color: var(--muted); }
.acct-value { display: flex; align-items: center; gap: 10px;
  background: #fafbfe; border: 1px solid var(--border); border-radius: 8px; padding: 8px 12px; }
.acct-text { flex: 1; word-break: break-all; font-size: 14px; color: var(--text); }
.acct-value .icon-btn { flex-shrink: 0; color: var(--primary); }
.acct-value .totp-code { font-family: Consolas, monospace; font-size: 20px; font-weight: 700;
  color: var(--primary); letter-spacing: 2px; flex: 1; }
.sms-status { font-size: 12px; color: var(--muted); margin-top: 4px; }
.totp-code.got { color: var(--sold); flex: 1; }

/* 等待验证码：旋转圈 + 呼吸文字 + 跳动省略号 */
.sms-spinner {
  width: 16px; height: 16px; flex-shrink: 0; border-radius: 50%;
  border: 2px solid var(--border); border-top-color: var(--primary);
  animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.sms-waiting {
  flex: 1; font-size: 16px; font-weight: 600; color: var(--muted); letter-spacing: 2px;
  animation: smsPulse 1.4s ease-in-out infinite;
}
.sms-waiting::after {
  content: ""; display: inline-block; width: 1.2em; text-align: left;
  animation: smsDots 1.4s steps(1, end) infinite;
}
@keyframes smsPulse { 0%,100% { opacity: .45; } 50% { opacity: 1; } }
@keyframes smsDots { 0% { content: ""; } 25% { content: "."; } 50% { content: ".."; } 75% { content: "..."; } }

/* ---------- 营销活动 ---------- */
/* 活动徽章：不同 style 不同配色 */
.camp-badge {
  display: inline-block; margin-left: 8px; padding: 2px 10px; border-radius: 20px;
  font-size: 11px; font-weight: 700; color: #fff; vertical-align: middle; white-space: nowrap;
}
.camp-badge.camp-hot { background: linear-gradient(135deg, #ff7a45, #f5222d); }
.camp-badge.camp-new { background: linear-gradient(135deg, #36cfc9, #08979c); }
.camp-badge.camp-sale { background: linear-gradient(135deg, #ff85c0, #eb2f96); }
.camp-badge.camp-limited { background: linear-gradient(135deg, #ffc53d, #d48806); }
.camp-badge.camp-discount { background: linear-gradient(135deg, #9254de, #531dab); }

/* 活动管理弹窗 */
.camp-add { display: flex; gap: 8px; margin-bottom: 14px; flex-wrap: wrap; }
.camp-add input, .camp-add select {
  padding: 8px 10px; border: 1px solid var(--border); border-radius: 8px; font-size: 14px;
}
.camp-add #c-name { flex: 1; min-width: 140px; }
.camp-list { display: flex; flex-direction: column; gap: 8px; max-height: 300px; overflow: auto; }
.camp-row { display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 8px 12px; background: #fafbfe; border: 1px solid var(--border); border-radius: 9px; }
.camp-row-left { display: flex; align-items: center; gap: 10px; min-width: 0; }

/* 商城：折扣划线原价 */
.shop-price-wrap { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.shop-price-old {
  color: rgba(255,255,255,.55); font-size: 16px; font-weight: 600;
  text-decoration: line-through; text-decoration-color: #ff6b6b; text-decoration-thickness: 2px;
}
.shop-save {
  font-size: 12px; font-weight: 700; color: #fff;
  background: linear-gradient(135deg, #ff7a45, #f5222d);
  padding: 2px 9px; border-radius: 20px; align-self: center;
}

/* 购买弹窗：已优惠 */
.buy-save {
  margin: 4px 0 2px; padding: 10px 12px; border-radius: 9px; font-size: 14px;
  color: #16a34a; background: #e7f6ec; border: 1px solid #b7ebc6;
}
.buy-save s { color: #8b90a0; margin-right: 4px; }
.buy-save b { font-size: 16px; }

/* 商城活动说明小条 */
.shop-camp-desc {
  align-self: flex-start; font-size: 12px; font-weight: 600; color: #d4380d;
  background: #fff2e8; border: 1px solid #ffd8bf; padding: 3px 10px; border-radius: 8px;
}
.shop-camp-desc.camp-sale { color: #c41d7f; background: #fff0f6; border-color: #ffadd2; }
.shop-camp-desc.camp-discount { color: #531dab; background: #f9f0ff; border-color: #d3adf7; }
.shop-camp-desc.camp-new { color: #08979c; background: #e6fffb; border-color: #87e8de; }
.shop-camp-desc.camp-limited { color: #d48806; background: #fffbe6; border-color: #ffe58f; }

/* 购买弹窗活动提示 */
.buy-camp {
  margin: 10px 0; padding: 10px 12px; border-radius: 9px; font-size: 13px; font-weight: 600;
  color: #d4380d; background: #fff2e8; border: 1px solid #ffd8bf;
}

/* 商城活动缎带 */
.shop-card { position: relative; }
.shop-camp-ribbon {
  position: absolute; top: 12px; left: 12px; z-index: 2;
  padding: 4px 12px; border-radius: 8px; color: #fff; font-size: 12px; font-weight: 700;
  box-shadow: 0 4px 12px rgba(0,0,0,.18);
}
.shop-camp-ribbon.camp-hot { background: linear-gradient(135deg, #ff7a45, #f5222d); }
.shop-camp-ribbon.camp-new { background: linear-gradient(135deg, #36cfc9, #08979c); }
.shop-camp-ribbon.camp-sale { background: linear-gradient(135deg, #ff85c0, #eb2f96); }
.shop-camp-ribbon.camp-limited { background: linear-gradient(135deg, #ffc53d, #d48806); }
.shop-camp-ribbon.camp-discount { background: linear-gradient(135deg, #9254de, #531dab); }
.shop-card.has-camp { border-width: 2px; }
.shop-card.camp-hot { border-color: #ff7a4560; }
.shop-card.camp-sale { border-color: #eb2f9660; }
.shop-card.camp-discount { border-color: #9254de60; }

/* ---------- 可售库存明细弹窗 ---------- */
.stock-acct-list { display: flex; flex-direction: column; gap: 8px;
  max-height: 380px; overflow: auto; margin: 6px 0; }
.stock-acct-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 12px; border: 1px solid var(--border); border-radius: 9px; background: #fafbfe;
}
.stock-acct-info { min-width: 0; }
.stock-acct-email { font-family: Consolas, monospace; font-size: 13px; color: var(--text); word-break: break-all; }
.stock-acct-note { font-size: 12px; margin-top: 2px; }

/* ---------- 公开兑换页 ---------- */
.redeem-body {
  min-height: 100vh; padding: 48px 16px;
  background-color: #eef0f8;
  background-image:
    radial-gradient(circle at 15% 15%, rgba(109,109,240,.20), transparent 40%),
    radial-gradient(circle at 85% 20%, rgba(91,91,214,.16), transparent 42%),
    radial-gradient(circle at 50% 100%, rgba(124,124,236,.18), transparent 45%);
}
.redeem-wrap {
  max-width: 560px; margin: 0 auto; background: var(--panel);
  border-radius: 18px; box-shadow: 0 20px 60px rgba(30,30,80,.35); padding: 30px 28px;
}
.redeem-brand { display: flex; align-items: center; gap: 10px; justify-content: center;
  font-size: 20px; font-weight: 700; }
.redeem-sub { text-align: center; color: var(--muted); font-size: 13px; margin: 6px 0 20px; }
.redeem-inputbar { display: flex; gap: 10px; }
.redeem-inputbar input {
  flex: 1; padding: 12px 14px; border: 1px solid var(--border); border-radius: 10px;
  font-size: 15px; font-family: Consolas, monospace; outline: none;
}
.redeem-inputbar input:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(91,91,214,.12); }
.redeem-inputbar .btn { white-space: nowrap; padding: 12px 20px; }
.redeem-result { margin-top: 22px; }
.redeem-card { margin-bottom: 16px; }
.redeem-actions { display: flex; gap: 10px; justify-content: flex-end; }
.redeem-error {
  background: #fdecec; color: #d92d20; padding: 14px; border-radius: 10px;
  text-align: center; font-size: 14px;
}
.redeem-code-text { color: var(--primary); font-weight: 600; }
.warranty-banner {
  padding: 12px 16px; border-radius: 10px; margin-bottom: 16px;
  font-size: 15px; font-weight: 600; text-align: center;
}
.warranty-banner.valid { background: #e7f6ec; color: #16a34a; }
.warranty-banner.expired { background: #fdecec; color: #d92d20; }
.warranty-banner.none { background: #f0f1f3; color: var(--muted); }

/* ============================================================
   移动端适配 Responsive
   ============================================================ */

/* 平板及以下 */
@media (max-width: 900px) {
  .detail-stats { grid-template-columns: repeat(2, 1fr); }
  .shop-grid { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
}

/* 手机端 */
@media (max-width: 640px) {
  body { font-size: 14px; }

  .app { padding: 0 12px 20px; }

  /* 顶栏：换行布局，导航单独一行可横向滚动 */
  .topbar {
    flex-wrap: wrap;
    gap: 10px 12px;
    margin: 10px 0 14px;
    padding: 10px 14px;
    border-radius: 18px;
  }
  .brand { font-size: 16px; gap: 8px; }
  .brand .logo { width: 30px; height: 30px; font-size: 17px; }

  /* 用户区推到品牌右边同一行 */
  .topbar-right { margin-left: auto; gap: 8px; }
  /* 导航整行铺满并可横向滑动 */
  .topnav {
    order: 3; width: 100%;
    overflow-x: auto; -webkit-overflow-scrolling: touch;
    padding-bottom: 2px; gap: 2px;
    scrollbar-width: none;
  }
  .topnav::-webkit-scrollbar { display: none; }
  .navlink { padding: 7px 12px; font-size: 13px; flex-shrink: 0; }

  /* 用户信息文字隐藏，仅留头像，节省空间 */
  .user-meta { display: none; }
  .nav-balance { padding: 5px 10px; font-size: 13px; }
  .btn-recharge { padding: 6px 11px; font-size: 12px; }
  .btn-logout { padding: 7px 11px; }
  .avatar { width: 30px; height: 30px; font-size: 14px; }

  /* 表单单列 */
  .form { grid-template-columns: 1fr; }

  /* 统计卡片纵向堆叠 */
  .stock-cards { flex-direction: column; gap: 10px; }
  .stat-card { padding: 16px 18px; }
  .stat-value { font-size: 26px; }

  /* 面板 / 页头内边距收紧 */
  .panel { padding: 16px 14px; }
  .page-head { flex-wrap: wrap; gap: 10px; }
  .page-head h2 { font-size: 18px; }

  /* 详情统计两列 */
  .detail-stats { grid-template-columns: repeat(2, 1fr); }

  /* 商品栅格单列 */
  .shop-grid { grid-template-columns: 1fr; }

  /* 窄屏：商品卡片改回竖排 */
  .shop-card { flex-direction: column; gap: 13px; }
  .shop-img-wrap { flex: none; }
  .shop-img { width: 100%; height: 172px; min-height: 0; }
  .shop-meta { margin-top: 6px; }

  /* 筛选栏输入占满 */
  .filter-bar { gap: 10px; }
  .filter-bar input { min-width: 0; width: 100%; }
  .seg { width: 100%; }
  .seg-btn { flex: 1; }

  /* 提取控制换行 */
  .withdraw-controls { flex-wrap: wrap; gap: 10px; }
  .withdraw-controls input { width: 100%; }

  /* 弹窗内边距 */
  .modal { padding: 20px 18px; }

  /* 订单卡片头部收紧 */
  .order-head { padding: 12px 14px; gap: 10px; }
  .order-card .order-accounts { margin: 0 14px 14px; }
  .order-right { gap: 8px; }

  /* 兑换页 */
  .redeem-body { padding: 32px 12px; }
  .redeem-wrap { padding: 24px 18px; }
  .redeem-inputbar { flex-direction: column; }
  .redeem-inputbar .btn { width: 100%; }

  /* 登录页 */
  .login-card { padding: 34px 24px; }

  /* 管理员账号库存表格页：移动端取消整页锁定，改为正常滚动 */
  body.page-accounts { overflow: auto; }
  body.page-accounts .app { height: auto; display: block; }
  body.page-accounts .table-wrap { flex: none; overflow-x: auto; }

  /* 详情抽屉铺满 */
  .drawer { width: 100%; max-width: 100%; }

  /* 价格专属弹窗输入换行 */
  .price-add { flex-wrap: wrap; }
  .price-add select { flex: 1 1 100%; }
}

/* 超小屏 */
@media (max-width: 380px) {
  .brand span:not(.logo) { font-size: 15px; }
  .navlink { padding: 6px 10px; }
  .stat-value { font-size: 24px; }
}


/* ---------- 激活管理页面 ---------- */
.pill-bad { background: #fdecec; color: #dc2626; }
.act-table-wrap {
  background: rgba(255,255,255,.62);
  -webkit-backdrop-filter: blur(26px) saturate(165%);
  backdrop-filter: blur(26px) saturate(165%);
  border: 1px solid rgba(255,255,255,.45); border-radius: 16px;
  overflow-x: auto; box-shadow: 0 12px 36px rgba(20,24,60,.16); }
.act-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.act-table th { text-align: left; color: var(--muted); font-weight: 600; font-size: 12px;
  padding: 12px 14px; border-bottom: 1px solid rgba(255,255,255,.4); white-space: nowrap;
  background: rgba(251,251,254,.75); }
.act-table td { padding: 11px 14px; border-bottom: 1px solid #f2f3f7; vertical-align: middle; }
.act-table tr:last-child td { border-bottom: none; }
.act-table tr:hover td { background: #f9faff; }
.act-code { font-family: Consolas, monospace; color: var(--primary); }
.act-ops { display: flex; gap: 6px; flex-wrap: wrap; }

@media (max-width: 760px) {
  .act-table th:nth-child(4), .act-table td:nth-child(4),
  .act-table th:nth-child(6), .act-table td:nth-child(6) { display: none; }
}


.managed-hint { background: #eef0ff; color: #4338ca; border: 1px solid #d6d9ff;
  border-radius: 8px; padding: 9px 12px; font-size: 13px; line-height: 1.5; margin: 6px 0 2px; }


.redeem-download { display: inline-block; margin: 0 0 14px; padding: 8px 16px;
  background: #eef0ff; color: #4338ca; border: 1px solid #d6d9ff; border-radius: 8px;
  font-size: 13px; font-weight: 600; text-decoration: none; }
.redeem-download:hover { background: #e0e4ff; }


/* ---------- 支付结果页 ---------- */
.pay-state { text-align: center; }
.pay-spinner { width: 42px; height: 42px; margin: 8px auto 14px; border-radius: 50%;
  border: 4px solid #e6e8f5; border-top-color: var(--primary); animation: payspin 0.9s linear infinite; }
@keyframes payspin { to { transform: rotate(360deg); } }
.pay-msg { font-size: 14px; color: var(--text); margin: 6px 0; }
.pay-ok { font-size: 16px; font-weight: 800; color: #0f9257; background: #e7f7ef;
  border: 1px solid #b6ead0; border-radius: 10px; padding: 12px; margin-bottom: 14px; }
.pay-acc { text-align: left; background: #fafbfe; border: 1px solid #eaecf2; border-radius: 10px;
  padding: 12px 14px; margin-bottom: 10px; }
.pay-acc-code { font-weight: 700; color: #4338ca; margin-bottom: 8px; font-size: 13px; }
.pay-acc-row { display: flex; align-items: center; gap: 8px; padding: 5px 0; font-size: 13px; }
.pay-acc-row .k { color: var(--muted); width: 48px; flex: none; }
.pay-acc-row .v { flex: 1; font-family: Consolas, monospace; word-break: break-all; }


/* ---------- 设置页 ---------- */
/* 多卡片横向自适应铺开，用满页面宽度；窄屏自动换行堆叠 */
.settings-wrap { display: flex; gap: 18px; flex-wrap: wrap; align-items: flex-start; }
/* 设置卡原来是**实心白底**，全站最扎眼的一个不一致：别的页面都是浮在照片上的
   半透明深色面板，这一页突然一整块白。统一到 --card-* 那套。 */
.settings-card {
  background: var(--card-bg);
  -webkit-backdrop-filter: var(--card-blur);
  backdrop-filter: var(--card-blur);
  border: 1px solid var(--card-border);
  border-radius: var(--card-radius);
  padding: 20px 22px; flex: 1 1 480px; max-width: 720px;
  box-shadow: var(--card-shadow);
  color: var(--card-txt);
}
.settings-title {
  margin: 0 0 12px; font-size: 16px; font-weight: 700;
  color: var(--card-txt); text-shadow: var(--card-txt-shadow);
}
/* 卡片内字段两列网格，宽屏时并排、窄屏单列 */
.settings-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 2px 18px; }
.settings-card label {
  display: block; font-size: 13px; color: var(--card-txt-dim);
  margin: 14px 0 6px; font-weight: 500;
}
/* 输入框保留浅底：深色面板里挖一块浅色输入区，「能往里打字」这件事最清楚，
   而且输入的内容（商户号、密钥、URL）本来就该是深色小字。 */
.settings-card input, .settings-card textarea, .settings-card select {
  width: 100%; padding: 10px 12px;
  border: 1px solid rgba(255,255,255,.28); border-radius: 8px;
  background: rgba(255,255,255,.92); color: var(--text);
  font-size: 14px; outline: none; font-family: inherit;
}
.settings-card input:focus, .settings-card textarea:focus, .settings-card select:focus {
  border-color: var(--primary); background: #fff;
  box-shadow: 0 0 0 3px rgba(99,102,241,.22);
}
/* range / checkbox 不该被上面那条撑成整行白块 */
.settings-card input[type="range"] { background: transparent; border: 0; padding: 0; }
.settings-card input[type="checkbox"], .settings-card input[type="radio"] {
  width: auto; padding: 0; accent-color: var(--primary);
}
.settings-card input[type="color"] { padding: 2px; }
.settings-card input[type="file"] {
  background: rgba(255,255,255,.14); color: var(--card-txt);
  border-color: var(--card-border);
}
/* 顶部滚动公告：通用滚动动画（预览 + 全站公告条共用），white-space:pre 保留用户输入的空格 */
@keyframes ann-scroll { 0% { transform: translateX(0); } 100% { transform: translateX(-100%); } }
.ann-track { display: inline-block; padding-left: 100%; white-space: pre; will-change: transform; animation: ann-scroll linear infinite; }
/* 代理登录后可见的固定公告卡片 */
.agent-notice { margin: 0 0 16px; padding: 14px 16px; border-radius: 10px; background: #fff7ed; border: 1px solid #fed7aa; border-left: 4px solid #f59e0b; }
.agent-notice-title { font-weight: 700; font-size: 14px; color: #b45309; margin-bottom: 6px; }
.agent-notice-body { font-size: 13px; color: #7c4a03; line-height: 1.7; white-space: pre-wrap; word-break: break-word; }
/* 提示条：深色面板里用半透明底 + 白字，ok/warn 只换色相不换明度，
   免得一条绿底浅字在深色卡里又变成看不清的那种。 */
.settings-hint {
  font-size: 13px; padding: 9px 12px; border-radius: 8px;
  background: rgba(255,255,255,.10); color: var(--card-txt-dim);
  border: 1px solid rgba(255,255,255,.12);
}
.settings-hint.ok {
  background: rgba(16,185,129,.16); border-color: rgba(16,185,129,.34); color: #6ee7b7;
}
.settings-hint.warn {
  background: rgba(245,158,11,.16); border-color: rgba(245,158,11,.36); color: #fcd34d;
}

.settings-actions { margin-top: 18px; display: flex; gap: 10px; flex-wrap: wrap; }
.settings-tip {
  font-size: 12px; color: var(--card-txt-mute); margin-top: 14px; line-height: 1.6;
}


/* ---------- 登录/注册弹窗（左右分栏 · 高级卡片） ---------- */
.auth-modal {
  position: relative; width: 760px; max-width: 94vw; padding: 0;
  display: flex; overflow: hidden; border-radius: 22px;
  background: #fff; border: 1px solid rgba(255,255,255,.6);
  box-shadow: 0 40px 100px rgba(20,20,60,.38), 0 6px 24px rgba(20,20,60,.2);
}
.auth-close {
  position: absolute; top: 14px; right: 16px; z-index: 3;
  width: 32px; height: 32px; border: 1px solid rgba(0,0,0,.08); border-radius: 50%;
  background: #fff; color: #555; font-size: 20px; line-height: 1;
  display: grid; place-items: center;
  box-shadow: 0 2px 10px rgba(0,0,0,.18); cursor: pointer;
  transition: color .15s, transform .15s, box-shadow .15s;
}
.auth-close:hover { color: #111; box-shadow: 0 3px 14px rgba(0,0,0,.26); transform: rotate(90deg); }

/* 左侧品牌区 */
.auth-hero {
  width: 288px; flex-shrink: 0; padding: 40px 32px;
  background: linear-gradient(155deg, #6d6df0 0%, #6a4fe0 48%, #4a37b8 100%);
  color: #fff; position: relative; overflow: hidden;
  display: flex; flex-direction: column; gap: 20px;
}
.auth-hero::before {
  content: ""; position: absolute; width: 320px; height: 320px; border-radius: 50%;
  top: -120px; right: -140px; background: radial-gradient(circle, rgba(255,255,255,.28), transparent 70%);
}
.auth-hero::after {
  content: ""; position: absolute; width: 240px; height: 240px; border-radius: 50%;
  bottom: -110px; left: -90px; background: radial-gradient(circle, rgba(255,255,255,.16), transparent 70%);
}
.auth-hero-logo { position: relative; z-index: 1; }
.auth-hero-logo .logo {
  width: 54px; height: 54px; border-radius: 16px; font-size: 28px; font-weight: 800;
  display: inline-grid; place-items: center;
  background: rgba(255,255,255,.22); color: #fff;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.4), 0 8px 20px rgba(0,0,0,.18);
}
.auth-hero-title { position: relative; z-index: 1; font-size: 26px; font-weight: 800; margin: 4px 0 0; letter-spacing: .5px; line-height: 1.25; }
.auth-hero-brand { position: relative; z-index: 1; font-size: 14px; opacity: .9; letter-spacing: .5px; margin-top: -8px; }
.auth-feats { position: relative; z-index: 1; list-style: none; padding: 0; margin: auto 0 0; display: flex; flex-direction: column; gap: 14px; }
.auth-feats li { display: flex; align-items: center; gap: 11px; font-size: 13.5px; color: rgba(255,255,255,.94); }
.auth-feats .feat-ic {
  width: 30px; height: 30px; flex-shrink: 0; border-radius: 9px; font-size: 15px;
  display: inline-grid; place-items: center; background: rgba(255,255,255,.18);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.28);
}

/* 右侧表单区 */
.auth-panel { flex: 1; padding: 44px 44px 36px; text-align: left; min-width: 0; }
.auth-title { margin: 0; font-size: 24px; font-weight: 800; color: var(--text); }
.auth-sub { margin: 8px 0 26px; font-size: 13.5px; color: var(--muted); }
.auth-form { display: flex; flex-direction: column; gap: 16px; text-align: left; }
.auth-row { display: flex; flex-direction: column; gap: 7px; }
.auth-lb { font-size: 12.5px; color: var(--muted); font-weight: 600; }
.auth-form input {
  width: 100%; padding: 13px 15px; border: 1.5px solid #e8e8f2; border-radius: 12px;
  font-size: 14.5px; outline: none; background: #f8f8fd; transition: border-color .15s, box-shadow .15s, background .15s;
}
.auth-form input:focus { border-color: var(--primary); box-shadow: 0 0 0 4px rgba(91,91,214,.14); background: #fff; }
.auth-err { background: #fdeceb; color: #d92d20; border-radius: 10px; padding: 10px 13px; font-size: 13px; }
.auth-submit {
  width: 100%; padding: 14px; font-size: 15.5px; font-weight: 700; margin-top: 6px; border-radius: 12px;
  background: linear-gradient(135deg, #6d6df0, #5b5bd6); border: none; letter-spacing: 2px;
  box-shadow: 0 10px 24px rgba(91,91,214,.34); transition: transform .12s, box-shadow .15s, filter .15s;
}
.auth-submit:hover { filter: brightness(1.05); box-shadow: 0 12px 28px rgba(91,91,214,.42); transform: translateY(-1px); }
.auth-submit:active { transform: translateY(0); }
.auth-submit:disabled { filter: grayscale(.3) brightness(.95); box-shadow: none; cursor: default; transform: none; }
.auth-toggle { text-align: center; margin: 18px 0 0; font-size: 13.5px; color: var(--muted); }
.auth-toggle a { color: var(--primary); font-weight: 700; text-decoration: none; cursor: pointer; }
.auth-toggle a:hover { text-decoration: underline; }

/* 招募代理块（注册模式左侧） */
.auth-recruit { position: relative; z-index: 1; margin-top: auto; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 8px; }
.recruit-title {
  font-size: 26px; font-weight: 900; letter-spacing: 4px; color: #fff;
  text-shadow: 0 2px 10px rgba(0,0,0,.25);
}
.recruit-desc { font-size: 13px; color: rgba(255,255,255,.92); }
/* .recruit-qr / .recruit-qr-fallback / .recruit-hint 已删除（对应元素已移除） */

/* 原二维码弹窗的那套样式已随该弹窗一起删除。 */

@media (max-width: 640px) {
  .auth-modal { width: 400px; flex-direction: column; }
  .auth-hero { width: auto; flex-direction: row; align-items: center; gap: 14px; padding: 22px 24px; flex-wrap: wrap; }
  .auth-hero-title { font-size: 20px; }
  .auth-hero-brand { display: none; }
  .auth-feats { display: none; }
  .auth-recruit { margin-top: 0; }
  .recruit-title { font-size: 20px; }
  /* .recruit-qr 的窄屏尺寸规则一并删除（二维码已移除） */
  .auth-panel { padding: 26px 26px 24px; }
  .auth-title { font-size: 21px; }
  .auth-sub { margin-bottom: 20px; }
}


/* ---------- 原分步引导弹窗的样式已删除 ---------- */
/* 只服务那个已下线的弹窗，无其它使用者。
   注意 /tutorial 页用的是下面的 .tut-content / .tut-editor 那套，别一起删。 */


/* ---------- 使用教程图文页 ---------- */
.card-doc { background: #fff; border: 1px solid #eaecf2; border-radius: 12px; padding: 22px 26px;
  box-shadow: 0 6px 20px -14px rgba(20,23,50,.25); width: 100%; line-height: 1.85; font-size: 15px; color: #1a1d29; }
.tut-content h2 { font-size: 20px; margin: 18px 0 10px; }
.tut-content h3 { font-size: 16px; margin: 16px 0 8px; color: #4338ca; }
.tut-content p { margin: 8px 0; }
.tut-content img { max-width: 100%; border-radius: 8px; margin: 8px 0; display: block; }
.tut-content ul, .tut-content ol { padding-left: 22px; margin: 8px 0; }
.tut-content a { color: var(--primary, #5b5bd6); }
.tut-content:empty::before { content: "暂无教程内容"; color: #b9bccb; }

.tut-editor-wrap { width: 100%; }
.tut-toolbar { display: flex; flex-wrap: wrap; gap: 6px; background: #f4f5fb; border: 1px solid #eaecf2;
  border-radius: 10px 10px 0 0; padding: 8px; }
.tut-toolbar button { border: 1px solid #e2e4ee; background: #fff; border-radius: 7px; padding: 5px 10px;
  font-size: 13px; cursor: pointer; color: #1a1d29; }
.tut-toolbar button:hover { background: #eef0ff; border-color: #c9cdf5; }
.tut-toolbar select { border: 1px solid #e2e4ee; background: #fff; border-radius: 7px; padding: 5px 8px;
  font-size: 13px; cursor: pointer; color: #1a1d29; }
.tut-color { display: inline-flex; align-items: center; gap: 5px; border: 1px solid #e2e4ee; background: #fff;
  border-radius: 7px; padding: 3px 8px; font-size: 13px; color: #1a1d29; cursor: pointer; }
.tut-color input[type=color] { width: 22px; height: 20px; border: none; background: none; padding: 0; cursor: pointer; }
.tut-editor { min-height: 320px; border: 1px solid #eaecf2; border-top: none; border-radius: 0 0 10px 10px;
  padding: 16px 18px; font-size: 15px; line-height: 1.85; outline: none; background: #fff; overflow-y: auto; }
.tut-editor:focus { border-color: var(--primary, #5b5bd6); }
.tut-editor img { max-width: 100%; }
.tut-editor-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 14px; }

/* 激活管理：在线状态 */
.online-dot { color: #16a34a; font-weight: 700; white-space: nowrap;
  animation: onlinePulse 1.6s ease-in-out infinite; }
.offline-txt { color: var(--muted); white-space: nowrap; }
@keyframes onlinePulse { 0%,100% { opacity: 1; } 50% { opacity: .4; } }


/* ---------- 库存表：API Key 列 ---------- */
.apikey-cell { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.apikey-cell .mono { font-size: 12px; opacity: .85; }


/* ===== 充值筛选栏（库存页） ===== */
.rch-filter {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 14px; margin: 0 0 10px; border-radius: 12px;
  background: rgba(255,255,255,.55); border: 1px solid rgba(0,0,0,.06);
}
.rch-filter .rch-label { font-size: 13px; font-weight: 600; color: #3a3f52; }
.rch-filter .rch-input {
  padding: 6px 10px; border-radius: 8px; font-size: 13px;
  border: 1px solid var(--border,#e6e8f0); background: #fff; color: #1a1d29;
}
.rch-filter .rch-count { font-size: 12px; color: #5b5bd6; }

/* 充值人单元格 */
.rchby { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 2px 6px; }
.rchby-time { flex-basis: 100%; width: 100%; font-size: 11px; color: #8b90a0; }
.rchby-name { font-size: 13px; color: #1a1d29; }
.rchby-role {
  font-size: 11px; padding: 1px 7px; border-radius: 999px;
  background: rgba(91,91,214,.12); color: #5b5bd6; border: 1px solid rgba(91,91,214,.2);
}

/* 报表：充值统计数据表 */
.rch-report-table { width: 100%; border-collapse: collapse; margin-top: 12px; color: rgba(255,255,255,.9); font-size: 13px; }
.rch-report-table th, .rch-report-table td { padding: 7px 10px; text-align: center; border-bottom: 1px solid rgba(255,255,255,.10); }
.rch-report-table th { color: #fff; font-weight: 600; background: rgba(255,255,255,.06); position: sticky; top: 0; }
.rch-report-table td.date-cell { text-align: left; color: rgba(255,255,255,.75); white-space: nowrap; }
.rch-report-table tr.total-row td { font-weight: 700; color: #ffd166; border-top: 2px solid rgba(255,255,255,.2); }
.rch-report-wrap { max-height: 340px; overflow: auto; border-radius: 10px; }


/* ============================================================
   手机端补充适配 v2（顾客端 + 管理端全面细化）
   ============================================================ */
@media (max-width: 640px) {
  /* ---- 统计卡：改两列网格，比单列堆叠更紧凑好看 ---- */
  .stock-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
  .stock-cards .stat-card { padding: 12px 14px; min-width: 0; }
  .stat-value { font-size: 22px; }
  .stat-label { font-size: 12px; }

  /* ---- 管理端表格：缩小内边距/字号，露出更多列，仍可横向滑动 ---- */
  .grid th { padding: 10px 10px; font-size: 11px; }
  .grid td { padding: 8px 10px; font-size: 13px; }
  .grid td .btn, .grid .col-actions .btn { padding: 5px 9px; font-size: 12px; }
  /* 表格圆角容器留一点内缩，避免贴边 */
  .table-wrap { border-radius: 14px; }

  /* ---- 库存页顶栏：搜索整行、操作按钮换行铺满 ---- */
  .topbar .search-box { order: 4; width: 100%; flex: 1 1 100%; }
  .topbar .actions { order: 5; width: 100%; flex-wrap: wrap; gap: 6px; }
  .topbar .actions .btn { padding: 7px 10px; font-size: 12px; }
  .topbar-userbox { margin-left: auto; }

  /* ---- 卡头 / 号池：吸顶统计卡在手机上取消吸顶（顶栏换行后高度不定，避免遮挡内容） ---- */
  .card-stats, .pool-stats { position: static !important; top: auto !important; }

  /* ---- 工具栏 / 表单换行紧凑 ---- */
  .card-toolbar, .pool-toolbar, .imp-actions { gap: 8px; }
  .card-toolbar .search, .card-toolbar input.search { min-width: 0; width: 100%; flex: 1 1 100%; }
  .card-toolbar .spacer, .pool-toolbar .spacer, .imp-actions .spacer { display: none; }
  .keyform { flex-direction: column; align-items: stretch; gap: 10px; }
  .keyform .f { width: 100%; }
  .keyform .f input, .keyform > .btn { width: 100%; }
  .rates .rate-it, .rate-it { min-width: 0; }

  /* 卡头 chip 行：横向滑动，避免堆成很多行 */
  .bins { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; padding-bottom: 4px; scrollbar-width: none; }
  .bins::-webkit-scrollbar { display: none; }
  .bin-chip { flex-shrink: 0; }

  /* 号池：可入池账号列表、套餐参考表可横向滑动 */
  .plan-ref { overflow-x: auto; }

  /* ---- 订单/筛选栏：日期选择、用户下拉、搜索框整行 ---- */
  .filter-bar .ord-select,
  .filter-bar .search-box { width: 100%; max-width: 100% !important; flex: 1 1 100%; }
  .filter-bar #f-date { width: 100%; }

  /* ---- 报表页：图卡内边距收紧、画布降高、数据表可滑动 ---- */
  .rp-grid { gap: 12px; }
  .rp-card { padding: 14px 12px; }
  .rp-card h3 { font-size: 14px; }
  .rp-card .rp-canvas-wrap { height: 240px; }
  .rp-card.tall .rp-canvas-wrap { height: 260px; }
  .rch-report-table th, .rch-report-table td { padding: 6px 8px; font-size: 12px; }

  /* ---- 弹窗 / 抽屉 ---- */
  .modal textarea { font-size: 13px; }
  .drawer { width: 100%; max-width: 100%; }

  /* ---- 商品购买弹窗：表单单列、按钮更好点 ---- */
  .buy-camp, .buy-save { font-size: 13px; }
  .modal-actions .btn { flex: 1 1 auto; }

  /* ---- 下载中心：卡片单列（模板内已有，补充内边距） ---- */
  .dl-wrap { margin: 14px auto; }
  .dl-card { padding: 16px; }
}

/* 平板中屏：报表两列→仍两列但降高；宽表继续可滑 */
@media (max-width: 900px) and (min-width: 641px) {
  .rp-card .rp-canvas-wrap { height: 280px; }
}


/* ============================================================
   手机端顶栏溢出修复 v3：右侧下载条/客服条撑爆宽度 → 换行收缩
   ============================================================ */
@media (max-width: 640px) {
  /* 兜底：禁止整页横向滚动（仅隐藏水平溢出，纵向正常） */
  html { overflow-x: hidden; }
  body:not(.page-accounts) { overflow-x: hidden; }

  /* 顶栏允许内部换行，任何子项都不许把宽度撑爆 */
  .topbar { gap: 8px 10px; }
  .topbar > * { min-width: 0; max-width: 100%; }

  /* 右侧区域：单独占一行，内部可换行、靠右 */
  .topbar-right {
    order: 2; width: 100%; margin-left: 0;
    flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 8px;
  }

  /* 顶栏右侧那两条徽标已移除，对应的窄屏规则一并删除 */

  /* 用户信息块不换行、不撑宽 */
  .topbar-userbox { padding-left: 10px; margin-left: 4px; }
  .user-chip { min-width: 0; }
}

/* ============ 库存页工具条（搜索 + 操作，从主导航栏拆出）============ */
.page-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 10px 20px;
  margin: 0;
}
.page-toolbar .search-box {
  flex: 1 1 320px;
  min-width: 220px;
  max-width: 520px;
}
.page-toolbar .search-box input {
  width: 100%;
  box-sizing: border-box;
}
.page-toolbar .actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-left: auto;
}
/* 顶栏用户盒靠右，与导航同一行 */
.topbar > .topbar-userbox { margin-left: auto; }

@media (max-width: 768px) {
  .page-toolbar { padding: 8px 12px; gap: 8px; }
  .page-toolbar .search-box { flex: 1 1 100%; max-width: 100%; }
  .page-toolbar .actions { margin-left: 0; width: 100%; }
  .page-toolbar .actions .btn { flex: 1 1 auto; }
}

/* ---------- 批量导入：识别结果预览表 ---------- */
.imp-prev-wrap {
  max-height: 300px; overflow: auto; margin-top: 8px;
  border: 1px solid var(--border); border-radius: 10px; background: #fff;
}
.imp-prev-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.imp-prev-table th {
  position: sticky; top: 0; z-index: 1;
  text-align: left; color: var(--muted); font-weight: 600;
  padding: 8px 10px; background: #fbfbfe;
  border-bottom: 1px solid var(--border); white-space: nowrap;
}
.imp-prev-table td {
  padding: 7px 10px; border-bottom: 1px solid #f2f3f7;
  vertical-align: middle; white-space: nowrap;
}
.imp-prev-table tr:last-child td { border-bottom: none; }
.imp-prev-table tr:hover td { background: #f9faff; }
/* 长字段（取码链接）允许截断，鼠标悬停看完整值 */
.imp-prev-table td.imp-ell {
  max-width: 220px; overflow: hidden; text-overflow: ellipsis;
}
.imp-prev-table td.imp-mono { font-family: Consolas, monospace; }
.imp-idp-github { color: #6b21a8; font-weight: 600; }
.imp-idp-google { color: #1a73e8; font-weight: 600; }
.imp-yes { color: #059669; }
.imp-no { color: #bbb; }
.imp-dup { color: #d97706; font-weight: 600; }
.imp-row-bad td { background: #fdecec; }
.imp-row-bad td.imp-reason { color: #dc2626; }

/* 账户列表分页栏 */
.pager {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 8px 14px; flex-wrap: wrap;
}
.pager-info { color: var(--muted, #6b7280); font-size: 13px; }
.pager-nav { display: flex; align-items: center; gap: 10px; font-size: 13px; }
.pager-nav select { padding: 3px 6px; }
.pager .btn { padding: 4px 12px; font-size: 13px; }
.pager .btn:disabled { opacity: .45; cursor: not-allowed; }
#page-cur { color: var(--muted, #6b7280); min-width: 84px; text-align: center; }

/* ---------- 设置页：背景素材选择器 ---------- */
/* 缩略图必须是真的能看出内容的大小 —— 背景这种东西靠文件名根本挑不出来。 */
.bg-assets {
  display: grid; gap: 12px; margin-top: 8px;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}
.bg-assets .empty { grid-column: 1 / -1; padding: 14px 0; }
.bg-asset {
  position: relative;
  border: 1px solid var(--border); border-radius: 12px;
  padding: 8px; background: #fff;
  transition: border-color .15s, box-shadow .15s;
}
.bg-asset.picked {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(99,102,241,.16);
}
.bg-asset-thumb {
  height: 84px; border-radius: 8px; overflow: hidden;
  background: #eef0f8 center / cover no-repeat;
}
.bg-asset-thumb video {
  width: 100%; height: 100%; object-fit: cover; display: block;
}
/* 勾选框压在缩略图左上角，点缩略图区域也方便命中 */
.bg-asset-pick {
  position: absolute; left: 12px; top: 12px; z-index: 2;
  width: 18px; height: 18px; cursor: pointer;
  accent-color: var(--primary);
}
.bg-asset-meta {
  display: flex; justify-content: space-between; align-items: center;
  gap: 6px; margin-top: 6px; font-size: 12px;
}
.bg-asset-ord { color: var(--primary); font-weight: 600; }
.bg-asset-size { color: #667085; }
.bg-asset-del {
  width: 100%; margin-top: 6px; padding: 5px 0;
  border: 1px solid var(--border); border-radius: 8px;
  background: #fff; color: #b42318; font-size: 12px; cursor: pointer;
  transition: background .15s, border-color .15s;
}
.bg-asset-del:hover { background: #fef3f2; border-color: #fda29b; }


/* Quick extraction only: grid children must not retain intrinsic input widths. */
#quick-mask .modal {
  box-sizing: border-box;
  width: min(560px, calc(100vw - 32px));
  max-width: calc(100vw - 32px);
  max-height: calc(100vh - 32px);
  max-height: calc(100dvh - 32px);
  overflow-y: auto;
}
#quick-mask .form {
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
}
#quick-mask .form > label { min-width: 0; max-width: 100%; }
#quick-mask .form > label:nth-child(3),
#quick-mask .form > label.full { grid-column: 1 / -1; }
#quick-mask .form input,
#quick-mask .form select {
  box-sizing: border-box;
  display: block;
  width: 100%;
  min-width: 0;
  max-width: 100%;
}
#quick-mask .hint { overflow-wrap: anywhere; }
#quick-mask .modal-actions { flex-wrap: wrap; }
@media (max-width: 540px) {
  #quick-mask .modal { padding: 20px 16px; }
  #quick-mask .form { grid-template-columns: minmax(0, 1fr); }
  #quick-mask .form > label { grid-column: 1 / -1; }
}

/* Extraction actions wrap when adding format-specific exports. */
#extract-mask .modal-actions { flex-wrap: wrap; }
#extract-mask textarea { box-sizing: border-box; min-width: 0; max-width: 100%; }
