/* ==========================================================================
   珠语 · DIY 天然石手串
   zhuyu.css —— 站点皮肤层
   --------------------------------------------------------------------------
   界面层只消费 design-system 的令牌，不写死颜色 / 字号 / 圆角 / 间距。
   唯一例外是第 0 节那份站点调色板：本站无素材状态下靠程序化矿石纹样撑场面，
   那些"石头本身的颜色"没有对应的语义令牌，集中在那里统一管理。

   保留了原站的手工温度感：
     · 衬线中文标题 + 字距（原站就是衬线体，气质延续）
     · 暖纸底、绛红强调（色值换成 [data-brand='zhuyu'] 的 #8A3B57）
     · 大圆角倾向（卡片 --r-lg / 内件 --r-sm / 药丸与圆珠 --r-full）

   去掉的是原站那股"AI 生成感"：
     · 每张卡各自的浮动 + 掠光 + 粒子漂移动画 → 全部删除
     · 只剩功能性动效：轮播切换、页面切换
   ========================================================================== */

/* ==========================================================================
   0. 站点调色板
   --------------------------------------------------------------------------
   tokens.css 给的是界面语义色（--bg / --ink / --accent…）。
   这里补的是"照片替代品"的物理色 —— 矿石、丝绳、展台台面。
   本站在无素材状态下完全靠程序化纹样撑场面，这些色值就是它的全部视觉资产，
   所以集中在此一处，方便一次性审校与替换。

   矿石与展台色写成 "R G B" 三元组，用 rgb(var(--x) / α) 取用 ——
   同一块石头在实心处与半透明处共用一份定义，不必两处维护。
   ========================================================================== */
:root {
  /* --- 通用（三元组） --- */
  --zy-white:   255 255 255;
  --zy-shadow:  60 48 30;      /* 暖色投影，与 tokens 的 --shadow-* 同源 */
  --zy-scrim:   20 12 6;       /* 底图上的压罩 */
  --zy-bokeh:   255 224 198;   /* 主视觉柔光晕（暖） */
  --zy-bokeh-2: 255 232 208;
  --zy-bokeh-3: 255 242 236;
  --zy-bokeh-4: 224 232 244;   /* 柔光晕（冷） */
  --zy-vein-dark: 96 78 60;    /* 石纹（暗） */
  --zy-caustic: 255 236 214;   /* 石体透光的暖芯 */

  /* --- 展台场景：主视觉三张底图的暗部 --- */
  --zy-stage-1a: 74 58 50;  --zy-stage-1b: 110 87 72;  --zy-stage-1c: 58 44 38;
  --zy-stage-2a: 85 48 60;  --zy-stage-2b: 124 74 88;  --zy-stage-2c: 62 34 44;
  --zy-stage-3a: 42 42 50;  --zy-stage-3b: 20 20 26;  --zy-stage-3c: 8 8 12;

  /* --- 矿石本色 ---
     l 为迎光面中性色，用于黑曜石/银曜石/乌金的边缘反光；
     每颗石头保持 亮部 / 暗部 成对，模拟石头的通透与收边。 */
  --zy-stone-cream:      233 226 214;
  --zy-stone-cream-d:    196 185 168;
  --zy-stone-lilac:      214 200 226;
  --zy-stone-lilac-d:    150 128 178;
  --zy-stone-amber:      226 208 190;
  --zy-stone-amber-d:    160 132 104;
  --zy-stone-rose:       240 200 212;
  --zy-stone-rose-d:     190 130 152;
  --zy-stone-violet:     216 196 236;
  --zy-stone-violet-d:   140 116 176;
  --zy-stone-gold:       238 216 168;
  --zy-stone-gold-d:     180 148 92;
  --zy-stone-ink-l:      180 186 198;  /* 迎光面 */
  --zy-stone-ink:        52 54 62;  /* 石体 */
  --zy-stone-ink-d:      16 16 20;
  --zy-stone-slate-l:    196 200 212;  /* 迎光面 */
  --zy-stone-slate:      58 58 68;  /* 石体 */
  --zy-stone-slate-d:    20 20 26;
  --zy-stone-steel-l:    200 202 210;  /* 迎光面 */
  --zy-stone-steel:      44 44 52;  /* 石体 */
  --zy-stone-steel-d:    14 14 18;

  /* --- 色系侧栏的 8 颗色标（不透明，直接给 hex） --- */
  --zy-swatch-white:     #F0EEE8;
  --zy-swatch-black:     #2A2020;
  --zy-swatch-red:       #C03030;
  --zy-swatch-yellow:    #C49020;
  --zy-swatch-green:     #508050;
  --zy-swatch-blue:      #3870A8;
  --zy-swatch-purple:    #7840B0;
  --zy-swatch-pink:      #E098B0;

  /* --- 绳子色卡 --- */
  --zy-rope-cream:       #F0EDE0;
  --zy-rope-black:       #2A2020;
  --zy-rope-red:         #C03030;
  --zy-rope-gold:        #D4A020;
  --zy-rope-blue:        #A0C0E0;
  --zy-rope-clear:       #F8F8F8;

  /* --- 作品展三张卡的台面底色 --- */
  --zy-card-spring:      #EAF2E6;
  --zy-card-tender:      #F7EBEF;
  --zy-card-plain:       #E8E8EC;
}
/* ==========================================================================
   1. 画布与屏幕容器
   ========================================================================== */
.app {
  position: relative;          /* .scr 是 absolute，此处必须是定位上下文 */
  overflow: hidden;
  height: 100dvh;
  background: var(--bg);
}

/* 屏幕：叠放 + 左右滑入滑出。类名与业务 JS 完全一致（.active ），
   写成 .is-active 会导致两个页面同时渲染。 */
.scr {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--bg);
  transform: translateX(100%);
  opacity: 0;
  visibility: hidden;
  transition: transform var(--dur-3) var(--ease-soft),
              opacity var(--dur-3) var(--ease-soft),
              visibility 0s linear var(--dur-3);
}
.scr.active {
  transform: translateX(0);
  opacity: 1;
  visibility: visible;
  transition: transform var(--dur-3) var(--ease-soft),
              opacity var(--dur-3) var(--ease-soft),
              visibility 0s;
  z-index: 1;
}
.scr.hidden-right { transform: translateX(100%); opacity: 0; }
.scr.hidden-left  { transform: translateX(-40%); opacity: .4; }
.scr:not(.active) { pointer-events: none; z-index: 0; }

/* 屏幕内的滚动体 */
.body,
.form-body,
.confirm-body,
.success-body,
.stone-cat-main {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.body::-webkit-scrollbar,
.form-body::-webkit-scrollbar,
.confirm-body::-webkit-scrollbar,
.success-body::-webkit-scrollbar,
.stone-cat-main::-webkit-scrollbar { display: none; }
.body { padding-bottom: calc(var(--safe-b) + var(--s-7)); }
.body:focus { outline: none; }

/* ==========================================================================
   2. 顶栏
   ========================================================================== */
.topbar__brand {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1px;
}
.brand-mark {
  font-family: var(--font-serif);
  font-size: var(--t-h2);
  font-weight: var(--fw-semi);
  letter-spacing: .18em;
  line-height: 1.15;
  color: var(--ink);
  margin: 0;
}
.brand-sub {
  font-family: var(--font-display);
  font-size: var(--t-micro);
  letter-spacing: var(--ls-caps);
  color: var(--muted);
}

/* 原站顶栏是「设 计 手 串」这种宽字距标题，保留 */
.topbar__title { letter-spacing: .16em; font-weight: var(--fw-medium); }

/* ==========================================================================
   3. 首页 · 主视觉轮播
   背景是程序化矿石纹样，不依赖任何外部图片
   ========================================================================== */
.hero-carousel {
  position: relative;
  overflow: hidden;
  margin: var(--s-4) var(--gutter) 0;
  height: 280px;
  border-radius: var(--r-lg);
  background: var(--ink);
  box-shadow: var(--shadow-lg);
}
.hero-slides {
  display: flex;
  width: 300%;
  height: 100%;
  transition: transform var(--dur-4) var(--ease-soft);
}
.hero-slide {
  position: relative;
  width: 33.333%;
  height: 100%;
  flex-shrink: 0;
  overflow: hidden;
}

/* 三张程序化底图：同一套矿石纹样，换色相与构图 */
.hero-bg {
  position: absolute;
  inset: 0;
  background-repeat: no-repeat;
  background-size: 100% 100%;
  transition: transform 8s var(--ease-soft);
}
.hero-slide.active .hero-bg { transform: scale(1.06); }

/* 每张底图 = 一层暖调铺底 + 一圈石珠 + 几颗散落的主石 + 柔光晕 */
.hero-bg-1 {  background-image:
    radial-gradient(circle at 18% 22%, rgb(var(--zy-bokeh) / .55) 0%, transparent 42%),
    radial-gradient(ellipse 29.7% 22.7% at calc(26% + -9px) calc(32% + -7px),rgb(var(--zy-caustic) / .5) 0%, transparent 72%),
    radial-gradient(ellipse 29.7% 22.7% at calc(26% + 11px) calc(32% + 9px),rgb(var(--zy-vein-dark) / .3) 0%, transparent 72%),
    radial-gradient(circle 54px at 26% 32%, rgb(var(--zy-white) / .85) 0%, rgb(var(--zy-stone-cream) / .95) 34%, rgb(var(--zy-stone-cream-d) / .95) 76%, transparent 100%),
    radial-gradient(ellipse 16.5% 12.6% at calc(70% + -5px) calc(24% + -4px),rgb(var(--zy-caustic) / .44) 0%, transparent 72%),
    radial-gradient(circle 30px at 70% 24%, rgb(var(--zy-white) / .7) 0%, rgb(var(--zy-stone-lilac) / .9) 40%, rgb(var(--zy-stone-lilac-d) / .95) 82%, transparent 100%),
    radial-gradient(ellipse 12.1% 9.2% at calc(82% + 4px) calc(62% + 4px),rgb(var(--zy-caustic) / .4) 0%, transparent 72%),
    radial-gradient(circle 22px at 82% 62%, rgb(var(--zy-white) / .6) 0%, rgb(var(--zy-stone-amber) / .9) 44%, rgb(var(--zy-stone-amber-d) / .95) 84%, transparent 100%),
    linear-gradient(158deg, rgb(var(--zy-stage-1a)) 0%, rgb(var(--zy-stage-1b)) 52%, rgb(var(--zy-stage-1c)) 100%)
}
.hero-bg-2 {  background-image:
    radial-gradient(circle at 76% 18%, rgb(var(--zy-bokeh-3) / .55) 0%, transparent 44%),
    radial-gradient(ellipse 25.3% 19.3% at calc(72% + 8px) calc(66% + 8px),rgb(var(--zy-caustic) / .48) 0%, transparent 72%),
    radial-gradient(ellipse 25.3% 19.3% at calc(72% + -10px) calc(66% + -8px),rgb(var(--zy-vein-dark) / .28) 0%, transparent 72%),
    radial-gradient(circle 46px at 72% 66%, rgb(var(--zy-white) / .8) 0%, rgb(var(--zy-stone-rose) / .95) 36%, rgb(var(--zy-stone-rose-d) / .95) 78%, transparent 100%),
    radial-gradient(ellipse 14.3% 10.9% at calc(24% + -5px) calc(30% + -4px),rgb(var(--zy-caustic) / .42) 0%, transparent 72%),
    radial-gradient(circle 26px at 24% 30%, rgb(var(--zy-white) / .68) 0%, rgb(var(--zy-stone-violet) / .9) 42%, rgb(var(--zy-stone-violet-d) / .95) 84%, transparent 100%),
    radial-gradient(ellipse 9.9% 7.6% at calc(34% + 4px) calc(74% + 3px),rgb(var(--zy-caustic) / .4) 0%, transparent 72%),
    radial-gradient(circle 18px at 34% 74%, rgb(var(--zy-white) / .55) 0%, rgb(var(--zy-stone-gold) / .9) 46%, rgb(var(--zy-stone-gold-d) / .95) 86%, transparent 100%),
    linear-gradient(162deg, rgb(var(--zy-stage-2a)) 0%, rgb(var(--zy-stage-2b)) 50%, rgb(var(--zy-stage-2c)) 100%)
}
.hero-bg-3 {  background-image:
    radial-gradient(circle at 50% 12%, rgb(var(--zy-bokeh-4) / .4) 0%, transparent 48%),
    radial-gradient(ellipse 30.8% 23.5% at calc(34% + -10px) calc(58% + -8px),rgb(var(--zy-caustic) / .2) 0%, transparent 72%),
    radial-gradient(ellipse 30.8% 23.5% at calc(34% + 12px) calc(58% + 10px),rgb(var(--zy-vein-dark) / .34) 0%, transparent 72%),
    radial-gradient(circle 56px at 34% 58%, rgb(var(--zy-stone-ink-l) / .7) 0%, rgb(var(--zy-stone-ink) / .95) 40%, rgb(var(--zy-stone-ink-d) / 1) 82%, transparent 100%),
    radial-gradient(ellipse 17.6% 13.4% at calc(74% + -6px) calc(36% + -5px),rgb(var(--zy-caustic) / .16) 0%, transparent 72%),
    radial-gradient(ellipse 17.6% 13.4% at calc(74% + 7px) calc(36% + 6px),rgb(var(--zy-vein-dark) / .3) 0%, transparent 72%),
    radial-gradient(circle 32px at 74% 36%, rgb(var(--zy-stone-slate-l) / .6) 0%, rgb(var(--zy-stone-slate) / .95) 44%, rgb(var(--zy-stone-slate-d) / 1) 84%, transparent 100%),
    radial-gradient(ellipse 11.0% 8.4% at calc(66% + 5px) calc(78% + 4px),rgb(var(--zy-vein-dark) / .28) 0%, transparent 72%),
    radial-gradient(circle 20px at 66% 78%, rgb(var(--zy-stone-steel-l) / .5) 0%, rgb(var(--zy-stone-steel) / .95) 48%, rgb(var(--zy-stone-steel-d) / 1) 86%, transparent 100%),
    linear-gradient(168deg, rgb(var(--zy-stage-3a)) 0%, rgb(var(--zy-stage-3b)) 54%, rgb(var(--zy-stage-3c)) 100%)
}

/* 内容压罩：保证任何底图上文字都可读 */
.hero-slide::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(to top, rgb(var(--zy-scrim) / .66) 0%, rgb(var(--zy-scrim) / .18) 52%, transparent 78%),
    linear-gradient(160deg, rgb(var(--zy-scrim) / .48) 0%, rgb(var(--zy-scrim) / .06) 58%, transparent 100%);
  pointer-events: none;
}
.hero-bokeh {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(circle 58px at 74% 26%, rgb(var(--zy-bokeh) / .18) 0%, transparent 70%),
    radial-gradient(circle 38px at 84% 46%, rgb(var(--zy-bokeh-2) / .12) 0%, transparent 70%);
}

.hero-content {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 2;
  padding: var(--s-6) var(--s-6) var(--s-7);
}
.hero-tag {
  display: inline-block;
  padding: var(--s-1) var(--s-3);
  margin-bottom: var(--s-3);
  border: 1px solid rgb(var(--zy-white) / .26);
  border-radius: var(--r-full);
  /* 底色必须是**压暗**的，不能只是半透白。
     实测：16% 白 + blur(8px) 压在浅色天空上，白字只有 2.3:1。
     模糊只是把背景搅匀，不改变它的明度 —— 要可读就得把底压下去。 */
  /* 底色必须压得够暗。
     实测：16% 白 + blur(8px) 压在浅色天空上，白字只有 2.3:1 —— 模糊只是
     把背景搅匀，不改变明度，要可读就得把底压下去。

     58% 是怎么来的：白字 + rgba(0,0,0,a)，最坏底图是纯白（背景越亮白字越难读），
     解得 a >= 0.54。取 0.58 留余量。这样它压在**任何**照片上都成立，
     不依赖当前这几张图恰好偏暗。 */
  background: rgb(0 0 0 / .58);
  -webkit-backdrop-filter: blur(10px) saturate(1.2);
  backdrop-filter: blur(10px) saturate(1.2);
  color: rgb(var(--zy-white));
  font-size: var(--t-micro);
  letter-spacing: var(--ls-caps);
}
.hero-h {
  margin-bottom: var(--s-2);
  color: rgb(var(--zy-white));
  font-family: var(--font-serif);
  font-size: var(--t-h1);
  font-weight: var(--fw-semi);
  line-height: var(--lh-heading);
  letter-spacing: var(--ls-heading);
}
/* 原站给「手串 / 最爱 / 矿石」换色强调，保留这个手法 */
.hero-h em {
  font-style: normal;
  color: var(--accent-line);
}
.hero-p {
  margin-bottom: var(--s-5);
  color: rgb(var(--zy-white) / .74);
  font-size: var(--t-sm);
  letter-spacing: .02em;
}
.hero-cta {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-height: var(--tap-min);
  padding: 0 var(--s-5);
  border: none;
  border-radius: var(--r-full);
  background: rgb(var(--zy-white) / .94);
  color: var(--accent-lo);
  font-family: var(--font-serif);
  font-size: var(--t-sm);
  font-weight: var(--fw-semi);
  letter-spacing: .14em;
  box-shadow: var(--shadow-md);
  transition: transform var(--dur-1) var(--ease-out),
              background var(--dur-2) var(--ease-out);
}
.hero-cta:hover { background: rgb(var(--zy-white)); }
.hero-cta:active { transform: scale(.96); }

.hero-dots {
  position: absolute;
  right: var(--s-5);
  bottom: var(--s-5);
  z-index: 3;
  display: flex;
  align-items: center;
  gap: var(--s-2);
}
/* 圆点改成 44px 命中区 + 内部细条，点得中又不显笨重 */
.hero-dot {
  position: relative;
  width: var(--tap-min);
  height: var(--tap-min);
  border: none;
  background: none;
}
.hero-dot::after {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  width: 6px; height: 6px;
  margin: -3px 0 0 -3px;
  border-radius: var(--r-full);
  background: rgb(var(--zy-white) / .45);
  transition: width var(--dur-2) var(--ease-out),
              margin var(--dur-2) var(--ease-out),
              background var(--dur-2) var(--ease-out);
}
.hero-dot.on::after {
  width: 18px;
  margin-left: -9px;
  background: rgb(var(--zy-white));
}

/* ==========================================================================
   4. 首页 · 区块标题
   ========================================================================== */
.section-head { margin-top: var(--s-7); margin-bottom: var(--s-4); }
.section-head__title {
  font-family: var(--font-serif);
  font-size: var(--t-h3);
  font-weight: var(--fw-semi);
  letter-spacing: .14em;
  color: var(--ink);
}
/* 标题下的一小段强调短线 —— 原站的记号，保留 */
.section-head__title::after {
  content: '';
  display: block;
  width: 18px;
  height: 2px;
  margin-top: var(--s-2);
  border-radius: var(--r-full);
  background: var(--accent-line);
}
.section-head__more {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  min-height: var(--tap-min);
  padding: 0 var(--s-2);
  margin-right: calc(var(--s-2) * -1);
  border: none;
  background: none;
  color: var(--accent);
  font-size: var(--t-xs);
  font-weight: var(--fw-medium);
}

/* ==========================================================================
   5. 首页 · 精选天然石（横滑）
   ========================================================================== */
.stone-zone {
  position: relative;
  margin: 0 var(--gutter);
  padding: var(--s-4) 0 var(--s-3);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  overflow: hidden;
}
.stone-scroll {
  display: flex;
  gap: var(--s-4);
  padding: 0 var(--s-4);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
}
.stone-scroll::-webkit-scrollbar { display: none; }
.stone-item {
  flex: 0 0 auto;
  width: 76px;
  padding: var(--s-1) var(--s-2);
  border-radius: var(--r-md);
  text-align: center;
  scroll-snap-align: start;
}
.stone-circle {
  display: block;
  width: 56px;
  height: 56px;
  margin: 0 auto var(--s-2);
  border-radius: var(--r-full);
  background-color: var(--surface-inset);
  box-shadow: var(--shadow-sm), inset 0 -2px 6px rgb(var(--zy-shadow) / .12);
}
.stone-name {
  display: block;
  font-size: var(--t-xs);
  font-weight: var(--fw-medium);
  letter-spacing: .04em;
  color: var(--ink);
}
.stone-desc {
  display: block;
  margin-top: 2px;
  font-size: var(--t-micro);
  color: var(--faint);
}

/* ==========================================================================
   6. 首页 · 作品展
   图片位由程序化珠串纹样承担；作品图恢复后自动盖在上面
   ========================================================================== */
.inspire-grid {
  display: flex;
  gap: var(--s-3);
  padding: 0 var(--gutter) var(--s-2);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  overscroll-behavior-x: contain;
}
.inspire-grid::-webkit-scrollbar { display: none; }

.inspire-card {
  flex: 0 0 auto;
  width: 176px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  overflow: hidden;
  text-align: left;
  scroll-snap-align: start;
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur-1) var(--ease-out),
              box-shadow var(--dur-2) var(--ease-out);
}
.inspire-card:hover { box-shadow: var(--shadow-md); }
.inspire-card:active { transform: scale(.98); }

.inspire-img {
  display: block;
  position: relative;
  aspect-ratio: 5 / 4;
  overflow: hidden;
  background: var(--surface-inset);
}
/* 程序化珠串底图（app.js 装饰层写入 backgroundImage） */
.bead-ring {
  position: absolute;
  inset: 0;
  display: block;
  background-repeat: no-repeat;
  background-size: 100% 100%;
}
/* 三张卡各自的底色，让珠串底色与卡名呼应 */
.inspire-img[data-scheme='春日治愈系'] { background: var(--zy-card-spring); }
.inspire-img[data-scheme='温柔守护']   { background: var(--zy-card-tender); }
.inspire-img[data-scheme='简约力量']   { background: var(--zy-card-plain); }
.inspire-img-overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgb(var(--zy-scrim) / .3) 0%, transparent 62%);
}
.inspire-body {
  display: block;
  padding: var(--s-3) var(--s-3) var(--s-4);
}
.inspire-name {
  display: block;
  margin-bottom: var(--s-1);
  font-family: var(--font-serif);
  font-size: var(--t-sm);
  font-weight: var(--fw-medium);
  letter-spacing: .06em;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.inspire-tags { display: block; }
.inspire-tag {
  display: inline-block;
  margin: 2px 3px 0 0;
  padding: 1px var(--s-2);
  border-radius: var(--r-full);
  background: var(--accent-soft);
  color: var(--accent);
  font-size: var(--t-micro);
}

/* ==========================================================================
   7. 设计手串 · 统计条
   ========================================================================== */
.stat-bar {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  padding: var(--s-3) var(--s-4);
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}
.stat { flex: 1; text-align: center; min-width: 0; }
.stat-l {
  display: block;
  margin-bottom: 2px;
  font-size: var(--t-micro);
  letter-spacing: var(--ls-caps);
  color: var(--faint);
}
.stat-v {
  display: block;
  font-family: var(--font-display);
  font-size: var(--t-h3);
  font-weight: var(--fw-semi);
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.stat-v.p { color: var(--accent); }
.stat-div {
  width: 1px;
  height: var(--s-7);
  flex: 0 0 auto;
  background: var(--line);
}
.act-btns { display: flex; gap: var(--s-2); margin-left: var(--s-3); flex-shrink: 0; }
.abtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--tap-min);
  height: var(--tap-min);
  border: none;
  border-radius: var(--r-full);
  transition: transform var(--dur-1) var(--ease-out);
}
.abtn:active { transform: scale(.93); }
.abtn-f {
  background: var(--accent);
  color: var(--on-accent);
  box-shadow: var(--shadow-sm);
}

/* ==========================================================================
   8. 设计手串 · 穿珠画布（本站的核心交互）
   ========================================================================== */
.canvas-area {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  padding: var(--s-3) 0;
  background: var(--surface-2);
  border-bottom: 1px solid var(--line);
}
.ring-wrap {
  position: relative;
  width: 168px;
  height: 168px;
}
.ring-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
/* 定位环：原站写死在 SVG 属性里，这里只给颜色与虚实 */
.ring-svg > circle:first-child {
  stroke: var(--accent-line);
  opacity: .55;
}
.ring-hint {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 118px;
  text-align: center;
  color: var(--muted);
  font-size: var(--t-xs);
  line-height: var(--lh-body);
  pointer-events: none;
}
.star-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  vertical-align: middle;
  color: var(--accent);
}
.star-ico svg { width: 10px; height: 10px; }
.arrow-ico { display: inline-flex; align-items: center; }
.arrow-ico svg { width: 14px; height: 14px; }

.ring-tools {
  position: absolute;
  right: var(--s-4);
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}
.rtool {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--tap-min);
  height: var(--tap-min);
  border: 1px solid var(--line);
  border-radius: var(--r-full);
  background: var(--surface);
  color: var(--ink-2);
  transition: background var(--dur-2) var(--ease-out),
              color var(--dur-2) var(--ease-out),
              transform var(--dur-1) var(--ease-out);
}
.rtool svg { width: 16px; height: 16px; }
.rtool:hover { background: var(--accent-soft); color: var(--accent); }
.rtool:active { transform: scale(.92); }

.sz-strip {
  position: absolute;
  left: var(--s-3);
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  align-items: center;
}
.sz-btn {
  width: var(--tap-min);
  height: 34px;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  background: none;
  color: var(--faint);
  font-family: var(--font-display);
  font-size: var(--t-xs);
  font-variant-numeric: tabular-nums;
  transition: background var(--dur-2) var(--ease-out),
              color var(--dur-2) var(--ease-out),
              border-color var(--dur-2) var(--ease-out);
}
.sz-btn:hover { border-color: var(--line); }
.sz-btn.on {
  background: var(--accent-soft);
  border-color: var(--accent-line);
  color: var(--accent);
  font-weight: var(--fw-semi);
}

/* ==========================================================================
   9. 设计手串 · 筛选与挑选
   ========================================================================== */
.el-tabs {
  display: flex;
  flex-shrink: 0;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}
.el-tab {
  flex: 1;
  min-height: var(--tap-min);
  padding: 0 var(--s-1);
  border: none;
  border-bottom: 2px solid transparent;
  background: none;
  color: var(--muted);
  font-size: var(--t-xs);
  letter-spacing: .08em;
  transition: color var(--dur-2) var(--ease-out),
              border-color var(--dur-2) var(--ease-out);
}
.el-tab.on {
  border-color: var(--accent);
  color: var(--accent);
  font-weight: var(--fw-semi);
}

/* 分类药丸：复用 .chip，只调间距 */
.chips {
  display: flex;
  gap: var(--s-2);
  flex-shrink: 0;
  padding: var(--s-3) var(--s-4);
  overflow-x: auto;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  scrollbar-width: none;
}
.chips::-webkit-scrollbar { display: none; }
.chips .chip { flex: 0 0 auto; }

.picker {
  display: flex;
  flex: 1;
  min-height: 0;
  overflow: hidden;
  background: var(--bg);
}
.color-side {
  width: 64px;
  flex-shrink: 0;
  overflow-y: auto;
  background: var(--surface);
  border-right: 1px solid var(--line);
  scrollbar-width: none;
}
.color-side::-webkit-scrollbar { display: none; }
.ci {
  display: block;
  width: 100%;
  padding: var(--s-3) 0;
  border: none;
  border-left: 3px solid transparent;
  background: none;
  color: var(--muted);
  font-size: var(--t-micro);
  letter-spacing: .02em;
  text-align: center;
  transition: color var(--dur-2) var(--ease-out),
              border-color var(--dur-2) var(--ease-out),
              background var(--dur-2) var(--ease-out);
}
.ci.on {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: var(--fw-semi);
}
.ci .cd {
  display: block;
  width: 14px;
  height: 14px;
  margin: 0 auto var(--s-1);
  border-radius: var(--r-full);
  box-shadow: var(--shadow-xs), inset 0 -1px 2px rgb(var(--zy-shadow) / .22);
}
.cd--white  { background: var(--zy-swatch-white); }
.cd--black  { background: var(--zy-swatch-black); }
.cd--red    { background: var(--zy-swatch-red); }
.cd--yellow { background: var(--zy-swatch-yellow); }
.cd--green  { background: var(--zy-swatch-green); }
.cd--blue   { background: var(--zy-swatch-blue); }
.cd--purple { background: var(--zy-swatch-purple); }
.cd--pink   { background: var(--zy-swatch-pink); }

/* 珠子网格 */
.bgrid-wrap {
  flex: 1;
  min-width: 0;
  overflow-y: auto;
  padding: var(--s-3) var(--s-2) calc(var(--safe-b) + var(--s-7));
  scrollbar-width: none;
}
.bgrid-wrap::-webkit-scrollbar { display: none; }
.bgrid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s-2);
}
/* 筛选组合无结果时（如「白色系 + 玛瑙」），renderGrid 会写空字符串。
   不给空态的话这里就是一块死白，补一句引导文案。
   纯 CSS 追加，不参与业务渲染，也不改变任何 id / class 契约。 */
.bgrid:empty::before {
  content: '这个筛选组合暂时没有珠子，换个材质或色系看看';
  grid-column: 1 / -1;
  padding: var(--s-8) var(--s-4);
  color: var(--muted);
  font-size: var(--t-sm);
  line-height: var(--lh-body);
  text-align: center;
}
.bc {
  position: relative;
  padding: var(--s-3) var(--s-2) var(--s-2);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
  text-align: center;
  cursor: pointer;
  transition: border-color var(--dur-2) var(--ease-out),
              box-shadow var(--dur-2) var(--ease-out),
              transform var(--dur-1) var(--ease-out);
}
.bc:hover { border-color: var(--accent-line); }
.bc:active { transform: scale(.95); }
.bc.sel {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-soft);
}
/* 石珠：底为矿石渐变（app.js 写入），图片只作覆盖层 */
.ball {
  position: relative;
  width: 44px;
  height: 44px;
  margin: 0 auto var(--s-2);
  border-radius: var(--r-full);
  overflow: hidden;
  background-color: var(--surface-inset);
  box-shadow: inset 0 -3px 7px rgb(var(--zy-shadow) / .16),
              inset 0 3px 7px rgb(var(--zy-white) / .5),
              var(--shadow-sm);
}
.ball::after {
  content: '';
  position: absolute;
  top: 8px; left: 9px;
  width: 11px; height: 7px;
  border-radius: var(--r-full);
  background: rgb(var(--zy-white) / .5);
  transform: rotate(-30deg);
  pointer-events: none;
}
/* 绳子：矩形色条，不是球 */
.ball-rope {
  width: 50px;
  height: 18px;
  margin: var(--s-3) auto var(--s-4);
  border-radius: var(--r-sm);
  box-shadow: inset 0 -2px 4px rgb(var(--zy-shadow) / .2),
              inset 0 2px 5px rgb(var(--zy-white) / .38),
              var(--shadow-xs);
}
.bc-rope { padding-top: var(--s-2); }
.bn {
  font-size: var(--t-micro);
  letter-spacing: .02em;
  color: var(--ink);
  margin-bottom: 2px;
}
.bp {
  font-family: var(--font-display);
  font-size: var(--t-xs);
  font-weight: var(--fw-semi);
  font-variant-numeric: tabular-nums;
  color: var(--accent);
}
.bsz {
  position: absolute;
  top: var(--s-1); right: var(--s-1);
  padding: 1px var(--s-1);
  border-radius: var(--r-xs);
  background: var(--surface-inset);
  color: var(--faint);
  font-size: var(--t-micro);
  line-height: 1.4;
}

/* ==========================================================================
   10. 定制详情
   ========================================================================== */
.preview-band {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  flex-shrink: 0;
  padding: var(--s-5) var(--s-5);
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}
.mini-ring-wrap { flex-shrink: 0; }
.mini-beads-info { flex: 1; min-width: 0; }
.mini-beads-info h3 {
  margin-bottom: var(--s-1);
  font-family: var(--font-serif);
  font-size: var(--t-h3);
  font-weight: var(--fw-semi);
  letter-spacing: .04em;
  color: var(--ink);
}
.mini-beads-info p { font-size: var(--t-xs); color: var(--muted); }
.price-line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3);
  margin-top: var(--s-3);
  padding-top: var(--s-3);
  border-top: 1px solid var(--line);
}
.price-line span { font-size: var(--t-xs); color: var(--faint); }
.price-line strong {
  font-family: var(--font-display);
  font-size: var(--t-h2);
  font-weight: var(--fw-semi);
  font-variant-numeric: tabular-nums;
  color: var(--accent);
}

.form-body { padding: var(--s-5) var(--gutter) calc(var(--safe-b) + var(--s-7)); }
.form-sec {
  margin-bottom: var(--s-4);
  padding: var(--s-5);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
}
.form-sec-title {
  margin-bottom: var(--s-4);
  font-size: var(--t-micro);
  letter-spacing: var(--ls-caps);
  color: var(--faint);
}
.form-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
}
.form-label { font-size: var(--t-sm); color: var(--ink-2); }
.form-hint {
  font-family: var(--font-display);
  font-size: var(--t-body);
  font-weight: var(--fw-semi);
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.cta-full {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  width: 100%;
  min-height: 52px;
  margin-top: var(--s-6);
  border: none;
  border-radius: var(--r-full);
  font-family: var(--font-serif);
  font-size: var(--t-h3);
  font-weight: var(--fw-semi);
  letter-spacing: .16em;
  transition: background var(--dur-2) var(--ease-out),
              transform var(--dur-1) var(--ease-out),
              box-shadow var(--dur-2) var(--ease-out);
}
.cta-full:active { transform: scale(.98); }
.cta-rg {
  background: var(--accent);
  color: var(--on-accent);
  box-shadow: var(--shadow-md);
}
.cta-rg:hover { background: var(--accent-hi); }

/* ==========================================================================
   11. 确认订单
   ========================================================================== */
.confirm-body { padding-bottom: var(--s-4); }
.addr-box,
.order-section,
.price-detail {
  margin: var(--s-4) var(--gutter) 0;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  overflow: hidden;
}
.addr-box { padding: var(--s-5); }

.addr-hd {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--s-3);
}
.addr-hd span { font-size: var(--t-micro); letter-spacing: var(--ls-caps); color: var(--faint); }
.addr-hd a { font-size: var(--t-xs); color: var(--accent); cursor: pointer; }
.addr-name {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  margin-bottom: var(--s-1);
  font-size: var(--t-h3);
  font-weight: var(--fw-medium);
  color: var(--ink);
}
.addr-phone { margin-bottom: var(--s-2); font-size: var(--t-sm); color: var(--muted); }
.addr-street { font-size: var(--t-sm); line-height: var(--lh-body); color: var(--muted); }

.order-section-title {
  padding: var(--s-4) var(--s-5) 0;
  font-size: var(--t-micro);
  letter-spacing: var(--ls-caps);
  color: var(--faint);
}
/* .order-row 的布局交给共享 .kv；这里只保留**这一站特有的左右内距**
   （共享 .kv 只管 padding-block，行贴在卡片里的水平位置是站点自己的事）*/
.order-row { padding-inline: var(--s-5); }
.order-section-title + .order-row { margin-top: var(--s-3); border-top: 1px solid var(--line); }
.order-row .lbl { flex: 0 0 auto; color: var(--muted); }
.order-row .val {
  min-width: 0;
  text-align: right;
  color: var(--ink);
  font-weight: var(--fw-medium);
  font-variant-numeric: tabular-nums;
}
.order-row .val--paid {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  color: var(--accent);
}

.price-detail { padding: var(--s-2) 0; }
.pd-row { padding-inline: var(--s-5); }
.pd-row .l { color: var(--muted); }
.pd-row .r { color: var(--ink); font-variant-numeric: tabular-nums; }
.pd-row.total { background: var(--surface-2); }
.pd-row.total .l { color: var(--ink); font-weight: var(--fw-medium); }
.pd-row.total .r {
  font-family: var(--font-display);
  font-size: var(--t-h2);
  font-weight: var(--fw-semi);
  color: var(--accent);
}

.bottom-order {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  flex-shrink: 0;
  padding: var(--s-4) var(--gutter) calc(var(--safe-b) + var(--s-4));
  background: var(--surface);
  border-top: 1px solid var(--line);
}
.total-mini .l { font-size: var(--t-micro); color: var(--faint); }
.total-mini .r {
  font-family: var(--font-display);
  font-size: var(--t-h1);
  font-weight: var(--fw-semi);
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
  color: var(--accent);
}
.submit-btn {
  min-height: 52px;
  padding: 0 var(--s-7);
  border: none;
  border-radius: var(--r-full);
  background: var(--accent);
  color: var(--on-accent);
  font-family: var(--font-serif);
  font-size: var(--t-h3);
  font-weight: var(--fw-semi);
  letter-spacing: .12em;
  box-shadow: var(--shadow-md);
  transition: background var(--dur-2) var(--ease-out),
              transform var(--dur-1) var(--ease-out);
}
.submit-btn:hover { background: var(--accent-hi); }
.submit-btn:active { transform: scale(.96); }

/* ==========================================================================
   12. 提交成功
   ========================================================================== */
.success-body {
  align-items: center;
  display: flex;
  flex-direction: column;
  padding: var(--s-8) var(--s-6) calc(var(--safe-b) + var(--s-7));
  text-align: center;
}
.success-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 96px;
  height: 96px;
  margin-bottom: var(--s-5);
  border-radius: var(--r-full);
  background: var(--accent-soft);
  color: var(--accent);
  box-shadow: var(--shadow-md);
}
.success-icon svg { width: 46px; height: 46px; }
.success-title {
  margin-bottom: var(--s-2);
  font-family: var(--font-serif);
  font-size: var(--t-h1);
  font-weight: var(--fw-semi);
  letter-spacing: .12em;
  color: var(--ink);
}
.success-sub {
  margin-bottom: var(--s-7);
  font-size: var(--t-sm);
  line-height: var(--lh-body);
  color: var(--muted);
}
.order-info-card {
  width: 100%;
  margin-bottom: var(--s-6);
  padding: var(--s-5);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  text-align: left;
}
.oic-row { padding-block: var(--s-2); }
.oic-row .k { flex: 0 0 auto; color: var(--faint); }
.oic-row .v {
  min-width: 0;
  text-align: right;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.oic-row .v.hi {
  font-family: var(--font-display);
  font-size: var(--t-h3);
  font-weight: var(--fw-semi);
  color: var(--accent);
}
.oic-row .v--wrap { max-width: 58%; line-height: var(--lh-tight); }
.success-btns { display: flex; flex-direction: column; gap: var(--s-3); width: 100%; }
.sbt {
  width: 100%;
  min-height: 52px;
  border: 1px solid transparent;
  border-radius: var(--r-full);
  font-family: var(--font-serif);
  font-size: var(--t-body);
  font-weight: var(--fw-medium);
  letter-spacing: .14em;
  transition: background var(--dur-2) var(--ease-out),
              transform var(--dur-1) var(--ease-out);
}
.sbt:active { transform: scale(.98); }
.sbt-dark { background: var(--ink); color: var(--bg); }
.sbt-dark:hover { background: var(--ink-2); }
.sbt-outline {
  background: transparent;
  border-color: var(--accent-line);
  color: var(--accent);
}
.sbt-outline:hover { background: var(--accent-soft); }

/* ==========================================================================
   13. 天然石图鉴
   ========================================================================== */
.stone-catalog-body {
  display: flex;
  flex: 1;
  min-height: 0;
  overflow: hidden;
}
.stone-cat-side {
  width: 64px;
  flex-shrink: 0;
  overflow-y: auto;
  background: var(--surface);
  border-right: 1px solid var(--line);
  scrollbar-width: none;
}
.stone-cat-side::-webkit-scrollbar { display: none; }
.stone-cat-ci {
  display: block;
  padding: var(--s-3) 0;
  border-left: 3px solid transparent;
  color: var(--muted);
  font-size: var(--t-micro);
  line-height: 1.35;
  text-align: center;
  cursor: pointer;
  transition: color var(--dur-2) var(--ease-out),
              border-color var(--dur-2) var(--ease-out),
              background var(--dur-2) var(--ease-out);
}
.stone-cat-ci.on {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: var(--fw-semi);
}
.stone-cat-ci .cd {
  width: 14px;
  height: 14px;
  margin: 0 auto var(--s-1);
  border-radius: var(--r-full);
  box-shadow: var(--shadow-xs), inset 0 -1px 2px rgb(var(--zy-shadow) / .22);
}
.stone-cat-main { padding: var(--s-4) var(--s-3) calc(var(--safe-b) + var(--s-7)); }

.stone-catalog-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s-3);
}
.stone-cat-item {
  padding: var(--s-2) var(--s-1);
  border-radius: var(--r-md);
  text-align: center;
  cursor: pointer;
  transition: background var(--dur-2) var(--ease-out),
              box-shadow var(--dur-2) var(--ease-out),
              transform var(--dur-1) var(--ease-out);
}
.stone-cat-item:hover {
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  transform: translateY(-1px);
}
.stone-cat-circle {
  position: relative;
  width: 54px;
  height: 54px;
  margin: 0 auto var(--s-2);
  border-radius: var(--r-full);
  overflow: hidden;
  background-color: var(--surface-inset);
  box-shadow: var(--shadow-sm), inset 0 -2px 6px rgb(var(--zy-shadow) / .14);
}
.stone-cat-circle::after {
  content: '';
  position: absolute;
  top: 7px; left: 10px;
  width: 14px; height: 9px;
  border-radius: var(--r-full);
  background: rgb(var(--zy-white) / .45);
  transform: rotate(-25deg);
  pointer-events: none;
}
.stone-cat-name {
  margin-bottom: 1px;
  font-size: var(--t-xs);
  font-weight: var(--fw-medium);
  letter-spacing: .02em;
  color: var(--ink);
}
.stone-cat-desc { font-size: var(--t-micro); line-height: 1.35; color: var(--faint); }
/* 绳子在图鉴里也是矩形色条，与珠子区分 */
.cat-circle-rope {
  width: 50px;
  height: 18px;
  margin-bottom: var(--s-3);
  border-radius: var(--r-sm);
}
.cat-circle-rope::after { display: none; }

/* ==========================================================================
   14. 弹层
   ========================================================================== */
.cat-overlay,
.ws-overlay,
.poster-overlay {
  position: absolute;
  inset: 0;
  z-index: var(--z-modal);
  display: none;
  align-items: center;
  justify-content: center;
  padding: var(--s-5);
  background: rgb(var(--zy-scrim) / .42);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}
.cat-overlay.show,
.ws-overlay.show,
.poster-overlay.show { display: flex; }
.poster-overlay { z-index: var(--z-drawer); }

/* 图鉴信息卡 */
.cat-card {
  position: relative;
  width: 100%;
  max-width: 210px;
  padding: var(--s-6) var(--s-5) var(--s-5);
  border-radius: var(--r-lg);
  background: var(--surface);
  text-align: center;
  box-shadow: var(--shadow-xl);
  animation: zhuyu-pop var(--dur-3) var(--ease-spring) both;
}
@keyframes zhuyu-pop {
  from { opacity: 0; transform: scale(.94); }
  to   { opacity: 1; transform: none; }
}
.cat-card-close {
  position: absolute;
  top: var(--s-2); right: var(--s-2);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px; height: 32px;
  border: none;
  border-radius: var(--r-full);
  background: var(--surface-inset);
  color: var(--muted);
  font-size: var(--t-xs);
  line-height: 1;
}
.cat-card-close:hover { background: var(--accent-soft); color: var(--accent); }
.cat-card-visual {
  width: 62px;
  height: 62px;
  margin: 0 auto var(--s-4);
  border-radius: var(--r-full);
  background-color: var(--surface-inset);
  background-repeat: no-repeat;
  box-shadow: var(--shadow-sm), inset 0 -2px 6px rgb(var(--zy-shadow) / .14);
}
.cat-card-visual.cat-vis-rope {
  width: 58px;
  height: 20px;
  border-radius: var(--r-sm);
}
.cat-card-name {
  margin-bottom: var(--s-2);
  font-family: var(--font-serif);
  font-size: var(--t-h3);
  font-weight: var(--fw-semi);
  letter-spacing: .12em;
  color: var(--ink);
}
.cat-card-desc { font-size: var(--t-sm); line-height: var(--lh-body); color: var(--muted); }

/* 手围弹层 */
.ws-card {
  width: 100%;
  max-width: 330px;
  padding: var(--s-6) var(--s-5) var(--s-5);
  border-radius: var(--r-xl);
  background: var(--surface);
  box-shadow: var(--shadow-xl);
  animation: zhuyu-pop var(--dur-3) var(--ease-spring) both;
}
.ws-card-title {
  margin-bottom: var(--s-1);
  font-family: var(--font-serif);
  font-size: var(--t-h2);
  font-weight: var(--fw-semi);
  letter-spacing: .12em;
  text-align: center;
  color: var(--ink);
}
.ws-card-sub {
  margin-bottom: var(--s-5);
  font-size: var(--t-xs);
  text-align: center;
  color: var(--faint);
}
.ws-label {
  margin-bottom: var(--s-2);
  font-size: var(--t-micro);
  letter-spacing: var(--ls-caps);
  color: var(--faint);
}
.ws-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--s-2);
  margin-bottom: var(--s-4);
}
.ws-item {
  padding: var(--s-3) var(--s-1);
  border: 1.5px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
  text-align: center;
  transition: border-color var(--dur-2) var(--ease-out),
              background var(--dur-2) var(--ease-out);
}
.ws-item:hover { border-color: var(--line-strong); }
.ws-item.on {
  border-color: var(--accent);
  background: var(--accent-soft);
}
.ws-item .ws-cm {
  display: block;
  font-family: var(--font-display);
  font-size: var(--t-h3);
  font-weight: var(--fw-semi);
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.ws-item.on .ws-cm { color: var(--accent); }
.ws-item .ws-cm--sm { font-size: var(--t-sm); }
.ws-item .ws-lbl { display: block; margin-top: 1px; font-size: var(--t-micro); color: var(--faint); }

.ws-custom-row { display: flex; gap: var(--s-2); margin-bottom: var(--s-4); }
.ws-custom-input {
  flex: 1;
  min-width: 0;
  padding: var(--s-3) var(--s-3);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  background: var(--surface-inset);
  color: var(--ink);
  font-size: var(--t-sm);
}
.ws-custom-input:focus {
  border-color: var(--accent);
  background: var(--surface);
}

.ws-rope-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin-bottom: var(--s-5);
}
/* 命中区 44px，珠子视觉 32px —— 点得中，看着仍然轻 */
.ws-rope {
  position: relative;
  width: var(--tap-min);
  height: var(--tap-min);
  border: none;
  background: none;
}
.ws-rope::after {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  width: 32px; height: 32px;
  margin: -16px 0 0 -16px;
  border: 2.5px solid transparent;
  border-radius: var(--r-full);
  background-clip: padding-box;
  transition: border-color var(--dur-2) var(--ease-out),
              box-shadow var(--dur-2) var(--ease-out);
}
.ws-rope.on::after {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.rope--mibai::after   { background: var(--zy-rope-cream); }
.rope--heise::after   { background: var(--zy-rope-black); }
.rope--hongse::after  { background: var(--zy-rope-red); }
.rope--jinse::after   { background: var(--zy-rope-gold); }
.rope--lanse::after   { background: var(--zy-rope-blue); }
.rope--touming::after {
  background: var(--zy-rope-clear);
  border-style: dashed;
  border-color: var(--line-strong);
}

.ws-confirm {
  width: 100%;
  min-height: 52px;
  border: none;
  border-radius: var(--r-full);
  background: var(--accent);
  color: var(--on-accent);
  font-family: var(--font-serif);
  font-size: var(--t-h3);
  font-weight: var(--fw-semi);
  letter-spacing: .14em;
  box-shadow: var(--shadow-md);
  transition: background var(--dur-2) var(--ease-out),
              transform var(--dur-1) var(--ease-out);
}
.ws-confirm:hover { background: var(--accent-hi); }
.ws-confirm:active { transform: scale(.97); }

/* 海报弹层 */
.poster-card {
  position: relative;
  width: 100%;
  max-width: min(400px, 90vw);
  max-height: 100%;
  display: flex;
  flex-direction: column;
  border-radius: var(--r-xl);
  background: var(--surface);
  overflow: hidden;
  box-shadow: var(--shadow-xl);
  animation: zhuyu-pop var(--dur-3) var(--ease-spring) both;
}
.poster-close {
  position: absolute;
  top: var(--s-3); right: var(--s-3);
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px; height: 32px;
  border: none;
  border-radius: var(--r-full);
  background: rgb(var(--zy-white) / .8);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  color: var(--ink-2);
  font-size: var(--t-xs);
  line-height: 1;
}
.poster-close:hover { background: rgb(var(--zy-white)); color: var(--ink); }
.poster-img-wrap {
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--s-3);
  background: var(--surface-inset);
  overflow: auto;
}
#poster-image {
  display: block;
  width: 100%;
  max-width: 344px;
  height: auto;
  border-radius: var(--r-md);
  box-shadow: var(--shadow-md);
}
.poster-actions {
  display: flex;
  gap: var(--s-3);
  flex-shrink: 0;
  padding: var(--s-4) var(--s-5) var(--s-5);
  background: var(--surface);
}
.poster-btn {
  flex: 1;
  min-height: 48px;
  border: none;
  border-radius: var(--r-full);
  font-family: var(--font-serif);
  font-size: var(--t-sm);
  font-weight: var(--fw-medium);
  letter-spacing: .12em;
  transition: background var(--dur-2) var(--ease-out),
              transform var(--dur-1) var(--ease-out);
}
.poster-btn:active { transform: scale(.97); }
.poster-btn-primary {
  background: var(--accent);
  color: var(--on-accent);
  box-shadow: var(--shadow-sm);
}
.poster-btn-primary:hover { background: var(--accent-hi); }

/* ==========================================================================
   15. 兜底 toast 容器
   共享层的 window.toast 是主呈现（带图标、会排队）。
   这个容器只在 app-shell.js 未加载时才可能有内容，保持克制样式。
   ========================================================================== */
#toast {
  position: fixed;
  left: 50%;
  top: var(--s-5);
  z-index: var(--z-toast);
  max-width: min(90vw, 360px);
  padding: var(--s-2) var(--s-5);
  border-radius: var(--r-full);
  /* 与共享层 toast 用同一对令牌，别再各自取 --ink/--bg */
  background: var(--ink-surface);
  color: var(--on-ink-surface);
  font-size: var(--t-sm);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0;
  transform: translateX(-50%) translateY(-8px);
  pointer-events: none;
  transition: opacity var(--dur-2) var(--ease-out),
              transform var(--dur-2) var(--ease-out);
}
#toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
#toast:empty { display: none; }

/* ==========================================================================
   16. 键盘可达性
   renderGrid / renderStoneGrid / showStoneCatalog 生成的是 div，
   由站点装配层补 role 与 tabindex；这里给它们焦点环与按压反馈。
   ========================================================================== */
.bc[role='button']:focus-visible,
.stone-cat-item[role='button']:focus-visible,
.stone-cat-ci[role='button']:focus-visible {
  outline: 2px solid var(--line-focus);
  outline-offset: 2px;
}

/* ==========================================================================
   17. 窄屏收敛
   ========================================================================== */
@media (max-width: 359px) {
  .hero-carousel { height: 240px; }
  .color-side { width: 56px; }
  .bgrid { gap: var(--s-1); }
  .ball { width: 38px; height: 38px; }
  .ring-wrap { width: 148px; height: 148px; }
}


/* ==========================================================================
   重构层 —— 按 xiao9qianduan 规范收口（精确命中版）
   --------------------------------------------------------------------------
   为什么写在各站自己的 CSS 里、不动共享层：
     共享层 7 站同步，改它会连带改到音纪（不在本次范围内）。
     各站 CSS 在 components.css 之后加载，覆盖一定生效。

   ⚠ 上一版我用了 `[class*='-card']` `[class*='__item']` `[class*='stat']`
     这类通配选择器，闯了三个祸，记录在此以免重蹈：
       1. `.glass` 命中了珠语首屏的 `<div class="glass hero-tag">`，
          把半透明标签刷成实色白块 —— 首屏大图上糊了一块白。
       2. `[class*='__item']` 命中润凯的 `.tab-item` / `.slider-item`，
          给它们强制加过渡，搅乱了它自己的跑马灯时序。
       3. `p, .desc, [class*='-desc'] { font-size: max(16px,1em) }` 一次性放大了
          大量本该更小的文字，各处换行崩坏。
     结论：**这个项目的类名体系没有统一命名法，通配选择器必然误伤。**
     改样式只能逐个类名精确写，改一条验一条。

   本文件只做三件低风险、可验证的事，都用精确类名。
   ========================================================================== */

:root {
  /* expo-out：前快后慢的减速。规范里所有 reveal / hover 都用它。 */
  --rf-ease: cubic-bezier(.16, 1, .3, 1);
}

/* ---------- 1. 缓动统一到 expo-out --------------------------------------
   只挑语义明确的"交互反馈"类名，不碰动画容器和列表项。 */
.btn,
.cta,
.chip,
.tab-btn,
.el-tab,
.sz-btn,
.ws-item,
.ws-rope,
.rope-swatch,
.ci,
.bc,
.stone-cat-ci,
.stone-cat-item {
  transition-timing-function: var(--rf-ease) !important;
}

/* ---------- 2. 数字等宽 -------------------------------------------------
   金额/颗数/百分比一变就左右跳，显业余。只命中数值语义的类。 */
.bp,
.bp *,
.bsz,
#sub,
#cnt,
.hero-stat-num,
.hero-stat-label,
.ring__num,
.progress__val,
.price,
.price *,
.amount,
.pay-num,
.order-num,
.stat-num,
.score,
.score-num {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

/* ---------- 3. 键盘焦点可见 ---------------------------------------------
   规范：focus 环必须即时出现，不做出现动画。 */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ---------- 4. 【已移除】毛玻璃收口 ----------
   这里原先有一组规则，把 .glass-card / .feature-card / .poster-card 等 10 个类名
   强制刷成实色 + 细边框，依据是规范里"只有导航栏可以用毛玻璃"。

   删掉的原因 —— 实机量完之后，它在**这一站里一个正确目标都没有**：
     · 全站真正带 backdrop-filter 的元素共 13~19 个，逐个看过，全是
       顶栏 / 底栏 / 模态遮罩 / 悬浮在照片上的标签 —— 正是规范允许的那类"表层"。
     · 唯一被它刷实的 5 个 .glass-card 全是压在图上的叠层
       （.gallery-item-bottom、.cs-image-overlay），背后是照片，模糊是必要的。
     · 9033 的 .feature-card--dark（九宫格唯一的深色落点）被刷成白底白字。
     · !important 不看特异性，会连变体自己的 background/border/box-shadow
       一起压掉 —— 用一个没上过实机的猜想覆盖了 8 个类名的真实样式。

   教训：**"某个属性在 CSS 里出现 N 次"不等于"N 处滥用"**。
   前者是数声明，后者得数**真的渲染出来的元素**，还得看它背后是什么。
   -------------------------------------------------------------------------- */

/* ---------- 5. 【已移除】触控目标下限 ----------
   这里原先强制 .btn / .chip / .sz-btn 等类 min-height:44px，依据是规范里
   "可点击区域 ≥ 44px"。

   删掉的原因 —— 实测它同时抬高和压低，而且压过的是作者**显式写死**的值：
     · 珠语 .sz-btn 34 -> 44：尺码条是 44 宽 x 34 高的竖排，撑高后整条
       从 186px 变 236px，把珠子网格往下推。
     · 珠语 .chip 32 -> 44：色系药丸行 40 -> 69px。
     · 礼续 .chip--sm 26 -> 44：那是**非交互**的 <span> 标签，撑高纯属破坏。
     · 归家 .btn--lg 52 -> 44、礼续 .gen-btn 54 -> 44：主 CTA 被**压扁**。
   而在多数站点它根本是空操作 —— 共享层
       .btn { min-height: var(--tap-min) }      // tokens.css: --tap-min: 44px
   和各站的 .el-tab { min-height: var(--tap-min) } 早已满足 44px。

   根因：带 !important 的 min-height 会**双向**覆盖，不管作者写的值
   是比 44 大还是比 44 小。而这里每个小于 44 的元素都是有意为之
   （尺码条 44x34、药丸 32 高），不是没设计过。
   真要兜底，该用 `min-height: max(44px, <作者值>)` 这类"只抬高不压低"的写法 ——
   但 CSS 取不到"元素自己的原值"，所以宁可交给作者。
   -------------------------------------------------------------------------- */

