/* H5 网页版基础样式（小程序浅色主题）。
   色值一律走 tokens.css 的 CSS 变量，本文件不写字面色值（静态检查会拦）。
   版式：手机单列（顶部胶囊导航可横滑）；≥768px 左侧固定导航 + 右侧内容居中限宽。
   触控目标 ≥44px；卡片圆角 + 浅阴影，与小程序排版页同一套视觉层级。 */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100vh;
  /* iOS Safari 的地址栏会吃掉 100vh：优先 dvh，旧浏览器忽略这行仍回退到 100vh。 */
  min-height: 100dvh;
  background: var(--c-bg);
  color: var(--c-text);
  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC",
    "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
  font-size: var(--fs-body);
  line-height: 1.6;
}

h1, h2, h3, p, ul, ol, figure { margin: 0; padding: 0; }
ul, ol { list-style: none; }
a { color: var(--c-info-ink); text-decoration: none; }
img { max-width: 100%; display: block; }
[hidden] { display: none !important; }
button { font-family: inherit; }

/* ── 骨架：导航 + 内容 ───────────────────────────────────────── */
.app-shell { display: block; }

.sidenav {
  position: sticky;
  top: 0;
  z-index: 10;
  padding: var(--sp-2) var(--sp-page);
  /* 刘海屏：顶部安全区，避免导航被状态栏压住（不支持 env() 的浏览器用上一行回退） */
  padding-top: calc(var(--sp-2) + env(safe-area-inset-top));
  background: var(--c-card);
  border-bottom: 1px solid var(--c-line);
}

.sidenav-brand { display: none; }

.nav-list {
  display: flex;
  gap: var(--sp-2);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding-bottom: 2px;
}
.nav-list::-webkit-scrollbar { display: none; }

.nav-item {
  display: inline-flex;
  align-items: center;
  min-height: var(--h-touch);
  padding: 0 var(--sp-4);
  border: 1px solid var(--c-line-strong);
  border-radius: var(--r-pill);
  background: var(--c-card);
  color: var(--c-ink);
  font-size: var(--fs-body);
  font-weight: 600;
  white-space: nowrap;
}
.nav-item.is-active {
  background: var(--c-primary-soft);
  border-color: var(--c-primary);
  color: var(--c-primary-ink);
}

.sidenav-foot { display: none; }

.content {
  padding: var(--sp-4) var(--sp-page) var(--sp-6);
  /* 横屏/刘海屏左右安全区 + 底部 Home 指示条安全区 */
  padding-left: calc(var(--sp-page) + env(safe-area-inset-left));
  padding-right: calc(var(--sp-page) + env(safe-area-inset-right));
  padding-bottom: calc(var(--sp-6) + env(safe-area-inset-bottom));
}

@media (min-width: 768px) {
  .app-shell {
    display: flex;
    align-items: flex-start;
    gap: var(--sp-5);
    max-width: 1180px;
    margin: 0 auto;
    padding: var(--sp-5) var(--sp-4);
  }
  .sidenav {
    position: sticky;
    top: var(--sp-5);
    flex: none;
    width: var(--w-nav);
    padding: var(--sp-3);
    border: 1px solid var(--c-line);
    border-radius: var(--r-card);
    box-shadow: var(--c-shadow-card);
  }
  .sidenav-brand {
    display: block;
    padding: var(--sp-1) var(--sp-2) var(--sp-3);
    color: var(--c-ink);
    font-size: var(--fs-body);
    font-weight: 700;
  }
  .nav-list { flex-direction: column; gap: 2px; overflow: visible; padding-bottom: 0; }
  .nav-item {
    width: 100%;
    padding: 0 var(--sp-3);
    border-color: transparent;
    border-radius: var(--r-card-sm);
    color: var(--c-text);
  }
  .nav-item:hover { background: var(--c-bg-soft); }
  .nav-item.is-active { background: var(--c-primary-soft); color: var(--c-primary-ink); }
  .sidenav-foot {
    display: block;
    margin-top: var(--sp-3);
    padding: var(--sp-3) var(--sp-2) var(--sp-1);
    border-top: 1px solid var(--c-line-soft);
    color: var(--c-faint);
    font-size: var(--fs-sub);
    line-height: 1.5;
  }
  .content { flex: 1; min-width: 0; max-width: var(--w-content); margin: 0 auto; padding: 0; }
}

/* ── 面板：面板头 + 内容 ─────────────────────────────────────── */
.panel { display: block; }
.panel-head { padding: var(--sp-2) 0 var(--sp-3); }
.panel-title { color: var(--c-ink); font-size: var(--fs-hero); font-weight: 800; line-height: 1.2; }
.panel-sub { margin-top: var(--sp-2); color: var(--c-muted); font-size: var(--fs-body); }
.panel-meta { margin-top: var(--sp-2); color: var(--c-primary-ink); font-size: var(--fs-sub); font-weight: 600; }
/* 生成次数常显：正常绿、用完红、会员提示色（都不新增色值） */
.quota-line { margin-top: var(--sp-1); font-size: var(--fs-body); font-weight: 700; }
.quota-line.is-empty { color: var(--c-danger); }
.quota-line.is-member { color: var(--c-warn); }
.quota-gate { border-color: var(--c-warn-line); background: var(--c-warn-soft); }
/* A2（2026-09-17 顾客要求）：未登录用完 / 网页版体验关闭这一态要「一眼看到、点得动」——
   ① 标题与正文都放大、四周留白加大、居中；② 确认按钮就是 #quotaGateBtn
   （<a data-tab="me">，点一下切到「账号管理」?tab=me，复用 shell.js 的导航拦截）。
   只动观感：额度判定与风控一个字没动，仍在服务端；色值全部走令牌，不新增。 */
.quota-gate.is-loud { padding: var(--sp-5) var(--sp-4); text-align: center; }
.quota-gate.is-loud .quota-gate-title {
  color: var(--c-ink);
  font-size: 24px;
  font-weight: 800;
  line-height: 1.25;
}
.quota-gate.is-loud .quota-gate-text {
  margin-top: var(--sp-3);
  color: var(--c-warn);
  font-size: var(--fs-title);
  font-weight: 700;
  line-height: 1.5;
}
.quota-gate.is-loud .btn-row { margin-top: var(--sp-4); }
.quota-gate.is-loud #quotaGateBtn { height: var(--h-cta); font-size: var(--fs-title); }

/* ── 通用标题 / 卡片 ─────────────────────────────────────────── */
.sec-title {
  display: flex;
  align-items: center;
  font-size: var(--fs-title);
  font-weight: 700;
  color: var(--c-ink);
  padding-left: var(--sp-2);
  border-left: 3px solid var(--c-primary);
  line-height: 1.2;
  margin-bottom: var(--sp-1);
}
.sec-sub { font-size: var(--fs-sub); color: var(--c-muted); margin-bottom: var(--sp-3); }
.sec-count {
  margin-left: var(--sp-2);
  font-size: var(--fs-sub);
  font-weight: 400;
  color: var(--c-primary-ink);
}

.card {
  margin-top: var(--sp-4);
  padding: var(--sp-4);
  border-radius: var(--r-card);
  background: var(--c-card);
  border: 1px solid var(--c-line);
  box-shadow: var(--c-shadow-card);
}
.card-compact { padding: var(--sp-3) var(--sp-4); }

/* ── 网络提示 ────────────────────────────────────────────────── */
.notice {
  margin-top: var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-card);
  background: var(--c-warn-soft);
  border: 1px solid var(--c-warn-line);
  color: var(--c-warn);
  font-size: var(--fs-sub);
}

/* ── 按钮：主按钮品牌绿实心、次按钮描边 ─────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--h-touch);
  width: 100%;
  padding: 0 var(--sp-4);
  border: 1px solid var(--c-line-strong);
  border-radius: var(--r-pill);
  background: var(--c-card);
  color: var(--c-ink);
  font-family: inherit;
  font-size: var(--fs-body);
  font-weight: 600;
  cursor: pointer;
}
.btn:disabled { opacity: var(--op-disabled); cursor: default; }
.btn-cta {
  height: var(--h-cta);
  border-color: transparent;
  background: var(--c-primary);
  color: var(--c-card);
  font-weight: 700;
}
.btn-ghost { color: var(--c-info-ink); border-color: var(--c-info-line); background: var(--c-info-soft); }
.btn-danger { color: var(--c-danger); border-color: var(--c-danger); background: var(--c-card); }
.btn-row { display: flex; gap: var(--sp-2); margin-top: var(--sp-3); }
.btn-row .btn { flex: 1; }

/* ── 占位面板（未上线的入口：说清楚 + 给小程序路径，不留死链）── */
.placeholder {
  margin-top: var(--sp-4);
  padding: var(--sp-5) var(--sp-4);
  border-radius: var(--r-card);
  background: var(--c-card);
  border: 1px solid var(--c-line);
  box-shadow: var(--c-shadow-card);
  text-align: center;
}
.placeholder-mark {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  margin: 0 auto var(--sp-3);
  border-radius: var(--r-card-sm);
  background: var(--c-info-soft);
  color: var(--c-info-ink);
  font-size: 24px;
  font-weight: 700;
}
.placeholder-title { color: var(--c-ink); font-size: var(--fs-title); font-weight: 700; }
.placeholder-desc { margin-top: var(--sp-2); color: var(--c-text); font-size: var(--fs-body); }
.placeholder-hint {
  margin-top: var(--sp-4);
  padding: var(--sp-3);
  border-radius: var(--r-card-sm);
  background: var(--c-bg-soft);
  color: var(--c-muted);
  font-size: var(--fs-sub);
  text-align: left;
}
.placeholder-actions { display: flex; gap: var(--sp-2); margin-top: var(--sp-4); }
.placeholder-actions .btn { flex: 1; }
.badge-soon {
  display: inline-block;
  margin-bottom: var(--sp-3);
  padding: 2px var(--sp-3);
  border-radius: var(--r-pill);
  background: var(--c-warn-soft);
  color: var(--c-warn);
  font-size: var(--fs-sub);
  font-weight: 700;
}

/* ── 上传 ───────────────────────────────────────────────────── */
.upload-drop {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 96px;
  padding: var(--sp-4);
  border: 1px dashed var(--c-info-line);
  border-radius: var(--r-card-sm);
  background: var(--c-info-soft);
  text-align: center;
  cursor: pointer;
}
.upload-drop:active { opacity: var(--op-disabled); }
.upload-main { font-size: var(--fs-title); font-weight: 700; color: var(--c-info-ink); }
.upload-hint { margin-top: var(--sp-1); font-size: var(--fs-sub); color: var(--c-muted); }
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
.progress { margin-top: var(--sp-3); }
.progress-bar { height: 6px; border-radius: var(--r-pill); background: var(--c-slate-soft); overflow: hidden; }
.progress-bar i { display: block; height: 100%; width: 0; background: var(--c-primary); }
.progress-text { margin-top: var(--sp-1); font-size: var(--fs-sub); color: var(--c-muted); }
.error-text { margin-top: var(--sp-2); font-size: var(--fs-sub); color: var(--c-danger); }
.thumbs { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-3); }
.thumbs img {
  width: 56px;
  height: 56px;
  object-fit: cover;
  border-radius: var(--r-card-sm);
  background: var(--c-slate-soft);
}

/* ── 眼珠列表：网格方块（每颗眼珠一个方块；紧凑、多列自适应） ────────
   列数由 auto-fill + 最小轨道宽决定：
     手机 375 ≈ 3 列、窄屏 320 不少于 2 列、≥768px（下方媒体查询）更多列。
   每格内容：缩略图（/api/eye_image/<id>，Cookie 带身份）+ 序号 + 操作入口。
   触控目标高度统一走 --h-touch（44px，静态与截图自检都会拦）。 */
.eyes {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(92px, 1fr));
  gap: var(--sp-2);
}
.eye-cell {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--c-line-strong);
  border-radius: var(--r-card-sm);
  background: var(--c-card);
  /* 长按拖动排序时，别让浏览器弹选择菜单/放大镜 */
  -webkit-touch-callout: none;
  user-select: none;
  -webkit-user-select: none;
}
.eye-cell.is-dragging {
  border-color: var(--c-primary);
  box-shadow: var(--c-shadow-float);
  opacity: .92;
}
.eye-shot {
  position: relative;
  /* 近正方缩略图区；移动键叠在两侧，操作键排在下方，整体仍是紧凑方块。
     min-height 是不支持 aspect-ratio 的老浏览器的兜底，保证方块不塌成一条线。 */
  aspect-ratio: 1 / 1;
  min-height: 72px;
  background: var(--c-bg-soft);
}
.eye-thumb { width: 100%; height: 100%; object-fit: contain; padding: 6px 24px; }
.eye-order {
  position: absolute;
  top: 2px;
  left: 2px;
  min-width: 18px;
  padding: 0 4px;
  border-radius: var(--r-pill);
  background: rgba(17, 24, 39, .55);
  color: var(--c-card);
  font-size: var(--fs-sub);
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}
/* 左/右移动键：叠在缩略图两侧（与小程序素材方块的 ‹ › 同一套交互） */
.eye-move {
  position: absolute;
  top: 50%;
  z-index: 2;
  width: 24px;
  height: var(--h-touch);
  min-height: var(--h-touch);
  padding: 0;
  border: 0;
  background: rgba(255, 255, 255, .86);
  color: var(--c-info-ink);
  font-family: inherit;
  font-size: 18px;
  font-weight: 700;
  line-height: 1;
  transform: translateY(-50%);
  cursor: pointer;
}
.eye-move-prev { left: 0; border-radius: 0 var(--r-card-sm) var(--r-card-sm) 0; }
.eye-move-next { right: 0; border-radius: var(--r-card-sm) 0 0 var(--r-card-sm); }
.eye-move:hover:not(:disabled) { background: var(--c-info-soft); }
.eye-move:disabled { opacity: var(--op-disabled); cursor: default; }
/* 底部操作键：翻转 / 旋转 90° / 删除，均 44px 高 */
.eye-ops {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border-top: 1px solid var(--c-line);
}
.eye-act {
  min-width: 0;
  min-height: var(--h-touch);
  padding: 0;
  border: 0;
  border-left: 1px solid var(--c-line);
  background: var(--c-card);
  color: var(--c-slate-ink);
  font-family: inherit;
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}
.eye-act:first-child { border-left: 0; }
.eye-act:hover:not(:disabled) { background: var(--c-bg-soft); }
.eye-act:disabled { opacity: var(--op-disabled); cursor: default; }
.eye-act-danger { color: var(--c-danger); }
.eye-act-danger:hover:not(:disabled) { background: var(--c-danger-soft); }
/* 旧列表用过的按钮类保留（其它面板/后续功能仍可复用），不再被眼珠列表使用 */
.icon-btn {
  min-width: var(--h-touch);
  min-height: var(--h-touch);
  padding: 0 var(--sp-1);
  border: 1px solid var(--c-line-strong);
  border-radius: var(--r-card-sm);
  background: var(--c-card);
  color: var(--c-slate-ink);
  font-family: inherit;
  font-size: var(--fs-sub);
  cursor: pointer;
}
.icon-btn:disabled { opacity: var(--op-disabled); cursor: default; }
.icon-btn-danger { border-color: var(--c-danger); color: var(--c-danger); }
@media (min-width: 768px) {
  /* 桌面内容列更宽：方块更大、列数更多（手机那档不受影响） */
  .eyes { grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); }
}

.empty { padding: var(--sp-4) 0; font-size: var(--fs-sub); color: var(--c-faint); }

/* ── 参数 ───────────────────────────────────────────────────── */
.field { margin-top: var(--sp-4); }
.field:first-child { margin-top: 0; }
.field-line { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-2); }
.field-label { font-size: var(--fs-body); color: var(--c-ink); font-weight: 600; }
.field-value { font-size: var(--fs-sub); color: var(--c-primary-ink); font-weight: 700; }
.field-desc { margin-top: 2px; font-size: var(--fs-sub); color: var(--c-muted); }

.range {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: var(--h-touch);
  margin: 0;
  background: transparent;
}
.range::-webkit-slider-runnable-track {
  height: 6px;
  border-radius: var(--r-pill);
  background: var(--c-slate-soft);
}
.range::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 24px;
  height: 24px;
  margin-top: -9px;
  border-radius: var(--r-pill);
  background: var(--c-primary);
  border: 2px solid var(--c-card);
  box-shadow: var(--c-shadow-card);
}
.range::-moz-range-track { height: 6px; border-radius: var(--r-pill); background: var(--c-slate-soft); }
.range::-moz-range-thumb { width: 22px; height: 22px; border: 2px solid var(--c-card); border-radius: var(--r-pill); background: var(--c-primary); }

.select-wrap { position: relative; }
.select {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  min-height: var(--h-touch);
  padding: 0 var(--sp-5) 0 var(--sp-3);
  border: 1px solid var(--c-line-strong);
  border-radius: var(--r-card-sm);
  background: var(--c-card);
  color: var(--c-ink);
  font-family: inherit;
  font-size: var(--fs-body);
}
.select-wrap::after {
  content: "▾";
  position: absolute;
  right: var(--sp-3);
  top: 50%;
  transform: translateY(-50%);
  color: var(--c-muted);
  pointer-events: none;
}

.switch-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  min-height: var(--h-touch);
  margin-top: var(--sp-3);
}
.switch {
  -webkit-appearance: none;
  appearance: none;
  flex: none;
  position: relative;
  width: 48px;
  height: 28px;
  margin: 0;
  border: 1px solid var(--c-line-strong);
  border-radius: var(--r-pill);
  background: var(--c-slate-soft);
  cursor: pointer;
}
.switch::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 20px;
  height: 20px;
  border-radius: var(--r-pill);
  background: var(--c-card);
  box-shadow: var(--c-shadow-card);
  transition: left .18s ease;
}
.switch:checked { background: var(--c-primary); border-color: var(--c-primary); }
.switch:checked::after { left: 23px; background: var(--c-card); }
.switch-row-text { font-size: var(--fs-body); color: var(--c-ink); }

/* ── 预览 ───────────────────────────────────────────────────── */
.preview-box {
  margin-top: var(--sp-3);
  min-height: 180px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-card-sm);
  background: var(--c-bg-soft);
  border: 1px solid var(--c-line);
  overflow: hidden;
}
.preview-box img { width: 100%; height: auto; }
.preview-empty { padding: var(--sp-5) var(--sp-3); text-align: center; font-size: var(--fs-sub); color: var(--c-faint); }
.preview-meta { margin-top: var(--sp-2); font-size: var(--fs-sub); color: var(--c-muted); }
.stale {
  margin-top: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-card-sm);
  background: var(--c-warn-soft);
  border: 1px solid var(--c-warn-line);
  font-size: var(--fs-sub);
  color: var(--c-warn);
}

/* ── 页脚 ───────────────────────────────────────────────────── */
.foot { margin-top: var(--sp-5); font-size: var(--fs-sub); color: var(--c-faint); }

/* ── 弹层 / 轻提示 / 加载态 ─────────────────────────────────── */
.overlay {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-5);
  background: var(--c-overlay);
  z-index: 20;
}
.dialog {
  width: 100%;
  max-width: 320px;
  padding: var(--sp-4);
  border-radius: var(--r-card);
  background: var(--c-card);
  border: 1px solid var(--c-line);
  box-shadow: var(--c-shadow-float);
}
.dialog-text { font-size: var(--fs-body); color: var(--c-ink); }
.toast {
  position: fixed;
  left: 50%;
  bottom: var(--sp-6);
  bottom: calc(var(--sp-6) + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  max-width: 80%;
  padding: var(--sp-2) var(--sp-4);
  border-radius: var(--r-pill);
  background: var(--c-ink);
  color: var(--c-card);
  font-size: var(--fs-sub);
  z-index: 30;
  text-align: center;
}
.loading-mask {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--c-overlay);
  color: var(--c-card);
  font-size: var(--fs-body);
  z-index: 25;
}

/* ── 扫码登录 / 「我的」 ───────────────────────────────────────── */
.login-box {
  margin-top: var(--sp-3);
  padding: var(--sp-4);
  border-radius: var(--r-card-sm);
  background: var(--c-bg-soft);
  border: 1px solid var(--c-line);
  text-align: center;
}
.login-qr {
  width: 180px;
  height: 180px;
  margin: 0 auto var(--sp-3);
  border-radius: var(--r-card-sm);
  background: var(--c-card);
  border: 1px solid var(--c-line);
}
.login-fallback {
  margin: var(--sp-2) 0;
  padding: var(--sp-3);
  border-radius: var(--r-card-sm);
  background: var(--c-warn-soft);
  border: 1px solid var(--c-warn-line);
  color: var(--c-warn);
  font-size: var(--fs-sub);
  text-align: left;
  white-space: pre-wrap;
  word-break: break-all;
}
/* 准备中：不确定进度条（斜纹滚动），静态截图里也是「一条进度条」而不是空白 */
.login-wait {
  margin: var(--sp-3) auto var(--sp-1);
  max-width: 260px;
}
.login-waitbar {
  height: 8px;
  border-radius: var(--r-pill);
  background: var(--c-slate-soft);
  overflow: hidden;
}
.login-waitbar i {
  display: block;
  height: 100%;
  width: 100%;
  background-image: repeating-linear-gradient(90deg,
    var(--c-primary) 0 10px, var(--c-info-soft) 10px 20px);
  background-size: 200% 100%;
  animation: login-wait-move 1s linear infinite;
}
@keyframes login-wait-move {
  from { background-position: 0 0; }
  to { background-position: 40px 0; }
}
.login-wait-hint {
  margin-top: var(--sp-1);
  color: var(--c-muted);
  font-size: var(--fs-sub);
}
.login-status {
  margin-top: var(--sp-2);
  color: var(--c-ink);
  font-size: var(--fs-title);
  font-weight: 700;
}
/* 准备中/升级提示用信息蓝，比正文更显眼（顾客一眼能看到「正在准备，马上就来」） */
.login-status.is-waiting {
  color: var(--c-info-ink);
}
.login-timer {
  margin-top: var(--sp-1);
  color: var(--c-primary-ink);
  font-size: var(--fs-sub);
  font-weight: 600;
}
.login-guide {
  margin-top: var(--sp-2);
  color: var(--c-muted);
  font-size: var(--fs-sub);
}
.kv {
  display: grid;
  gap: var(--sp-2);
  margin-top: var(--sp-3);
}
.kv-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  min-height: var(--h-touch);
  padding: 0 var(--sp-3);
  border-radius: var(--r-card-sm);
  background: var(--c-bg-soft);
}
.kv-key {
  color: var(--c-muted);
  font-size: var(--fs-sub);
}
.kv-val {
  color: var(--c-ink);
  font-size: var(--fs-body);
  font-weight: 600;
}
/* 开通会员成功提示：用主色文字（不新增色值），比正文更显眼 */
.member-success {
  margin-top: var(--sp-2);
  color: var(--c-primary-ink);
  font-size: var(--fs-sub);
  font-weight: 700;
}

/* ── 跨端打磨（P3）：去掉点击延迟、补齐安全区与触控目标 ────────────
   1. touch-action: manipulation 去掉 iOS/Android 的 300ms 点击延迟；
   2. env(safe-area-inset-*) 已在 body/sidenav/content/toast 处理（viewport-fit=cover）；
   3. 字体回退链在 body 的 font-family（-apple-system → PingFang SC → 微软雅黑），
      不引外部字体（零依赖、首屏不阻塞）；
   4. 所有可点元素的命中区高度统一走 --h-touch（44px）。 */
a, button, label, select, input, .nav-item, .icon-btn, .tut-card { touch-action: manipulation; }

/* ── 教程中心（P3）：分类 tab + 列表 + 详情 + 相关推荐 ──────────── */
.tut-cats {
  display: flex;
  gap: var(--sp-2);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: var(--sp-2) 0 var(--sp-1);
}
.tut-cats::-webkit-scrollbar { display: none; }
.tut-cat {
  flex: none;
  min-height: var(--h-touch);
  padding: 0 var(--sp-4);
  border: 1px solid var(--c-line-strong);
  border-radius: var(--r-pill);
  background: var(--c-card);
  color: var(--c-text);
  font-family: inherit;
  font-size: var(--fs-sub);
  font-weight: 600;
  cursor: pointer;
}
.tut-cat.is-active {
  background: var(--c-primary-soft);
  border-color: var(--c-primary);
  color: var(--c-primary-ink);
}
.tut-state { padding: var(--sp-4) 0; color: var(--c-muted); font-size: var(--fs-sub); }
.tut-list { display: grid; gap: var(--sp-3); margin-top: var(--sp-3); }

.tut-card {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  width: 100%;
  min-height: var(--h-touch);
  padding: var(--sp-3);
  border: 1px solid var(--c-line);
  border-radius: var(--r-card);
  background: var(--c-card);
  box-shadow: var(--c-shadow-card);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}
.tut-card:active { background: var(--c-bg-soft); }
.tut-thumb {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  overflow: hidden;
  border-radius: var(--r-card-sm);
  background: var(--c-info-soft);
  color: var(--c-info-ink);
  font-size: 20px;
  font-weight: 700;
}
.tut-cover { width: 100%; height: 100%; object-fit: cover; }
.tut-main { flex: 1; min-width: 0; display: block; }
.tut-title-row { display: flex; align-items: center; gap: var(--sp-2); }
.tut-title {
  display: -webkit-box;
  overflow: hidden;
  color: var(--c-ink);
  font-size: var(--fs-body);
  font-weight: 700;
  line-height: 1.4;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.tut-badge {
  flex: none;
  padding: 1px var(--sp-2);
  border-radius: var(--r-pill);
  background: var(--c-warn-soft);
  color: var(--c-warn);
  font-size: var(--fs-sub);
  font-weight: 700;
}
.tut-desc {
  display: -webkit-box;
  overflow: hidden;
  margin-top: 2px;
  color: var(--c-muted);
  font-size: var(--fs-sub);
  line-height: 1.5;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.tut-meta { display: block; margin-top: var(--sp-1); color: var(--c-faint); font-size: var(--fs-sub); }
.tut-arrow { flex: none; color: var(--c-faint); font-size: 20px; }

.tut-back {
  display: inline-flex;
  align-items: center;
  min-height: var(--h-touch);
  margin-bottom: var(--sp-2);
  padding: 0 var(--sp-3);
  border: 1px solid var(--c-line-strong);
  border-radius: var(--r-pill);
  background: var(--c-card);
  color: var(--c-info-ink);
  font-family: inherit;
  font-size: var(--fs-sub);
  font-weight: 600;
  cursor: pointer;
}
.tut-detail-title { color: var(--c-ink); font-size: var(--fs-hero); font-weight: 800; line-height: 1.3; }
.tut-detail-meta { margin-top: var(--sp-2); color: var(--c-muted); font-size: var(--fs-sub); }
.tut-body { margin-top: var(--sp-3); }
.tut-h3 {
  margin: var(--sp-4) 0 var(--sp-2);
  padding-left: var(--sp-2);
  border-left: 3px solid var(--c-info);
  color: var(--c-ink);
  font-size: var(--fs-title);
  font-weight: 700;
  line-height: 1.4;
}
.tut-body > .tut-h3:first-child { margin-top: 0; }
.tut-p { margin-top: var(--sp-2); color: var(--c-text); font-size: var(--fs-body); line-height: 1.75; }
.tut-tip {
  margin-top: var(--sp-3);
  padding: var(--sp-3);
  border-radius: var(--r-card-sm);
  background: var(--c-warn-soft);
  border: 1px solid var(--c-warn-line);
  color: var(--c-warn);
  font-size: var(--fs-sub);
}
.tut-quote {
  margin-top: var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  border-left: 3px solid var(--c-line-strong);
  color: var(--c-muted);
  font-size: var(--fs-sub);
}
.tut-takeaway {
  margin-top: var(--sp-3);
  padding: var(--sp-3);
  border-radius: var(--r-card-sm);
  background: var(--c-primary-soft);
}
.tut-takeaway-title { display: block; color: var(--c-primary-ink); font-size: var(--fs-sub); font-weight: 700; }
.tut-takeaway-text { margin-top: var(--sp-1); color: var(--c-text); font-size: var(--fs-sub); line-height: 1.7; }
.tut-steps { display: grid; gap: var(--sp-2); margin-top: var(--sp-3); }
.tut-step { display: flex; align-items: flex-start; gap: var(--sp-2); }
.tut-step-index {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  margin-top: 2px;
  border-radius: var(--r-pill);
  background: var(--c-info-soft);
  color: var(--c-info-ink);
  font-size: var(--fs-sub);
  font-weight: 700;
}
.tut-step-text { flex: 1; color: var(--c-text); font-size: var(--fs-body); line-height: 1.7; }
.tut-bullets { display: grid; gap: var(--sp-1); margin-top: var(--sp-3); }
.tut-bullet { display: flex; align-items: flex-start; gap: var(--sp-2); }
.tut-bullet-dot {
  flex: none;
  width: 6px;
  height: 6px;
  margin-top: 8px;
  border-radius: var(--r-pill);
  background: var(--c-primary);
}
.tut-bullet-text { flex: 1; color: var(--c-text); font-size: var(--fs-body); line-height: 1.7; }
.tut-figure { margin-top: var(--sp-3); }
.tut-image { width: 100%; height: auto; border-radius: var(--r-card-sm); border: 1px solid var(--c-line); }
.tut-inline-image { max-width: 100%; height: auto; margin-top: var(--sp-2); border-radius: var(--r-card-sm); }
.tut-figcaption { margin-top: var(--sp-1); color: var(--c-muted); font-size: var(--fs-sub); text-align: center; }
.tut-image-placeholder {
  padding: var(--sp-4);
  border-radius: var(--r-card-sm);
  background: var(--c-bg-soft);
  color: var(--c-faint);
  font-size: var(--fs-sub);
  text-align: center;
}
.tut-divider { margin: var(--sp-4) 0; border: 0; border-top: 1px solid var(--c-line-soft); }

/* ═══════════════════════════════════════════════════════════════════════════
   会员入口（方案 C · 多触点组合，2026-09-17 顾客调整后）
   —— 设计稿与逐行清单：miniapp/deploy/design-preview/h5-member-entry-design.md §3.2
   调整后只剩两处：C1 顶部黑金横幅（**只在「已登录非会员 + 次数用尽」出现**，是排版页
   唯一的金 CTA）→ C4 账号管理页金按钮「最后一步」。
   本轮下线：C2 次数旁金胶囊（样式一并删除）；C3 金色引导卡（.member-gate 样式保留，
   但由 layout.js 决定不再显示 —— 要改回「引导卡是唯一入口」时只动 JS 两处显隐）。
   显隐规则（见 layout.js）：还有次数 → 零金 CTA；已登录非会员用完 → 只留 C1；
   未登录用完走黄色 #quotaGate；已是会员 → 全隐藏；h5_anon_disabled（体验关闭）→
   连金 CTA 都不显示，避免误导。
   为什么金晕写在 background-image 里：H5 自检按 getBoundingClientRect() 判横向溢出，
   绝对定位的金晕即使被 overflow:hidden 裁掉也会被判「超出视口」。
   色值全部走 tokens.css 的黑金令牌，本文件不写字面黑金色值。
   ═══════════════════════════════════════════════════════════════════════════ */
.g-crown { display: block; flex: none; }

/* ── C1：主区顶部黑金横幅（2026-09-17 起只在「次数用尽」时出现，是唯一的金 CTA）── */
.member-banner {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  overflow: hidden;
  margin-bottom: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-card);
  background-image:
    radial-gradient(240px 240px at 100% 0%, rgba(247, 231, 166, .28) 0%, rgba(247, 231, 166, 0) 70%),
    var(--g-card-bg);
  border: 1px solid rgba(247, 231, 166, .45);
  box-shadow: var(--g-shadow);
}
.member-banner-row { position: relative; display: flex; align-items: center; gap: var(--sp-3); }
.member-banner-crown { width: 26px; height: 26px; }
.member-banner-copy { flex: 1; min-width: 0; }
.member-banner-title {
  display: block;
  color: var(--g-light);
  font-size: var(--fs-title);
  font-weight: 700;
  line-height: 1.3;
}
.member-banner-desc {
  display: block;
  margin-top: var(--sp-1);
  color: rgba(255, 255, 255, .72);
  font-size: var(--fs-sub);
  line-height: 1.45;
}
.member-cta {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: var(--h-touch);
  padding: 0 var(--sp-4);
  border-radius: var(--r-pill);
  background: var(--g-grad);
  color: var(--g-ink);
  font-size: var(--fs-body);
  font-weight: 700;
  box-shadow: 0 10px 24px rgba(201, 162, 39, .32);
}
.member-banner.is-strong { border-color: rgba(247, 231, 166, .9); box-shadow: var(--g-shadow-strong); }

/* ── C2：次数行（顾客看次数的地方）─────────────────────────────────────────
   2026-09-17：顾客要求去掉次数旁的「开通会员」金胶囊，.member-pill 不再渲染，样式同步删除。
   .quota-row 保留：只服务会员态那一句「会员 · 不限次生成」状态。 */
.quota-row { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; margin-top: var(--sp-1); }
.quota-row .quota-line { margin-top: 0; }

/* ── C3：金色引导卡（本轮保留样式、不再显示；金 CTA 由顶部横幅承担）────────
   注：黄色 .quota-gate 仍然保留并继续显示，它还要服务「未登录用完」与「总开关关闭」两态。
   2026-09-17 决定：次数用尽时同屏只留一个金 CTA，选的是顶部横幅（#memberBanner）；
   本卡（#memberGate）元素与样式都留着，要改回它当唯一入口只需改 layout.js 两处显隐。 */
.member-gate {
  position: relative;
  overflow: hidden;
  border-color: rgba(247, 231, 166, .9);
  background-image:
    radial-gradient(220px 220px at 100% 0%, rgba(247, 231, 166, .28) 0%, rgba(247, 231, 166, 0) 70%),
    var(--g-card-bg);
  box-shadow: var(--g-shadow-strong);
}
.member-gate-head { position: relative; display: flex; align-items: center; gap: var(--sp-2); }
.member-gate-crown { width: 24px; height: 24px; }
.member-gate-title { position: relative; color: var(--g-light); border-left-color: var(--g-deep); }
.member-gate-sub { position: relative; color: rgba(255, 255, 255, .72); }
.member-gate .btn-row { position: relative; }

/* ── C4：账号管理页的金色大按钮（只换皮肤，入口条件一个字不动）────────── */
.btn-gold {
  height: var(--h-cta);
  border-color: transparent;
  background: var(--g-grad);
  color: var(--g-ink);
  font-weight: 700;
  box-shadow: 0 10px 24px rgba(201, 162, 39, .32);
}


/* ── 会员档位（服务端下发；主推档金色高亮）────────────────────────────────
   价格/天数/标签全部来自 /api/h5/me 的 plans，这里只负责排版：
   一行一档，左边档位名 + 标签，右边价格；主推档（服务端标了 highlight）金描边 + 浅金底。 */
.tier-list { display: grid; gap: var(--sp-2); margin-top: var(--sp-3); }
.tier {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  width: 100%;
  min-height: var(--h-touch);
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--c-line-strong);
  border-radius: var(--r-card-sm);
  background: var(--c-card);
  color: var(--c-ink);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}
.tier.is-active { border-color: var(--g-deep); background: var(--c-warn-soft); }
.tier-main { flex: 1; min-width: 0; }
.tier-days { font-size: var(--fs-body); font-weight: 700; }
.tier-tag {
  display: inline-block;
  margin-left: var(--sp-2);
  padding: 1px var(--sp-2);
  border-radius: var(--r-pill);
  background: var(--g-grad);
  color: var(--g-ink);
  font-size: var(--fs-sub);
  font-weight: 700;
}
.tier-note { display: block; margin-top: 2px; color: var(--c-muted); font-size: var(--fs-sub); }
.tier-price { flex: none; color: var(--c-warn); font-size: var(--fs-title); font-weight: 800; }
.tier.is-active .tier-price { color: var(--g-deep); }

/* 只给点击一个轻微反馈，不加常驻动效（H5 是每天用的工作台，常驻动画会吵） */
.member-cta:active,
.btn-gold:active { opacity: .88; }

@media (min-width: 768px) {
  /* 桌面：横幅横排（文案在左、按钮在右），与设计稿 §3.2 一致 */
  .member-banner { flex-direction: row; align-items: center; margin-bottom: var(--sp-4); }
  .member-banner-row { flex: 1; min-width: 0; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   会员码弹层「尊贵加冕」（候选 3）—— 2026-09-17 顾客拍板落地
   —— 设计稿与逐行清单：miniapp/deploy/design-preview/h5-member-qr-design.md §6.2
   这段 CSS 原样搬自设计稿脚本 miniapp/deploy/design-preview/build_member_qr.py 的
   MQ_HEADER + MQ_STRUCT + MQ_CSS["crown"]（三个候选共用一套 DOM，差别只在金色加在哪）。
   现有 DOM 全部保留：#memberQr / #memberQrStatus / #memberQrWait / #memberQrGuide /
   #memberQrError / #memberQrTimeout / #memberQrActions / #memberSuccess 一个都不改名；
   .login-box / .login-qr 既有规则一个字不动，未登录的登录码继续用浅色那套。

   可扫性第一（顾客拍板第 1 条）：金色只做托盘 / 描边 / 金晕 / 文字，绝不压进二维码 ——
   二维码本体是纯白底 + 黑模块，外面再套 12px 白码托（.member-qr-tile）+ 金渐变托盘
   （.member-qr-plate），四周留白完整。落地后用 OpenCV 在真实页面截图里再解码验过一次。

   色值全部走 tokens.css 的黑金令牌与白名单（零新增色值）：
     规范色板  #f7e7a6  #e8c86a  #c9a227  #1f1a14  #17130e
     全局色板  #3a2e12（金底深字）/ #17202a / #6b7280 / #ffffff
     rgba 底色 247,231,166 / 201,162,39 / 23,19,14 / 255,255,255（均已登记）

   为什么金晕写在 background-image 里：H5 自检按 getBoundingClientRect() 判横向溢出，
   绝对定位的金晕即使被 overflow:hidden 裁掉也会被判「超出视口」。
   ═══════════════════════════════════════════════════════════════════════════ */
/* ── 结构（三个候选共用）────────────────────────────────────────────────── */
.member-qr {
  position: relative;
  overflow: hidden;
  margin-top: var(--sp-3);
  padding: var(--sp-4) var(--sp-4) var(--sp-3);
  border-radius: var(--r-card);
  text-align: center;
}
.member-qr-head { position: relative; display: flex; align-items: center; justify-content: center; gap: var(--sp-2); }
.member-qr-crown { width: 26px; height: 26px; }
.member-qr-tag {
  display: inline-block;
  padding: 2px var(--sp-2);
  border-radius: var(--r-pill);
  font-size: 10px;
  font-weight: 800;
  letter-spacing: .12em;
}
.member-qr-title { position: relative; margin-top: var(--sp-2); font-size: var(--fs-title); font-weight: 800; line-height: 1.3; }
.member-qr-tier {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-top: var(--sp-2);
  font-size: var(--fs-sub);
}
.member-qr-tier-name { font-weight: 700; }
.member-qr-tier-tag {
  display: inline-block;
  padding: 1px var(--sp-2);
  border-radius: var(--r-pill);
  font-size: 10px;
  font-weight: 800;
}
.member-qr-tier-price { font-size: var(--fs-hero); font-weight: 800; line-height: 1; }
.member-qr-scanline { position: relative; display: flex; align-items: center; justify-content: center; gap: var(--sp-2); margin-top: var(--sp-4); }
.member-qr-scanline::before,
.member-qr-scanline::after { content: ''; flex: 1; height: 1px; }
.member-qr-scan { font-size: var(--fs-sub); font-weight: 700; letter-spacing: .06em; }
.member-qr-plate { display: inline-block; margin-top: var(--sp-3); padding: 8px; border-radius: var(--r-card); }
.member-qr-tile { display: block; padding: 10px; border-radius: var(--r-card-sm); background: #ffffff; }
/* 二维码本体：纯白底 + 不带描边（白边就是静默区，任何装饰都不许压进来） */
.member-qr-code { display: block; width: 168px; height: 168px; margin: 0; border: 0; border-radius: 0; background: #ffffff; }
/* 落地修正（设计意图是「二维码下方一条绶带」，设计稿镜像的桌面端会跟托盘并排；这里用
   display:block + 自动外边距钉成单独一行并居中，手机 / 桌面都一致）。 */
.member-qr-badge {
  display: block;
  width: fit-content;
  margin: var(--sp-3) auto 0;
  padding: 2px var(--sp-3);
  border-radius: var(--r-pill);
  font-size: 10px;
  font-weight: 800;
  letter-spacing: .1em;
}
.member-qr-status { position: relative; margin-top: var(--sp-3); }
.member-qr-guide { position: relative; }
.member-qr-note { position: relative; margin-top: var(--sp-2); font-size: var(--fs-sub); }
.member-qr-wait { position: relative; margin-top: var(--sp-4); }
.member-qr-actions { position: relative; margin-top: var(--sp-3); }
.member-qr-success {
  position: relative;
  overflow: hidden;
  margin-top: var(--sp-3);
  padding: var(--sp-5) var(--sp-4);
  border-radius: var(--r-card);
  text-align: center;
}
.member-qr-success-crown { width: 44px; height: 44px; margin: 0 auto; }
.member-qr-success-title { position: relative; margin-top: var(--sp-2); font-size: var(--fs-title); font-weight: 800; }
.member-qr-success .member-success { position: relative; margin-top: var(--sp-2); }
.member-qr-success-meta { position: relative; margin-top: var(--sp-2); font-size: var(--fs-sub); }

/* ── 候选 3「尊贵加冕」：黑金 + 金晕 + 金渐变托盘 + 双金环 + 会员绶带 ─────────── */
.member-qr.is-crown {
  border: 1px solid rgba(247, 231, 166, .9);
  background-image:
    radial-gradient(320px 320px at 50% -10%, rgba(247, 231, 166, .34) 0%, rgba(247, 231, 166, 0) 70%),
    radial-gradient(240px 240px at 100% 100%, rgba(201, 162, 39, .45) 0%, rgba(201, 162, 39, 0) 70%),
    linear-gradient(160deg, #1f1a14 0%, #17130e 100%);
  box-shadow: 0 18px 44px rgba(201, 162, 39, .45);
}
.member-qr.is-crown .member-qr-tag { background: linear-gradient(135deg, #f7e7a6 0%, #e8c86a 35%, #c9a227 100%); color: #3a2e12; }
.member-qr.is-crown .member-qr-title { color: #f7e7a6; font-size: 18px; letter-spacing: .02em; }
.member-qr.is-crown .member-qr-tier-name { color: rgba(255, 255, 255, .72); }
.member-qr.is-crown .member-qr-tier-tag { background: linear-gradient(135deg, #f7e7a6 0%, #e8c86a 35%, #c9a227 100%); color: #3a2e12; }
.member-qr.is-crown .member-qr-tier-price { color: #f7e7a6; }
.member-qr.is-crown .member-qr-tier-note { color: rgba(255, 255, 255, .72); }
.member-qr.is-crown .member-qr-scanline::before,
.member-qr.is-crown .member-qr-scanline::after { background: rgba(247, 231, 166, .9); }
.member-qr.is-crown .member-qr-scan { color: #f7e7a6; }
/* 金渐变托盘：金色是「底」，白底二维码压在金上，二维码四周仍是纯白（不动可扫性） */
.member-qr.is-crown .member-qr-plate {
  padding: 10px;
  background: linear-gradient(135deg, #f7e7a6 0%, #e8c86a 35%, #c9a227 100%);
  border-radius: 18px;
  box-shadow: 0 0 0 1px rgba(201, 162, 39, .9), 0 0 0 10px rgba(247, 231, 166, .28), 0 16px 34px rgba(23, 19, 14, .55);
}
.member-qr.is-crown .member-qr-tile { padding: 12px; border-radius: 12px; }
.member-qr.is-crown .member-qr-badge {
  background: linear-gradient(135deg, #f7e7a6 0%, #e8c86a 35%, #c9a227 100%);
  color: #3a2e12;
}
/* C1（2026-09-17 顾客反馈「引导句被二维码卡片压住」）：
   真因不在层叠顺序，而在 account.js 的等待态切换用 className 整体覆盖，把
   member-qr-status 这个 class 抹掉了 —— 白色文字规则随之失效，黑字落在黑金卡上，
   看起来就像被卡片压住。修法在 account.js（改用 classList 只切 is-waiting），
   这里再补两点可读性：引导句单独留出行高与左右安全内边距。 */
.member-qr.is-crown .member-qr-status { color: #ffffff; padding: 0 var(--sp-2); line-height: 1.55; }
.member-qr.is-crown .member-qr-status.is-waiting { color: #f7e7a6; }
.member-qr.is-crown .member-qr-guide { color: rgba(255, 255, 255, .72); }
.member-qr.is-crown .member-qr-note { color: rgba(255, 255, 255, .72); }
.member-qr.is-crown .login-wait-hint { color: rgba(255, 255, 255, .72); }
.member-qr.is-crown .login-waitbar { background: rgba(247, 231, 166, .18); }
.member-qr.is-crown .login-waitbar i {
  background-image: repeating-linear-gradient(90deg, #f7e7a6 0 10px, rgba(201, 162, 39, .35) 10px 20px);
}
.member-qr.is-crown .member-qr-actions .btn { background: rgba(247, 231, 166, .12); border-color: rgba(247, 231, 166, .45); color: #f7e7a6; }
.member-qr.is-crown .member-qr-success {
  border: 1px solid rgba(247, 231, 166, .9);
  background-image:
    radial-gradient(300px 300px at 50% -10%, rgba(247, 231, 166, .34) 0%, rgba(247, 231, 166, 0) 70%),
    linear-gradient(160deg, #1f1a14 0%, #17130e 100%);
  box-shadow: 0 18px 44px rgba(201, 162, 39, .45);
}
.member-qr.is-crown .member-qr-success-title { color: #f7e7a6; font-size: 18px; }
.member-qr.is-crown .member-success { color: #ffffff; }
.member-qr.is-crown .member-qr-success-meta { color: rgba(255, 255, 255, .72); }

/* ═══════════════════════════════════════════════════════════════════════════
   分享（P1）：设置弹层（H5 排版页）+ 分享提取页（share.html）
   色值 100% 走 tokens.css 的 var(--c-*)，零新增色（色值白名单不用改）。
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 分享设置弹层 ───────────────────────────────────────────── */
.share-box {
  max-width: 360px;
  max-height: 86vh;
  overflow-y: auto;
  text-align: left;
}
.share-title { font-size: var(--fs-title); font-weight: 800; color: var(--c-ink); }
.share-sub { margin-top: var(--sp-1); font-size: var(--fs-sub); color: var(--c-muted); }
.share-preview {
  margin-top: var(--sp-3);
  border-radius: var(--r-card-sm);
  background: var(--c-bg-soft);
  border: 1px solid var(--c-line);
  overflow: hidden;
}
.share-preview img { display: block; width: 100%; height: auto; max-height: 220px; object-fit: contain; }
.share-link {
  margin-top: var(--sp-1);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-card-sm);
  background: var(--c-bg-soft);
  border: 1px solid var(--c-line);
  color: var(--c-ink);
  font-size: var(--fs-sub);
  word-break: break-all;
}
.share-code { margin-top: var(--sp-2); font-size: var(--fs-body); color: var(--c-ink); font-weight: 600; }
.share-code b { color: var(--c-primary-ink); font-size: var(--fs-title); letter-spacing: 2px; }
.share-qr-wrap { margin-top: var(--sp-3); text-align: center; }
.share-qr {
  width: 160px;
  height: 160px;
  border-radius: var(--r-card-sm);
  background: var(--c-card);
  border: 1px solid var(--c-line);
}
#shareResult .field-label { margin-top: var(--sp-3); }

/* ── 分享提取页（share.html：独立页面，不走 app-shell）──────── */
.page-share { min-height: 100dvh; background: var(--c-bg); }
.page-share .content { max-width: 560px; margin: 0 auto; padding: var(--sp-4) var(--sp-page); }
.share-head { padding: var(--sp-4) 0 var(--sp-2); }
.share-brand { color: var(--c-ink); font-size: var(--fs-title); font-weight: 800; }
.share-brand small { display: block; margin-top: var(--sp-1); color: var(--c-muted); font-size: var(--fs-sub); font-weight: 400; }
.share-state { text-align: center; }
.share-state-title { color: var(--c-ink); font-size: var(--fs-title); font-weight: 700; }
.share-state-text { margin-top: var(--sp-2); color: var(--c-muted); font-size: var(--fs-body); }
.share-lock { text-align: center; }
.share-lock-hint { color: var(--c-ink); font-size: var(--fs-body); font-weight: 600; }
.share-code-input {
  margin-top: var(--sp-3);
  width: 100%;
  height: var(--h-cta);
  padding: 0 var(--sp-4);
  border-radius: var(--r-card-sm);
  border: 1px solid var(--c-line-strong);
  background: var(--c-card);
  color: var(--c-ink);
  font-size: var(--fs-hero);
  letter-spacing: 8px;
  text-align: center;
  font-family: inherit;
}
.share-tip { margin-top: var(--sp-2); color: var(--c-muted); font-size: var(--fs-sub); }
.share-source { margin-top: var(--sp-4); color: var(--c-faint); font-size: var(--fs-sub); }

/* ═══════════════════════════════════════════════════════════════════════════
   眼珠管理对齐（P2.4）+ 高级设置（P2.1，2026-09-17 顾客确认）
   色值 100% 走 tokens.css 的 var(--c-*)，零新增色值（色板白名单不用改）。
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 眼珠列表列数：由断点决定（2026-09-17 顾客真机实测后拍板）──
   手机（< 768px）一行 4 个、电脑（≥768px）一行 6 个（顾客实测「一列 6 个效果最好」）；
   不再有列数按钮与切换，列数也不进 localStorage（旧值一律忽略）。
   列数写在 class 上，优先级高于手机/桌面两条 auto-fill 规则。 */
.eyes.cols-4 { grid-template-columns: repeat(4, 1fr); }
.eyes.cols-6 { grid-template-columns: repeat(6, 1fr); }
.eyes.cols-6 .eye-thumb { padding: 4px 10px; }
.eyes.cols-6 .eye-move { width: 18px; font-size: 14px; }

/* ── 手机端（< 768px，与项目既有的 @media (min-width: 768px) 断点互补）──
   手机屏窄，格子必须更紧凑；即使 class 上残留 cols-6（旧缓存），也强制一行 4 个。 */
@media (max-width: 767px) {
  .eyes.cols-6 { grid-template-columns: repeat(4, 1fr); }
  .eyes.cols-4 .eye-thumb,
  .eyes.cols-6 .eye-thumb { padding: 4px 10px; }
  .eyes.cols-6 .eye-move { width: 20px; font-size: 14px; }
}

/* ── 批量管理模式：勾选角标 + 批量操作条（全选 / 复制 / 删除）──
   批量模式下逐只操作键与序号收起（与小程序管理态一致），只留缩略图 + 勾选。 */
.eye-cell.is-manage { cursor: pointer; }
.eye-cell.is-selected { border-color: var(--c-primary); box-shadow: var(--c-shadow-card); }
.eye-cell.is-manage .eye-move,
.eye-cell.is-manage .eye-ops,
.eye-cell.is-manage .eye-order { display: none; }
.eye-check {
  position: absolute;
  top: 6px;
  right: 6px;
  z-index: 3;
  width: 22px;
  height: 22px;
  border-radius: var(--r-card-sm);
  border: 1px solid var(--c-line-strong);
  background: var(--c-card);
  color: var(--c-card);
  font-size: 14px;
  font-weight: 700;
  line-height: 20px;
  text-align: center;
}
.eye-check.is-on { border-color: var(--c-primary); background: var(--c-primary); }
.batch-bar { display: flex; gap: var(--sp-2); margin-top: var(--sp-3); }
.batch-bar .btn { flex: 1; min-height: var(--h-touch); padding: 0 var(--sp-2); font-size: var(--fs-sub); }

/* ── 高级设置弹层（浅色；分组与收纳方式照小程序的「高级设置」弹层）── */
.advanced-box { max-width: 360px; max-height: 86vh; overflow-y: auto; text-align: left; }
.advanced-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-2); }
.advanced-close {
  flex: none;
  width: var(--h-touch);
  height: var(--h-touch);
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--c-muted);
  font-family: inherit;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
}
.group-title {
  margin: var(--sp-4) 0 var(--sp-1);
  padding-left: var(--sp-2);
  border-left: 3px solid var(--c-primary);
  color: var(--c-ink);
  font-size: var(--fs-body);
  font-weight: 700;
}
.switch-row-copy { display: flex; flex-direction: column; gap: 2px; }

/* ── 我的分享（P3，账号管理里的一块）──
   一条分享一行：左边缩略图，右边短码 / 有没有提取码 / 剩余天数 / 下载次数 / 创建时间，
   下面一行操作（复制链接 / 撤回 / 延长）。过期与撤回的行保留可见但复制、延长禁用。
   配色全部走既有令牌，不新增色值。 */
.my-share {
  margin-top: var(--sp-5);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--c-line);
}
.my-share-state {
  margin-top: var(--sp-3);
  font-size: var(--fs-sub);
  color: var(--c-muted);
}
.my-share-list {
  display: grid;
  gap: var(--sp-3);
  margin-top: var(--sp-3);
  list-style: none;
}
.my-share-item {
  display: grid;
  grid-template-columns: 64px 1fr;
  gap: var(--sp-3);
  padding: var(--sp-3);
  border: 1px solid var(--c-line);
  border-radius: var(--r-card);
  background: var(--c-card);
}
.my-share-item.is-off { background: var(--c-bg-soft); }
.my-share-thumb {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  overflow: hidden;
  border: 1px solid var(--c-line);
  border-radius: var(--r-card-sm);
  background: var(--c-bg-soft);
}
.my-share-thumb img { width: 100%; height: 100%; object-fit: contain; }
.my-share-thumb-text {
  padding: 0 var(--sp-1);
  color: var(--c-faint);
  font-size: 10px;
  line-height: 1.4;
  text-align: center;
}
.my-share-head { display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-1); }
.my-share-code {
  color: var(--c-ink);
  font-size: var(--fs-body);
  font-weight: 700;
  letter-spacing: .06em;
}
.my-share-tag {
  padding: 1px var(--sp-2);
  border-radius: var(--r-pill);
  background: var(--c-info-soft);
  color: var(--c-info-ink);
  font-size: 10px;
  font-weight: 700;
}
.my-share-badge {
  padding: 1px var(--sp-2);
  border-radius: var(--r-pill);
  background: var(--c-slate-soft);
  color: var(--c-slate-ink);
  font-size: 10px;
  font-weight: 700;
}
.my-share-badge.is-warn { background: var(--c-warn-soft); color: var(--c-warn); }
.my-share-badge.is-danger { background: var(--c-danger-soft); color: var(--c-danger); }
.my-share-meta { margin-top: 2px; font-size: var(--fs-sub); color: var(--c-muted); }
.my-share-actions {
  grid-column: 1 / -1;
  display: flex;
  gap: var(--sp-2);
  margin-top: var(--sp-2);
}
.my-share-actions .btn {
  flex: 1;
  width: auto;
  padding: 0 var(--sp-2);
  font-size: var(--fs-sub);
}
.my-share-extend { grid-column: 1 / -1; margin-top: var(--sp-2); }
.my-share-extend-hint { margin-bottom: var(--sp-2); font-size: var(--fs-sub); color: var(--c-muted); }

/* ═══════════════════════════════════════════════════════════════════════════
   眼柄库（P4，2026-09-19）：与小程序 pages/library/* 同一套观感与交互。
   色值全部走 tokens.css 的既有变量（零新增字面色值，静态检查会拦）：
     · 容量条 / 分组封面 / 「对」卡片 / 候选网格 = 浅色业务页那一套（与眼珠列表同一气质）；
     · 危险操作（删除、删组）走 --c-danger / --c-danger-soft；
     · 容量快满的提示走 --c-warn / --c-warn-soft（与小程序 lib-quota-warn 同一语义）。
   「对」＝两只挨着显示在同一个卡片里（底层仍是单个素材，不绑定关系）。
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 库首页：容量条 ─────────────────────────────────────────────── */
.lib-quota-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  margin-bottom: var(--sp-2);
}
.lib-quota-used { margin-top: 0; }
.lib-quota-tag {
  flex: none;
  padding: 1px var(--sp-2);
  border-radius: var(--r-pill);
  background: var(--c-info-soft);
  color: var(--c-info-ink);
  font-size: 10px;
  font-weight: 700;
}
.lib-quota-track {
  height: 8px;
  overflow: hidden;
  border-radius: var(--r-pill);
  background: var(--c-slate-soft);
}
.lib-quota-fill {
  display: block;
  height: 100%;
  width: 0;
  border-radius: var(--r-pill);
  background: var(--c-info);
}
/* 容量快满 / 已满：给「清理腾空间」入口（与小程序 .lib-quota-warn 同一语义） */
.lib-quota-warn {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-top: var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--c-warn-line);
  border-radius: var(--r-card-sm);
  background: var(--c-warn-soft);
}
.lib-quota-warn-text { flex: 1; min-width: 0; color: var(--c-warn); font-size: var(--fs-sub); line-height: 1.5; }
.lib-quota-warn-btn { flex: none; width: auto; min-height: var(--h-touch); margin: 0; padding: 0 var(--sp-3); font-size: var(--fs-sub); }

.lib-state { margin-top: var(--sp-3); color: var(--c-muted); font-size: var(--fs-sub); }
.lib-empty { text-align: center; }
/* 库首页的主 CTA：上传眼柄（与小程序 .lib-primary 同一位置：标题区下面） */
.lib-primary-row { margin-top: var(--sp-3); }

/* ── 我的分组：一行 3 个卡片（封面 + 组名 + 只数）────────────────── */
.lib-groups { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-2); margin-top: var(--sp-3); }
.lib-group {
  padding: var(--sp-2);
  border: 1px solid var(--c-line);
  border-radius: var(--r-card-sm);
  background: var(--c-card);
  cursor: pointer;
}
.lib-group:active { background: var(--c-bg-soft); }
.lib-group-cover {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  aspect-ratio: 1 / 1;
  min-height: 64px;
  overflow: hidden;
  border: 1px solid var(--c-line);
  border-radius: var(--r-card-sm);
  background: var(--c-bg-soft);
  color: var(--c-faint);
  font-size: var(--fs-sub);
}
/* 封面必须完整显示整只眼珠：缩略图是等比白底图，容器是正方形，
   object-fit: cover 会把长边裁掉一圈（顾客 2026-09-24 反馈「放大后不完整」）。 */
.lib-group-img { width: 100%; height: 100%; object-fit: contain; }
.lib-group-name {
  margin-top: var(--sp-2);
  color: var(--c-ink);
  font-size: var(--fs-sub);
  font-weight: 700;
  line-height: 1.3;
  word-break: break-all;
}
.lib-group-count { margin-top: 2px; color: var(--c-faint); font-size: 10px; line-height: 1.3; }

/* ── 「未分组 / 全部眼柄」入口 ───────────────────────────────────── */
.lib-entry {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  width: 100%;
  min-height: var(--h-touch);
  margin-top: var(--sp-2);
  padding: var(--sp-3);
  border: 1px solid var(--c-line);
  border-radius: var(--r-card-sm);
  background: var(--c-card);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}
.lib-entry:active { background: var(--c-bg-soft); }
.lib-entry-copy { flex: 1; min-width: 0; display: block; }
.lib-entry-title { display: block; color: var(--c-ink); font-size: var(--fs-body); font-weight: 700; line-height: 1.25; }
.lib-entry-desc { display: block; margin-top: 2px; color: var(--c-faint); font-size: var(--fs-sub); line-height: 1.3; }
.lib-entry-arrow { flex: none; color: var(--c-faint); font-size: 20px; line-height: 1; }

.lib-head-actions { display: flex; align-items: center; gap: var(--sp-2); }

/* ── 眼柄网格：手机一行 4 个、电脑一行 6 个（与眼珠列表同一套断点口径）── */
.lib-grid { display: grid; gap: var(--sp-2); margin-top: var(--sp-3); }
.lib-grid.cols-4 { grid-template-columns: repeat(4, 1fr); }
.lib-grid.cols-6 { grid-template-columns: repeat(6, 1fr); }
.lib-cell {
  position: relative;
  overflow: hidden;
  aspect-ratio: 1 / 1;
  min-height: 60px;
  border: 1px solid var(--c-line-strong);
  border-radius: var(--r-card-sm);
  background: var(--c-bg-soft);
  cursor: pointer;
}
/* 「对」＝两只挨着显示：跨两列，中间一条虚线分隔（不绑定、可分别删改） */
.lib-cell.is-pair { grid-column: span 2; aspect-ratio: 2 / 1; }
.lib-cell.is-on { border-color: var(--c-info); background: var(--c-info-soft); }
/* 拖动中的那一格（与眼珠列表的 .is-dragging 同一套观感） */
.lib-cell.is-dragging { border-color: var(--c-primary); box-shadow: var(--c-shadow-float); opacity: .92; }
.lib-thumbs { display: flex; width: 100%; height: 100%; }
.lib-thumb {
  position: relative;
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.lib-cell.is-pair .lib-thumb + .lib-thumb { border-left: 1px dashed var(--c-info-line); }
.lib-thumb-img { width: 100%; height: 100%; object-fit: contain; }
.lib-thumb-failed { color: var(--c-faint); font-size: 10px; }
.lib-check {
  position: absolute;
  top: 2px;
  left: 2px;
  z-index: 2;
  width: 16px;
  height: 16px;
  box-sizing: border-box;
  border: 2px solid var(--c-card);
  border-radius: var(--r-pill);
  background: rgba(17, 24, 39, .34);
  color: var(--c-card);
  font-size: 10px;
  font-weight: 700;
  line-height: 12px;
  text-align: center;
}
.lib-cell.is-on .lib-check { background: var(--c-primary); }
.lib-pair-tag {
  position: absolute;
  right: 2px;
  bottom: 2px;
  z-index: 2;
  padding: 0 var(--sp-1);
  border-radius: var(--r-pill);
  background: rgba(17, 24, 39, .58);
  color: var(--c-card);
  font-size: 10px;
  line-height: 14px;
}
.lib-cell-badge {
  position: absolute;
  left: 2px;
  bottom: 2px;
  z-index: 2;
  padding: 0 var(--sp-1);
  border-radius: var(--r-pill);
  background: var(--c-warn-soft);
  color: var(--c-warn);
  font-size: 10px;
  line-height: 14px;
}

/* ── 多选操作条（管理态）──────────────────────────────────────── */
.lib-bar {
  position: sticky;
  bottom: 0;
  z-index: 5;
  margin-top: var(--sp-3);
  padding: var(--sp-3);
  border: 1px solid var(--c-line);
  border-radius: var(--r-card);
  background: var(--c-card);
  box-shadow: var(--c-shadow-float);
}
.lib-bar-count { color: var(--c-ink); font-size: var(--fs-sub); font-weight: 700; }
.lib-bar-row { display: flex; gap: var(--sp-2); margin-top: var(--sp-2); }
.lib-bar-btn { flex: 1; width: auto; min-height: var(--h-touch); padding: 0 var(--sp-1); font-size: var(--fs-sub); }

/* ── 上传眼柄（两步式：选图 → 候选择）──────────────────────────── */
.lib-upload, .lib-filter { margin-top: var(--sp-4); }
.lib-upload-list { display: grid; gap: var(--sp-1); margin-top: var(--sp-2); }
.lib-upload-row { display: flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-sub); }
.lib-upload-name { flex: 1; min-width: 0; color: var(--c-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lib-upload-state { flex: none; color: var(--c-muted); }
.lib-upload-state.is-failed { color: var(--c-danger); }
.lib-upload-remove {
  flex: none;
  min-height: var(--h-touch);
  padding: 0 var(--sp-2);
  border: 1px solid var(--c-line-strong);
  border-radius: var(--r-card-sm);
  background: var(--c-card);
  color: var(--c-slate-ink);
  font-family: inherit;
  font-size: var(--fs-sub);
  cursor: pointer;
}
.lib-upload-remove:disabled { opacity: var(--op-disabled); cursor: default; }

/* ── 移组弹层与分组名输入（复用 .overlay/.dialog，只补两个小组件）── */
.lib-sheet { display: grid; gap: var(--sp-2); margin-top: var(--sp-3); max-height: 50vh; overflow-y: auto; }
.lib-sheet-title { color: var(--c-ink); font-weight: 700; }
.lib-sheet-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  width: 100%;
  min-height: var(--h-touch);
  padding: 0 var(--sp-3);
  border: 1px solid var(--c-line);
  border-radius: var(--r-card-sm);
  background: var(--c-bg-soft);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}
.lib-sheet-name { color: var(--c-ink); font-size: var(--fs-body); font-weight: 600; }
.lib-sheet-count { color: var(--c-faint); font-size: var(--fs-sub); }
.lib-name-input {
  width: 100%;
  min-height: var(--h-touch);
  margin-top: var(--sp-3);
  padding: 0 var(--sp-3);
  border: 1px solid var(--c-line-strong);
  border-radius: var(--r-card-sm);
  background: var(--c-card);
  color: var(--c-ink);
  font-family: inherit;
  font-size: var(--fs-body);
}

/* ── 排版页「从眼柄库上传」选材弹层 ───────────────────────────── */
.lib-picker-box { text-align: left; }
.lib-chips { margin-top: var(--sp-3); }
.lib-picker-count { margin-top: var(--sp-3); color: var(--c-ink); font-weight: 700; }

@media (max-width: 767px) {
  /* 手机：分组一行 3 个已够；网格 6 列一律兜底成 4 列（与眼珠列表同一条兜底规则） */
  .lib-grid.cols-6 { grid-template-columns: repeat(4, 1fr); }
}


