/* ===== 主页渲染版式 · 网页端唯一一份 =====
   公共主页（index.html）与编辑台右侧的实时预览（edit.html）都用这一份，
   保证「编辑时看到的」和「访客看到的」不会有第二套样式。

   数值全部照抄 miniprogram/pages/preview/preview.wxss，
   把小程序的 750rpx 设计稿折算成 --rpx，因此两端比例完全一致。 */

:root { --rpx: calc(min(100vw, 480px) / 750); }

html, body {
  overflow-x: hidden;
  overscroll-behavior: none;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
html::-webkit-scrollbar, body::-webkit-scrollbar {
  display: none;
  width: 0;
  height: 0;
}

.pv-page {
  position: relative;
  min-height: 100vh;
  height: auto;
  max-width: 480px;
  margin: 0 auto;
  overflow-x: hidden;
  /* 下留白由使用方决定：公开页要跟小程序对齐（index.html 里覆盖成 190rpx），
     编辑台预览框不需要那么多 */
  padding-bottom: calc(80 * var(--rpx));
  display: flex;
  flex-direction: column;
  align-items: center;
}

.pv-photo-host {
  position: relative;
  overflow: hidden;
  touch-action: pan-y;
  -webkit-user-drag: none;
  background: none !important;
  border: 0 solid transparent;
  -webkit-border-image: var(--pv-src) 0 fill;
  border-image: var(--pv-src) 0 fill;
}
.pv-skin {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
}
.pv-bg-img {
  position: absolute; left: 0; top: 0; width: 100%; height: 100%;
  z-index: 0; pointer-events: none; overflow: hidden;
}
.pv-links,
.pv-card-img,
.pv-card-embed,
.pv-card-items,
.pv-card-qr,
.pv-card-header,
.pv-card-line,
.pv-link,
.pv-avatar,
.pv-name-row,
.pv-intro,
.pv-socials,
.pv-mylink,
.pv-search,
.pv-empty {
  flex-shrink: 0;
}

.pv-avatar, .pv-name-row, .pv-intro, .pv-socials, .pv-mylink,
.pv-search, .pv-search-bar, .pv-link, .pv-empty { position: relative; z-index: 2; }
.pv-footer { z-index: 3; }

/* 右上角三点：数值照抄小程序 preview.wxss 的 .pv-more，两端位置一致 */
.pv-more {
  position: absolute; top: calc(64 * var(--rpx)); right: calc(48 * var(--rpx));
  width: calc(80 * var(--rpx)); height: calc(80 * var(--rpx)); border-radius: 50%;
  background: rgba(255, 255, 255, .75); border: 0; padding: 0;
  display: flex; align-items: center; justify-content: center; z-index: 3;
}
button.pv-more { cursor: pointer; }
.pv-more-dots { display: flex; gap: calc(8 * var(--rpx)); }
.pv-more-dots .d {
  width: calc(8 * var(--rpx)); height: calc(8 * var(--rpx));
  border-radius: 50%; background: #666;
}

.pv-avatar {
  margin-top: calc(130 * var(--rpx));
  width: calc(190 * var(--rpx)); height: calc(190 * var(--rpx));
  border-radius: 50%; background: #000; color: #fff;
  font-size: calc(80 * var(--rpx)); font-weight: 700;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden; flex-shrink: 0;
  position: relative;
}
.pv-avatar { background-size: cover; background-position: center; background-repeat: no-repeat; }

/* iOS/Safari/微信内置浏览器会把 <img> 当文件拖。
   图本身不接收手势；透明遮罩盖在图上，长按/拖动手势打在容器上。 */
/* 手指打在这层上，垂直滑交给页面滚动，不要去拖底下的图。 */
.pv-finger {
  position: absolute; inset: 0; z-index: 8;
  touch-action: pan-y;
  -webkit-user-drag: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  background-color: rgba(255, 255, 255, 0.02);
  transform: translateZ(0);
}
.pv-card-img,
.pv-avatar,
.pv-cover,
.pv-qr-img,
.pv-store-pic {
  touch-action: pan-y;
  -webkit-user-drag: none;
}
.pv-swiper-slide { touch-action: pan-x pan-y; }
.pv-swiper-slide .pv-finger { touch-action: pan-x pan-y; }

.pv-name-row { margin-top: calc(36 * var(--rpx)); display: flex; align-items: center; }
.pv-name { font-size: calc(38 * var(--rpx)); font-weight: 700; color: #111; }
.pv-bluev {
  width: calc(34 * var(--rpx)); height: calc(34 * var(--rpx));
  margin-left: calc(10 * var(--rpx)); border-radius: 50%;
  background: #1e9bf0; color: #fff; font-size: calc(22 * var(--rpx)); font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}

.pv-intro {
  margin-top: calc(18 * var(--rpx)); font-size: calc(27 * var(--rpx));
  color: #444; padding: 0 calc(60 * var(--rpx)); text-align: center;
}

.pv-socials {
  margin-top: calc(24 * var(--rpx)); display: flex; flex-wrap: wrap;
  justify-content: center; gap: calc(18 * var(--rpx)); padding: 0 calc(40 * var(--rpx));
}
.pv-social {
  width: calc(68 * var(--rpx)); height: calc(68 * var(--rpx)); border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: calc(32 * var(--rpx)); color: #fff; border: 0; cursor: pointer;
  box-shadow: 0 calc(4 * var(--rpx)) calc(12 * var(--rpx)) rgba(0, 0, 0, .12);
}

/* 文字兜底徽标：只有目录里没有矢量徽标的类型才会画出来（渲染层判断，见 render.js 的 glyph） */
.icon-mark {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1em; height: 1em; font-family: Arial, sans-serif;
  font-size: .72em; font-weight: 800; line-height: 1; letter-spacing: -.04em;
}

.pv-mylink {
  margin-top: calc(24 * var(--rpx)); font-size: calc(26 * var(--rpx)); color: #31b8f6;
  background: rgba(255, 255, 255, .7); border-radius: calc(26 * var(--rpx));
  padding: calc(8 * var(--rpx)) calc(28 * var(--rpx)); cursor: pointer;
}

.pv-search {
  margin-top: calc(24 * var(--rpx)); display: flex; align-items: center;
  font-size: calc(26 * var(--rpx)); color: #333; background: rgba(255, 255, 255, .85);
  border-radius: calc(26 * var(--rpx)); padding: calc(10 * var(--rpx)) calc(30 * var(--rpx));
  border: 0; cursor: pointer;
}
.pv-search-ic {
  width: calc(26 * var(--rpx)); height: calc(26 * var(--rpx)); margin-right: calc(8 * var(--rpx));
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23333333' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='10.5' cy='10.5' r='6.5'/%3E%3Cpath d='M15.5 15.5 21 21'/%3E%3C/svg%3E") no-repeat center / contain;
}
.pv-search-bar {
  margin-top: calc(16 * var(--rpx)); width: calc(100% - 120 * var(--rpx));
  height: calc(72 * var(--rpx)); background: rgba(255, 255, 255, .92);
  border-radius: calc(36 * var(--rpx)); display: flex; align-items: center;
  padding: 0 calc(28 * var(--rpx));
}
.pv-search-bar input {
  flex: 1; border: 0; outline: 0; background: transparent;
  font-size: calc(28 * var(--rpx)); color: #111;
}

.pv-links {
  width: 100%; display: flex; flex-direction: column; align-items: center;
  flex: 0 0 auto; min-height: min-content;
}

/* 底色 / 圆角 / 描边 / 阴影由 render.js 的 skinCard() 按主题写入内联样式 */
.pv-link {
  margin-top: calc(40 * var(--rpx)); width: calc(100% - 60 * var(--rpx));
  min-height: calc(104 * var(--rpx));
  display: flex; align-items: center; padding: calc(12 * var(--rpx)) calc(34 * var(--rpx));
  text-decoration: none; color: inherit; cursor: pointer;
  transition: transform .15s;
}
.pv-link:active { transform: scale(.985); }
.pv-link:first-child { margin-top: calc(80 * var(--rpx)); }
.pv-cover {
  width: calc(120 * var(--rpx)); height: calc(120 * var(--rpx));
  border-radius: calc(12 * var(--rpx)); margin-right: calc(24 * var(--rpx));
  flex-shrink: 0; position: relative; overflow: hidden;
}
.pv-link-icon {
  width: calc(52 * var(--rpx)); height: calc(52 * var(--rpx)); border-radius: 50%;
  margin-right: calc(18 * var(--rpx)); display: flex; align-items: center; justify-content: center;
  font-size: calc(26 * var(--rpx)); color: #fff; flex-shrink: 0;
}
.pv-link-content { flex: 1; display: flex; flex-direction: column; gap: calc(8 * var(--rpx)); min-width: 0; }
.pv-link-title {
  font-size: calc(30 * var(--rpx)); font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pv-link-views { font-size: calc(22 * var(--rpx)); color: #999; }
.pv-link-dots { display: flex; flex-direction: column; gap: calc(8 * var(--rpx)); margin-left: calc(12 * var(--rpx)); }
.pv-link-dots i { width: calc(7 * var(--rpx)); height: calc(7 * var(--rpx)); border-radius: 50%; background: #333; }

/* ===== 多类型卡片 ===== */

/* 整图卡：图片就是卡片本身，不套白底 */
.pv-card-img {
  margin-top: calc(40 * var(--rpx)); width: calc(100% - 60 * var(--rpx));
  position: relative; z-index: 2; overflow: hidden; display: block;
  flex: 0 0 auto;
  min-height: min-content;
  box-shadow: 0 calc(6 * var(--rpx)) calc(16 * var(--rpx)) rgba(0, 0, 0, .05);
  text-decoration: none; color: inherit;
}
.pv-card-img:first-child { margin-top: calc(80 * var(--rpx)); }
/* 对齐小程序 mode=widthFix：只锁宽度，高度跟原图走。
   不要 height:0 + padding-top：全局 box-sizing:border-box 会把盒子压成 0。
   不要 height:100%：iOS 纵向 flex 会把子项压扁。 */
.pv-card-photo {
  position: relative; display: block; width: 100%; height: auto;
  overflow: hidden;
  touch-action: pan-y; -webkit-user-drag: none;
}
.pv-card-img-pic {
  display: block; width: 100%; height: auto !important;
  max-height: none !important;
  object-fit: contain; object-position: top center;
  pointer-events: none; -webkit-user-drag: none;
  flex-shrink: 0;
}
.pv-card-img-cap {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 9;
  padding: calc(24 * var(--rpx)) calc(28 * var(--rpx)) calc(18 * var(--rpx));
  font-size: calc(28 * var(--rpx)); font-weight: 600; color: #fff;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, .62) 100%);
  touch-action: pan-y;
}

/* 内嵌播放器卡 */
.pv-card-embed {
  margin-top: calc(40 * var(--rpx)); width: calc(100% - 60 * var(--rpx));
  position: relative; z-index: 2; overflow: hidden;
  padding: calc(16 * var(--rpx));
  box-shadow: 0 calc(6 * var(--rpx)) calc(16 * var(--rpx)) rgba(0, 0, 0, .05);
}
.pv-card-embed:first-child { margin-top: calc(80 * var(--rpx)); }
.pv-card-embed-title {
  font-size: calc(28 * var(--rpx)); font-weight: 600;
  margin-bottom: calc(14 * var(--rpx)); text-align: left;
}
.pv-embed-video {
  display: block; width: 100%; aspect-ratio: 16 / 9; border: 0;
  border-radius: calc(10 * var(--rpx)); background: #000;
}
.pv-embed-audio {
  display: block; width: 100%; height: calc(180 * var(--rpx)); border: 0;
  border-radius: calc(10 * var(--rpx));
}

/* 带子项的卡片：商品橱窗与图片轮播 */
.pv-card-items {
  margin-top: calc(40 * var(--rpx)); width: calc(100% - 60 * var(--rpx));
  position: relative; z-index: 2;
}
.pv-card-items:first-child { margin-top: calc(80 * var(--rpx)); }
.pv-card-items-title {
  font-size: calc(28 * var(--rpx)); font-weight: 600;
  margin-bottom: calc(16 * var(--rpx)); text-align: left;
}

.pv-store-grid { display: grid; gap: calc(20 * var(--rpx)); }
/* 底色 / 圆角 / 描边 / 阴影由 render.js 的 skinCard() 按主题写入内联样式 */
.pv-store-cell {
  display: block; overflow: hidden; position: relative;
  text-decoration: none; color: inherit;
}
.pv-store-pic {
  display: block; width: 100%; aspect-ratio: 1 / 1;
  position: relative; overflow: hidden;
}
.pv-store-pic .pv-pic { position: absolute; inset: 0; }
.pv-store-meta { padding: calc(16 * var(--rpx)) calc(18 * var(--rpx)) calc(18 * var(--rpx)); }
.pv-store-name {
  font-size: calc(26 * var(--rpx)); font-weight: 600; line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.pv-store-price { margin-top: calc(8 * var(--rpx)); font-size: calc(26 * var(--rpx)); color: #f43b3b; font-weight: 700; }

.pv-swiper-frame {
  position: relative; display: block; width: 100%; overflow: hidden;
  border-radius: calc(16 * var(--rpx)); background: rgba(0, 0, 0, .04);
}
.pv-swiper-sizer {
  display: block; width: 100%; height: auto; visibility: hidden;
  pointer-events: none; -webkit-user-drag: none;
}
.pv-swiper-track {
  position: absolute; inset: 0; display: flex;
  overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none;
}
.pv-swiper-track::-webkit-scrollbar { display: none; }
.pv-swiper-slide {
  flex: 0 0 100%; scroll-snap-align: start; display: block; height: 100%;
  position: relative; overflow: hidden;
}
.pv-pic {
  display: block; width: 100%; height: 100%;
  pointer-events: none; -webkit-user-drag: none;
}
.pv-fit-contain { object-fit: contain; object-position: center; }
.pv-fit-cover { object-fit: cover; object-position: center; }
.pv-swiper-go {
  position: absolute; right: calc(20 * var(--rpx)); bottom: calc(20 * var(--rpx)); z-index: 12;
  padding: calc(10 * var(--rpx)) calc(22 * var(--rpx)); border-radius: 999px;
  background: rgba(0, 0, 0, .58); color: #fff; font-size: calc(22 * var(--rpx)); font-weight: 600;
  text-decoration: none; line-height: 1.2;
}
.pv-lightbox {
  position: fixed; inset: 0; z-index: 80; background: rgba(0, 0, 0, .92);
  display: flex; align-items: center; justify-content: center;
}
.pv-lightbox-pic {
  max-width: 100%; max-height: 100%;
  width: auto; height: auto; object-fit: contain;
  pointer-events: none; -webkit-user-drag: none;
}
.pv-lightbox-go {
  position: absolute; right: 20px; bottom: 28px; z-index: 81;
  padding: 10px 18px; border-radius: 999px; background: #31b8f6; color: #fff;
  font-size: 14px; font-weight: 600; text-decoration: none;
}
.pv-swiper-dots {
  display: flex; justify-content: center; gap: calc(12 * var(--rpx)); margin-top: calc(16 * var(--rpx));
}
.pv-swiper-dots i {
  width: calc(12 * var(--rpx)); height: calc(12 * var(--rpx)); border-radius: 50%;
  background: rgba(0, 0, 0, .22); cursor: pointer; transition: background .2s;
}
.pv-swiper-dots i.on { background: rgba(0, 0, 0, .62); }

/* 分组标题 / 分隔线 / 二维码 */
.pv-card-header {
  width: calc(100% - 60 * var(--rpx)); position: relative; z-index: 2;
  margin-top: calc(56 * var(--rpx)); text-align: left;
  font-size: calc(30 * var(--rpx)); font-weight: 700; letter-spacing: .02em;
}
.pv-card-header:first-child { margin-top: calc(80 * var(--rpx)); }

.pv-card-line {
  width: calc(100% - 60 * var(--rpx)); position: relative; z-index: 2;
  margin-top: calc(36 * var(--rpx)); padding: calc(12 * var(--rpx)) 0;
}
.pv-card-line i { display: block; height: calc(2 * var(--rpx)); opacity: .18; }

.pv-card-qr {
  width: calc(100% - 60 * var(--rpx)); position: relative; z-index: 2;
  margin-top: calc(40 * var(--rpx)); padding: calc(28 * var(--rpx));
  display: flex; flex-direction: column; align-items: center;
}
.pv-card-qr:first-child { margin-top: calc(80 * var(--rpx)); }
.pv-qr-img {
  display: block; width: calc(320 * var(--rpx)); max-width: 70%;
  position: relative; aspect-ratio: 1 / 1; background-color: #fff;
}
.pv-qr-cap { margin-top: calc(18 * var(--rpx)); font-size: calc(26 * var(--rpx)); text-align: center; }

.pv-empty { margin-top: calc(120 * var(--rpx)); text-align: center; padding: 0 calc(60 * var(--rpx)); }
.pv-empty-title { font-size: calc(30 * var(--rpx)); font-weight: 600; opacity: .75; }
.pv-empty-tip { margin-top: calc(14 * var(--rpx)); font-size: calc(25 * var(--rpx)); opacity: .55; }

/* 动态主题的流光层，关键帧与 preview.wxss 同一套。
   渐变不写死在这里：render.js 把主题表的渐变经 --dyn-bg 下发（唯一真源）。 */
.pv-page.dyn-theme::before {
  content: ""; position: absolute; top: -20%; left: -20%; width: 140%; height: 140%;
  background: var(--dyn-bg);
  background-size: 300% 300%; animation: vip-shimmer 20s ease-in-out infinite;
  z-index: 0; pointer-events: none;
}
@keyframes vip-shimmer {
  0% { background-position: 0% 50%; }
  50% { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}

/* ---------- 氛围特效层（fx）----------
   节点的锚点/延迟/时长由共享 FX 表内联下发（见 render.js），这里只写形状与
   运动路径。关键帧只动 transform 与 opacity（合成层，不回流不重绘）；
   选择器与关键帧名两端（preview.wxss / preview.css）必须同名同义。
   盖在内容上但 pointer-events:none，节点小、透明度低，不碍读。 */
.pv-fx { position: fixed; inset: 0; z-index: 1; pointer-events: none; overflow: hidden; }
.pv-fx .fx-i {
  position: absolute; display: block;
  animation-timing-function: linear; animation-iteration-count: infinite; animation-fill-mode: both;
  will-change: transform, opacity;
}

/* 星尘 / 流星共用的星点底：一组白点铺在层背景上做透明度呼吸 */
.fx-sparkle, .fx-meteor {
  background-image:
    radial-gradient(1.5px 1.5px at 12% 18%, rgba(255,255,255,.9) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 78% 12%, rgba(255,255,255,.8) 50%, transparent 51%),
    radial-gradient(2px 2px at 42% 32%, rgba(255,255,255,.95) 50%, transparent 51%),
    radial-gradient(1px 1px at 88% 44%, rgba(255,255,255,.7) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 22% 58%, rgba(255,255,255,.85) 50%, transparent 51%),
    radial-gradient(1px 1px at 62% 66%, rgba(255,255,255,.7) 50%, transparent 51%),
    radial-gradient(2px 2px at 33% 82%, rgba(255,255,255,.9) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 72% 88%, rgba(255,255,255,.8) 50%, transparent 51%),
    radial-gradient(1px 1px at 8% 92%, rgba(255,255,255,.6) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 92% 74%, rgba(255,255,255,.75) 50%, transparent 51%);
  animation: fx-breathe 6s ease-in-out infinite;
}
@keyframes fx-breathe {
  0%, 100% { opacity: .35; }
  50% { opacity: .9; }
}

/* 流星：细长渐隐划痕，往右下划出一段后熄灭，周期大部分时间安静。
   位移用 px 不用 vw/vh：划痕角度（rotate 25deg）要和位移方向吻合，
   视口比例一变 vw/vh 的角度就歪了。 */
.fx-meteor .fx-i {
  width: 120px; height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, rgba(255,255,255,0), var(--fxc, rgba(255,255,255,.9)));
  opacity: 0; animation-name: fx-shoot; animation-timing-function: ease-in;
}
@keyframes fx-shoot {
  0% { transform: translate3d(0, 0, 0) rotate(25deg) scale(var(--s, 1)); opacity: 0; }
  4% { opacity: .9; }
  18% { transform: translate3d(520px, 240px, 0) rotate(25deg) scale(var(--s, 1)); opacity: 0; }
  100% { transform: translate3d(520px, 240px, 0) rotate(25deg) scale(var(--s, 1)); opacity: 0; }
}

/* 花瓣：从屏顶落到屏底，途中左右摇摆并翻转；a / b 两条路径错开步调 */
.fx-petals .fx-i {
  width: 16px; height: 16px; top: -6%;
  border-radius: 88% 6% 88% 6%;
  background: linear-gradient(135deg, var(--fxc, #eeb3c0), rgba(255,255,255,.5));
  opacity: 0; animation-name: fx-fall-a;
}
.fx-petals .fx-i2 { animation-name: fx-fall-b; }
@keyframes fx-fall-a {
  0% { transform: translate3d(0, 0, 0) rotate(0deg) scale(var(--s, 1)); opacity: 0; }
  6% { opacity: .85; }
  50% { transform: translate3d(-4vw, 52vh, 0) rotate(170deg) scale(var(--s, 1)); }
  88% { opacity: .85; }
  100% { transform: translate3d(3vw, 108vh, 0) rotate(320deg) scale(var(--s, 1)); opacity: 0; }
}
@keyframes fx-fall-b {
  0% { transform: translate3d(0, 0, 0) rotate(40deg) scale(var(--s, 1)); opacity: 0; }
  6% { opacity: .8; }
  50% { transform: translate3d(4vw, 50vh, 0) rotate(-140deg) scale(var(--s, 1)); }
  88% { opacity: .8; }
  100% { transform: translate3d(-3vw, 106vh, 0) rotate(-300deg) scale(var(--s, 1)); opacity: 0; }
}

/* 气泡：从屏底浮到屏顶，轻微左右漂，越浮越大一点点 */
.fx-bubbles .fx-i {
  width: 12px; height: 12px; top: 104%;
  border: 1.5px solid var(--fxc, rgba(200,240,250,.8)); border-radius: 50%;
  background: radial-gradient(circle at 32% 30%, rgba(255,255,255,.5), rgba(255,255,255,0) 60%);
  opacity: 0; animation-name: fx-rise-a;
}
.fx-bubbles .fx-i2 { animation-name: fx-rise-b; }
@keyframes fx-rise-a {
  0% { transform: translate3d(0, 0, 0) scale(var(--s, 1)); opacity: 0; }
  8% { opacity: .8; }
  55% { transform: translate3d(2.5vw, -58vh, 0) scale(var(--s, 1)); }
  92% { opacity: .5; }
  100% { transform: translate3d(-2vw, -112vh, 0) scale(calc(var(--s, 1) * 1.25)); opacity: 0; }
}
@keyframes fx-rise-b {
  0% { transform: translate3d(0, 0, 0) scale(var(--s, 1)); opacity: 0; }
  8% { opacity: .7; }
  55% { transform: translate3d(-2.5vw, -56vh, 0) scale(var(--s, 1)); }
  92% { opacity: .45; }
  100% { transform: translate3d(2vw, -110vh, 0) scale(calc(var(--s, 1) * 1.25)); opacity: 0; }
}

/* 萤火：锚点在下半屏，小范围漂移，亮度明灭；带光晕（box-shadow 是静态的，不参与动画） */
.fx-fireflies .fx-i {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--fxc, rgba(240,250,190,.95));
  box-shadow: 0 0 12px 3px var(--fxc, rgba(240,250,190,.5));
  opacity: 0; animation-name: fx-drift-a; animation-timing-function: ease-in-out;
}
.fx-fireflies .fx-i2 { animation-name: fx-drift-b; }
@keyframes fx-drift-a {
  0% { transform: translate3d(0, 0, 0) scale(var(--s, 1)); opacity: 0; }
  20% { opacity: .9; }
  45% { transform: translate3d(5vw, -6vh, 0) scale(var(--s, 1)); opacity: .25; }
  70% { transform: translate3d(-3vw, -11vh, 0) scale(var(--s, 1)); opacity: .8; }
  100% { transform: translate3d(1vw, -16vh, 0) scale(var(--s, 1)); opacity: 0; }
}
@keyframes fx-drift-b {
  0% { transform: translate3d(0, 0, 0) scale(var(--s, 1)); opacity: 0; }
  20% { opacity: .75; }
  45% { transform: translate3d(-4vw, -5vh, 0) scale(var(--s, 1)); opacity: .2; }
  70% { transform: translate3d(3vw, -10vh, 0) scale(var(--s, 1)); opacity: .7; }
  100% { transform: translate3d(-1vw, -15vh, 0) scale(var(--s, 1)); opacity: 0; }
}

/* 浮尘：全屏极慢斜向漂移，若隐若现，最克制的一档 */
.fx-dust .fx-i {
  width: 3px; height: 3px; border-radius: 50%;
  background: var(--fxc, rgba(255,255,255,.7));
  opacity: 0; animation-name: fx-float;
}
@keyframes fx-float {
  0% { transform: translate3d(0, 0, 0) scale(var(--s, 1)); opacity: 0; }
  12% { opacity: .55; }
  88% { opacity: .35; }
  100% { transform: translate3d(-6vw, -18vh, 0) scale(var(--s, 1)); opacity: 0; }
}

/* 背景图暗化遮罩：压住用户照片的高光，让上层文字读得清 */
.pv-bg-dim { position: absolute; left: 0; top: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none; }

/* 尊重系统「减弱动态效果」：流光停摆、特效层整层收起（花瓣定格在半空比没有更怪） */
@media (prefers-reduced-motion: reduce) {
  .pv-page.dyn-theme::before { animation: none; }
  .pv-fx { display: none; }
}

/* 页脚是个链到官网的 <a>（编辑台预览里是惰性的 <div>），得显式收掉继承的下划线 */
/* margin-top:auto 把页脚顶到 .pv-page 底部：内容少时它待在屏幕下方
   （对齐小程序里 position:fixed 的观感），内容多时容器被撑高，
   它自然跟在最后一张卡后面。写死 margin-top 的话，只有一张卡就会浮在页面正中间。 */
.pv-footer {
  display: flex; align-items: center; justify-content: center;
  margin-top: auto; padding-top: calc(60 * var(--rpx));
  text-decoration: none; color: inherit;
}
.pv-footer[href] { cursor: pointer; }
.pv-footer[href]:hover { opacity: .82; }
/* 放真 logo 图，不再是蓝底色块里塞 14px 的 FLINK 五个字母 */
.pv-footer-logo {
  width: calc(48 * var(--rpx)); height: calc(48 * var(--rpx));
  border-radius: calc(10 * var(--rpx)); margin-right: calc(16 * var(--rpx));
  display: block; flex-shrink: 0; position: relative; overflow: hidden;
}
.pv-footer-text { font-size: calc(34 * var(--rpx)); font-weight: 700; }
