/* ============================================================================
   shop.css —— 卡套 · 周边 · 预定（shop.html 专用）
   ----------------------------------------------------------------------------
   2026-10-19 用户：「制作一个卡套、周边、预定的商店…美术在线，排版优美直观」。

   设计口径：
     · 图优先：有真实原画的（卡套 / 桌垫 / 整盒）用图；没有的就用**字形 + 品牌底**，
       绝不摆破图或假照片（`.shop-ph` 那一档）。
     · 一屏能扫完：卡片 4 列（大屏）/ 3 列 / 2 列，图区固定高度，标题两行截断，
       价格与状态永远在同一个位置 —— 找东西时眼睛不用来回跳。
     · 只用品牌变量（--gold / --ink-* / --brand-2），不新增硬编码颜色。
   ========================================================================== */

.shoppage { padding-bottom: 60px; }

/* ── 头部：标题 + 一句话 + 三档数量 ───────────────────────────────── */
.shop-hero { display: flex; align-items: flex-end; gap: 18px; flex-wrap: wrap;
  padding: 6px 0 18px; border-bottom: 1px solid var(--ink-4); }
.shop-hero h1 { margin: 0; font-size: 24px; line-height: 1.3; color: var(--text); letter-spacing: .5px; }
.shop-hero h1 em { font-style: normal; color: var(--gold-ink); }
.shop-hero p { margin: 6px 0 0; font-size: 12.5px; line-height: 1.7; color: var(--text-3); }
.shop-hero .shop-stat { margin-left: auto; display: flex; gap: 22px; }
.shop-stat span { display: flex; flex-direction: column; gap: 2px; }
.shop-stat i { font-style: normal; font-size: 11px; color: var(--text-3); }
.shop-stat b { font-size: 18px; color: var(--gold-ink); font-weight: 800; }

/* ── 分类：**方块**（项目铁律：二级导航一律块状，不做一条文字行）──────────
   2026-10-22 用户圈图：「这里要注意对齐」——
   原来右侧「搜索 + 排序」只有 36px 高，被垂直居中吊在 68px 的分类块中间，
   上下各空 15px，看着像两排没对齐的东西。现在整条 bar 统一一套高度：
     · `.shop-bar` 用 align-items:stretch（子项都撑满 68）；
     · `.shop-tools` 改成**两行竖排**（搜索 30 + 8 间隙 + 排序 30 = 68），
       左缘、上下缘与分类块严格对齐，中间不再留空；
     · `.shop-tabs` 从 `repeat(4, 1fr)` 改成 `grid-auto-flow:column` —— 分类数由
       收卡端数据决定（4 个 + 后加的「单卡」跳转块 = 5），写死列数会在加减分类时错位。 */
.shop-bar { display: flex; align-items: stretch; gap: 12px; flex-wrap: wrap; margin: 16px 0 16px; }
.shop-tabs { flex: 1 1 640px; display: grid; grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr); gap: 10px; }
/* 分类块 = **一行**：图标 + 名称 + 数量，垂直居中（2026-10-22 用户：「我说的是要一行一行对齐！
   你这文字往上飘了，下面空着留着干嘛」）
   🔴 上一版是 `grid-template-rows: auto auto` + 图标跨两行：那两行是给"方块下面那句说明"
      （`.shop-blk-n`）留的，而说明 2026-10-21 已被用户删掉 —— 第二行就空了，
      于是文字贴着块顶、图标居中、底下空出小半块。现在改成单行 flex + `align-items:center`：
      图标与文字中心线对齐，上下留白相等，五个块的字都在同一条基线上。 */
.shop-blk { position: relative; appearance: none; cursor: pointer; font: inherit; text-align: left;
  display: flex; align-items: center; gap: 10px;
  min-height: 68px; padding: 0 13px; border-radius: 12px;
  color: var(--text-2); background: var(--ink-2); border: 1px solid var(--ink-4);
  transition: border-color .16s, background .16s, transform .16s; }
.shop-blk:hover { border-color: rgba(255,224,0,.5); background: var(--ink-3); transform: translateY(-2px); }
/* 图标固定 28px 宽并居中：✦ 只有 16px、🎴/🧩/📦/🃏 是 27.5px，
   不钉宽度的话每个块的**文字起点会差 11px**（"全部"贴左、"卡套"右移），
   五块排在一起就不是一条竖线了 —— 2026-10-22「一行一行对齐」的另一半就是这条。 */
.shop-blk-ic {
  flex: none; width: 28px; height: 20px;
  display: flex; align-items: center; justify-content: center;
  font-size: 18px; line-height: 1;
}
.shop-blk-t {
  display: flex; align-items: baseline; gap: 6px;
  min-width: 0; font-size: 13.5px; font-weight: 700; line-height: 1.3; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.shop-blk-t i { flex: none; font-style: normal; font-size: 11.5px; font-weight: 700; color: var(--text-3); }
.shop-blk.on { border-color: var(--gold); background: rgba(255,224,0,.07); }
.shop-blk.on .shop-blk-t, .shop-blk.on .shop-blk-t i { color: var(--gold-ink); }
/* 选中态：顶边一条金线（方块的"选中"用块本身表达，不靠药丸底色） */
.shop-blk.on::before { content: ""; position: absolute; left: 12px; right: 12px; top: -1px; height: 2px;
  border-radius: 0 0 2px 2px; background: var(--gold); }
/* 「单卡」跳转块（2026-10-22）：和分类块同宽同高，但不是筛选 —— 用右上角箭头 + 悬停位移区分。
   它是 <a>，所以要抹掉链接的下划线与蓝色，鼠标指针也保持手型。 */
.shop-blk-go { text-decoration: none; }
.shop-blk-go-arrow { position: absolute; right: 10px; bottom: 8px; font-size: 13px;
  color: var(--text-3); transition: transform .16s, color .16s; }
.shop-blk-go:hover .shop-blk-go-arrow { transform: translateX(3px); color: var(--gold-ink); }

/* 工具区：只剩搜索框（排序控件 2026-10-22 删除 —— 见 shop.html 的注释）。
   它仍然撑满整个 68px，与分类块同高、上下缘齐平 —— 对齐口径没变，
   只是把一个空盒子做成了"搜索条"：左侧放大镜 + 稍大的字号，不然 68px 高会显得空。 */
.shop-tools { margin-left: auto; flex: 0 0 320px; display: flex; flex-direction: column; gap: 8px; }
.shop-search {
  flex: 1 1 0; width: 100%; min-height: 28px; padding: 4px 14px 4px 40px;
  font: inherit; font-size: 13.5px;
  color: var(--text); background: var(--ink-3); border: 1px solid var(--ink-4); border-radius: 8px;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-3.6-3.6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: 14px 50%; background-size: 17px 17px; }
.shop-search::placeholder { color: var(--text-3); }
.shop-search:focus { outline: none; border-color: var(--gold); }

/* ── 网格 ───────────────────────────────────────────────────────── */
.shop-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(216px, 1fr)); gap: 14px; }

/* ── 商品卡 ─────────────────────────────────────────────────────── */
.shop-card { position: relative; display: flex; flex-direction: column;
  background: var(--ink-2); border: 1px solid var(--ink-4); border-radius: 14px;
  overflow: hidden; transition: border-color .18s, transform .18s, box-shadow .18s; }
.shop-card:hover {
  border-color: rgba(255, 224, 0, .82);
  transform: translateY(-3px);
  box-shadow: 0 16px 34px rgba(0,0,0,.42), inset 0 0 0 1px rgba(255,224,0,.18);
}

.shop-art {
  position: relative;
  /* 2026-10-24 设计返工：原来定高 208px（≈1:1），而卡套是**竖版 5:7** ——
     `cover` 会上下各切掉一截，图案只剩中间一段。改成 4:5 容器 + cover 居中，
     裁切从约 30% 降到 10% 以内；横版补充包仍走 `.is-wide` 的 contain。 */
  aspect-ratio: 4 / 5;
  height: auto;
  background: var(--ink-3);
  overflow: hidden;
}
.shop-art img { width: 100%; height: 100%; object-fit: cover; object-position: center 30%;
  display: block; transition: transform .35s ease; }
/* 横版横幅（补充包 banner）：cover 会把它裁成一条竖缝，改用 contain 保住整张图 */
.shop-art.is-wide { background: var(--ink-2); }
.shop-art.is-wide img { object-fit: contain; object-position: center; }
.shop-card:hover .shop-art img { transform: scale(1.04); }
/* 图上盖一层由下往上的暗角，保证角标与"售罄"可读 */
.shop-art::after { content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(0,0,0,.28) 0%, rgba(0,0,0,0) 34%, rgba(0,0,0,.30) 100%); }

/* 无图商品：字形 + 品牌底（不摆假照片） */
.shop-ph { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: 62px; line-height: 1; }
.shop-ph.tone-gold { color: var(--gold-ink); background:
  radial-gradient(120% 90% at 30% 10%, rgba(255,224,0,.20), rgba(255,224,0,0) 62%),
  linear-gradient(150deg, var(--ink-3), var(--ink-2)); }
.shop-ph.tone-teal { color: #5fd8c4; background:
  radial-gradient(120% 90% at 30% 10%, rgba(95,216,196,.20), rgba(95,216,196,0) 62%),
  linear-gradient(150deg, var(--ink-3), var(--ink-2)); }
.shop-ph.tone-violet { color: #b79bff; background:
  radial-gradient(120% 90% at 30% 10%, rgba(183,155,255,.20), rgba(183,155,255,0) 62%),
  linear-gradient(150deg, var(--ink-3), var(--ink-2)); }
.shop-ph.tone-red { color: #ff8f8f; background:
  radial-gradient(120% 90% at 30% 10%, rgba(255,143,143,.18), rgba(255,143,143,0) 62%),
  linear-gradient(150deg, var(--ink-3), var(--ink-2)); }

/* 角标 / 售罄 / 价签 */
.shop-badge { position: absolute; left: 10px; top: 10px; z-index: 2;
  padding: 2px 9px; border-radius: 999px; font-size: 11px; font-weight: 700;
  color: var(--on-accent); background: var(--gold); }
.shop-badge.pre { background: #b79bff; }
.shop-badge.ask { background: var(--ink-3); color: var(--text-2); border: 1px solid var(--ink-4); }
.shop-out { position: absolute; inset: 0; z-index: 2; display: flex; align-items: center; justify-content: center;
  font-size: 13px; letter-spacing: 2px; color: rgba(255,255,255,.85);
  background: rgba(10,10,11,.54); backdrop-filter: blur(1px); }

.shop-info { display: flex; flex-direction: column; gap: 5px; padding: 12px 13px 13px; flex: 1 1 auto; }
.shop-name { font-size: 13.5px; line-height: 1.45; color: var(--text); font-weight: 700;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.shop-sub { font-size: 11.5px; color: var(--text-3); }
/* `.shop-note` 随商品卡那行描述一起删了 —— 2026-10-21「只删商品卡小字」。
   数据里的 note 还在（发布层产物勿手改）；要恢复就在 shop.html 的 cardHtml 里把那行加回来。 */

.shop-foot { display: flex; align-items: center; gap: 8px; margin-top: auto; padding-top: 8px; }
.shop-price { display: flex; align-items: baseline; gap: 6px; margin-right: auto; }
.shop-price b { font-size: 17px; font-weight: 800; color: var(--gold-ink); letter-spacing: .3px; }
.shop-price b i { font-style: normal; font-size: 12px; margin-right: 1px; }
.shop-price s { font-size: 11px; color: var(--text-3); }
.shop-price .ask { font-size: 13px; color: var(--text-2); font-weight: 700; }
.shop-price .ask em { font-style: normal; font-size: 11px; color: var(--text-3); }
/* 预定 = 尾款形式：主行「定金 ¥86」，副行「尾款 ¥344 · 合计 ¥430」 */
.shop-price.pre { flex-direction: column; align-items: flex-start; gap: 1px; }
.shop-price.pre .pp-main { display: flex; align-items: baseline; gap: 5px; }
.shop-price.pre .pp-main em { font-style: normal; font-size: 10.5px; color: var(--text-3); }
.shop-price.pre .pp-sub { font-size: 10.5px; color: var(--text-3); line-height: 1.3; }

.shop-buy { appearance: none; cursor: pointer; font: inherit; font-size: 12px; font-weight: 700;
  padding: 7px 13px; border-radius: 8px; white-space: nowrap;
  color: var(--on-accent); background: var(--gold); border: 1px solid var(--gold);
  transition: filter .15s, background .15s, color .15s; }
.shop-buy:hover { filter: brightness(1.08); }
.shop-buy.pre { background: transparent; color: #b79bff; border-color: rgba(183,155,255,.55); }
.shop-buy.pre:hover { background: rgba(183,155,255,.12); }
.shop-buy.done { background: transparent; color: #5fd8c4; border-color: rgba(95,216,196,.5); cursor: default; }
.shop-buy:disabled { background: var(--ink-3); border-color: var(--ink-4); color: var(--text-3); cursor: not-allowed; }

.shop-empty { grid-column: 1 / -1; padding: 60px 10px; text-align: center;
  font-size: 13px; color: var(--text-3); }

/* ── 底部说明 ────────────────────────────────────────────────────── */
.shop-foot-note { margin: 26px 0 0; padding: 13px 15px; border-radius: 10px;
  font-size: 11.5px; line-height: 1.85; color: var(--text-3);
  background: var(--ink-3); border: 1px solid var(--ink-4); border-left: 3px solid var(--brand-2); }
.shop-foot-note b { color: var(--text-2); }

/* ── 我的预定（mypre.html）──────────────────────────────────────────
   与商品卡同一套视觉：左图右字，定金金色、尾款与登记时间是灰小字。 */
.pre-hero { padding: 2px 0 16px; border-bottom: 1px solid var(--ink-4); margin-bottom: 16px; }
.pre-hero h1 { margin: 0; font-size: 22px; line-height: 1.3; color: var(--text); }
.pre-hero p { margin: 6px 0 12px; font-size: 12.5px; line-height: 1.7; color: var(--text-3); }
.pre-hero p b { color: var(--text-2); }
.pre-stat { display: flex; gap: 26px; flex-wrap: wrap; }
.pre-stat span { display: flex; flex-direction: column; gap: 2px; }
.pre-stat i { font-style: normal; font-size: 11px; color: var(--text-3); }
.pre-stat b { font-size: 18px; font-weight: 800; color: var(--gold-ink); }

.pre-list { display: flex; flex-direction: column; gap: 10px; }
.pre-item { display: flex; align-items: center; gap: 14px; padding: 12px;
  background: var(--ink-2); border: 1px solid var(--ink-4); border-radius: 12px;
  transition: border-color .15s; }
.pre-item:hover { border-color: rgba(255,224,0,.30); }
.pre-art { position: relative; flex: none; width: 62px; height: 86px; border-radius: 6px;
  overflow: hidden; background: var(--ink-3); }
.pre-art img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* 横幅类商品（补充包）：40×56 的小框里 cover 会只剩一条缝，改用 contain 保完整 */
.pre-art.is-wide { background: var(--ink-2); }
.pre-art.is-wide img { object-fit: contain; }
.pre-art .shop-ph { font-size: 26px; }
.pre-info { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pre-name { font-size: 14px; line-height: 1.4; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pre-sub { font-size: 11.5px; color: var(--text-3); }
.pre-money { display: flex; align-items: baseline; gap: 6px; margin-top: 3px; flex-wrap: wrap; }
.pre-money em { font-style: normal; font-size: 10.5px; color: var(--text-3); }
.pre-money b { font-size: 16px; font-weight: 800; color: var(--gold-ink); }
.pre-money span { font-size: 11px; color: var(--text-3); }
.pre-money .pre-ask { font-size: 12px; color: var(--text-2); font-weight: 700; }
.pre-at { font-size: 10.5px; color: var(--text-3); font-variant-numeric: tabular-nums; }
.pre-act { flex: none; display: flex; flex-direction: column; gap: 6px; }
.pre-go, .pre-cancel { appearance: none; cursor: pointer; font: inherit; font-size: 12px;
  text-align: center; padding: 6px 12px; border-radius: 8px; white-space: nowrap; }
.pre-go { color: var(--text-2); background: var(--ink-3); border: 1px solid var(--ink-4); text-decoration: none; }
.pre-go:hover { border-color: var(--gold); color: var(--gold-ink); }
.pre-cancel { color: #ff8f8f; background: transparent; border: 1px solid rgba(255,143,143,.4); }
.pre-cancel:hover { background: rgba(255,143,143,.10); border-color: rgba(255,143,143,.7); }

.pre-empty { padding: 56px 20px; text-align: center; border-radius: 14px;
  background: var(--ink-2); border: 1px solid var(--ink-4); }
.pre-empty-ic { font-size: 40px; line-height: 1; margin-bottom: 10px; }
.pre-empty b { display: block; font-size: 15px; color: var(--text); margin-bottom: 6px; }
.pre-empty p { margin: 0; font-size: 12.5px; line-height: 1.9; color: var(--text-3); }
.pre-empty a { color: var(--gold-ink); }

/* ── 我的预定 · 卡片墙（2026-10-26 店主：「这里不是卡牌形式展示」）───────────
   原来是"一行一条"的横条（图 + 文字 + 按钮），在 1080 宽的大窗口里一行只有一条、
   右边留一大片空 —— 店主圈的就是这个。改成**方块网格**：一行 2–5 张，形状随窗口。
   🔴 只挂在 `.pre-cards` 上：myrecall / vip 也复用 `.pre-item` 那套行版式，
      不能因为这一页改版把另两页一起改掉。 */
.pre-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(168px, 1fr));
  gap: 12px;
  align-items: stretch;
}
.pre-cards .pre-item {
  flex-direction: column;
  align-items: stretch;
  gap: 7px;
  padding: 9px;
  border-radius: 12px;
}
.pre-cards .pre-art {
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;          /* 商品图多为方图/横幅：4:3 比 5:7 更少裁掉内容 */
  border-radius: 8px;
}
.pre-cards .pre-art img { object-fit: cover; }
.pre-cards .pre-art.is-wide img { object-fit: contain; }
.pre-cards .pre-info { gap: 3px; }
/* 名字最多两行 —— 一行会截成「BP19 补充包…」，两行能看出是什么盒子 */
.pre-cards .pre-name {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  white-space: normal;
  overflow: hidden;
  font-size: 12.5px;
  line-height: 1.4;
  min-height: 2.8em;
}
.pre-cards .pre-sub { font-size: 10.5px; line-height: 1.5; }
.pre-cards .pre-money { margin-top: 2px; gap: 4px; }
.pre-cards .pre-money b { font-size: 14px; }
.pre-cards .pre-money span { font-size: 10px; }
.pre-cards .pre-at { font-size: 10px; line-height: 1.5; }
/* 操作区贴底：卡高不一时按钮仍在同一条线上 */
.pre-cards .pre-act {
  flex-direction: row;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: auto;
}
.pre-cards .pre-act > [data-pay] { flex: 1 1 100%; }         /* 主操作独占一行 */
.pre-cards .pre-act > .pre-cancel,
.pre-cards .pre-act > .pre-go { flex: 1 1 calc(50% - 3px); } /* 次操作并排 */
.pre-cards .pre-go, .pre-cards .pre-cancel { padding: 6px 8px; font-size: 11.5px; }

@media (max-width: 720px) {
  .pre-item { align-items: flex-start; flex-wrap: wrap; gap: 10px; }
  .pre-art { width: 52px; height: 72px; }
  .pre-act { flex-direction: row; width: 100%; }
  .pre-act > * { flex: 1 1 0; }
  .pre-stat { gap: 18px; }
  /* 卡片墙在手机上 2 列（上面的 .pre-art 固定 52×72 是"行版式"用的，这里必须收回来） */
  .pre-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .pre-cards .pre-item { align-items: stretch; flex-wrap: nowrap; }
  .pre-cards .pre-art { width: 100%; height: auto; aspect-ratio: 4 / 3; }
}

@media (max-width: 720px) {
  .shop-hero h1 { font-size: 20px; }
  .shop-hero .shop-stat { margin-left: 0; gap: 16px; }
  /* 方块在手机上 2×2（+「单卡」落单一行），块本身还是方块（不退回一条文字行）。
     ⚠️ 这里必须把 grid-auto-flow 改回 row：PC 用的是 column（分类数不固定），
        手机要用「2 列多行」，不改的话第 3 块会往右边长出新列、整排被撑出屏幕。 */
  .shop-tabs { flex-basis: 100%; grid-auto-flow: row; grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-auto-columns: auto; gap: 8px; }
  .shop-blk { min-height: 62px; padding: 0 11px; }
  .shop-blk-ic { font-size: 17px; }
  /* 「单卡」是第 5 块，2 列会落单在第三行左边、右边空一格 —— 让它横跨整行当"去卡库"的宽条 */
  .shop-blk-go { grid-column: 1 / -1; }
  /* 手机上工具区回到单行（搜索框 36 高），本来就只有它一个了 */
  .shop-tools { width: 100%; margin-left: 0; flex: 0 0 auto; flex-direction: row; gap: 8px; }
  .shop-search { flex: 1 1 auto; width: auto; height: 36px; min-height: 36px; padding: 6px 12px 6px 38px; }
  .shop-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
  .shop-art { aspect-ratio: 4 / 5; height: auto; }
  .shop-ph { font-size: 44px; }
  .shop-name { font-size: 12.5px; }
  .shop-price b { font-size: 15px; }
  .shop-buy { padding: 6px 10px; font-size: 11.5px; }
}

/* 预定单状态（2026-10-19 P1）：mypre.html 读服务端 shop_orders 后需要显示状态。
   只用一个中性小标 —— 状态文案本身已经说清了，不必再上五种颜色。 */
.pre-state { display: inline-block; font-size: 10.5px; font-weight: 700; letter-spacing: .02em;
  padding: 2px 8px; border-radius: 999px; color: var(--text-2);
  background: var(--ink-3); border: 1px solid var(--ink-4); }

/* ── 我的地址（myaddr.html，2026-10-19）────────────────────────────
   列表卡片 + 页内表单。默认那条用金色描边与角标，一眼能认出来。 */
.addr-list { display: flex; flex-direction: column; gap: 10px; }
.addr-item { display: flex; align-items: center; gap: 14px; padding: 13px 15px;
  background: var(--ink-2); border: 1px solid var(--ink-4); border-radius: 12px;
  transition: border-color .15s; }
.addr-item:hover { border-color: rgba(255,224,0,.28); }
.addr-item.is-def { border-color: rgba(255,224,0,.55); background: rgba(255,224,0,.04); }
.addr-main { flex: 1 1 auto; min-width: 0; }
.addr-top { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.addr-top b { font-size: 14px; color: var(--text); }
.addr-tel { font-size: 12px; color: var(--text-3); }
.addr-badge { font-size: 10.5px; font-weight: 700; line-height: 1.7; padding: 0 9px;
  border-radius: 999px; color: var(--on-accent); background: var(--gold); }
.addr-text { margin: 4px 0 0; font-size: 12.5px; line-height: 1.65; color: var(--text-2); }
.addr-act { flex: none; display: flex; gap: 6px; }
.addr-act button { appearance: none; cursor: pointer; font: inherit; font-size: 11.5px;
  padding: 5px 11px; border-radius: 7px; color: var(--text-2);
  background: var(--ink-3); border: 1px solid var(--ink-4); }
.addr-act button:hover { border-color: var(--gold); color: var(--gold-ink); }
.addr-act button.danger { color: #ff8f8f; border-color: rgba(255,143,143,.35); }
.addr-act button.danger:hover { background: rgba(255,143,143,.10); color: #ff8f8f; }

.addr-add { margin: 14px 0 4px; }
.addr-add-btn { appearance: none; cursor: pointer; font: inherit; font-size: 13px; font-weight: 700;
  width: 100%; padding: 12px; border-radius: 12px; color: var(--gold-ink);
  background: rgba(255,224,0,.06); border: 1px dashed rgba(255,224,0,.45);
  transition: background .15s; }
.addr-add-btn:hover { background: rgba(255,224,0,.13); }

.addr-form { margin-top: 14px; padding: 15px; border-radius: 12px;
  background: var(--ink-2); border: 1px solid var(--ink-4); }
.addr-form-hd { display: flex; align-items: center; margin-bottom: 12px; }
.addr-form-hd b { font-size: 14px; color: var(--text); }
.addr-x { margin-left: auto; appearance: none; cursor: pointer; font: inherit;
  width: 26px; height: 26px; border-radius: 7px; font-size: 11px;
  color: var(--text-3); background: var(--ink-3); border: 1px solid var(--ink-4); }
.addr-x:hover { border-color: var(--gold); color: var(--gold-ink); }
.addr-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.addr-f { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.addr-f.wide { grid-column: 1 / -1; }
.addr-f span { font-size: 11.5px; color: var(--text-3); }
.addr-f input { font: inherit; font-size: 13px; padding: 8px 11px; border-radius: 8px;
  color: var(--text); background: var(--ink-3); border: 1px solid var(--ink-4); }
.addr-f input::placeholder { color: var(--text-3); }
.addr-f input:focus { outline: none; border-color: var(--gold); }
.addr-def { display: flex; align-items: center; gap: 8px; margin: 13px 0 12px;
  font-size: 12.5px; color: var(--text-2); cursor: pointer; }
.addr-def input { accent-color: var(--gold); }
.addr-actions { display: flex; gap: 10px; }
.addr-save { appearance: none; cursor: pointer; font: inherit; font-size: 13px; font-weight: 700;
  padding: 9px 22px; border-radius: 9px; color: var(--on-accent);
  background: var(--gold); border: 1px solid var(--gold); }
.addr-save:hover { filter: brightness(1.08); }
.addr-cancel { appearance: none; cursor: pointer; font: inherit; font-size: 13px;
  padding: 9px 18px; border-radius: 9px; color: var(--text-2);
  background: transparent; border: 1px solid var(--ink-4); }
.addr-cancel:hover { border-color: var(--gold); color: var(--gold-ink); }

@media (max-width: 720px) {
  .addr-item { flex-wrap: wrap; align-items: flex-start; gap: 10px; }
  .addr-act { width: 100%; }
  .addr-act > button { flex: 1 1 0; }
  .addr-grid { grid-template-columns: 1fr; }
}
/* ── 回收申请：实物照片（recall.html，2026-10-20）──────────────────
   1~3 张，选完立即压缩上传；缩略图 84×84，右上角 ✕ 删除。
   上传中/失败都盖一层蒙版，避免"以为传上了其实没有"。 */
.rc-photos { grid-column: 1 / -1; display: flex; flex-direction: column; gap: 8px; }
.rc-ph-label { font-size: 11.5px; color: var(--text-3); }
.rc-ph-label i { font-style: normal; opacity: .85; margin-left: 4px; }
.rc-ph-grid { display: flex; gap: 8px; flex-wrap: wrap; }
.rc-ph { position: relative; width: 84px; height: 84px; border-radius: 8px; overflow: hidden;
  border: 1px solid var(--ink-4); background: var(--ink-3); }
.rc-ph.is-err { border-color: rgba(255,143,143,.6); }
.rc-ph img { width: 100%; height: 100%; object-fit: cover; display: block; }
.rc-ph-mask { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: 10.5px; letter-spacing: .02em; color: #fff; background: rgba(0,0,0,.55); }
.rc-ph-mask.err { color: #ff8f8f; }
/* 「原图」角标（2026-10-22）：让玩家一眼看出这张是**没被压缩**发出去的。
   放左下角，避开右上角的 ✕。 */
.rc-ph-tag { position: absolute; left: 3px; bottom: 3px; padding: 1px 5px; border-radius: 5px;
  font-size: 9.5px; letter-spacing: .02em; color: #1a1a1a; background: rgba(255,224,0,.88); }
.rc-ph-label i b { color: var(--gold-ink); font-weight: 700; }
.rc-ph-x { position: absolute; right: 3px; top: 3px; width: 18px; height: 18px; padding: 0;
  border-radius: 50%; border: 0; cursor: pointer; font: inherit; font-size: 9px; line-height: 18px;
  color: #fff; background: rgba(0,0,0,.62); }
.rc-ph-x:hover { background: rgba(255,143,143,.85); }
.rc-ph-add { align-self: flex-start; appearance: none; cursor: pointer; font: inherit;
  font-size: 12.5px; padding: 8px 15px; border-radius: 8px; color: var(--gold-ink);
  background: rgba(255,224,0,.06); border: 1px dashed rgba(255,224,0,.45); }
.rc-ph-add:hover { background: rgba(255,224,0,.13); }

/* ── 会员月卡（vip.html，2026-10-20）──────────────────────────────
   复用 .pre-* / .addr-* 那套骨架，这里只补三样这一页独有的东西：
   三档卡片、二维码付款区、区块小标题。 */
.vp-plans { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
@media (max-width: 720px) { .vp-plans { grid-template-columns: 1fr; } }
.vp-plan { position: relative; display: flex; flex-direction: column; align-items: flex-start;
  gap: 4px; padding: 16px 15px; border-radius: 12px;
  background: var(--ink-2); border: 1px solid var(--ink-4); }
/* 「最划算」那档：金色描边 + 角标。选中态靠描边，不靠放大 ——
   三张卡尺寸一致时比较价格才不费劲。 */
.vp-plan.is-hot { border-color: rgba(255,224,0,.55); background: rgba(255,224,0,.04); }
.vp-hot { position: absolute; top: 10px; right: 10px; font-size: 10.5px; font-weight: 700;
  line-height: 1.7; padding: 0 8px; border-radius: 999px;
  color: var(--on-accent); background: var(--gold); }
.vp-name { font-size: 14px; color: var(--text); }
.vp-days { font-size: 11.5px; color: var(--text-3); }
.vp-price { font-size: 24px; line-height: 1.1; color: var(--gold-ink);
  font-variant-numeric: tabular-nums; }
.vp-avg { font-size: 11.5px; color: var(--text-3); font-variant-numeric: tabular-nums; }
.vp-note { font-size: 11.5px; color: var(--text-2); }
.vp-buy { appearance: none; cursor: pointer; font: inherit; font-size: 13px; font-weight: 700;
  width: 100%; margin-top: 10px; padding: 9px 0; border-radius: 9px;
  color: var(--on-accent); background: var(--gold); border: 1px solid var(--gold); }
.vp-buy:hover { filter: brightness(1.08); }

/* 二维码区：**底色必须是白的** —— 深底上的黑码扫不出来是这个页面最容易犯的错。 */
.vp-pay { display: flex; gap: 18px; align-items: flex-start; flex-wrap: wrap;
  margin-top: 14px; padding: 16px; border-radius: 12px;
  background: var(--ink-2); border: 1px solid var(--ink-4); }
.vp-qr { flex: none; width: 200px; height: 200px; padding: 10px; border-radius: 10px;
  background: #fff; display: flex; align-items: center; justify-content: center; }
.vp-qr svg { width: 100%; height: 100%; display: block; }
.vp-payinfo { flex: 1 1 200px; min-width: 0; }
.vp-payinfo b { font-size: 14px; color: var(--text); }
.vp-payinfo p { margin: 8px 0 10px; font-size: 12.5px; line-height: 1.7; color: var(--text-2); }
.vp-h2 { font-size: 14px; font-weight: 500; color: var(--text); margin: 26px 0 12px; }

/* ── 付定金 / 付尾款浮层（mypre.html，2026-10-20）────────────────────
   和 vip.html 的付款区同一个观感：二维码**必须白底**，否则深底上的黑码扫不出来。 */
.pp-mask { position: fixed; inset: 0; z-index: 90; display: flex; align-items: center;
  justify-content: center; padding: 20px; background: rgba(0,0,0,.62); }
.pp-box { width: 100%; max-width: 340px; display: flex; flex-direction: column;
  align-items: center; gap: 12px; padding: 20px 18px; border-radius: 14px;
  background: var(--ink-2); border: 1px solid var(--ink-4); text-align: center; }
.pp-box > b { font-size: 14px; color: var(--text); }
.pp-qr { width: 200px; height: 200px; padding: 10px; border-radius: 10px;
  background: #fff; display: flex; align-items: center; justify-content: center; }
.pp-qr svg { width: 100%; height: 100%; display: block; }
.pp-note { margin: 0; font-size: 12.5px; line-height: 1.7; color: var(--text-2); }

/* 预定/补款日期行（shop.html，2026-10-20）：跟在价格下面，一行小字。
   不抢价格的位置 —— 日期是"什么时候能买"，价格才是"要不要买"。 */
.shop-date { display: block; margin-top: 4px; font-size: 11.5px; line-height: 1.5;
  color: var(--text-3); font-variant-numeric: tabular-nums; }

/* 预定名额「已满」那一行（2026-10-20）：用红色警示，和日期行同一位置。
   故意的：名额满了还在页面上挂着"预定"按钮，玩家点进去才发现是空的，比直接说更糟。 */
.shop-date.full { color: #ff8f8f; }

/* ── 商品详情弹窗（2026-10-21）──────────────────────────────────────
   点商品卡打开；左图右信息，底部沿用卡片里的「预定 / 咨询购买」按钮。 */
body.shd-open { overflow: hidden; }
.shd-mask { position: fixed; inset: 0; z-index: 900; display: flex;
  align-items: center; justify-content: center; padding: 20px;
  background: rgba(4,7,12,.72); backdrop-filter: blur(3px); }
.shd-mask[hidden] { display: none; }
/* 2026-10-24：改成 flex-start —— 原来 stretch 会把右栏拉到与左图同高，
   内容到 440 就结束，下方留一大块空白（店主：「不能这么空」）。 */
.shd { position: relative; display: flex; align-items: flex-start; gap: 24px; width: min(820px, 100%);
  max-height: 88vh; overflow: auto; padding: 22px;
  background: var(--ink-2); border: 1px solid var(--ink-4); border-radius: 14px;
  box-shadow: 0 24px 60px rgba(0,0,0,.55); }
.shd-x { position: absolute; right: 10px; top: 10px; width: 30px; height: 30px;
  border-radius: 50%; border: 1px solid var(--ink-4); background: var(--ink-3);
  color: var(--text-2); font-size: 14px; line-height: 1; cursor: pointer; }
.shd-x:hover { color: var(--text); border-color: var(--gold); }
.shd-art { flex: 0 0 220px; }
.shd-art img { display: block; width: 100%; height: auto; border-radius: 10px; }
.shd-bd { flex: 1 1 auto; min-width: 0; }
.shd-cat { display: inline-block; margin-bottom: 6px; padding: 1px 8px; border-radius: 999px;
  font-size: 11px; color: var(--gold-ink); border: 1px solid rgba(255,224,0,.35); }
.shd-name { margin: 0 0 4px; font-size: 19px; color: var(--text); }
.shd-sub { margin: 0 0 10px; font-size: 12.5px; color: var(--text-3); }
.shd-note { margin: 0 0 14px; font-size: 13px; line-height: 1.8; color: var(--text-2); }
.shd-meta { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 10px 14px; margin: 0 0 16px; padding: 12px 14px;
  background: var(--ink-3); border: 1px solid var(--ink-4); border-radius: 10px; }
.shd-meta dt { font-size: 11px; color: var(--text-3); margin-bottom: 2px; }
.shd-meta dd { margin: 0; font-size: 14px; color: var(--text); }
.shd-meta .shd-date { grid-column: 1 / -1; font-size: 11.5px; color: var(--text-3); }
.shd-act { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.shd-cancel { padding: 8px 14px; border-radius: 8px; border: 1px solid var(--ink-4);
  background: transparent; color: var(--text-2); font-size: 13px; cursor: pointer; }
.shd-cancel:hover { color: var(--text); border-color: var(--gold); }
@media (max-width: 640px) {
  .shd { flex-direction: column; padding: 16px; }
  .shd-art { flex: none; width: 160px; margin: 0 auto; }
}

/* ============================================================================
   补充包宣传轮播（2026-10-21 用户：「在商城界面也加一个轮播图功能」）
   ----------------------------------------------------------------------------
   结构与交互**全部复用首页 hero 的 .hc**（同一个 `assets/js/carousel.js`），
   这里只做两件事：① 把版口缩到商城页的尺寸；② 箭头贴到主图内缘。

   🔴 别在这里写 .hc-slide 的 width / height —— 高度统一由 --hc-h 一个口径控制，
      宽度由 CSS 用 16:9 反推。一旦按屏宽写百分比，比例随屏漂，
      宣传图两侧的日期与商标就会被裁掉（首页那条注释同样适用这条规矩）。
   ========================================================================== */
.spb {
  /* 380 这个上限是**首屏预算**倒推的（判据见 data/viewports.js）：
     1920×940 实测 顶栏 67 + 页头 75 + 轮播 380 + 圆点 30 + 分类条 68 ≈ 620，
     分类条与第一行商品都不用滚动就看得见。
     手机端 34vw 会瘦到 130 出头，所以下限给 160（低于这个数整张图的字读不出来）。 */
  --hc-h: clamp(160px, min(34vw, 40vh), 380px);
  --hc-pad-top: 0;
  margin: 2px 0 4px;
  padding: 0;
  background: none;
  border-bottom: 0;
}
/* 幻灯片是 <button>（点开商品详情），不是首页那种 <a> —— 抹掉按钮的默认皮肤 */
.spb-slide {
  padding: 0; appearance: none; -webkit-appearance: none;
  font: inherit; cursor: pointer;
}
/* 拖拽翻页交给 track 上的 pointer 逻辑；<img> 自己认领拖拽会把整条轨道拖成半透明幽灵图 */
.spb-slide img { pointer-events: none; }
/* 箭头贴**主图内缘**（同 #heroCarousel 的算法）：容器左右露出邻居，
   按容器边缘定位（.hc-nav 的默认值）会把箭头压到邻居图上。--hc-w = 主图宽度。 */
.spb .hc-nav {
  width: 42px; height: 42px; border-radius: 50%;
  background: rgba(10, 10, 11, .52);
  border-color: rgba(255, 255, 255, .22);
  box-shadow: 0 6px 18px rgba(0, 0, 0, .35);
}
.spb .hc-prev { left: calc(50% - var(--hc-w) / 2 + 12px); }
.spb .hc-next { right: calc(50% - var(--hc-w) / 2 + 12px); }
.spb .hc-nav:hover { background: var(--gold); border-color: var(--gold); box-shadow: 0 8px 24px rgba(255, 224, 0, .28); }
.spb .hc-dots { padding: 12px 0 0; }

/* 只有一张宣传图时（脚本加 .spb-single）：静态摆中间，收起箭头与圆点 */
.spb-single .hc-track { justify-content: center; }
.spb-single .hc-nav, .spb-single .hc-dots { display: none; }

@media (max-width: 900px) {
  /* .hc 的 900px 断点会把 --hc-h 抬到 190；商城页显式接住，保持同一个口径 */
  .spb { --hc-h: clamp(160px, 46vw, 240px); }
  .spb .hc-nav { width: 34px; height: 34px; }
}

/* ══ 2026-10-24 设计返工（详情弹窗 + 卡片等高）════════════════════════
   问题（实测截图）：
   ① `.shd-meta` 是 auto-fit 网格，我插入的 `.shd-pre` 只占到**一格**宽度，
      三个时间节点被压成竖排（"预定/开始"一行一个字）。
   ② 22 张卡片高度 354~434 不等，网格第二行起底部按钮错位。
   ③ 字阶是 13.5 / 11.5 / 11 这种半像素差，没有节奏。 */

/* ① 预定区跨满整行 */
.shd-meta .shd-pre { grid-column: 1 / -1; margin-top: 6px; }

/* ② 四格信息固定一行四列（弹窗加宽到 820 后右栏约 500，每格 120 出头） */
.shd-meta { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* ③ 时间节点：日期不换行，标签压暗 */
.shd-tl > i { min-width: 0; }
.shd-tl b { white-space: nowrap; font-variant-numeric: tabular-nums; }

/* ④ 卡片等高：信息区撑满，操作条永远贴底 */
.shop-info { display: flex; flex-direction: column; min-width: 0; }
.shop-foot { margin-top: auto; }
.shop-name { line-height: 1.32; min-height: 2.5em; }

/* ⑤ 字阶对齐到 14 / 12 / 11 / 18 四档（原来 13.5 / 11.5 没有节奏） */
.shop-name { font-size: 14px; }
.shop-sub { font-size: 12px; }
.shop-price b { font-size: 18px; }

/* ══ 2026-10-24 设计返工（详情弹窗 + 卡片等高）════════════════════════
   问题（实测截图）：
   ① `.shd-meta` 是 auto-fit 网格，我插入的 `.shd-pre` 只占到**一格**宽度，
      三个时间节点被压成竖排（"预定/开始"一行一个字）。
   ② 22 张卡片高度 354~434 不等，网格第二行起底部按钮错位。
   ③ 字阶是 13.5 / 11.5 / 11 这种半像素差，没有节奏。 */

/* ① 预定区跨满整行 */
.shd-meta .shd-pre { grid-column: 1 / -1; margin-top: 6px; }

/* ② 四格信息固定一行四列（弹窗加宽到 820 后右栏约 500，每格 120 出头） */
.shd-meta { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* ③ 时间节点：日期不换行，标签压暗 */
.shd-tl > i { min-width: 0; }
.shd-tl b { white-space: nowrap; font-variant-numeric: tabular-nums; }

/* ④ 卡片等高：信息区撑满，操作条永远贴底 */
.shop-info { display: flex; flex-direction: column; min-width: 0; }
.shop-foot { margin-top: auto; }
.shop-name { line-height: 1.35; min-height: 2.7em; }

/* ⑤ 字阶对齐到 14 / 12 / 11 / 18 四档（原来 13.5 / 11.5 没有节奏） */
.shop-name { font-size: 14px; }
.shop-sub { font-size: 12px; }
.shop-price b { font-size: 18px; }

/* 「单卡」跳转入口（2026-10-24 从分类带挪到工具栏）：
   紧凑胶囊，与搜索框同高；右侧箭头在悬停时右移 2px，表明"是跳转不是筛选"。 */
.shop-jump {
  flex: none;
  display: inline-flex; align-items: center; gap: 6px;
  height: 38px; padding: 0 14px;
  border: 1px solid var(--ink-4); border-radius: 10px;
  background: var(--ink-2);
  color: var(--text-2); font-size: 13px; font-weight: 700;
  text-decoration: none; white-space: nowrap;
  transition: border-color .18s, color .18s, background .18s;
}
.shop-jump > i { font-style: normal; font-size: 11.5px; font-weight: 700; color: var(--text-3); }
.shop-jump > b { font-weight: 400; color: var(--text-3); transition: transform .18s; }
.shop-jump:hover { border-color: rgba(255,224,0,.72); color: var(--gold-ink); background: rgba(255,224,0,.06); }
.shop-jump:hover > b { transform: translateX(2px); color: var(--gold-ink); }

/* 「单卡」跳转入口（2026-10-24 从分类带挪到工具栏）：
   紧凑胶囊，与搜索框同高；右侧箭头在悬停时右移 2px，表明"是跳转不是筛选"。 */
.shop-jump {
  flex: none;
  display: inline-flex; align-items: center; gap: 6px;
  height: 38px; padding: 0 14px;
  border: 1px solid var(--ink-4); border-radius: 10px;
  background: var(--ink-2);
  color: var(--text-2); font-size: 13px; font-weight: 700;
  text-decoration: none; white-space: nowrap;
  transition: border-color .18s, color .18s, background .18s;
}
.shop-jump > i { font-style: normal; font-size: 11.5px; font-weight: 700; color: var(--text-3); }
.shop-jump > b { font-weight: 400; color: var(--text-3); transition: transform .18s; }
.shop-jump:hover { border-color: rgba(255,224,0,.72); color: var(--gold-ink); background: rgba(255,224,0,.06); }
.shop-jump:hover > b { transform: translateX(2px); color: var(--gold-ink); }

/* 商城页的宣传轮播（`.hc.spb`）单独压低 —— 2026-10-24 设计体检：
   首页轮播是"门面"，商城轮播是"横幅"，后者不该和前者一样高。
   实测原来 401px，吃掉首屏 42%，商品卡只能露出 2/3 张。
   这里只覆盖 `.spb`，**不动首页 `.hc`**（首页高度另有视口适配验收脚本）。 */
.hc.spb { --hc-h: clamp(150px, min(24vw, 28vh), 300px); }

/* 商城页的宣传轮播（`.hc.spb`）单独压低 —— 2026-10-24 设计体检：
   首页轮播是"门面"，商城轮播是"横幅"，后者不该和前者一样高。
   实测原来 401px，吃掉首屏 42%，商品卡只能露出 2/3 张。
   这里只覆盖 `.spb`，**不动首页 `.hc`**（首页高度另有视口适配验收脚本）。 */
.hc.spb { --hc-h: clamp(150px, min(24vw, 28vh), 300px); }

/* 工具栏：搜索框与「单卡」胶囊**同一行**（原来 column 竖排，只放两个元素时白占一行高度） */
.shop-tools { flex: 0 0 auto; flex-direction: row; align-items: center; gap: 8px; }
.shop-tools .shop-search { flex: 0 1 240px; min-width: 150px; }

/* 工具栏：搜索框与「单卡」胶囊**同一行**（原来 column 竖排，只放两个元素时白占一行高度） */
.shop-tools { flex: 0 0 auto; flex-direction: row; align-items: center; gap: 8px; }
.shop-tools .shop-search { flex: 0 1 240px; min-width: 150px; }

/* ═══════════════════════════════════════════════════════════════════════════
   商城页视觉重构（2026-10-24，店主：「这一页太难看了，全面重改」）
   ---------------------------------------------------------------------------
   原则：只在 `.shoppage` 作用域内改，**不动首页 `.hc` 与手机端断点**（另一会话在改手机）。
   四个问题 → 四条对策：
     ① 三张横幅等亮 → 焦点散      → 非激活 slide 压暗 + 缩 0.95 + 降饱和，只留中间亮
     ② 分类块 68px 高、占满一行    → 压到 54px，选中用**金底黑字**（比金边强，扫读更快）
     ③ 卡片层级平                  → 卡名 15/700 单行省略、价格 20 金、按钮改描边（黄色实心×5 太吵）
     ④ 纯黑底没有呼吸              → 顶部一层极淡径向光，卡片 gap 18
   ========================================================================= */

/* ① 横幅：只让中间那张是"亮的" */
.shoppage .hc.spb .hc-slide {
  transition: opacity .42s var(--mv-ease, ease), transform .42s var(--mv-ease, ease),
              filter .42s var(--mv-ease, ease);
}
.shoppage .hc.spb .hc-slide:not(.is-active) {
  opacity: .38;
  filter: saturate(.5) brightness(.7);
  transform: scale(.95);
}
.shoppage .hc.spb .hc-slide.is-active { opacity: 1; }

/* ② 分类块：变矮、选中金底 */
.shoppage .shop-blk {
  min-height: 54px;
  padding: 0 12px;
  border-radius: 10px;
  background: rgba(255,255,255,.028);
}
.shoppage .shop-blk-ic { font-size: 16px; width: 22px; height: 18px; }
.shoppage .shop-blk-t { font-size: 13px; }
.shoppage .shop-blk-t i { font-size: 11px; }
.shoppage .shop-blk.on {
  background: var(--gold);
  border-color: var(--gold);
  box-shadow: 0 6px 18px rgba(255,224,0,.18);
}
.shoppage .shop-blk.on .shop-blk-t,
.shoppage .shop-blk.on .shop-blk-t i { color: #17130a; }
.shoppage .shop-blk.on .shop-blk-ic { filter: grayscale(1) brightness(.25); }
.shoppage .shop-blk.on::before { display: none; }   /* 金底已经够明确，顶线多余 */

/* ③ 卡片层级 */
.shoppage .shop-grid { gap: 18px; }
.shoppage .shop-card { border-radius: 12px; border-color: rgba(255,255,255,.07); }
.shoppage .shop-name {
  font-size: 15px; font-weight: 700; line-height: 1.35; min-height: 0;
  display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical;
  overflow: hidden;
}
.shoppage .shop-sub { font-size: 11.5px; color: rgba(255,255,255,.42); }
.shoppage .shop-price { color: var(--gold-ink); }
.shoppage .shop-price b { font-size: 20px; font-weight: 800; letter-spacing: -.01em; }
.shoppage .shop-price b i { font-size: 13px; font-weight: 700; opacity: .85; margin-right: 1px; }
/* 按钮：黄色实心 5 个连成一片太吵，改描边；悬停才填满 */
.shoppage .shop-buy {
  background: transparent;
  border: 1px solid rgba(255,224,0,.55);
  color: var(--gold-ink);
  box-shadow: none;
}
.shoppage .shop-buy:hover {
  background: var(--gold); border-color: var(--gold); color: #17130a;
}
.shoppage .shop-buy.buy { font-weight: 700; }

/* ④ 背景呼吸：顶部一层极淡金雾，卡片区不再"贴在纯黑上" */
.shoppage { position: relative; }
.shoppage::before {
  content: '';
  position: absolute; inset: 0 0 auto 0; height: 520px;
  pointer-events: none; z-index: 0;
  background: radial-gradient(78% 68% at 50% -12%, rgba(184,147,46,.13), transparent 68%);
}
.shoppage > * { position: relative; z-index: 1; }

/* 页头：标题收字号 + 统计做成胶囊 */
.shoppage .shop-hero h1 { font-size: 22px; letter-spacing: .01em; }
.shoppage .shop-stat > span {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 12px; margin-left: 8px;
  border: 1px solid rgba(255,255,255,.10); border-radius: 99px;
  background: rgba(255,255,255,.03);
  font-size: 11.5px;
}
.shoppage .shop-stat i { font-style: normal; color: rgba(255,255,255,.45); }
.shoppage .shop-stat b { font-size: 13px; color: var(--text); }

/* ═══════════════════════════════════════════════════════════════════════════
   商城页视觉重构（2026-10-24，店主：「这一页太难看了，全面重改」）
   ---------------------------------------------------------------------------
   原则：只在 `.shoppage` 作用域内改，**不动首页 `.hc` 与手机端断点**（另一会话在改手机）。
   四个问题 → 四条对策：
     ① 三张横幅等亮 → 焦点散      → 非激活 slide 压暗 + 缩 0.95 + 降饱和，只留中间亮
     ② 分类块 68px 高、占满一行    → 压到 54px，选中用**金底黑字**（比金边强，扫读更快）
     ③ 卡片层级平                  → 卡名 15/700 单行省略、价格 20 金、按钮改描边（黄色实心×5 太吵）
     ④ 纯黑底没有呼吸              → 顶部一层极淡径向光，卡片 gap 18
   ========================================================================= */

/* ① 横幅：只让中间那张是"亮的" */
.shoppage .hc.spb .hc-slide {
  transition: opacity .42s var(--mv-ease, ease), transform .42s var(--mv-ease, ease),
              filter .42s var(--mv-ease, ease);
}
.shoppage .hc.spb .hc-slide:not(.is-active) {
  opacity: .38;
  filter: saturate(.5) brightness(.7);
  transform: scale(.95);
}
.shoppage .hc.spb .hc-slide.is-active { opacity: 1; }

/* ② 分类块：变矮、选中金底 */
.shoppage .shop-blk {
  min-height: 54px;
  padding: 0 12px;
  border-radius: 10px;
  background: rgba(255,255,255,.028);
}
.shoppage .shop-blk-ic { font-size: 16px; width: 22px; height: 18px; }
.shoppage .shop-blk-t { font-size: 13px; }
.shoppage .shop-blk-t i { font-size: 11px; }
.shoppage .shop-blk.on {
  background: var(--gold);
  border-color: var(--gold);
  box-shadow: 0 6px 18px rgba(255,224,0,.18);
}
.shoppage .shop-blk.on .shop-blk-t,
.shoppage .shop-blk.on .shop-blk-t i { color: #17130a; }
.shoppage .shop-blk.on .shop-blk-ic { filter: grayscale(1) brightness(.25); }
.shoppage .shop-blk.on::before { display: none; }   /* 金底已经够明确，顶线多余 */

/* ③ 卡片层级 */
.shoppage .shop-grid { gap: 18px; }
.shoppage .shop-card { border-radius: 12px; border-color: rgba(255,255,255,.07); }
.shoppage .shop-name {
  font-size: 15px; font-weight: 700; line-height: 1.35; min-height: 0;
  display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical;
  overflow: hidden;
}
.shoppage .shop-sub { font-size: 11.5px; color: rgba(255,255,255,.42); }
.shoppage .shop-price { color: var(--gold-ink); }
.shoppage .shop-price b { font-size: 20px; font-weight: 800; letter-spacing: -.01em; }
.shoppage .shop-price b i { font-size: 13px; font-weight: 700; opacity: .85; margin-right: 1px; }
/* 按钮：黄色实心 5 个连成一片太吵，改描边；悬停才填满 */
.shoppage .shop-buy {
  background: transparent;
  border: 1px solid rgba(255,224,0,.55);
  color: var(--gold-ink);
  box-shadow: none;
}
.shoppage .shop-buy:hover {
  background: var(--gold); border-color: var(--gold); color: #17130a;
}
.shoppage .shop-buy.buy { font-weight: 700; }

/* ④ 背景呼吸：顶部一层极淡金雾，卡片区不再"贴在纯黑上" */
.shoppage { position: relative; }
.shoppage::before {
  content: '';
  position: absolute; inset: 0 0 auto 0; height: 520px;
  pointer-events: none; z-index: 0;
  background: radial-gradient(78% 68% at 50% -12%, rgba(184,147,46,.13), transparent 68%);
}
.shoppage > * { position: relative; z-index: 1; }

/* 页头：标题收字号 + 统计做成胶囊 */
.shoppage .shop-hero h1 { font-size: 22px; letter-spacing: .01em; }
.shoppage .shop-stat > span {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 12px; margin-left: 8px;
  border: 1px solid rgba(255,255,255,.10); border-radius: 99px;
  background: rgba(255,255,255,.03);
  font-size: 11.5px;
}
.shoppage .shop-stat i { font-style: normal; color: rgba(255,255,255,.45); }
.shoppage .shop-stat b { font-size: 13px; color: var(--text); }

/* 二轮微调（同上，2026-10-24）：
   ① 标题与统计同一基线（原来标题左、统计右，中间空一大片，像两个不相干的区块）
   ② 网格 5 列 → 一屏多看一张；gap 18 → 16
   ③ 横幅再压到 224（255 → 224），让首排卡片整张露出来 */
.shoppage .shop-hero { align-items: center; }
.shoppage .shop-stat { display: flex; align-items: center; }
.shoppage .shop-grid { grid-template-columns: repeat(auto-fill, minmax(198px, 1fr)); gap: 16px; }
.shoppage .hc.spb { --hc-h: clamp(140px, min(21vw, 23vh), 224px); }

/* 二轮微调（同上，2026-10-24）：
   ① 标题与统计同一基线（原来标题左、统计右，中间空一大片，像两个不相干的区块）
   ② 网格 5 列 → 一屏多看一张；gap 18 → 16
   ③ 横幅再压到 224（255 → 224），让首排卡片整张露出来 */
.shoppage .shop-hero { align-items: center; }
.shoppage .shop-stat { display: flex; align-items: center; }
.shoppage .shop-grid { grid-template-columns: repeat(auto-fill, minmax(198px, 1fr)); gap: 16px; }
.shoppage .hc.spb { --hc-h: clamp(140px, min(21vw, 23vh), 224px); }
