/* ==========================================================================
   礼·续 · LIXU
   lixu.css —— 站点皮肤层
   --------------------------------------------------------------------------
   只消费 design-system 的令牌（主题 xuan-night：暖黑底 + 金强调）。

   本站的视觉契约（从原站继承，必须保住）：
     · 直角金线 —— 圆角一律 --r-xs（4px），不用大圆角
     · 金色高光渐变（--ink → --accent-hi → --accent）
     · 衬线体（--font-display = Newsreader + Noto Serif SC）
     · 发丝线、菱形节点、字距拉开的英文小标
     · 暗色暖黑底（--bg #14120F），不是冷调科技黑

   原站自定义令牌 -> 设计系统令牌 的映射（全部已替换，不留旧变量）：
     --gold       -> --accent        --gold-light -> --accent-hi
     --cream      -> --ink           --ink(#070705) -> --bg
     --muted      -> --muted         --border     -> --line / --accent-line
     --jade 系    -> --accent（见 AUDIT.md「关于原站的茶绿辅助色」一节）

   本文件不出现任何字面色值：颜色、字号、圆角、间距、动效全部走令牌。
   唯一例外是 lixu-art.js 里内联 SVG 的字面量 —— data-uri 里的 SVG 是
   独立文档，读不到页面上的 CSS 变量，这是 DESIGN-SYSTEM 第 1 节认可的例外。
   ========================================================================== */

/* 金色高光渐变。三个停靠点全部指向令牌，改令牌即改渐变。 */
:root {
  --gold-grad: linear-gradient(135deg,
    var(--ink) 0%, var(--accent-hi) 38%, var(--accent) 72%, var(--accent-hi) 100%);
}

/* ==========================================================================
   1. 版式基础
   ========================================================================== */
body {
  font-family: var(--font-serif);
  background: var(--bg);
  color: var(--ink);
}

/* 极细纸纹。原站用 feTurbulence 噪点铺满全屏且 z-index 9000，
   这里保留「覆盖全站」的观感但挂到 --z-toast 档：
   高于弹层（--z-modal），低于加载遮罩（--z-loading），
   且 pointer-events:none —— 不影响任何点击命中。
   注意：不要给 .app 的子元素批量加 z-index，那会把 .topbar（--z-nav）
   和弹层（--z-modal）压到同一层，导致顶栏盖住弹层、遮罩点不中。 */
.app::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: var(--z-toast);
  pointer-events: none;
  opacity: .5;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.03'/%3E%3C/svg%3E");
}

/* ==========================================================================
   2. 顶栏品牌
   ========================================================================== */
.topbar__brand { display: flex; flex-direction: column; justify-content: center; min-width: 0; }
.brand-mark {
  font-family: var(--font-display);
  font-size: var(--t-h3);
  font-weight: var(--fw-semi);
  letter-spacing: .14em;
  color: var(--ink);
  line-height: 1.1;
}
.brand-sub {
  font-size: var(--t-micro);
  letter-spacing: var(--ls-caps);
  /* 可见副标而非装饰文字，用 --muted（5.5:1）过 AA */
  color: var(--muted);
  margin-top: 1px;
}

/* ==========================================================================
   3. 主视觉 HERO
   ========================================================================== */
.hero {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: var(--s-9) var(--s-7) var(--s-8);
}

.hero__glow {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 58% 42% at 50% 34%,
      color-mix(in srgb, var(--accent) 12%, transparent) 0%,
      color-mix(in srgb, var(--accent) 6%, transparent) 44%,
      transparent 64%),
    radial-gradient(ellipse 62% 32% at 50% 88%,
      color-mix(in srgb, var(--accent) 7%, transparent) 0%,
      transparent 52%);
}

.hero__eyebrow {
  position: relative;
  font-size: var(--t-micro);
  font-weight: var(--fw-medium);
  letter-spacing: .42em;
  color: var(--accent);
  margin-bottom: var(--s-5);
  opacity: .85;
}

.hero__title-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--s-4);
  width: 100%;
}

.hero__title {
  font-family: var(--font-display);
  font-size: clamp(46px, 14vw, 84px);
  font-weight: var(--fw-bold);
  line-height: 1.02;
  letter-spacing: .04em;
  background: var(--gold-grad);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: var(--accent);   /* 不支持 background-clip 时的回退，仍是金色 */
  white-space: nowrap;
}

/* 标题两侧的发丝线与菱形节点 —— 本站的标志性细节 */
.ht-deco {
  position: relative;
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--accent));
}
.ht-deco:last-child { background: linear-gradient(90deg, var(--accent), transparent); }
.ht-diamond {
  position: absolute;
  top: 50%;
  right: -3px;
  width: 5px; height: 5px;
  background: var(--accent);
  transform: translateY(-50%) rotate(45deg);
}
.ht-deco:last-child .ht-diamond { right: auto; left: -3px; }

.hero__sub {
  position: relative;
  margin-top: var(--s-5);
  font-size: var(--t-xs);
  font-weight: var(--fw-light);
  letter-spacing: .46em;
  color: var(--ink-2);
  opacity: .78;
}

.hero__divider {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--s-3);
  width: 100%;
  max-width: 168px;
  margin-top: var(--s-5);
}
.hd-line {
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
}
.hd-diamond { width: 4px; height: 4px; background: var(--accent); transform: rotate(45deg); flex-shrink: 0; }

/* 浮尘粒子。6 个，位置写在 CSS 里，替掉原站 8 条内联 style。 */
.hero__particles { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.particle {
  position: absolute;
  width: 3px; height: 3px;
  border-radius: var(--r-full);
  background: var(--accent);
  opacity: 0;
  animation: floatParticle 6.4s var(--ease-soft) infinite;
}
.particle:nth-child(1) { left: 8%;  top: 22%; animation-delay: 0s;   animation-duration: 6s; }
.particle:nth-child(2) { left: 22%; top: 66%; animation-delay: 1.2s; animation-duration: 7.5s; width: 2px; height: 2px; }
.particle:nth-child(3) { left: 47%; top: 13%; animation-delay: 2.5s; animation-duration: 5.5s; }
.particle:nth-child(4) { left: 71%; top: 52%; animation-delay: .6s;  animation-duration: 8s;   width: 2px; height: 2px; }
.particle:nth-child(5) { left: 88%; top: 29%; animation-delay: 3.2s; animation-duration: 6.6s; }
.particle:nth-child(6) { left: 38%; top: 43%; animation-delay: .9s;  animation-duration: 7.8s; width: 2px; height: 2px; }

@keyframes floatParticle {
  0%   { opacity: 0;   transform: translateY(10px); }
  16%  { opacity: .34; }
  52%  { transform: translateY(-30px) translateX(7px); }
  86%  { opacity: .14; }
  100% { opacity: 0;   transform: translateY(-58px) translateX(-4px); }
}

/* ==========================================================================
   4. 页签导航
   ========================================================================== */
.feat-nav {
  position: sticky;
  top: calc(var(--header-h) + var(--safe-t));
  z-index: var(--z-sticky);
  display: flex;
  gap: 0;
  overflow-x: auto;
  scrollbar-width: none;
  padding-inline: var(--s-5);
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: saturate(1.4) blur(14px);
  -webkit-backdrop-filter: saturate(1.4) blur(14px);
  border-bottom: 1px solid var(--line);
}
.feat-nav::-webkit-scrollbar { display: none; }

.feat-tab {
  position: relative;
  min-height: var(--tap-min);          /* 44px 最小点击高度 */
  padding: var(--s-3) var(--s-4);
  border: 0;
  background: none;
  color: var(--muted);
  font-family: var(--font-serif);
  font-size: var(--t-sm);
  letter-spacing: .1em;
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--dur-2) var(--ease-out);
}
.feat-tab::after {
  content: '';
  position: absolute;
  left: var(--s-4); right: var(--s-4); bottom: -1px;
  height: 2px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: center;
  transition: transform var(--dur-3) var(--ease-out);
}
.feat-tab:hover { color: var(--ink-2); }
.feat-tab.active { color: var(--ink); }
.feat-tab.active::after { transform: scaleX(1); }
/* 状态不只用颜色：当前页签额外加一个金色菱形标记 */
.feat-tab.active::before {
  content: '';
  position: absolute;
  left: 50%; top: 7px;
  width: 3px; height: 3px;
  margin-left: -1.5px;
  background: var(--accent);
  transform: rotate(45deg);
}

.feat-panels { padding-inline: var(--s-5); }

.feat-panel { display: none; padding-top: var(--s-8); }
.feat-panel.active { display: block; }
.feat-panel:focus-visible { outline-offset: -2px; }

.panel-eyebrow {
  font-size: var(--t-micro);
  font-weight: var(--fw-medium);
  letter-spacing: .42em;
  color: var(--accent);
  opacity: .78;
  margin-bottom: var(--s-3);
}
.panel-title {
  font-family: var(--font-display);
  font-size: var(--t-display);
  font-weight: var(--fw-normal);
  line-height: var(--lh-heading);
  letter-spacing: var(--ls-heading);
  color: var(--ink);
  margin-bottom: var(--s-6);
}
/* 关键词靠斜体与金色分层，不给每个词乱换色 */
.panel-title em {
  font-style: italic;
  color: var(--accent);
}

/* ==========================================================================
   5. 匠心故事
   ========================================================================== */

/* --- 工艺展示卡 --- */
.craft-showcase {
  border: 1px solid var(--accent-line);
  border-radius: var(--r-xs);
  overflow: hidden;
  margin-bottom: var(--s-4);
  background: var(--surface);
}

.cs-image {
  position: relative;
  height: 232px;
  border-radius: 0;
  background: var(--surface-inset);
}
.cs-image > img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity var(--dur-4) var(--ease-out);
}
.cs-image > img.active { opacity: 1; }

.cs-image-overlay {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 2;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s-3);
  padding: var(--s-4);
  background: linear-gradient(transparent, color-mix(in srgb, var(--bg) 88%, transparent));
}
.cs-image-tag {
  /* 外观交给共享 .badge--on-media —— 原来用 --bg 62% 做底，
     在浅色主题下等于盖了一层白雾，照片上的白字反而更读不出来。
     字距是本站的排版个性，保留。 */
  letter-spacing: .22em;
}
.cs-image-loc {
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--t-sm);
  color: var(--ink);
  opacity: .9;
  text-align: right;
}

.cs-details { padding: var(--s-5); }
.cs-label {
  font-size: var(--t-micro);
  letter-spacing: .42em;
  color: var(--accent);
  opacity: .75;
  margin-bottom: var(--s-2);
}
.cs-title {
  font-size: var(--t-h3);
  letter-spacing: var(--ls-heading);
  color: var(--ink);
  margin-bottom: var(--s-5);
}

/* 工艺三步：序号 + 连线 + 菱形端点 */
.cs-steps {
  display: flex;
  align-items: center;
  list-style: none;
  margin: 0;
  padding: 0;
}
.cs-step { display: flex; align-items: center; gap: var(--s-2); min-width: 0; }
.cs-step-num {
  font-family: var(--font-display);
  font-size: var(--t-h3);
  font-weight: var(--fw-bold);
  /* 原 46% 透明 = 2.9:1。它是"步骤序号"，是内容不是装饰，必须读得清 */
  color: var(--accent);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.cs-step-text {
  font-size: var(--t-xs);
  color: var(--muted);
  letter-spacing: .02em;
}
.cs-step-line {
  flex: 1;
  min-width: var(--s-4);
  height: 1px;
  margin-inline: var(--s-2);
  position: relative;
  background: linear-gradient(90deg, var(--accent-line), transparent);
}
.cs-step-line::after {
  content: '';
  position: absolute;
  right: 0; top: 50%;
  width: 3px; height: 3px;
  background: var(--accent);
  opacity: .5;
  transform: translateY(-50%) rotate(45deg);
}

/* --- 时间轴 --- */
.story-timeline {
  position: relative;
  padding-left: var(--s-6);
  margin-bottom: var(--s-6);
}
.story-timeline::before {
  content: '';
  position: absolute;
  left: 0; top: var(--s-2); bottom: var(--s-2);
  width: 1px;
  background: linear-gradient(180deg, var(--accent), transparent);
}

.story-node {
  position: relative;
  padding-bottom: var(--s-7);
  opacity: 0;
  transform: translateX(-10px);
  transition: opacity var(--dur-4) var(--ease-out), transform var(--dur-4) var(--ease-out);
}
.story-node.vis { opacity: 1; transform: translateX(0); }
.story-node:last-child { padding-bottom: 0; }
.story-node::before {
  content: '';
  position: absolute;
  /* 金色节点要与 .story-timeline 的 1px 竖线严格对齐。
     竖线在 padding 盒原点处（宽 1px），所以节点中心应落在 -0.5px；
     节点自身 8px 宽，故 left = -0.5 - 4。留 0.5px 让圆点视觉居中。 */
  left: calc(var(--s-6) * -1 - 4.5px);
  top: 6px;
  width: 8px; height: 8px;
  border-radius: var(--r-full);
  background: var(--accent);
  box-shadow: 0 0 12px color-mix(in srgb, var(--accent) 42%, transparent);
}
.sn-tag {
  /* 外观交给共享 .badge--ghost；字距保留 */
  letter-spacing: .22em;
  margin-bottom: var(--s-1);
}
.sn-title {
  font-size: var(--t-body);
  font-weight: var(--fw-semi);
  color: var(--ink);
  letter-spacing: .02em;
  margin-bottom: var(--s-1);
}
.sn-body {
  font-size: var(--t-sm);
  font-weight: var(--fw-light);
  color: var(--muted);
  line-height: var(--lh-body);
  max-width: 34ch;
}

/* ==========================================================================
   6. 私人祝福
   ========================================================================== */
.blessing-sender {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  padding: var(--s-4) var(--s-5);
  border: 1px solid var(--line);
  border-radius: var(--r-xs);
  margin-bottom: var(--s-4);
  background: var(--surface);
}
.sender-avatar {
  width: 48px; height: 48px;
  flex-shrink: 0;
  border-radius: var(--r-full);
  border: 1px solid var(--accent-line);
  overflow: hidden;
}
.sender-avatar > img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sender-info { flex: 1; min-width: 0; }
.sender-name {
  font-size: var(--t-body);
  color: var(--ink);
  letter-spacing: .02em;
  margin-bottom: 2px;
}
.sender-role { font-size: var(--t-xs); color: var(--muted); letter-spacing: .04em; }

/* --- 祝福卡 --- */
.blessing-card {
  position: relative;
  margin: 0 0 var(--s-4);
  padding: var(--s-7) var(--s-5) var(--s-4);
  border: 1px solid var(--accent-line);
  border-radius: var(--r-xs);
  background:
    linear-gradient(145deg,
      color-mix(in srgb, var(--accent) 6%, transparent),
      transparent 62%),
    var(--surface);
}
.blessing-card::before {
  content: '\201C';
  position: absolute;
  top: var(--s-3); left: var(--s-4);
  font-family: var(--font-display);
  font-size: 56px;
  line-height: 1;
  color: color-mix(in srgb, var(--accent) 24%, transparent);
}
.blessing-text {
  position: relative;
  margin: 0;
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--t-h3);
  line-height: var(--lh-body);
  color: var(--ink);
  max-width: 30ch;
}
.blessing-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-4);
  margin-top: var(--s-4);
  padding-top: var(--s-3);
  border-top: 1px solid var(--line);
}
.bm-item {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--t-xs);
  color: var(--muted);
  letter-spacing: .04em;
}
.bm-item svg { color: var(--accent); flex: 0 0 auto; }

/* --- 语音祝福 --- */
.media-types { display: flex; flex-direction: column; gap: var(--s-3); }
.media-type {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  padding: var(--s-4);
  border: 1px solid var(--line);
  border-radius: var(--r-xs);
  background: var(--surface);
  transition: border-color var(--dur-2) var(--ease-out),
              background var(--dur-2) var(--ease-out);
}
.media-type:hover { border-color: var(--accent-line); background: var(--surface-2); }

.mt-icon-wrap {
  width: 44px; height: 44px;
  border-radius: var(--r-full);
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  color: var(--accent);
}
.mt-body { flex: 1; min-width: 0; }
.mt-label { font-size: var(--t-sm); color: var(--ink); margin-bottom: 2px; }
.mt-sub { font-size: var(--t-xs); color: var(--muted); margin-bottom: var(--s-2); }
.mt-bar {
  height: 3px;
  border-radius: var(--r-2xs);
  background: var(--surface-inset);
  overflow: hidden;
}
.mt-bar-fill {
  height: 100%;
  border-radius: var(--r-2xs);
  background: linear-gradient(90deg, var(--accent), var(--accent-lo));
  transition: width var(--dur-3) var(--ease-out);
}
.mt-play {
  flex-shrink: 0;
  width: var(--tap-min);
  height: var(--tap-min);
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-full);
  border: 1px solid var(--accent-line);
  background: var(--accent-soft);
  color: var(--accent);
  cursor: pointer;
  transition: background var(--dur-2) var(--ease-out),
              border-color var(--dur-2) var(--ease-out), color var(--dur-2) var(--ease-out);
}
.mt-play:hover { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
.mt-play[aria-disabled='true'] { opacity: .45; cursor: not-allowed; }

/* --- 龙井茶视频 --- */
.tea-video-preview {
  position: relative;
  height: 190px;
  margin-top: var(--s-4);
  border: 1px solid var(--line);
  border-radius: var(--r-xs);
  overflow: hidden;
  cursor: pointer;
  background: var(--surface-inset);
}
/* 视频封面图。素材 mp4 不可达时（服务端 EIO）浏览器会停用 poster 并把 video
   渲染成黑框，所以封面用一张真实的 <img> 承载 —— 它永远可见、可被 html2canvas
   抓取，也不依赖 <video> 的 poster 行为。
   视频可正常播放时由 lixu-boot.js 加 .is-live 把它淡出。 */
.tea-video-poster {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: opacity var(--dur-3) var(--ease-out);
}
.tea-video-preview.is-live .tea-video-poster { opacity: 0; }

.tea-video-player {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  background: transparent;
}
.tea-video-overlay {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--s-3);
  background: color-mix(in srgb, var(--bg) 42%, transparent);
  transition: opacity var(--dur-3) var(--ease-out);
}
.tea-video-preview.playing .tea-video-overlay { opacity: 0; pointer-events: none; }

.tvp-play-btn {
  width: 52px; height: 52px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding-left: 3px;
  border-radius: var(--r-full);
  border: 1px solid color-mix(in srgb, var(--ink) 42%, transparent);
  background: color-mix(in srgb, var(--bg) 46%, transparent);
  color: var(--ink);
  transition: background var(--dur-3) var(--ease-out),
              border-color var(--dur-3) var(--ease-out),
              transform var(--dur-3) var(--ease-out);
}
.tea-video-preview:hover .tvp-play-btn {
  background: color-mix(in srgb, var(--accent) 26%, transparent);
  border-color: var(--accent-hi);
  transform: scale(1.06);
}
.tvp-label {
  font-size: var(--t-xs);
  letter-spacing: .18em;
  color: var(--ink);
  opacity: .8;
}

.tvp-fs-btn {
  position: absolute;
  right: var(--s-3); bottom: var(--s-3);
  z-index: 3;
  width: var(--tap-min);
  height: var(--tap-min);
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-full);
  border: 1px solid var(--line-strong);
  background: color-mix(in srgb, var(--bg) 66%, transparent);
  color: var(--ink-2);
  cursor: pointer;
  transition: background var(--dur-2) var(--ease-out),
              border-color var(--dur-2) var(--ease-out), color var(--dur-2) var(--ease-out);
}
.tvp-fs-btn:hover {
  background: color-mix(in srgb, var(--accent) 24%, transparent);
  border-color: var(--accent-hi);
  color: var(--ink);
}

/* --- 隐私说明 --- */
.blessing-privacy {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  margin-top: var(--s-4);
  padding: var(--s-4);
  border: 1px solid var(--line);
  border-radius: var(--r-xs);
  background: var(--surface-inset);
}
.bp-icon { flex-shrink: 0; color: var(--accent); margin-top: 1px; }
.bp-text {
  margin: 0;
  font-size: var(--t-xs);
  font-weight: var(--fw-light);
  color: var(--ink-2);
  line-height: var(--lh-body);
}

/* ==========================================================================
   7. 社交分享
   ========================================================================== */
.share-preview {
  border: 1px solid var(--accent-line);
  border-radius: var(--r-xs);
  overflow: hidden;
  margin-bottom: var(--s-5);
  background: var(--surface);
}
.sp-preview-label {
  padding: var(--s-4) var(--s-5) 0;
  font-size: var(--t-micro);
  letter-spacing: .34em;
  color: var(--accent);
  opacity: .72;
}
.sp-brand-row {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-5) var(--s-4);
}
.sp-logo {
  width: 36px; height: 36px;
  flex-shrink: 0;
  border-radius: var(--r-sm);
  border: 1px solid var(--accent-line);
  overflow: hidden;
}
.sp-logo > img { width: 100%; height: 100%; display: block; object-fit: contain; }
.sp-brand-info { flex: 1; min-width: 0; }
.sp-brand-name { font-size: var(--t-sm); color: var(--ink); }
.sp-brand-tag { font-size: var(--t-micro); color: var(--muted); margin-top: 1px; }
.sp-certified {
  flex-shrink: 0;
  font-size: var(--t-micro);
  letter-spacing: .12em;
  color: var(--accent);
  border: 1px solid var(--accent-line);
  padding: var(--s-1) var(--s-2);
  white-space: nowrap;
}

.sp-image {
  position: relative;
  min-height: 200px;
  height: 220px;
  border-radius: 0;
  background: var(--surface-inset);
}
.sp-image > img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity var(--dur-4) var(--ease-out);
}
.sp-image > img.active { opacity: 1; }
/* 底部压暗：原站用来让照片上的文字可读。
   现在图是自绘的（lixu-art.js），画面底部已经自带暗调与留白，
   所以这里收到极轻的程度，只做一层刊物式的收边，不再糊掉图内文字。 */
.sp-image::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(180deg, transparent 78%, color-mix(in srgb, var(--bg) 34%, transparent));
}

.sp-caption {
  margin: 0;
  padding: var(--s-4) var(--s-5) 0;
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--t-sm);
  line-height: var(--lh-body);
  color: var(--ink-2);
}
.sp-bottom {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s-3);
  padding: var(--s-4) var(--s-5) var(--s-5);
}
.sp-tags { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.sp-tag {
  /* 外观交给共享 .chip；只保留色偏 */
  color: var(--accent);
}

/* --- 生成按钮：在 .btn.btn--primary 上只加本站的字距与金线质感 --- */
.gen-btn {
  min-height: 54px;
  border-radius: var(--r-xs);
  font-family: var(--font-serif);
  font-size: var(--t-sm);
  letter-spacing: .2em;
  gap: var(--s-3);
}
.gen-btn:disabled { opacity: .6; cursor: progress; }
.gen-btn-label { display: inline-block; }
.gen-hint {
  margin: var(--s-3) 0 0;
  font-size: var(--t-xs);
  /* 这是提示文案而非装饰文字，必须过 AA —— 用 --muted（5.5:1）不用 --faint（3.2:1） */
  color: var(--muted);
  text-align: center;
  line-height: var(--lh-body);
}

/* ==========================================================================
   8. 页脚
   ========================================================================== */
.site-foot {
  margin-top: var(--s-10);
  padding: var(--s-7) var(--s-5);
  border-top: 1px solid var(--line);
  text-align: center;
}
.site-foot p {
  font-size: var(--t-xs);
  letter-spacing: .16em;
  color: var(--muted);
}
.site-foot__sub { margin-top: var(--s-2); color: var(--muted); letter-spacing: .2em; }

/* ==========================================================================
   9. 分享卡片弹层
   ========================================================================== */
.modal-overlay {
  position: fixed;
  inset: 0;
  /* 必须高于顶栏（--z-nav 200）与页签栏（--z-sticky 100），
     否则弹层顶部会被 sticky 顶栏盖住，点遮罩关不掉。
     也不能低于 .app::after 的纸纹层 —— 见顶部第 1 节说明。 */
  z-index: var(--z-modal);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--s-6);
  background: color-mix(in srgb, var(--bg-sunken) 84%, transparent);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur-3) var(--ease-out), visibility var(--dur-3);
}
/* 业务 JS 切换的就是 .show，不可改 */
.modal-overlay.show { opacity: 1; visibility: visible; }

.modal-card {
  position: relative;
  width: 100%;
  max-width: 340px;
  max-height: 88dvh;
  overflow-y: auto;
  transform: translateY(24px) scale(.96);
  transition: transform var(--dur-3) var(--ease-out);
}
.modal-overlay.show .modal-card { transform: none; }

.modal-close {
  position: absolute;
  top: var(--s-2);
  right: var(--s-2);
  z-index: 2;
  width: var(--tap-min);
  height: var(--tap-min);
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-full);
  border: 1px solid var(--line-strong);
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  color: var(--ink-2);
  cursor: pointer;
  transition: background var(--dur-2) var(--ease-out),
              color var(--dur-2) var(--ease-out), border-color var(--dur-2) var(--ease-out);
}
.modal-close:hover { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }

.modal-share-card {
  border: 1px solid var(--accent-line);
  border-radius: var(--r-xs);
  background: var(--bg);
  overflow: hidden;
}
.msc-header {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-4) var(--s-5);
  border-bottom: 1px solid var(--line);
}
.msc-logo {
  width: 32px; height: 32px;
  flex-shrink: 0;
  border-radius: var(--r-sm);
  border: 1px solid var(--accent-line);
  overflow: hidden;
}
.msc-logo > img { width: 100%; height: 100%; display: block; object-fit: contain; }
.msc-brand-info { flex: 1; min-width: 0; }
.msc-brand-name { font-size: var(--t-sm); color: var(--ink); }
.msc-brand-sub { font-size: var(--t-micro); color: var(--muted); margin-top: 1px; }

.msc-image { border-radius: 0; }
.msc-image > img { width: 100%; height: 100%; object-fit: cover; display: block; }

.msc-body { padding: var(--s-5); }
.msc-quote {
  margin: 0 0 var(--s-4);
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--t-sm);
  line-height: var(--lh-body);
  color: var(--ink-2);
}
.msc-tags { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.msc-tags span {
  font-size: var(--t-xs);
  color: var(--accent);
  opacity: .8;
  border: 1px solid var(--accent-line);
  padding: 2px var(--s-2);
}

.modal-actions { display: flex; gap: var(--s-3); margin-top: var(--s-4); }
.ma-btn {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  min-height: var(--tap-min);
  padding: var(--s-3);
  border: 1px solid var(--accent-line);
  border-radius: var(--r-xs);
  background: var(--accent-soft);
  color: var(--accent);
  font-family: var(--font-serif);
  font-size: var(--t-sm);
  letter-spacing: .12em;
  cursor: pointer;
  transition: background var(--dur-2) var(--ease-out),
              border-color var(--dur-2) var(--ease-out), color var(--dur-2) var(--ease-out);
}
.ma-btn:hover { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
.ma-btn:disabled { opacity: .6; cursor: progress; }

/* ==========================================================================
   10. 入场动画
   页面整体只入场一次；面板内的 .rev / .story-node 由业务 observer 逐个
   加 .vis —— 保持原站的时序与 stagger，不额外加动画。
   ========================================================================== */
@keyframes lixu-panel-in {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}
.feat-panel.active { animation: lixu-panel-in var(--dur-4) var(--ease-out); }

.rev {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity .8s var(--ease-out), transform .8s var(--ease-out);
}
.rev.vis { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .rev { opacity: 1; transform: none; transition: none; }
  .story-node { opacity: 1; transform: none; transition: none; }
  .feat-panel.active { animation: none; }
  .particle { animation: none; opacity: .25; }
}

/* ==========================================================================
   11. 媒体兜底
   app-shell.js 给失败容器加 .is-broken 并显示斜纹底 + data-fallback 文案。
   本站容器多为自定义类名，这里保证它们在 is-broken 下不塌陷、不留白洞。
   ========================================================================== */
.media.is-broken.cs-image,
.media.is-broken.sp-image { height: 220px; }
.media.is-broken > img { visibility: hidden; }

/* 图片未就绪时也维持骨架底色，不闪白 */
.cs-image, .sp-image, .msc-image, .sender-avatar,
.sp-logo, .msc-logo { background: var(--surface-inset); }

/* --------------------------------------------------------------------------
   视频区的兜底改写。
   app-shell.js 给失效的 <video> 宿主打 .is-media-broken，并用
   ::before/::after 画「中性灰播放三角 + 视频暂缺」的通用占位。
   本站的视频区已经有完整的一手处理：一张真实的封面 <img> + 金色播放按钮
   + 「点击播放 · 龙井茶韵」标签 + 全屏按钮。
   再叠一层通用占位就是两套图标打架，所以在这里（站点皮肤层，
   不改共享层）把通用占位让位给本站的封面。
   注意 .is-media-broken > video 的隐藏规则保留，video 仍需被藏起来。      */
.tea-video-preview.is-media-broken {
  background-color: var(--surface-inset);
  background-image: none;
}
.tea-video-preview.is-media-broken::before,
.tea-video-preview.is-media-broken::after { content: none; }


/* ==========================================================================
   重构层 —— 按 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 取不到"元素自己的原值"，所以宁可交给作者。
   -------------------------------------------------------------------------- */

