/* 奶酪社区 APP · 原生移动端样式
   主色 #FFE411  背景 #FAFAFA  纯白卡片  低阴影大圆角 */

:root{
  --brand:#FFE411;
  --brand-16:rgba(255,228,17,.16);
  --brand-30:rgba(255,228,17,.30);
  --brand-45:rgba(255,228,17,.45);
  --ink:#1B1F24;
  --gray-1:#4C5768;
  --gray-2:#7A869A;
  --gray-3:#98A2B3;
  --gray-4:#C2C9D4;
  --line:#EDF0F5;
  --line-2:#F4F6F9;
  --bg:#FAFAFA;
  /* --bg 的 RGB 分量，供「渐变到背景色」时构造半透明色阶使用。
     ⚠️ rgba(var(--bg), .5) 是不合法的 —— rgba() 不能直接吃颜色变量，
     只能吃数字分量。改 --bg 时这里必须同步改。 */
  --bg-rgb:250,250,250;
  /* --bg-2：比页面底色 --bg(#FAFAFA) 略深一档的「占位/按压」灰。
     ⚠️ 这个变量此前【从未定义过】，但全站有 20 处在用 ——
     var() 取不到值时整条声明失效，那 20 处的 background 会退回初始值（透明），
     表现为：图片占位块透明、圈子详情 190px 的 hero 区透明、按压态无反馈。
     不报错、控制台也不提示，只有渲染后逐项查才能发现。
     取值 #F2F4F7 与既有同类占位色保持一致（.lc-img/.rcard .cover/.pc-ava/
     .cgi-ava/.cir2-ava 用的就是这个值），避免同一用途出现两种灰。 */
  --bg-2:#F2F4F7;
  --ok:#12B76A;
  --err:#F04438;
  --warn:#F79009;
  --tab-h:54px;
  --nav-h:52px;   /* navbar 固定高度，供「我的」页 hero 精确定位在其下方 */
  --safe-b:env(safe-area-inset-bottom, 0px);
  --safe-t:env(safe-area-inset-top, 0px);

  /* UI 字体栈：优先使用各系统自带的现代界面字体，
     比默认的「苹方/雅黑」更精致，笔画更规整、数字辨识度更高。
     顺序说明：
       · iOS / macOS  → -apple-system / SF Pro
       · 鸿蒙         → HarmonyOS Sans SC
       · 小米         → MiSans
       · Android / Linux → Noto Sans SC / Source Han Sans
       · Windows      → Microsoft YaHei UI（比雅黑字重更均匀）
     全部为系统内置字体，无需联网加载，不影响首屏速度。 */
  --font-ui:-apple-system,BlinkMacSystemFont,"SF Pro SC","SF Pro Text","PingFang SC",
    "HarmonyOS Sans SC","MiSans","Noto Sans SC","Source Han Sans SC",
    "Microsoft YaHei UI","Microsoft YaHei",sans-serif;
  /* 标题/昵称等强调文字：在 UI 字体基础上收紧字距，观感更精神 */
  --font-title:var(--font-ui);
}
*{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}
/* 修复底部 Tab 文字下方的黑线：
   底部导航的 4 个 Tab 是 <a class="tab">，而此处此前缺少对 a 标签的重置，
   浏览器默认的 text-decoration:underline 会被内部 <span>文字</span> 继承，
   表现为每个 Tab 文字底下一条线。后台 admin.css 有这条重置，前台漏了。 */
a{color:inherit;text-decoration:none;-webkit-tap-highlight-color:transparent}
html,body{height:100%}
/* 底部黑色横杠修复：
   1) html 必须显式给背景色 —— 否则 iOS 橡皮筋回弹、安全区、以及 100% 高度
      之外的区域会露出浏览器画布底色（深色模式下为纯黑），
      看起来就是导航栏下方一条黑杠。
   2) color-scheme:light —— 明确告知浏览器本页为浅色主题，
      避免系统深色模式把画布底色、滚动条、表单控件渲染成深色。 */
html{background:var(--bg);color-scheme:light}
body{
  font-family:var(--font-ui);
  background:var(--bg);color:var(--ink);font-size:14px;line-height:1.55;
  -webkit-font-smoothing:antialiased;overflow:hidden;
}
img{display:block;max-width:100%}
button{font-family:inherit;cursor:pointer;border:none;background:none;color:inherit}
input,textarea{font-family:inherit;font-size:15px;color:var(--ink);border:none;outline:none;background:none}
svg{display:block;flex:none}
::-webkit-scrollbar{width:0;height:0}

/* ============ 全屏容器（无手机外壳，铺满视口） ============ */
.phone{position:fixed;inset:0;background:var(--bg);overflow:hidden}
.frame{position:relative;width:100%;height:100%;background:var(--bg);overflow:hidden}

/* 桌面端：内容居中但铺满高度，不做手机边框 */
@media (min-width:720px){
  .frame{width:100%;max-width:560px;margin:0 auto;box-shadow:0 0 40px rgba(16,24,40,.06)}
}
.app{position:absolute;left:0;right:0;top:0;bottom:0;display:flex;flex-direction:column;overflow:hidden}

/* 图片占位块：imgTag() 在 src 为空时输出它，
   替代会触发无效请求并误报错误的 <img src=""> */
.img-ph{
  display:block;width:100%;height:100%;min-height:56px;
  background:linear-gradient(135deg,#F2F4F7 0%,#E8EBF1 100%);
  border-radius:inherit;
}

/* ============ 页面栈 & 转场 ============ */
.pages{position:relative;flex:1;overflow:hidden}
.page{
  position:absolute;inset:0;overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;
  background:var(--bg);transform:translateX(100%);visibility:hidden;
}
.page.active{transform:translateX(0);visibility:visible}

/* ============ 顶部导航 ============ */
.navbar{
  position:sticky;top:0;z-index:20;
  /* v1.7.71：顶部导航统一「白 → #FAFAFA」纵向渐变。
     顶部纯白让导航区从页面里「提」出来，底部正好落在页面底色 --bg 上，
     滚动时内容从导航下方穿过，衔接处不会出现色差断层。
     ⚠️ 两个色标都不透明 —— sticky 导航要靠自身背景遮挡滚过的内容，
        任何一端带 alpha 都会让内容从导航里透出来。 */
  background:linear-gradient(to bottom,#FFFFFF 0%,var(--bg) 100%);
  padding:calc(8px + var(--safe-t)) 14px 10px;display:flex;align-items:center;gap:10px;
  min-height:calc(var(--nav-h) + var(--safe-t));
}
.navbar.plain{background:linear-gradient(to bottom,#FFFFFF 0%,var(--bg) 100%);border-bottom:none}
/* 按需求彻底移除导航栏底部分隔线，首页 / 鱼塘 / 消息 / 我的 均不再显示 */
.navbar{border-bottom:none !important}
/* 明确移除导航栏文字下方的任何装饰条（历史版本曾在此处有黄色下划线，
   个别用户浏览器缓存旧 CSS 仍会渲染，这里做一次显式重置并加注释说明） */
.navbar .nb-title,
.navbar .nb-title.center,
#homeTitle{
  text-decoration:none !important;
  border-bottom:none !important;
  background-image:none !important;
}
.navbar .nb-title::before,
.navbar .nb-title::after{display:none !important;content:none !important}
.navbar .nb-title{font-size:17px;font-weight:800;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.navbar .nb-title.center{text-align:center}
.ic-btn{width:34px;height:34px;border-radius:11px;display:flex;align-items:center;justify-content:center;color:var(--ink);flex:none;transition:.14s}
.ic-btn:active{background:var(--line-2);transform:scale(.92)}
/* v1.7.82：导航栏按钮的"隐藏但保留占位"态。
   用于 #resMoreBtn —— 它默认不可见，由 Resource.render() 按 can_manage 放开。

   ⚠️ 这里不能用 display:none。导航栏是 flex，.nb-title.center 用 flex:1 + text-align:center，
      它居中的是【自己那块区域】而不是整个导航栏。右侧按钮一旦 display:none，
      这块区域的右边界就从「距右 58px」变成「贴右边」，中心右移 22px，
      标题看着就"没在中间"。左右各 34px 按钮时才真正居中 —— 这正是
      其它居中标题页右侧都写了 <span style="width:34px"> 占位的原因。
      visibility:hidden 保留 34px 盒子，标题在任何权限下都正居中，
      也避免了按钮出现/消失时标题左右跳动。 */
.ic-btn.nav-gone{visibility:hidden;pointer-events:none}
.ic-btn.brand{background:var(--brand)}

/* 搜索框 */
.searchbar{
  margin:0 14px 10px;height:42px;border-radius:14px;background:#fff;border:1px solid var(--line);
  display:flex;align-items:center;gap:8px;padding:0 12px;color:var(--gray-3);
}
.searchbar .ph{font-size:13.5px;flex:1;color:var(--gray-3)}
/* 首页：搜索框移入顶部导航（取消文字 Logo），占据剩余宽度 */
.navbar.home-nav{gap:8px;padding-top:calc(6px + var(--safe-t));padding-bottom:8px}
.nb-search{
  /* v1.7.10：与放大后的图标按钮（40px）齐平，整行高度一致 */
  flex:1;min-width:0;margin:0;height:40px;border-radius:13px;
  padding:0 12px;gap:8px;
}
.nb-search .ph{font-size:13px}
/* 导航内图标按钮：v1.7.10 随图标放大到 25px 同步调整。
   之前是 36px 容器配 20px 图标（四周留白 8px）；
   图标改为 25px 后仍用 36px 会只剩 5.5px，明显发挤，
   故容器放到 40px（留白 7.5px），并按图标比例略增圆角。 */
.navbar.home-nav .ic-btn{width:40px;height:40px;border-radius:12px;flex:none}

/* ============ 分类横滑 ============ */
.cates{display:flex;gap:7px;padding:10px 14px 12px;overflow-x:auto;scrollbar-width:none}
.cates::-webkit-scrollbar{display:none}
/* 方形 + 小圆角（10px），整体尺寸收小 */
.cate-pill{
  flex:none;display:flex;align-items:center;gap:5px;padding:6px 11px;border-radius:10px;
  background:#fff;border:1px solid var(--line);font-size:12.5px;color:var(--gray-1);
  transition:.18s;white-space:nowrap;min-height:30px;
}
.cate-pill.on{background:var(--brand);border-color:var(--brand);color:var(--ink);font-weight:700}
.cate-pill:active{transform:scale(.95)}
/* 分类显示图 / 图标同步收小（实际类名为 .cate-ic） */
.cate-pill .cate-ic{width:16px;height:16px;border-radius:5px;flex:none}
.cate-pill .cate-ic.img{background-size:cover;background-position:center}
.cate-pill svg{width:15px;height:15px;flex:none}
.cate-ic{width:24px;height:24px;border-radius:9px;display:flex;align-items:center;justify-content:center;flex:none}

/* ============ 轮播 ============ */
.swiper{position:relative;margin:0 14px 14px;height:126px;border-radius:16px;overflow:hidden}
.swiper-track{display:flex;height:100%;transition:transform .42s cubic-bezier(.22,.9,.28,1)}
.swiper-slide{
  min-width:100%;height:100%;border-radius:16px;padding:18px 20px;color:var(--ink);
  display:flex;flex-direction:column;justify-content:center;position:relative;overflow:hidden;
}
.swiper-slide h4{font-size:17px;font-weight:800;line-height:1.35;margin-bottom:6px;position:relative;z-index:1}
.swiper-slide p{font-size:12.5px;opacity:.75;position:relative;z-index:1}
.swiper-slide .deco{position:absolute;right:-20px;top:-24px;width:150px;height:150px;border-radius:50%;background:rgba(255,255,255,.35)}
.swiper-dots{position:absolute;bottom:10px;left:0;right:0;display:flex;justify-content:center;gap:5px}
.swiper-dots i{width:6px;height:6px;border-radius:4px;background:rgba(27,31,36,.22);transition:.25s}
.swiper-dots i.on{width:16px;background:var(--ink)}

/* ============ 瀑布流 ============ */
.waterfall{padding:0 10px;display:grid;grid-template-columns:1fr 1fr;gap:10px;align-items:start}
.rcard{
  background:#fff;border-radius:15px;overflow:hidden;box-shadow:0 2px 10px rgba(16,24,40,.05);
  transition:transform .16s;animation:fadeUp .3s both;
}
.rcard:active{transform:scale(.975)}
@keyframes fadeUp{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
/* ===== v1.7.18 性能：列表卡片的渲染隔离 + 入场动画收敛 =====
 *
 * 1) contain:layout style
 *    布局隔离：卡片内部的变化不会触发外部重排，浏览器滚动时
 *    只需重算可视区域附近的卡片，不必把整条列表的布局推倒重来 ——
 *    长列表滚动掉帧主要就来自这里。
 *
 *    这里刻意不用 contain:content（= layout+paint+style）：
 *    它带 paint 裁剪，会把认证标、+N 遮罩这类略微外溢的元素切掉。
 *    layout 已经是收益最大的部分，不值得为此冒裁剪的风险。
 *
 * 2) 只对首屏卡片播放入场动画
 *    原本每张卡都带 fadeUp，一次渲染 15 张就是 15 个动画同时跑，
 *    中低端机上直接掉帧；「加载更多」追加时还会整片重新抖动。
 *    现在只有前 6 张（首屏可见范围）有动画，后面的直接呈现。
 */
.lcard,.rcard,.mcard,.mc2{contain:layout style}
.rcard{animation:fadeUp .3s both}
/* 第 7 张起不做入场动画：避免一次性播放十几个动画造成掉帧 */
.rcard:nth-child(n+7){animation:none}
/* 尊重系统「减弱动效」 */
@media (prefers-reduced-motion:reduce){
  .rcard{animation:none}
  .bubble-row{animation:none}
}
.rcard .cover{width:100%;position:relative;background:#F0F2F6;overflow:hidden}
.rcard .cover img{width:100%;height:100%;object-fit:cover}
.rcard .cover .ph{display:flex;align-items:center;justify-content:center;width:100%;height:100%;color:rgba(27,31,36,.18)}
.rcard .badges{position:absolute;left:8px;top:8px;display:flex;gap:4px;flex-wrap:wrap;max-width:calc(100% - 16px)}
/* v1.7.57【性能优化】去掉 backdrop-filter:blur(6px)
 *
 * 这是全站最贵的一处常驻开销，原因有三：
 *  1. 数量极大 —— .badge 是每张资源卡片封面的角标（免费/解锁/精选），
 *     首页和鱼塘是【无限滚动】，DOM 持续累积，滚几页就有几十个。
 *  2. 滚动即重算 —— backdrop-filter 需要采样元素背后的内容再高斯模糊，
 *     列表中每个 badge 在滚动时每帧都要重算一次，是移动端掉帧的头号原因。
 *  3. 效果本就看不见 —— 三个变体的背景都是高不透明度：
 *       free   不透明黄   → 背景被自身挡死，blur 【完全无效】
 *       pick   90% 白     → 只透出 10%，可忽略
 *       unlock 72% 黑     → 透出 28%，很微弱
 *     即：为 1 个几乎无效 + 2 个效果微弱的效果，付出了最大的性能代价。
 *
 * 补偿：去掉 blur 后，unlock / pick 会略微更透，文字可读性下降，
 *       所以把两者的不透明度各提一档（.72→.82 / .9→.94）。
 *       实测两档差异肉眼几乎不可辨，但滚动帧率显著改善。
 */
.badge{padding:2.5px 7px;border-radius:7px;font-size:10.5px;font-weight:800;line-height:1.5}
.badge.free{background:var(--brand);color:var(--ink)}
.badge.unlock{background:rgba(27,31,36,.82);color:#fff}
.badge.pick{background:rgba(255,255,255,.94);color:var(--ink)}
.rcard .body{padding:9px 10px 11px}
.rcard .t{font-size:13.5px;font-weight:600;line-height:1.45;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;min-height:39px}
.rcard .meta{display:flex;align-items:center;gap:5px;margin-top:8px;font-size:11px;color:var(--gray-3)}
.rcard .meta .au{display:flex;align-items:center;gap:4px;flex:1;min-width:0}
/* 只作用于昵称，不能写成 `.au span` ——
   .avatar 自身就是 span，会被这条规则的 overflow:hidden 命中，
   从而把右下角溢出的认证标裁掉（资源卡片认证图标消失的真因）。 */
.rcard .meta .au .au-nm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:70px}
/* 头像：统一正圆 + 外圈阴影
   占位底色用中性浅灰（v1.7.22）。
   此前用 var(--ink) 近黑色，图片没加载出来时是一块很突兀的黑圆；
   列表卡片里的 .lc-ava 又是 var(--brand) 亮黄，两处颜色还不一致。
   统一成浅灰后，占位状态低调不抢视线，且和图片占位块 #F0F2F6 一致。
   注意文字色要同步改深，否则浅灰底配黄字会看不清。 */
.avatar{
  width:20px;height:20px;border-radius:50%;
  background:#F0F2F6;color:var(--gray-2);
  display:flex;align-items:center;justify-content:center;
  font-size:10px;font-weight:800;flex:none;
  /* v1.7.22：这里原本写的是 overflow:hidden，与下方 .avatar{overflow:visible}
     特异性相同、只能靠「后者在后面」生效 —— 一旦有人调整规则顺序，
     认证标就会被无声裁掉，且极难排查。
     直接从源头去掉 hidden：图片圆角由 .avatar>img 自身的 border-radius 保证，
     不依赖父级裁剪，效果完全一致。 */
  position:relative;
  box-shadow:0 0 0 2px #fff, 0 2px 8px rgba(16,24,40,.16);
}
/* 放开裁剪后，图片自身的圆角必须显式声明（v1.7.22） */
.avatar > img,.avatar img{border-radius:50%}
.avatar img{width:100%;height:100%;object-fit:cover;display:block}
.avatar.lg{width:42px;height:42px;font-size:16px}
/* v1.7.44：64px → 56px（用户要求"稍微改小一点"）*/
.avatar.xl{width:56px;height:56px;font-size:22px}
/* 大号头像阴影更明显
   ⚠️ v1.7.44：白环由 box-shadow 改为 border。
      box-shadow:0 0 0 3px 会向【外】扩张 3px，使头像视觉左边缘比同列内容
      （个人中心统一为 12px margin + 16px padding = 28px）左移 3px ——
      用户看到的"头像左边跟下面卡片没对齐"就是这么来的。
      border 在全局 border-box 下不增加外框尺寸、也不向外扩张，
      于是头像外沿精确落在 28px，与下方卡片内文字、菜单图标完全对齐。 */
.avatar.lg,.avatar.xl{border:3px solid #fff;box-shadow:0 4px 14px rgba(16,24,40,.18)}
/* 会员金色光环（同样零外扩）
   外圈浅黄走 border，内圈金色用 padding 露出 + background 填充。
   ⚠️ 不能用 inset 阴影画内圈：头像内 img 是 100% 宽高、
      铺在 content box 上，会把 inset 阴影完全盖住。 */
.avatar.vip{box-shadow:0 0 0 2px #FFE411, 0 0 0 4px #FFF3A8, 0 3px 10px rgba(255,190,0,.4)}
.avatar.lg.vip,.avatar.xl.vip{
  border-color:#FFF3A8;background:#FFE411;padding:2px;
  box-shadow:0 4px 16px rgba(255,190,0,.45);
}

/* ============ 首页展示模式 ============ */
.home-wrap{width:100%}
/* 瀑布流（默认）：两列错落 */
.mode-waterfall .waterfall{display:grid;grid-template-columns:1fr 1fr;gap:10px;padding:0 12px;align-items:start}
/* 图文列表：单列横向卡片 */
.mode-list .waterfall{display:flex;flex-direction:column;gap:11px;padding:0 12px;align-items:stretch}
.mode-list .lcard{
  display:block;background:#fff;border-radius:16px;overflow:hidden;
  box-shadow:0 2px 10px rgba(16,24,40,.055);transition:transform .16s;
}
.mode-list .lcard:active{transform:scale(.985)}

/* 头部：头像 + 昵称等级 / 时间位置 + 关注按钮 */
.mode-list .lc-head{display:flex;align-items:center;gap:9px;padding:12px 13px 8px}
.mode-list .lc-ava{
  /* position:relative + overflow:visible：让右下角认证标能正常显示（不被裁切） */
  position:relative;overflow:visible;
  width:38px;height:38px;border-radius:50%;flex:none;
  background:#F0F2F6;color:var(--gray-2);display:flex;align-items:center;justify-content:center;
  font-size:15px;font-weight:800;
}
/* 放开 overflow 后，图片自身需保留圆角 */
.mode-list .lc-ava > img{border-radius:50%}
.mode-list .lc-ava img{width:100%;height:100%;object-fit:cover;display:block}
.mode-list .lc-uinfo{flex:1;min-width:0}
.mode-list .lc-uname{display:flex;align-items:center;gap:6px;min-width:0}
.mode-list .lc-nick{
  font-size:14px;font-weight:700;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:150px;
}
.mode-list .lc-lv{
  flex:none;font-size:10px;font-weight:800;color:#8A6100;
  background:rgba(255,228,17,.28);border-radius:5px;padding:1px 5px;line-height:1.5;
}
.mode-list .lc-usub{
  font-size:11.5px;color:var(--gray-3);margin-top:2px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.mode-list .lc-follow{
  flex:none;height:28px;padding:0 14px;border-radius:14px;border:1px solid var(--brand);
  background:#fff;color:var(--ink);font-size:12.5px;font-weight:700;transition:.15s;
}
.mode-list .lc-follow:active{transform:scale(.94)}
.mode-list .lc-follow.on{background:var(--bg-2);border-color:var(--line);color:var(--gray-3);font-weight:600}

/* 标题 */
.mode-list .lc-title{
  padding:0 13px 9px;font-size:15px;font-weight:700;line-height:1.45;color:var(--ink);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}

/* 图片区：1 张铺满、2 张并排、3 张三列 */
.mode-list .lc-imgs{display:grid;gap:4px;padding:0 13px}
.mode-list .lc-imgs.n1{grid-template-columns:1fr}
.mode-list .lc-imgs.n2{grid-template-columns:1fr 1fr}
.mode-list .lc-imgs.n3{grid-template-columns:1fr 1fr 1fr}
.mode-list .lc-img{position:relative;overflow:hidden;background:var(--bg-2);border-radius:8px}
.mode-list .lc-imgs.n1 .lc-img{aspect-ratio:16/9}
.mode-list .lc-imgs.n2 .lc-img,
.mode-list .lc-imgs.n3 .lc-img{aspect-ratio:1/1}
.mode-list .lc-imgs.n0 .lc-img{aspect-ratio:16/9}
.mode-list .lc-img img{width:100%;height:100%;object-fit:cover;display:block}
.mode-list .lc-img.ph{display:flex;align-items:center;justify-content:center;color:rgba(27,31,36,.2)}

/* 分类与标签 */
.mode-list .lc-cates{
  display:flex;align-items:center;gap:7px;flex-wrap:wrap;padding:10px 13px 0;
}
.mode-list .lc-cate{
  display:inline-flex;align-items:center;gap:3px;font-size:11px;font-weight:600;
  color:#8A6100;background:rgba(255,228,17,.16);border-radius:6px;padding:3px 7px;
}
.mode-list .lc-tag{font-size:11px;color:var(--gray-2)}
.mode-list .lc-badges{margin-left:auto;display:flex;gap:4px}
.mode-list .lc-badges .badge{font-size:9.5px;padding:1px 5px;border-radius:5px}

/* 底部：点赞 / 评论 / 热度 */
.mode-list .lc-foot{
  display:flex;align-items:center;gap:20px;padding:10px 13px 12px;margin-top:2px;
}
.mode-list .lc-stat{
  display:inline-flex;align-items:center;gap:4px;
  font-size:12.5px;color:var(--gray-2);
}
.mode-list .lc-stat b{font-weight:600;color:var(--gray-1)}

/* ============ 骨架屏 ============ */
.sk{background:#fff;border-radius:15px;overflow:hidden;box-shadow:0 2px 10px rgba(16,24,40,.05)}
.sk .sk-cover{height:110px}
.sk-line{height:11px;border-radius:6px;margin:10px}
/* ===== v1.7.18 骨架屏：动画改为 GPU 合成 =====
 *
 * 原实现是「background 渐变 + background-position 位移」的 shimmer。
 * background-position 不可合成，每一帧都会触发重绘（repaint）：
 * 列表里几十个骨架块同时重绘，在中低端机上直接掉帧。
 *
 * 现改为：底色固定 + 一条高光伪元素做 translateX 位移。
 * transform 走 GPU 合成层，不产生重绘，成本几乎为零。
 */
.sk-cover,.sk-line,.sk-av,.sk-box,.sk-pill{
  position:relative;overflow:hidden;
  background:#EDF0F4;
}
.sk-cover::after,.sk-line::after,.sk-av::after,.sk-box::after,.sk-pill::after{
  content:"";position:absolute;top:0;left:0;right:0;bottom:0;
  background:linear-gradient(90deg,rgba(255,255,255,0) 0%,rgba(255,255,255,.72) 50%,rgba(255,255,255,0) 100%);
  transform:translateX(-100%);
  animation:skSweep 1.15s ease-in-out infinite;
  pointer-events:none;
}
@keyframes skSweep{100%{transform:translateX(100%)}}
/* 尊重系统「减弱动效」：只留静态底色 */
@media (prefers-reduced-motion:reduce){
  .sk-cover::after,.sk-line::after,.sk-av::after,.sk-box::after,.sk-pill::after{animation:none;opacity:0}
}
.sk-row{display:flex;gap:12px;padding:14px;background:#fff;border-radius:15px;margin-bottom:10px}
.sk-av{width:42px;height:42px;border-radius:50%;flex:none}

/* ---- 结构性骨架块：用于拼出接近真实布局的占位 ---- */
.sk-stack{display:flex;flex-direction:column;gap:9px;flex:1;min-width:0}
.sk-hrow{display:flex;gap:9px;align-items:center}
.sk-inline{display:flex;gap:6px;flex-wrap:wrap}
.sk-box{border-radius:9px}
.sk-pill{border-radius:20px;height:30px;flex:none}
/* 卡片容器：与真实列表卡片同圆角同间距，避免加载完跳动 */
.sk-card{background:#fff;border-radius:15px;padding:14px;margin-bottom:10px;box-shadow:0 2px 10px rgba(16,24,40,.05)}

/* ============ 图片淡入（v1.7.18） ============
 *
 * 默认 opacity:0，图片加载完成后由 JS 加 .ld 淡入。
 * 容器需要有底色，否则淡入前是一片刺眼的白。
 *
 * 注意：不要给 .img-fade 加 transition:all —— 那会让它
 * 参与所有属性变化的过渡，和列表里的 transform 动画打架。
 * 这里只过渡 opacity。
 */
img.img-fade{opacity:0;transition:opacity .28s ease}
img.img-fade.ld{opacity:1}
img.img-fade.err{opacity:.35}
/* 封面/头像这类有容器底色包裹的图片，直接显示也 OK，
   避免出现「容器有底、图片迟迟不现」的割裂感 */
.lc-img,.rcard .cover,.pc-ava,.cgi-ava,.cir2-ava{background:#F2F4F7}

/* ============ 下拉刷新 & 加载更多 ============ */
.ptr{height:0;overflow:hidden;display:flex;align-items:center;justify-content:center;color:var(--gray-3);font-size:12.5px;transition:height .22s}
.ptr.on{height:52px}
.ptr .sp{width:20px;height:20px;border:2.4px solid var(--line);border-top-color:var(--brand);border-radius:50%;animation:spin .7s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.loadmore{padding:18px 0 24px;text-align:center;font-size:12.5px;color:var(--gray-3);display:flex;align-items:center;justify-content:center;gap:7px}
/* v1.7.90：.hint 此前在 app.css 里【没有定义】，但 app.js 用了 4 处
   （转账页的两句说明、话题加载失败/暂无话题），拿不到小灰字样式。
   ⚠️ 后台 admin.css 里有自己的 `.frm .hint`（字号 11.5px + --muted），
   那是另一套，后台 50 处调用都正常 —— 别误以为这个类已经有了。
   这里补的是前端 app 侧的定义，用 app 自己的灰阶 --gray-3。
   margin 一律由调用处用内联 style 给（各处的间距不同），这里不设。 */
.hint{font-size:12px;color:var(--gray-3);line-height:1.6}

/* ============ 底部 Tab ============ */
.tabbar{
  flex:none;height:calc(var(--tab-h) + var(--safe-b));padding-bottom:var(--safe-b);
  /* v1.7.18：原为 .94 白底 + backdrop-filter:blur(14px)。
     背景已 94% 不透明，透出的内容只剩 6%，模糊与否几乎看不出来；
     但 backdrop-filter 在页面滚动时要逐帧重算，是常驻开销。
     改为 .97 实色并去掉 blur，观感几乎一致、合成成本归零。 */
  background:rgba(255,255,255,.97);border-top:1px solid var(--line);
  display:flex;align-items:stretch;position:relative;z-index:30;
  overflow:visible;   /* 中间的发布按钮要向上凸出，不能被裁切 */
}
/* v1.7.57【性能优化】transition 由 all 收窄到具体属性。
   原先写 transition:.16s（= all），选中的 .on 会同时变 color 和 font-weight。
   font-weight 是离散值、不可插值，浏览器仍会逐帧尝试过渡，
   而字重变化会改变文字宽度 → 触发【重排】（比重绘贵得多），
   切换 Tab 的瞬间四个标签同时重排，容易掉帧。
   限定成 color / transform 后，字重立即跳变，不再参与过渡。 */
.tabbar .tab{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;color:var(--gray-3);font-size:10.5px;position:relative;transition:color .16s,transform .16s}
.tabbar .tab.on{color:var(--ink);font-weight:700}
/* v1.7.57：文字固定宽度，避免选中时 font-weight 400→700 撑宽文字引起回流。
   一次切换要重排 4 个 tab，在 tabbar 这种常驻栏上是白给的开销。
   四个 tab 的文字都是 2 字，2.4em 足以容纳加粗后的宽度。 */
.tabbar .tab > span:not(.ti){width:2.4em;text-align:center}
.tabbar .tab:active{transform:scale(.9)}
.tabbar .tab .ti{
  position:relative;transition:transform .2s;
  /* v1.7.33：为未读角标预留定位空间。
     角标若直接贴 22px 图标定位，20px 的胶囊会压掉图标大半 ——
     v1.7.22 改成内嵌（top:2px/right:2px）后几乎整块盖在图标正中央，
     消息图标因此完全看不见。
     这里用 padding 撑开定位基准、再用等量负 margin 抵消：
     外边距盒仍是 22×22，布局尺寸分毫未变，
     但角标可以坐到图标右上角外沿，只压住约 17% 的图形。 */
  padding:6px 10px;
  margin:-6px -10px;
}
.tabbar .tab.on .ti{transform:translateY(-1px) scale(1.08)}
/* 底部 Tab 的未读角标：单独一套尺寸与定位，覆盖通用 .dot-badge。
   ⚠️ 不要改回内嵌（top/right 取正值）：那正是图标被完全盖住的原因。 */
.tabbar .tab .ti > .dot-badge{
  /* 定位到「角标中心 ≈ 图标右上角顶点」：够贴合，又只压住约 9% 的图形。
     测试 test_tab_badge.js 会按这些数值算实际遮挡比例。 */
  top:0;right:3px;
  min-width:13px;height:13px;padding:0 4px;
  font-size:9px;font-weight:800;line-height:1;letter-spacing:0;
  border:2px solid #fff;border-radius:10px;
  z-index:4;
}
/* ---- 底部 Tab 图标动画（v1.7.56 引入，v1.7.57 性能优化）----

   【v1.7.57 卡顿的根因与对策，改之前务必读完】

   1. 根因：原来是「一个 svg 内的两个 g」。SVG 内部元素（g / path）
      无法被提升为独立合成层，任何一帧重绘都要回退到父层，
      而父层可能是整个 tabbar（375×60 = 22500 px²）——
      22px 的图标动画却要重绘 46 倍的面积。
      → 改成【两个独立 svg】，各自成层，重绘被限制在 22×22 内。

   2. nav-bounce（选中后弹一下）的 transform 与填充的动画在时间轴上
      重叠（0.38~0.48s），transform 一变就得重算另一路，
      与 v1.7.18「filter + animation 同元素逐帧重算」是同一类问题。
      → 去掉 bounce；选中反馈交给 .ti 已有的 scale(1.08)，语义本就重复。

   3. 描边绘制的 stroke-dashoffset 是【必须重绘】的属性，无法 GPU 加速，
      只能缩短它 —— 四个图标的「线画完」统一压到约 0.26s。

   结构（由 navIcon() 输出）：
     span.ni-wrap        定位基准
       svg.ni-fill       填充层，clip-path 动画
       svg.ni-line       线稿层，stroke-dashoffset 动画
   层序固定 fill 在前、line 在后 —— 线稿必须压在填充之上，
   否则灌色会把黑色轮廓盖掉，图标只剩一个黄块。 */
.ni-wrap{position:relative;display:block;flex:none}
.ni-wrap .nav-ic{position:absolute;inset:0;width:100%;height:100%;display:block}
/* ⚠️ 别把这里的 clip-path 换成 transform:translateY。实测两者视觉不同：
     clip-path inset 的 top 从 100% 收到 0 = 【水位从底部往上涨】
       （先露出图形下半截，实测上边界 0.60 → 0.25 → 0.18 单调下移）；
     translateY(-100% → 0) = 【整个图形从上方滑入】
       （露出的是图形下半截但出现在画面顶部，实测质心 0.07）。
     要的是前者。clip-path 每帧重光栅化，但它作用在独立的 22×22 图层上，
     成本已由上面的结构改造压到最低。 */
.ni-fill{
  clip-path:inset(100% 0 0 0);
  -webkit-clip-path:inset(100% 0 0 0);
}
.ni-fill > *{fill:var(--brand);stroke:none}
.ni-line{fill:none;stroke:currentColor}

/* 每条笔画的实测长度 --l / 延迟 --d / 时长 --t。
   --l 由 path 数值积分实测（见 CS_NAV_ICONS 注释），+2 给圆帽留余量，
   改了 d 必须重算 --l，否则线画不满或提前收尾。
   限定在 .nav-ic 内，避免这些短类名污染全局。
   时长在 v1.7.57 又压了一档：stroke-dashoffset 必须重绘，
   缩短它就是最直接的性能优化。 */
.nav-ic .hm-roof{--l:25;--d:0s;  --t:.13s}
.nav-ic .hm-wall{--l:48;--d:.11s;--t:.13s}
.nav-ic .pd-ring{--l:55;--d:0s;  --t:.17s}
.nav-ic .pd-w1  {--l:9; --d:.14s;--t:.08s}
.nav-ic .pd-w2  {--l:8; --d:.19s;--t:.07s}
/* v1.8.7：消息图标气泡内的两条弧线 → 两个圆点（仍是 3 笔）。
   v1.8.10：气泡等比放大到与鱼塘同宽（外框 17.8 → 18.8），--l 全部重算：
     气泡 51.74 → 54.96 → --l:57（余量 2.04）
     点 r 1.1 → 1.17、周长 6.91 → 7.35 → --l:9（余量 1.65）
   点是 <circle> 描边：闭合路径无圆帽，--l 取周长 +1 即可（不用 +2）。
   ⚠️ 最后一笔的「--d + --t」必须 ≤ 0.26s（填充层起步点），当前 0.17+0.05=0.22s。 */
.nav-ic .ct-all {--l:57;--d:0s;  --t:.15s}
.nav-ic .ct-d1  {--l:9; --d:.13s;--t:.05s}
.nav-ic .ct-d2  {--l:9; --d:.17s;--t:.05s}
.nav-ic .me-head{--l:24;--d:0s;  --t:.12s}
.nav-ic .me-body{--l:16;--d:.10s;--t:.13s}

/* 选中态：线逐笔画出 → 灌色。
   ⚠️ dasharray/dashoffset 必须写在 .on 之内：
      若常驻设置，未选中 Tab 的线稿会一直是隐藏的（图标整个消失）。
   ⚠️ 不需要 JS 加 .play 类：syncTab 用的是 classList.toggle('on', bool)，
      toggle 到已存在的值不会重新触发动画，天然满足
      「切过去播一次、停着不重播、从详情页返回也不重播」；
      而 switchTab 在点当前 Tab 时会提前 return（回顶刷新），也不会重播。 */
.tabbar .tab.on .ni-line > *{
  stroke-dasharray:var(--l);
  stroke-dashoffset:var(--l);
  animation:nav-draw var(--t,.2s) ease-out var(--d,0s) forwards;
  will-change:stroke-dashoffset;
}
/* 填充在线画完之后（0.26s）才起步，与描边串行、不重叠。 */
.tabbar .tab.on .ni-fill{
  animation:nav-fill .20s cubic-bezier(.22,.9,.3,1) .26s forwards;
  will-change:clip-path;
}
@keyframes nav-draw{to{stroke-dashoffset:0}}
@keyframes nav-fill{
  from{clip-path:inset(100% 0 0 0);-webkit-clip-path:inset(100% 0 0 0)}
  to  {clip-path:inset(0 0 0 0);  -webkit-clip-path:inset(0 0 0 0)}
}

/* 系统开启减弱动效时直接给终态。
   ⚠️ 不能只写 animation:none —— 默认 clip-path 是全裁（填充不可见）、
      dashoffset 是全长（线不可见），禁用动画会让两层双双消失，图标变空白。 */
@media (prefers-reduced-motion: reduce){
  .ni-fill{clip-path:inset(0 0 0 0);-webkit-clip-path:inset(0 0 0 0)}
  .tabbar .tab.on .ni-line > *{animation:none;stroke-dashoffset:0;will-change:auto}
  .tabbar .tab.on .ni-fill{animation:none;will-change:auto}
}

/* 选中态不做顶部黄色装饰条，仅靠图标放大 + 文字加粗区分 */
/* ---- 中间凸起发布按钮（鱼塘与消息之间，白色包裹） ---- */
.tab-pub{
  flex:0 0 64px;          /* 固定占位，4 个 Tab 仍均分剩余空间 */
  position:relative;
  pointer-events:none;    /* 占位本身不拦截点击，只有按钮可点 */
}
/* 白色包裹圈：向上凸出，同时盖住 tabbar 顶部的分隔线，形成挖孔效果 */
.tab-pub::before{
  content:"";
  position:absolute;
  left:50%;top:50%;
  width:62px;height:62px;
  margin-left:-31px;margin-top:-41px;   /* 圆心上移 10px → 顶部凸出 14px */
  border-radius:50%;
  background:#fff;
  box-shadow:0 -3px 13px rgba(16,24,40,.09);
  pointer-events:none;
}
.pub-btn{
  position:absolute;
  left:50%;top:50%;
  width:50px;height:50px;
  margin-left:-25px;margin-top:-35px;   /* 与白圈同心 */
  border-radius:50%;
  background:var(--brand);
  color:var(--ink);
  display:flex;align-items:center;justify-content:center;
  box-shadow:0 3px 12px rgba(255,228,17,.55);
  transition:transform .18s cubic-bezier(.34,1.56,.64,1), box-shadow .18s;
  pointer-events:auto;
  z-index:1;
}
/* 透明热区扩展到白圈大小，点到白色边缘也能触发 */
.pub-btn::after{
  content:"";
  position:absolute;left:-6px;top:-6px;right:-6px;bottom:-6px;border-radius:50%;
}
.pub-btn:active{transform:scale(.88)}
/* v1.8.9：发布按钮尺寸恒定，不再随 Tab 变化。
   原 .on{scale(1.06)} 会在「首页 ↔ 鱼塘」切换时让按钮忽大忽小；
   更要命的是它与 App.publish() 的内联 transform 打架 ——
   内联样式清空后会回落到 1.06，点一次就「弹一下变大定住」，
   在首页回落 1、在鱼塘回落 1.06，同一个按钮两种表现。
   现在按下反馈统一走 .pressed（class 而非内联样式），
   任何 Tab 下都从 scale(1) 按下到 .88 再回 1。 */
.pub-btn.pressed{transform:scale(.88)}

.dot-badge{
  /* v1.7.22：从「向外偏移」改为「内嵌在右上角内侧」。
     原 top:-7px/right:-15px 依赖祖先不裁剪，而消息列表的 .page 有
     overflow-x:hidden，红点会被横向切掉；导航栏处又会顶出屏幕边缘。
     内嵌后无论祖先怎么裁剪都安全，视觉上仍紧贴右上角。
     （更早的 top:-2px/right:-9px 会压在 22px 图标上盖住图形，
       所以取 2px 内缩而不是完全贴边。） */
  position:absolute;top:2px;right:2px;min-width:16px;height:16px;padding:0 4px;border-radius:9px;
  background:var(--err);color:#fff;font-size:10px;font-weight:800;display:flex;align-items:center;justify-content:center;
  border:2px solid #fff;box-sizing:content-box;z-index:3;
}
.dot-badge.sm{min-width:9px;height:9px;padding:0;top:6px;right:8px;border:none}

/* ============ 弹窗 ============ */
.mask{position:absolute;inset:0;background:rgba(16,24,40,.42);opacity:0;visibility:hidden;transition:.26s;z-index:60;backdrop-filter:blur(2px)}
.mask.on{opacity:1;visibility:visible}
.sheet{
  position:absolute;left:0;right:0;bottom:0;z-index:61;background:#fff;
  border-radius:22px 22px 0 0;padding:8px 0 calc(18px + var(--safe-b));
  transform:translateY(100%);transition:transform .3s cubic-bezier(.22,.9,.28,1);max-height:84%;overflow-y:auto;
}
.sheet.on{transform:translateY(0)}
.sheet .grip{width:38px;height:4px;border-radius:3px;background:#DDE2E9;margin:6px auto 10px}
.sheet h3{font-size:16.5px;text-align:center;padding:6px 20px 14px;font-weight:800}
.sheet-item{display:flex;align-items:center;gap:12px;padding:14px 20px;font-size:15px;transition:.14s;color:var(--ink);width:100%;text-align:left}
.sheet-item:active{background:var(--line-2)}
.sheet-item .si-ic{width:34px;height:34px;border-radius:11px;background:var(--brand-16);color:var(--ink);display:flex;align-items:center;justify-content:center;flex:none}
.sheet-item.on{font-weight:700;color:var(--ink)}
.sheet-item.on .si-ic{background:var(--brand)}
.sheet-item .ck{margin-left:auto;color:var(--brand);opacity:0}
.sheet-item.on .ck{opacity:1}
.sheet-foot{padding:6px 16px 4px;display:flex;gap:10px}
.dialog{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%) scale(.86);z-index:62;
  width:78%;max-width:320px;background:#fff;border-radius:20px;padding:22px 20px 18px;text-align:center;
  opacity:0;visibility:hidden;transition:.24s cubic-bezier(.2,1.1,.4,1);
}
.dialog.on{opacity:1;visibility:visible;transform:translate(-50%,-50%) scale(1)}
.dialog .d-ic{width:56px;height:56px;margin:0 auto 12px;border-radius:50%;background:var(--brand-16);color:var(--ink);display:flex;align-items:center;justify-content:center}
.dialog h3{font-size:16.5px;font-weight:800;margin-bottom:7px}
.dialog p{font-size:13.5px;color:var(--gray-2);line-height:1.6}
.dialog .btns{display:flex;gap:10px;margin-top:18px}
.dialog .btns button{flex:1;height:44px;border-radius:13px;font-size:15px;font-weight:700}
.btn-main{background:var(--brand);color:var(--ink)}
.btn-main:active{filter:brightness(.95)}
.btn-sec{background:#F2F4F7;color:var(--gray-1)}
.btn-dark{background:var(--ink);color:#fff}
.toast{
  position:absolute;left:50%;top:88px;transform:translateX(-50%) translateY(-14px);z-index:80;
  background:rgba(27,31,36,.9);color:#fff;padding:10px 18px;border-radius:14px;font-size:13.5px;
  opacity:0;visibility:hidden;transition:.24s;max-width:80%;text-align:center;backdrop-filter:blur(8px);
}
.toast.on{opacity:1;visibility:visible;transform:translateX(-50%) translateY(0)}
.loading-wrap{position:absolute;inset:0;z-index:70;display:flex;align-items:center;justify-content:center;background:rgba(250,250,250,.6);opacity:0;visibility:hidden;transition:.2s}
.loading-wrap.on{opacity:1;visibility:visible}
.loading-wrap .lb{background:rgba(27,31,36,.86);border-radius:16px;padding:20px 24px;display:flex;flex-direction:column;align-items:center;gap:11px;color:#fff;font-size:13px}
.loading-wrap .sp{width:26px;height:26px;border:3px solid rgba(255,255,255,.24);border-top-color:var(--brand);border-radius:50%;animation:spin .7s linear infinite}

/* ============ 详情页 ============ */
.detail-hero{width:100%;position:relative;background:#F0F2F6}
.detail-hero img{width:100%;display:block}
.imgview{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none}
.imgview::-webkit-scrollbar{display:none}
.imgview .slide{min-width:100%;scroll-snap-align:center;background:#000}
.imgview .slide img{width:100%;display:block}
.img-count{position:absolute;right:12px;bottom:12px;background:rgba(27,31,36,.66);color:#fff;padding:3px 10px;border-radius:20px;font-size:11.5px}
.sec{background:#fff;border-radius:16px;padding:15px 16px;margin:10px 12px;box-shadow:0 2px 10px rgba(16,24,40,.04)}
.sec-h{display:flex;align-items:center;gap:8px;font-size:15px;font-weight:800;margin-bottom:10px}
.sec-h .bar{width:3.5px;height:15px;border-radius:3px;background:var(--brand)}
.sec p{font-size:14px;color:var(--gray-1);line-height:1.72;white-space:pre-wrap;word-break:break-word}
.author-row{display:flex;align-items:center;gap:11px;background:#fff;border-radius:16px;padding:14px 16px;margin:10px 12px}
.author-row .info{flex:1;min-width:0}
.author-row .info b{font-size:14.5px;display:block}
.author-row .info span{font-size:12px;color:var(--gray-3);display:block;margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.btn-mini{padding:7px 15px;border-radius:20px;background:var(--brand);font-size:13px;font-weight:700;flex:none;display:inline-flex;align-items:center;gap:4px;border:none;font-family:inherit;cursor:pointer;transition:.15s}
.btn-mini.gray{background:#F2F4F7;color:var(--gray-1)}
.btn-mini:active{transform:scale(.95)}
.btn-mini:disabled{opacity:.5;cursor:not-allowed}

/* 小号按钮（任务/关注等列表项内使用） */
.btn-brand-sm{
  padding:6px 13px;border-radius:16px;background:var(--brand);color:var(--ink);
  font-size:12.5px;font-weight:700;border:none;font-family:inherit;cursor:pointer;
  display:inline-flex;align-items:center;gap:3px;flex:none;transition:.15s;white-space:nowrap;
}
.btn-brand-sm:active{transform:scale(.94)}
.btn-brand-sm:disabled{opacity:.5;cursor:not-allowed}
.btn-ghost-sm{
  padding:6px 13px;border-radius:16px;background:#F2F4F7;color:var(--gray-2);
  font-size:12.5px;font-weight:600;border:none;font-family:inherit;cursor:pointer;
  display:inline-flex;align-items:center;gap:3px;flex:none;transition:.15s;white-space:nowrap;
}
.btn-ghost-sm:active{transform:scale(.94)}
.btn-ghost-sm:disabled{opacity:.5;cursor:not-allowed}
/* 大号主按钮（表单/引导页） */
.btn-brand{
  padding:12px 20px;border-radius:14px;background:var(--brand);color:var(--ink);
  font-size:15px;font-weight:800;border:none;font-family:inherit;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;gap:6px;transition:.15s;
}
.btn-brand:active{transform:scale(.97)}
.btn-brand:disabled{opacity:.5;cursor:not-allowed}
.hscroll{display:flex;gap:10px;overflow-x:auto;padding:2px 12px 6px;scrollbar-width:none}
.hscroll::-webkit-scrollbar{display:none}
.hscroll .mini-card{width:118px;flex:none;background:#fff;border-radius:12px;overflow:hidden;box-shadow:0 2px 8px rgba(16,24,40,.05)}
.hscroll .mini-card .c{height:78px;background:#F0F2F6;display:flex;align-items:center;justify-content:center;color:rgba(27,31,36,.16)}
.hscroll .mini-card .c img{width:100%;height:100%;object-fit:cover}
.hscroll .mini-card .t{font-size:12px;padding:7px 8px;line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}

/* 底部操作栏 */
.actionbar{
  /* 修复「底部点赞/评论/收藏栏跟着内容上下滑动」：
     此前它位于 .page 内部，而 .page 带 transform（translateX 转场），
     会为 fixed 后代创建包含块 —— position:fixed 因此被降级成类似 absolute，
     仍然处在滚动内容流里，上下滑时会被带走。
     现改为 .pages 之外的 .app 直接子项（flex 布局的兄弟节点），
     不参与任何页面滚动，天然固定在内容区下方；且会占据真实布局高度，
     内容不会被遮挡。 */
  /* v1.7.18：同上，资源详情滚动时此栏常驻，改为实色去掉 backdrop 重算 */
  flex:none;display:none;z-index:25;background:rgba(255,255,255,.98);
  border-top:1px solid var(--line);padding:9px 14px calc(9px + var(--safe-b));
  align-items:center;gap:10px;
}
.actionbar.on{display:flex}
.act-ic{display:flex;flex-direction:column;align-items:center;gap:1px;font-size:10.5px;color:var(--gray-2);padding:0 8px;flex:none;transition:.14s}
.act-ic:active{transform:scale(.86)}
.act-ic.on{color:var(--err)}
.act-ic.on svg{animation:pop .32s}
@keyframes pop{0%{transform:scale(1)}40%{transform:scale(1.35)}70%{transform:scale(.92)}100%{transform:scale(1)}}
.act-main{flex:1;height:46px;border-radius:15px;background:var(--brand);font-size:15.5px;font-weight:800;display:flex;align-items:center;justify-content:center;gap:7px}
.act-main:active{filter:brightness(.95)}
.act-main.dark{background:var(--ink);color:#fff}
/* 操作栏已改为 .app 的 flex 子项并占据真实高度，不再需要页面预留底部空间 */
.has-bar{padding-bottom:0 !important}

/* 评论 */
.cmt{display:flex;gap:10px;padding:11px 0;border-bottom:1px solid var(--line-2)}
.cmt:last-child{border-bottom:none}
.cmt .c{flex:1;min-width:0}
.cmt .c .n{font-size:13px;color:var(--gray-2);font-weight:600}
.cmt .c .x{font-size:14px;margin-top:3px;line-height:1.6;word-break:break-word}
.cmt .c .f{font-size:11.5px;color:var(--gray-3);margin-top:5px;display:flex;gap:12px}
.sub-cmt{margin-left:30px;padding:9px 0 0;border-bottom:none}
.reply-box{display:flex;align-items:center;gap:8px;padding:8px 12px;background:var(--line-2);border-radius:12px;margin-top:8px}
.reply-box .r-t{font-size:13px;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--gray-2)}
.empty{text-align:center;padding:46px 20px;color:var(--gray-3);font-size:13.5px}
.empty .e-ic{width:64px;height:64px;margin:0 auto 14px;border-radius:50%;background:var(--line-2);color:var(--gray-4);display:flex;align-items:center;justify-content:center}
/* v1.7.76：空状态放进网格容器时必须跨满整行 ——
   瀑布流是两列 grid，.empty 作为网格项默认只落在第一列（半屏宽），
   于是"暂无资源""没有找到相关资源"看着像贴在左边。
   grid-column 在非网格容器里会被忽略，故再补 width:100% 兜住
   列表模式的 flex 布局（那边的 align-items:stretch 其实已经生效）。 */
.waterfall > .empty{grid-column:1 / -1;width:100%}

/* ============ 鱼塘 ============ */
.mcard{background:#fff;border-radius:16px;padding:14px 16px;margin:0 12px 10px;box-shadow:0 2px 10px rgba(16,24,40,.04)}
/* v1.7.65：个人主页列表容器 #userList 自带 12px 内边距，
   卡片自身的左右 margin 必须清掉，否则叠加成 24px ——
   比上方 .stat-row / .seg（统一 12px）多缩进 12px，看着"窄一截"。
   只清左右：margin-bottom:10px 是卡片间距，要保留。 */
#userList .mcard{margin-left:0;margin-right:0}
.mcard .hd{display:flex;align-items:center;gap:10px;margin-bottom:10px}
.mcard .hd .n{flex:1;min-width:0}
.mcard .hd .n b{font-size:14.5px;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mcard .hd .n span{font-size:11.5px;color:var(--gray-3)}
.mcard .txt{font-size:14.5px;line-height:1.7;white-space:pre-wrap;word-break:break-word;margin-bottom:10px}
/* 帖子图片网格 —— 通用规则，不绑定具体卡片容器。
   此前这些规则写在 .mcard .imgs 下，板块帖子卡片用的是 .mc2，
   结果完全没有分栏、没有裁切，图片按原尺寸整张往下堆。 */
.imgs{display:grid;gap:5px;margin-bottom:10px}
.imgs.i1{grid-template-columns:1fr}
.imgs.i2{grid-template-columns:1fr 1fr}
.imgs.i3{grid-template-columns:1fr 1fr 1fr}
.imgs.i4{grid-template-columns:1fr 1fr}
.imgs > div{
  position:relative;aspect-ratio:1;border-radius:10px;overflow:hidden;
  background:#F0F2F6;cursor:pointer;
}
.imgs > div:active{opacity:.86}
.imgs img{width:100%;height:100%;object-fit:cover;display:block}
/* imgTag() 在 src 为空时输出的占位块，需要撑满格子 */
.imgs .img-ph{width:100%;height:100%;min-height:0;background:#F0F2F6}
/* 单图：保持正方形太浪费，放宽到 4:3 并限制最大高度 */
.imgs.i1 > div{aspect-ratio:4/3;max-height:340px}
/* 超过 4 张时，第 4 格显示「+N」遮罩 */
.imgs .more-mask{
  position:absolute;inset:0;background:rgba(16,24,40,.46);color:#fff;
  display:flex;align-items:center;justify-content:center;
  font-size:19px;font-weight:800;letter-spacing:.5px;
}
.mcard .ft{display:flex;align-items:center;gap:22px;padding-top:4px}
.mcard .ft button{display:flex;align-items:center;gap:5px;font-size:13px;color:var(--gray-2);transition:.14s}
.mcard .ft button:active{transform:scale(.9)}
.mcard .ft button.on{color:var(--err)}
.mcard .ft button.on svg{animation:pop .32s}
.circle-tag{display:inline-flex;align-items:center;gap:4px;padding:3px 9px;border-radius:8px;background:var(--brand-16);font-size:11.5px;font-weight:700;color:#8A6100}
/* 消息 */
/* v1.7.22：必须 position:relative。
   此前缺失，未读红点 .dot-badge 的 position:absolute 会向上找到 .page
   （它是 position:absolute）作为定位基准，right:-15px 等于跑到页面右边界外，
   而 .page 又有 overflow-x:hidden —— 结果是红点彻底看不见。
   这是「消息页未读数不显示」的根因。 */
.msg-item{position:relative;display:flex;gap:11px;padding:13px 14px;background:#fff;border-bottom:1px solid var(--line-2);align-items:center}
.msg-item:active{background:var(--line-2)}
.msg-item .mi{flex:1;min-width:0}
.msg-item .mi .r1{display:flex;align-items:baseline;gap:8px}
.msg-item .mi .r1 b{font-size:15px;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.msg-item .mi .r1 span{font-size:11.5px;color:var(--gray-3);flex:none}
.msg-item .mi .r2{font-size:13px;color:var(--gray-3);margin-top:3px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.seg{display:flex;gap:4px;background:#F2F4F7;padding:3.5px;border-radius:12px;margin:0 14px 10px}
.seg button{flex:1;height:33px;border-radius:9px;font-size:13.5px;color:var(--gray-2);transition:.16s;position:relative}
.seg button.on{background:#fff;font-weight:700;color:var(--ink);box-shadow:0 1px 4px rgba(16,24,40,.09)}

/* ============ v1.7.50 消息页 UI 重做 ============ */

/* Tab 上的未读角标：内嵌在按钮内、与文字同一行。
   ⚠️ 用 inline-flex + margin-left，不用 absolute：
      .seg button 有 position:relative 且高度只有 33px，
      绝对定位很容易顶出按钮边界被相邻元素盖住（v1.7.22 的教训）。 */
.seg-badge{
  display:none;margin-left:5px;min-width:16px;height:16px;padding:0 4px;
  border-radius:8px;background:var(--err);color:#fff;
  font-size:10px;font-weight:800;line-height:16px;text-align:center;
  box-sizing:border-box;flex:none;
}

/* ==================================================================
   v1.8.22：消息页改版
   ------------------------------------------------------------------
   ① .msg-panel  —— 白卡容器（四宫格、三个入口、好友消息各一张）
   ② .msg-sec    —— 卡片之间的小节标题（「好友消息」）
   ③ .fr-*       —— 好友消息行（头像 / 昵称 / 摘要 / 日期 / 未读数字）

   ⚠️ .msg-cats 与 .msg-entries 的【外边距已移到 .msg-panel 上】：
      它们现在都住在卡片内部，各自再留 14px 就会出现双重缩进
      （卡片本身有 margin，里面再 padding，内容被挤到中间一条）。
   ⚠️ 卡片内的 .msg-cat / .msg-entry 必须【去掉自己的边框和圆角】：
      卡片套卡片会出现双边框，圆角也会和外框打架。
      这条用 .msg-panel 后代选择器写，不要改成全局 ——
      .msg-cat 的白卡样式在别处（骨架屏等）仍要能用。
   ⚠️ .fr-* 是新前缀，不要复用 .msg-item：
      .msg-item 的样式被会话列表其它位置引用，改它会连带改到别处
      （本项目已多次踩到「改 A 坏 B」）。
   ================================================================== */

/* ① 白卡容器 */
.msg-panel{
  background:#fff;border:1px solid var(--line);border-radius:16px;
  margin:0 14px 12px;overflow:hidden;
}
/* 首个卡片紧贴 navbar（原先 .seg 占掉的 10px 下边距没了，这里补回来） */
.msg-panel:first-child{margin-top:12px}

/* ② 小节标题 */
.msg-sec{
  padding:2px 16px 8px;font-size:12.5px;font-weight:800;color:var(--gray-2);
}

/* ③ 好友消息行 */
.fr-list{display:flex;flex-direction:column}

/* ---- v1.8.23：左滑删除 ----
   .fr-row  定位容器（相对定位，让删除按钮能垫在下面）
   .fr-del  删除按钮，绝对定位贴右侧，被 .fr-item 盖住
   .fr-item 内容层，白底不透明，靠 translateX 滑走露出下层按钮

   ⚠️ .fr-item 必须【不透明】：它是靠盖住 .fr-del 来隐藏按钮的，
      一旦背景变透明，下面的红色按钮会一直透出来。
   ⚠️ 滑动用 transform 不用 margin/left：后者每帧触发重排，
      快速滑动时明显掉帧。transform 走合成层，才有「跟手」的手感。 */
.fr-row{position:relative;overflow:hidden;background:var(--err)}
.fr-del{
  position:absolute;top:0;right:0;bottom:0;width:76px;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
  background:var(--err);color:#fff;font-size:11px;font-weight:700;
}
.fr-item{
  position:relative;z-index:1;
  display:flex;align-items:center;gap:11px;
  padding:12px 14px;background:#fff;transition:background .16s;
}
.fr-item:active{background:var(--line-2)}
/* 行分隔线用相邻兄弟选择器，最后一行不画线 ——
   给每行都写 border-bottom 会在卡片底边留一条多余的横线。 */
.fr-item + .fr-item{border-top:1px solid var(--line-2)}
.fr-item .fr-b{flex:1;min-width:0}
.fr-item .fr-r1{display:flex;align-items:baseline;gap:6px}
.fr-item .fr-r1 b{
  flex:1;min-width:0;font-size:14.5px;font-weight:700;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.fr-item .fr-r2{
  font-size:12.5px;color:var(--gray-3);margin-top:4px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
/* 右侧列：日期在上、未读数字在下，都右对齐。
   ⚠️ 不用 absolute：日期和角标是两个元素，
      绝对定位后没有文档流撑着，未读数为 0 时整行高度会塌一截。 */
.fr-item .fr-rt{
  flex:none;display:flex;flex-direction:column;align-items:flex-end;gap:6px;
}
.fr-item .fr-tm{font-size:11px;color:var(--gray-4);line-height:1;flex:none}
/* 未读数字角标（红色胶囊）。
   ⚠️ 与 .mc-badge 的区别：那个是四宫格入口角标，带 2px 白描边
      因为它压在彩色图标上；这里在纯白底上，不需要描边。 */
.fr-item .fr-bd{
  min-width:18px;height:18px;padding:0 5px;border-radius:9px;
  background:var(--err);color:#fff;
  font-size:11px;font-weight:800;line-height:18px;text-align:center;
  box-sizing:border-box;flex:none;
}

/* ---- v1.8.25：好友消息骨架（.fr-sk） ----
   复用 .fr-item 的行结构（头像 + fr-b + fr-rt），只把内容换成灰条，
   这样行高、内边距、间距与真实行逐像素一致，数据到达时不跳。

   ⚠️ 摘要条 .fr-sk-s 做淡（opacity .62）：
      两根同色同灰的平行条看着就是「两根灰条」，不像文字；
      做出浓淡差才有「标题 + 正文」的层次。
   ⚠️ 骨架头像不加白环阴影：真实 .avatar.lg 那圈白边在纯白卡片上
      本就看不出来，加了反而比真实头像大一圈。 */
.fr-sk .fr-b{display:flex;flex-direction:column;gap:8px;min-width:0}
.fr-sk .fr-sk-n{border-radius:7px;flex:none}
.fr-sk .fr-sk-s{border-radius:6px;flex:none;opacity:.62}
.fr-sk .fr-sk-tm{border-radius:5px;flex:none}
.fr-sk .fr-sk-bd{border-radius:9px;flex:none}

/* v1.8.23：三个入口的未读角标
   .me-bd  数字角标（系统通知 / 创作者小助手，有精确未读数）
   .me-dot 圆点（活动中心，只有「有/没有」两种状态）

   ⚠️ 两者都要 absolute 定位：
      角标不是行内元素，写进文档流会把右侧箭头挤走、并撑高整行。
   ⚠️ right 要给箭头让位（箭头 15px + 行内边距），
      贴到 14px 会和 > 图标叠在一起。 */
.msg-entry{position:relative}
.me-bd{
  position:absolute;right:34px;top:50%;transform:translateY(-50%);
  min-width:18px;height:18px;padding:0 5px;border-radius:9px;
  background:var(--err);color:#fff;
  font-size:11px;font-weight:800;line-height:18px;text-align:center;
  box-sizing:border-box;
}
.me-dot{
  position:absolute;right:40px;top:50%;transform:translateY(-50%);
  width:8px;height:8px;border-radius:50%;background:var(--err);
}

/* 分类入口（v1.8.22 改为四宫格：收到评论 / @我的 / 赞和收藏 / 新增关注） */
.msg-cats{display:flex;padding:14px 4px 12px}
/* 卡片内：格子不再各自带边框 —— 卡片套卡片会出现双边框 */
.msg-panel .msg-cat{border:none;background:transparent;border-radius:0;padding:0}
.msg-panel .msg-cat:active{transform:scale(.94)}
.msg-cat{
  flex:1;position:relative;display:flex;flex-direction:column;align-items:center;gap:6px;
  padding:13px 6px 11px;border-radius:15px;
  background:#fff;border:1px solid var(--line);
  font-family:inherit;cursor:pointer;transition:.16s;
}
.msg-cat:active{transform:scale(.97)}
/* ============ 选中态：v1.7.53【彻底取消】 ============
 *
 * 演进过程，避免以后有人又加回来：
 *   v1.7.50 品牌黄描边 + 浅黄底  → 反馈过艳，且与未读卡片的浅黄撞色
 *   v1.7.52 深色描边 + 浅灰底    → 反馈"还是不要"
 *   v1.7.53 无任何视觉差异       → 用户明确要求：取消就是取消，不要改色
 *
 * ⚠️ 【不要再给 .msg-cat.on 加任何颜色/边框/阴影】。
 *    这里刻意【不写】.msg-cat.on 规则，让它完全继承 .msg-cat 的基础样式。
 *
 * 那用户怎么知道当前在哪个分类？靠下方列表内容本身：
 * 选「点赞」列表里就只有赞，选「评论和回复」就只有评论。
 * 内容即反馈，不需要再给入口上色。
 *
 * 保留 .on 类只是【状态标记】（JS 侧判断当前分类用），不带任何视觉，
 * 所以这里不要为它写样式。 */
.msg-cat .mc-ic{
  /* v1.8.22：38px 圆角方块 → 42px 正圆。
     与全站头像/图标容器统一（.msg-card .nc-ic 也是圆），
     且骨架屏里画的就是 42px 圆，不改会对不齐。 */
  width:42px;height:42px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;flex:none;
}
.msg-cat .mc-t{font-size:12.5px;font-weight:700;color:var(--gray-2);line-height:1}
/* v1.7.53：选中态文字也不再加深 —— 见上方「选中态彻底取消」说明 */
/* 分类入口的未读角标：右上角内嵌（同 .dot-badge 的内嵌原则）。
   外溢会被 .msg-cats 的父级裁剪，且四格并排时相邻的会互相压住。 */
.msg-cat .mc-badge{
  position:absolute;top:7px;right:8px;min-width:17px;height:17px;padding:0 5px;
  border-radius:9px;background:var(--err);color:#fff;
  font-size:10.5px;font-weight:800;line-height:17px;text-align:center;
  box-sizing:border-box;border:2px solid #fff;
}

/* 通知卡片列表（v1.7.94 UI 重做）
   ------------------------------------------------------------------
   ⚠️ 子元素前缀【必须是 nc-】，不能沿用旧版的 mc2-：
      .mc2-tag / .mc2-ic 等被【鱼塘动态卡片】共用（见 Moment 渲染的
      .mc2-tags > .mc2-tag），改它们的样式会连带改掉动态列表。
      本项目已多次踩到「改 A 坏 B」（.empty / .hint / --bg-2 都是这么来的）。
   ⚠️ 也别用 nt- 前缀：那是 v1.7.51 系统消息独立页的（页面已废弃，
      但 .nt-card 的 CSS 还在），混用会导致两套规则互相覆盖。

   类型色走 CSS 变量 --nc（主色）/ --ncbg（底色），由渲染时写在
   .msg-card 的 inline style 上，子元素统一 var() 取用 ——
   旧版是图标底色、图标色、标签三处各写一遍 inline style，改配色要改三处。
   ------------------------------------------------------------------ */
.msg-list{display:flex;flex-direction:column;gap:10px;padding:0 14px 14px}
.msg-card{
  position:relative;display:flex;gap:12px;align-items:flex-start;
  padding:14px;border-radius:16px;
  background:#fff;border:1px solid var(--line);
  box-shadow:0 1px 2px rgba(27,31,36,.03);
  transition:background .16s;
}
.msg-card:active{background:var(--line-2)}
/* 未读态：浅黄底 + 左侧色条 + 右侧圆点（三重标记）。
   旧版只靠图标底色区分，在列表里扫视时几乎看不出来。 */
.msg-card.unread{background:#FFFDF3;border-color:#FDE68A}
.msg-card.unread::before{
  content:'';position:absolute;left:0;top:11px;bottom:11px;width:3px;
  border-radius:0 3px 3px 0;background:var(--brand);
}
/* 图标：40px 圆形（旧版 38px 圆角方块），与全站头像/图标容器统一 */
.msg-card .nc-ic{
  width:40px;height:40px;border-radius:50%;flex:none;
  display:flex;align-items:center;justify-content:center;
  background:var(--ncbg);color:var(--nc);
}
.msg-card .nc-b{flex:1;min-width:0}
.msg-card .nc-hd{display:flex;align-items:baseline;gap:8px}
.msg-card .nc-hd b{
  flex:1;min-width:0;font-size:14.5px;font-weight:800;line-height:1.4;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.msg-card .nc-tm{font-size:11.5px;color:var(--gray-3);flex:none}
.msg-card .nc-tx{
  font-size:13px;color:var(--gray-2);line-height:1.6;margin-top:5px;
  /* 最多两行：通知内容普遍偏长，不限制会把列表撑得很散 */
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;word-break:break-word;
}
/* 底部行：类型标签独立成行（旧版是裸 span 直接跟在正文后，行距松散） */
.msg-card .nc-ft{margin-top:9px;display:flex;align-items:center}
.msg-card .nc-tag{
  display:inline-block;padding:2.5px 9px;border-radius:8px;
  background:var(--ncbg);color:var(--nc);
  font-size:10.5px;font-weight:800;line-height:1.5;
}
/* 未读圆点：内嵌在卡片右侧内沿，不依赖外溢。
   ⚠️ 必须 padding-right 留位置，否则圆点会压住文字。 */
.msg-card .nc-dot{
  position:absolute;top:50%;right:11px;width:7px;height:7px;margin-top:-3.5px;
  border-radius:50%;background:var(--brand);flex:none;
}
.msg-card.unread .nc-b{padding-right:9px}

/* ============ v1.7.51 系统消息页（独立页面，卡片更大更正式） ============ */
.nt-list{display:flex;flex-direction:column;gap:11px;padding:0 14px 16px}
.nt-card{
  position:relative;padding:14px 15px 13px;border-radius:16px;
  background:#fff;border:1px solid var(--line);
  transition:background .16s;
}
.nt-card:active{background:var(--line-2)}
.nt-card.unread{background:#FFFDF3;border-color:#FDE68A}
/* 未读左侧色条：与消息页卡片保持同一套视觉语言 */
.nt-card.unread::before{
  content:'';position:absolute;left:0;top:13px;bottom:13px;width:3px;
  border-radius:0 3px 3px 0;background:var(--brand);
}
/* 头部：图标 + 署名 + 日期 */
.nt-card .ntc-hd{display:flex;align-items:center;gap:9px}
.nt-card .ntc-ic{
  width:30px;height:30px;border-radius:9px;flex:none;
  display:flex;align-items:center;justify-content:center;
}
.nt-card .ntc-sender{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
.nt-card .ntc-sender b{font-size:12.5px;font-weight:800;line-height:1.3;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.nt-card .ntc-sender span{font-size:10.5px;color:var(--gray-3);line-height:1.3}
.nt-card .ntc-date{font-size:11px;color:var(--gray-3);flex:none}
.nt-card .ntc-title{
  margin-top:10px;font-size:15px;font-weight:800;line-height:1.45;
  word-break:break-word;
}
.nt-card .ntc-txt{
  margin-top:6px;font-size:13px;color:var(--gray-2);line-height:1.6;
  /* 站方通知正文较长，限制三行，超出省略 */
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;
  overflow:hidden;word-break:break-word;
}
/* 底部跳转行：整卡可点，这里只做视觉引导，不再单独绑定事件 */
.nt-card .ntc-act{
  margin-top:11px;padding-top:10px;border-top:1px solid var(--line-2);
  display:flex;align-items:center;gap:3px;color:var(--brand);
}
.nt-card .ntc-btn{font-size:12.5px;font-weight:800}
.nt-card .ntc-act svg{margin-left:-2px}
/* 未读圆点：内嵌右上角，不依赖外溢（v1.7.22 原则） */
.nt-card .ntc-dot{
  position:absolute;top:13px;right:13px;width:7px;height:7px;
  border-radius:50%;background:var(--brand);
}
/* 有圆点时给日期留出空间，否则会压在一起 */
.nt-card.unread .ntc-date{padding-right:11px}

/* 系统消息页的分类 seg：5 个按钮放不下一行时允许横向滚动。
   ⚠️ 不能用 flex:1 均分 —— 5 个中文标签挤在 375px 屏上会换行，
      把下面的列表整体顶下去。 */
#noticeSeg{
  overflow-x:auto;flex-wrap:nowrap;gap:6px;
  scrollbar-width:none;-ms-overflow-style:none;
}
#noticeSeg::-webkit-scrollbar{display:none}
#noticeSeg button{flex:none;min-width:56px;padding:0 12px;white-space:nowrap}

/* 聊天 */
.chat-body{padding:12px 14px 14px;display:flex;flex-direction:column;gap:12px}
.bubble-row{display:flex;gap:8px;align-items:flex-end;animation:fadeUp .26s both}
.bubble-row.mine{flex-direction:row-reverse}
.bubble{
  max-width:74%;padding:9px 13px;border-radius:16px;font-size:14.5px;line-height:1.55;
  word-break:break-word;position:relative;
}
.bubble-row:not(.mine) .bubble{background:#fff;border:1px solid var(--line);border-bottom-left-radius:6px}
.bubble-row.mine .bubble{background:var(--brand);border-bottom-right-radius:6px;color:var(--ink);font-weight:500}
.bubble .bt{font-size:10.5px;color:var(--gray-3);margin-top:4px;text-align:right}
.bubble-row.mine .bubble .bt{color:rgba(27,31,36,.5)}
.chat-input{position:sticky;left:0;right:0;bottom:0;background:rgba(255,255,255,.98);border-top:1px solid var(--line);padding:9px 12px calc(9px + var(--safe-b));display:flex;gap:9px;align-items:flex-end;z-index:25}
.chat-input textarea{flex:1;background:var(--line-2);border-radius:18px;padding:9px 14px;max-height:96px;resize:none;font-size:14.5px;line-height:1.5}
.chat-input .send{width:38px;height:38px;border-radius:50%;background:var(--brand);color:var(--ink);display:flex;align-items:center;justify-content:center;flex:none;transition:.14s}
.chat-input .send:active{transform:scale(.9)}
.chat-input .send.dis{background:#E9EDF2;color:var(--gray-4)}

/* 我的 */
/* ⚠️ v1.7.45：外边距归零 + 内边距 12px，让头像与白色卡片【外框】对齐。
   演进（务必读完再改，别再走回头路）：
     v1.7.44 之前：margin:0 12px + padding:18px 16px → 内容落在 28px，
       与白色卡片【内的文字】对齐。但用户看到的参照物是卡片【白色外框】
       （在 12px），于是觉得头像"缩进去了、没对齐"。
     v1.7.45：margin:0 + padding-left:12px → 内容落在 12px，
       与 .menu-group / .vip-card / .stat-row 的白色外框在同一条竖线上。
   ⚠️ 这张卡是【透明】的（background:transparent），没有可见边框，
      所以 margin 归零不会产生"卡片贴边"的观感 —— 用户只看得到内容。
      只改 margin 不改 padding 会让内容贴到 0px，两者必须一起改。 */
.profile-card{
  margin:0;border-radius:20px;padding:18px 12px;position:relative;overflow:hidden;
  background:transparent;color:var(--ink);z-index:1;
}
/* 改为顶部对齐：签名已并入信息列，若仍居中会让头像随内容变长而下移 */
.profile-card .pc-top{display:flex;align-items:flex-start;gap:13px;position:relative;z-index:1}
/* 昵称 / 徽章 / ID / 签名这一列整体上移 10px。
   用负 margin 而非 transform：整体流随之收缩，下方快捷栏间距保持不变，
   不会因为位移而与快捷栏挤在一起。 */
.profile-card .pc-top .i{margin-top:-10px}
/* 该列与头像均可点击进入个人主页，补上手势反馈 */
.profile-card .pc-top .i,
.profile-card .pc-top .avatar{cursor:pointer}
.profile-card .pc-top .i:active,
.profile-card .pc-top .avatar:active{opacity:.7}
.profile-card .pc-top .i{flex:1;min-width:0}
/* v1.7.65：个人主页（pc-other）取消上移，昵称行顶部与头像顶部齐平。
   -10px 是为【个人中心】加的——那里信息列有三行（昵称 / ID / 签名），
   上移是为了压缩 pc-top 高度、让下方快捷栏 pc-quick 更紧凑。
   个人主页只有昵称 + ID 两行，继承这条会把整列顶到头像上方 10px，
   昵称看着比头像"高出一截"。这里两处结构不同，不能共用同一个上移量。
   ⚠️ 若以后给个人主页补上第三行，记得重新评估这个值。 */
.profile-card.pc-other .pc-top .i{margin-top:0}
/* v1.7.44：昵称 18px → 16.5px（用户要求"改小一点"）
   ⚠️ 这条规则的【特异性是 (0,3,1)，高于 .pc-name b 的 (0,1,1)】，
      个人中心与个人主页两处昵称的实际字号都由它决定。
      只改 .pc-name b 不会生效 —— 必须同步改这里。 */
.profile-card .pc-top .i b{font-size:16.5px;font-weight:800;display:block}
.profile-card .pc-top .i span{font-size:12.5px;opacity:.72;display:block;margin-top:3px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.profile-card .sig{font-size:12.5px;opacity:.72;margin-top:4px;position:relative;z-index:1;line-height:1.5;text-align:left}
.stat-row{display:flex;background:#fff;border-radius:16px;margin:0 12px 10px;padding:14px 0;box-shadow:0 2px 10px rgba(16,24,40,.04)}
.stat-row .st{flex:1;text-align:center;position:relative}
.stat-row .st:not(:last-child)::after{content:"";position:absolute;right:0;top:4px;bottom:4px;width:1px;background:var(--line-2)}
.stat-row .st b{display:block;font-size:18px;font-weight:800}
.stat-row .st span{display:block;font-size:11.5px;color:var(--gray-3);margin-top:2px}
.menu-group{background:#fff;border-radius:16px;margin:0 12px 10px;overflow:hidden;box-shadow:0 2px 10px rgba(16,24,40,.04)}
.menu-group .gt{font-size:12px;color:var(--gray-3);padding:12px 16px 6px;font-weight:600}
.menu-item{display:flex;align-items:center;gap:12px;padding:14px 16px;width:100%;text-align:left;transition:.14s}
.menu-item:active{background:var(--line-2)}
.menu-item .mi-ic{width:32px;height:32px;border-radius:10px;display:flex;align-items:center;justify-content:center;flex:none;background:var(--brand-16);color:var(--ink)}
.menu-item .mi-t{flex:1;font-size:14.5px}
.menu-item .mi-x{font-size:12.5px;color:var(--gray-3);display:flex;align-items:center;gap:5px}
/* 菜单行里的副标题（描述文字）
   ⚠️ 必须 display:block —— 它与前面的 <b> 同为 inline 元素，
      不加的话标题与描述会挤在同一行（v1.7.60 管理中心「内容管理」四行）。
   ⚠️ 类名保持 .mi-sub 通用，不要写成 mg-*，其它菜单行以后也能用。 */
.menu-item .mi-t .mi-sub{display:block;font-size:11.5px;color:var(--gray-3);margin-top:3px;line-height:1.4}

/* 表单 */
.field{margin-bottom:14px}
.field label{display:block;font-size:13px;color:var(--gray-1);margin-bottom:7px;font-weight:600}
.field input,.field textarea{
  width:100%;background:#fff;border:1px solid var(--line);border-radius:13px;padding:12px 14px;
  font-size:14.5px;transition:.15s;resize:none;
}
.field input:focus,.field textarea:focus{border-color:var(--brand);box-shadow:0 0 0 4px var(--brand-16)}
.img-picker{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}
.img-picker .cell{aspect-ratio:1;border-radius:12px;background:var(--line-2);display:flex;align-items:center;justify-content:center;color:var(--gray-3);position:relative;overflow:hidden}
.img-picker .cell img{width:100%;height:100%;object-fit:cover}
.img-picker .cell .del{position:absolute;right:3px;top:3px;width:19px;height:19px;border-radius:50%;background:rgba(27,31,36,.62);color:#fff;display:flex;align-items:center;justify-content:center}

/* ==========================================================
   发布表单通用 UI（v1.7.36：去掉卡片容器）
   发图文 / 发图集 / 发布资源 三处共用同一套

   v1.7.35 用过白色卡片容器，反馈太重，改为无容器平铺：
   · 分组只保留「图标 + 标题 + 说明」的标题行，靠留白分隔，不再画框
   · 输入框改为【白底 + 描边】——没有白卡托底后，
     原来的浅灰底（#F7F9FC）直接放在页面底色（#FAFAFA）上几乎看不出边界
   ========================================================== */
/* v1.7.37：发布三页背景改纯白 —— 只改这三个发布页，全站其他页面保持 #FAFAFA
 *
 * 为什么可以改白：发布页是「填表」场景，内容本身没有白卡片，
 * 不存在「白卡浮不起来」的问题，反而更适合干净的底色。
 * 为什么【不能】全站改白：站内列表卡片、菜单组本身是白的，
 * 全靠 #FAFAFA 的背景才「浮」得起来，背景一白整页会糊成一片。
 *
 * ⚠️ 配套约束：背景一白，输入框就【不能再是白底】，
 *    否则两者同色、边界只剩 1px 描边，几乎看不见 ——
 *    这正是 v1.7.36 刚修掉的问题，不能自己改回去。
 *    所以输入框同步转为浅灰。测试 test_publish_ui.js 会守住这条。
 */
.pb-wrap{padding:8px 14px 40px}
/* 三个发布页的页面底色改纯白 */
.page#pg-dynamic,.page#pg-publish,.page#pg-resform{background:#fff}
/* 分组：无背景无边框，只用间距区分 */
.pb-sec{margin-bottom:22px}
/* 组标题：图标 + 标题 + 右侧计数 */
.pb-sec-h{
  display:flex;align-items:center;gap:9px;
  padding:0 2px 10px;
}
.pb-sec-h .ph-ic{
  width:26px;height:26px;border-radius:8px;flex:none;
  background:var(--brand-16);color:#8A6100;
  display:flex;align-items:center;justify-content:center;
}
.pb-sec-h .ph-t{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
.pb-sec-h .ph-t b{font-size:14px;font-weight:800;color:var(--ink);line-height:1.3}
.pb-sec-h .ph-t span{font-size:11.5px;color:var(--gray-3);line-height:1.4}
.pb-sec-h .ph-n{
  flex:none;font-size:11.5px;font-weight:700;color:var(--gray-3);
  /* v1.7.37：页面改白后 --line-2(#F4F6F9) 偏浅，改用与输入框一致的 #F7F9FC
     并加一道描边，保证在纯白底上仍看得见 */
  background:#F7F9FC;border:1px solid var(--line);border-radius:9px;padding:2px 8px;
}
/* 行：组与组之间靠 .pb-sec 的 margin 分隔，组内靠这里 */
.pb-row{padding:0 0 13px}
.pb-row + .pb-row{padding-top:0}
.pb-lab{
  display:flex;align-items:center;gap:5px;
  font-size:12.5px;font-weight:700;color:var(--gray-2);margin-bottom:7px;
}
.pb-lab .req{color:var(--err);font-weight:800}
.pb-lab .opt{font-size:11px;font-weight:600;color:var(--gray-4)}
/* 输入框：浅灰底 + 描边。
   v1.7.37：页面改纯白后，输入框若仍是白底会与背景同色、只剩描边撑边界。
   浅灰底 #F7F9FC 与页面白形成层次，聚焦时转白底强化「正在输入」。 */
.pb-inp,.pb-ta{
  width:100%;background:#F7F9FC;border:1px solid var(--line);border-radius:13px;
  padding:11px 13px;font-size:14.5px;font-family:inherit;color:var(--ink);
  outline:none;transition:.15s;resize:none;
}
.pb-ta{line-height:1.7;min-height:88px}
.pb-inp::placeholder,.pb-ta::placeholder{color:var(--gray-4)}
/* 聚焦：灰转白 + 品牌色描边，两层变化同时给出「已聚焦」的反馈 */
.pb-inp:focus,.pb-ta:focus{
  background:#fff;border-color:var(--brand);box-shadow:0 0 0 3.5px var(--brand-16);
}
/* 无框大字（标题用）：没有卡片也要保持干净，聚焦时只加下划线色 */
.pb-inp.bare{
  background:transparent;border:none;border-radius:0;padding:2px 0;
  font-size:17px;font-weight:800;letter-spacing:.2px;
}
.pb-inp.bare:focus{background:transparent;border:none;box-shadow:none}
/* 行内提示 */
.pb-tip{font-size:11.5px;color:var(--gray-3);line-height:1.6;margin-top:6px}
/* 分段选择（获取方式等二选一） */
.pb-seg{display:flex;gap:9px}
.pb-seg button{
  flex:1;min-height:42px;border-radius:13px;border:1.5px solid var(--line);
  background:#F7F9FC;color:var(--gray-1);
  font-size:13.5px;font-weight:700;font-family:inherit;cursor:pointer;
  display:flex;align-items:center;justify-content:center;gap:6px;transition:.16s;
}
.pb-seg button.on{
  background:var(--brand-16);border-color:var(--brand);color:#8A6100;
}
.pb-seg button:active{transform:scale(.97)}
/* 胶囊组（分类 / 圈子） */
.pb-pills{display:flex;flex-wrap:wrap;gap:8px}
.pb-pill{
  padding:7px 13px;border-radius:12px;border:1.5px solid var(--line);
  background:#F7F9FC;color:var(--gray-1);
  font-size:13px;font-weight:600;font-family:inherit;cursor:pointer;
  white-space:nowrap;transition:.16s;min-height:33px;
}
.pb-pill.on{background:var(--brand);border-color:var(--brand);color:var(--ink);font-weight:800}
.pb-pill:active{transform:scale(.95)}
/* 图片区：三列网格 */
.pb-imgs{
  display:grid;grid-template-columns:repeat(3,1fr);gap:9px;
}
.pb-img{
  position:relative;aspect-ratio:1/1;border-radius:14px;overflow:hidden;
  background:var(--line-2);
}
.pb-img img{width:100%;height:100%;object-fit:cover;display:block}
.pb-img .del{
  position:absolute;right:4px;top:4px;width:21px;height:21px;border-radius:50%;
  background:rgba(27,31,36,.6);color:#fff;border:none;
  display:flex;align-items:center;justify-content:center;cursor:pointer;
}
.pb-add{
  aspect-ratio:1/1;border-radius:14px;border:1.5px dashed var(--gray-4);
  background:#F7F9FC;color:var(--gray-3);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;
  cursor:pointer;transition:.16s;
}
.pb-add:active{background:var(--brand-16);border-color:var(--brand);color:#8A6100}
.pb-add span{font-size:11px;font-weight:600}
/* 底部操作：主按钮 + 草稿 */
.pb-submit{
  width:100%;height:50px;margin-top:4px;border-radius:16px;border:none;
  background:var(--brand);color:var(--ink);
  font-size:15.5px;font-weight:800;font-family:inherit;cursor:pointer;
  display:flex;align-items:center;justify-content:center;gap:7px;transition:.15s;
}
.pb-submit:active{transform:scale(.98)}
.pb-note{text-align:center;font-size:11.5px;color:var(--gray-3);margin-top:10px;line-height:1.6}

/* 登录/启动页 */
.launch{
  position:absolute;inset:0;z-index:90;background:var(--bg);display:flex;flex-direction:column;
  /* v1.7.72：登录页目标「一屏装下、不用上下滑」。
     上下内边距与关键间距全部改为 clamp(下限, 视口比例, 上限)：
     大屏保持原来的舒展，矮屏（如 iPhone SE 667px）自动收紧。
     ⚠️ overflow-y:auto 必须保留 —— 注册态会多出确认密码/邮箱/验证码三个
        输入框，加上弹出的软键盘，此时一屏必然装不下，去掉就点不到按钮了。 */
  padding:clamp(22px,4.2vh,40px) 26px clamp(18px,3vh,30px);
  padding-top:calc(clamp(22px,4.2vh,40px) + var(--safe-t));
  padding-bottom:calc(clamp(18px,3vh,30px) + var(--safe-b));
  overflow-y:auto;
}
/* ---- 站点 Logo：整体微微歪一点（rotate -5deg） ----
   变形修复要点：
     · flex:none   —— 不被 flex 容器压缩，这是「不变形」的前提
     · overflow:hidden + 内边距 —— 文字再多也不会撑破方块
     · line-height:1 / letter-spacing:0 —— 多字时不会撑高
     · 字号由脚本按字数换算（见 index.php 底部的 fitLogo）
*/
.launch .l-logo{
  position:relative;
  width:78px;height:78px;flex:none;overflow:hidden;
  box-sizing:border-box;padding:7px;
  /* v1.7.72：6vh → clamp，矮屏下自动收缩，避免整页被撑出滚动条 */
  border-radius:22px;margin:clamp(14px,4vh,44px) auto clamp(12px,2.4vh,20px);
  background:linear-gradient(158deg,rgba(255,255,255,.62) 0%,rgba(255,255,255,0) 56%),var(--brand);
  display:flex;align-items:center;justify-content:center;
  font-size:36px;font-weight:800;line-height:1.05;letter-spacing:0;
  text-align:center;word-break:break-all;
  transform:rotate(-5deg);
  box-shadow:0 13px 26px rgba(255,180,0,.34),inset 0 1px 0 rgba(255,255,255,.55);
  animation:logoIn .5s cubic-bezier(.34,1.5,.5,1) both;
}
@keyframes logoIn{
  from{opacity:0;transform:rotate(-13deg) scale(.86)}
  to  {opacity:1;transform:rotate(-5deg) scale(1)}
}
@media (prefers-reduced-motion:reduce){
  .launch .l-logo{animation:none}
}
.launch h1{font-size:26px;text-align:center;font-weight:800}
.launch .l-sub{text-align:center;color:var(--gray-2);font-size:13.5px;margin-top:8px}
/* v1.7.72：34px → clamp，与上面的内边距同步收紧 */
.launch .form{margin-top:clamp(18px,3.4vh,34px)}
.launch .switch{text-align:center;font-size:13.5px;color:var(--gray-2);margin-top:clamp(14px,2vh,20px)}
.launch .switch b{color:var(--ink);font-weight:700}

/* v1.7.73：登录页「立即注册 … 忘记密码」一行。
   左侧走原来的 .switch（JS 依赖 .switch b 与 #lgSwitchTxt，沿用可不动 JS），
   右侧「忘记密码」贴到最右，用 space-between 而不是 margin-left:auto，
   这样注册态隐藏右项后，左侧仍从最左边起排。 */
.lg-links{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  margin:clamp(10px,1.8vh,16px) 0 2px;
}
/* 覆盖 .launch .switch 的居中与外边距 —— 进了这一行就该左对齐、不留上边距。
   ⚠️ 用 .launch 前缀提到 (0,3,0)：单写 .lg-links .switch 与 .launch .switch
      同为 (0,2,0)，只能靠"写在后面"取胜，一旦有人调整规则顺序就会失效。 */
.launch .lg-links .switch{margin-top:0;text-align:left;flex:none}
.lg-links .fp{
  flex:none;font-size:13px;color:var(--gray-2);cursor:pointer;
  padding:4px 2px;transition:.14s;
}
.lg-links .fp:active{opacity:.55}

/* 找回密码页的状态提示（发码成功 / 失败原因） */
.fg-tip{
  font-size:12.5px;line-height:1.7;margin-top:12px;text-align:center;color:var(--gray-3);
}
.fg-tip.err{color:#E5484D}
.fg-tip.ok{color:#2E7D5B}
.launch .guest{display:block;width:100%;text-align:center;margin-top:clamp(14px,2.6vh,26px);font-size:13.5px;color:var(--gray-2)}
.launch .copyright{text-align:center;font-size:11.5px;color:var(--gray-4);margin-top:auto;padding-top:clamp(14px,2.4vh,30px)}

/* v1.7.72：两个输入框之间的 14px 也随视口收紧，矮屏再省约 10px。
   只作用于登录页 —— .field 是全站通用样式，改全局会波及所有表单页。 */
.launch .form .field{margin-bottom:clamp(9px,1.6vh,14px)}

/* v1.7.72【登录页底部暂时隐藏】演示账号按钮 + 版本号/Copyright。
   这两块加起来约 95px，是登录页被撑出滚动条的主要原因之一。
   ⚠️ 是隐藏不是删除，需要恢复时把下面两条 display:none 去掉即可。
      .guest.demo 的样式（12.5px / gray-3）原本写在 index.php 的行内
      style 里，为避免隐藏后恢复时丢样式，已一并收进这条规则。 */
.launch .guest.demo{font-size:12.5px;color:var(--gray-3);margin-top:10px;display:none}
.launch .copyright{display:none}

/* v1.7.72：注册态（.launch.reg，由 Auth.applyMode 切换）。
   比登录态多三行输入框，留白再收一档，少滑一点是一点。
   v1.7.73：删掉原来「Logo 缩到 60px」的规则 —— 需求要求注册与登录的
   Logo 一样大。留白收紧保留，那不影响 Logo 尺寸。 */
.launch.reg .form{margin-top:clamp(14px,2.4vh,34px)}
.launch.reg .guest{margin-top:clamp(10px,1.8vh,26px)}

/* ---------- 第三方登录（v1.7.67：QQ）---------- */
.oauth-wrap{margin-top:24px}
.oauth-line{display:flex;align-items:center;gap:10px;margin-bottom:16px}
.oauth-line::before,.oauth-line::after{content:"";flex:1;height:1px;background:var(--line)}
/* 「其他登录方式」这句话本身就是分隔线的一部分，所以放进 ::before/::after 之间，
   用 flex 让它居中。不用 absolute 定位，是为了避免文字长度变化时偏移。 */
.oauth-line span{font-size:11.5px;color:var(--gray-4);flex:0 0 auto}
.oauth-btn{display:flex;align-items:center;justify-content:center;gap:8px;width:100%;
  height:46px;border-radius:14px;border:1px solid var(--line);background:#fff;
  font-size:14.5px;font-weight:600;color:var(--ink);cursor:pointer;
  transition:.15s;-webkit-tap-highlight-color:transparent}
.oauth-btn:active{background:#F2F4F7}
.oauth-btn svg{flex:0 0 auto}
/* QQ 蓝。用品牌蓝能立刻被认出是 QQ 入口，
   但整体仍是白底描边，不会破坏登录页的浅色基调。 */
.oauth-btn.qq:active{background:#EAF3FF;border-color:#BBD9FF}
.oauth-btn.qq svg{color:#12B7F5}

/* 全屏图片预览 */
.previewer{position:absolute;inset:0;z-index:85;background:rgba(0,0,0,.94);display:flex;align-items:center;justify-content:center;opacity:0;visibility:hidden;transition:.24s}
.previewer.on{opacity:1;visibility:visible}
.previewer img{max-width:100%;max-height:100%;object-fit:contain}
.previewer .pv-close{position:absolute;top:calc(16px + var(--safe-t));right:18px;color:#fff;opacity:.9}
.previewer .pv-idx{position:absolute;bottom:calc(40px + var(--safe-b));left:0;right:0;text-align:center;color:rgba(255,255,255,.8);font-size:13px}

/* 支付/下载弹窗 */
.pay-box{text-align:center;padding:4px 0 6px}
.pay-box .p-ic{width:58px;height:58px;margin:0 auto 12px;border-radius:50%;background:var(--brand-16);color:var(--ink);display:flex;align-items:center;justify-content:center}
.pay-box h3{font-size:17px;font-weight:800;margin-bottom:5px}
.pay-box .price{font-size:30px;font-weight:800;margin:10px 0 4px;letter-spacing:-.5px}
.pay-box .price small{font-size:15px;font-weight:700}
.pay-box .desc{font-size:12.5px;color:var(--gray-3)}
.link-box{background:var(--line-2);border-radius:14px;padding:13px 14px;text-align:left;margin-top:4px}
.link-box .lb-r{display:flex;align-items:center;gap:8px;margin-bottom:9px}
.link-box .lb-r:last-child{margin-bottom:0}
.link-box .lb-r .k{font-size:12.5px;color:var(--gray-3);flex:none;width:52px}
.link-box .lb-r .v{flex:1;font-size:13.5px;word-break:break-all;line-height:1.5}
.link-box .lb-r .cp{font-size:12.5px;font-weight:700;color:var(--ink);padding:3px 10px;border-radius:8px;background:var(--brand);flex:none}

/* ============ 创作者中心（v1.3.5 重做）============ */
.cr-lv{
  margin:0 12px 14px;padding:15px;display:flex;align-items:center;gap:12px;
  border-radius:17px;background:linear-gradient(120deg,#FFF9E8,#FFFDE8);border:1px solid var(--brand);
}
.cr-lv-badge{
  width:46px;height:46px;border-radius:50%;background:var(--brand);color:var(--ink);
  display:flex;align-items:center;justify-content:center;font-size:15px;font-weight:800;flex:none;
}
.cr-lv-info{flex:1;min-width:0}
.cr-lv-t{font-size:14.5px;font-weight:800;color:var(--ink)}
.cr-lv-bar{height:7px;border-radius:6px;background:rgba(27,31,36,.09);margin-top:7px;overflow:hidden}
.cr-lv-bar i{display:block;height:100%;background:var(--brand);border-radius:6px;transition:width .4s}
.cr-lv-n{flex:none;font-size:12px;font-weight:700;color:#7A5B00;text-align:right}
.cr-lv-n span{font-weight:500;opacity:.7}

.cr-box{
  margin:0 12px 14px;padding:18px 16px;border-radius:16px;background:#fff;
  border:1px solid var(--line);text-align:center;
}
.cr-box.warn{background:#FFFAEB;border-color:#FEDF89}
.cr-box.err{background:#FEF3F2;border-color:#FECDCA}
.cr-box-ic{
  width:46px;height:46px;margin:0 auto 10px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
}
.cr-box.warn .cr-box-ic{background:#FEDF89;color:#B54708}
.cr-box.err .cr-box-ic{background:#FECDCA;color:#B42318}
.cr-box-t{font-size:14.5px;font-weight:800;color:var(--ink)}
.cr-box.warn .cr-box-t{color:#B54708}
.cr-box.err .cr-box-t{color:#B42318}
.cr-box-d{font-size:12.5px;color:var(--gray-2);margin-top:6px;line-height:1.75}
.cr-box.warn .cr-box-d{color:#7A5B00}
.cr-box-q{
  margin-top:11px;padding:9px 11px;border-radius:10px;background:rgba(255,255,255,.7);
  font-size:12px;color:var(--gray-1);text-align:left;line-height:1.7;
}
.cr-tip{
  margin:0 12px 14px;padding:13px 14px;border-radius:14px;background:var(--bg-2);
  font-size:12.5px;color:#475467;line-height:1.85;
}

/* 收益卡 */
.cr-money{
  margin:0 12px 14px;padding:17px 18px;border-radius:18px;display:flex;align-items:center;
  background:linear-gradient(120deg,#1B1F24,#2C323B);color:#fff;
  box-shadow:0 8px 22px rgba(27,31,36,.16);
}
.cr-money-l{flex:1;min-width:0}
.cr-money-r{flex:none;text-align:right;padding-left:14px;border-left:1px solid rgba(255,255,255,.16)}
.cr-money-t{font-size:11.5px;opacity:.7}
.cr-money-v{font-size:26px;font-weight:800;letter-spacing:-.5px;margin-top:4px;color:var(--brand)}
.cr-money-v.sm{font-size:18px}

/* 数据四宫格 */
.cr-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:9px;margin:0 12px 14px}
.cr-cell{background:#fff;border-radius:14px;padding:12px 6px;text-align:center;box-shadow:0 2px 10px rgba(16,24,40,.04)}
.cr-cell-v{font-size:17px;font-weight:800;color:var(--ink)}
.cr-cell-t{font-size:11px;color:var(--gray-3);margin-top:3px}

/* 待审提醒 */
.cr-alert{
  margin:0 12px 14px;padding:11px 13px;border-radius:13px;background:#FFFAEB;border:1px solid #FEDF89;
  display:flex;align-items:center;gap:8px;font-size:13px;color:#B54708;cursor:pointer;
}
.cr-alert span{flex:1;min-width:0}

/* 文章管理列表 */
.cr-art{
  display:flex;gap:10px;align-items:center;margin:0 12px 10px;padding:10px;
  background:#fff;border-radius:14px;box-shadow:0 2px 10px rgba(16,24,40,.04);
}
.cr-art-cov{
  width:62px;height:62px;border-radius:11px;flex:none;background:var(--bg-2);
  display:flex;align-items:center;justify-content:center;color:rgba(27,31,36,.2);overflow:hidden;
}
.cr-art-b{flex:1;min-width:0}
.cr-art-t{
  font-size:13.5px;font-weight:600;color:var(--ink);line-height:1.45;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.cr-art-m{font-size:11px;color:var(--gray-3);margin-top:3px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cr-art-s{display:flex;align-items:center;gap:10px;margin-top:5px;font-size:11px;color:var(--gray-3)}
.cr-art-s span{display:inline-flex;align-items:center;gap:3px}
.cr-art-st{margin-left:auto;font-weight:700}
.cr-art-a{flex:none;display:flex;flex-direction:column;gap:6px}
/* v1.7.40：文章管理行的「编辑 / 删除」与管理员范围切换 */

/* 危险操作（删除）用红色文字区分，不能和「下架」这类常规操作长得一样，
   否则容易误点。这里只改文字色，保留灰底 —— 整块变红会太抢眼。 */
.btn-ghost-sm.danger{color:#F04438}

/* 管理员范围切换（我的文章 / 全部文章） */
.arts-scope{
  display:flex;gap:8px;margin:0 12px 10px;padding:3px;
  background:#F2F4F7;border-radius:12px;
}
.arts-scope .as-btn{
  flex:1;min-height:32px;border:none;border-radius:9px;background:transparent;
  color:var(--gray-2);font-size:12.5px;font-weight:600;font-family:inherit;
  cursor:pointer;transition:.16s;
}
.arts-scope .as-btn.on{
  background:#fff;color:var(--ink);font-weight:800;
  box-shadow:0 1px 3px rgba(16,24,40,.10);
}

/* v1.7.48【已废弃】详情页底部的「这是你的文章 + 编辑/删除」提示栏。
   整块删除的原因：
     · 它把正文往下推、占首屏
     · 对管理员是句错话 —— 打开别人的文章却显示"这是你的文章"
   管理入口已收进导航栏右上角的【竖排三点】菜单（Resource.moreMenu）。
   ⚠️ 这里【不保留样式】：留着没人用，反而会让后人误以为还有这套结构。 */

/* 编辑态顶部提示 + 表单内的文字链按钮 */
.pb-tip-box{
  display:flex;align-items:center;gap:7px;
  margin:4px 0 16px;padding:10px 12px;border-radius:12px;
  background:#FFFBEB;border:1px solid #FDE68A;
  font-size:12.5px;line-height:1.5;color:#B54708;
}
.pb-tip-box svg{flex:none}
.pb-link{
  background:none;border:none;padding:0;font-family:inherit;font-size:inherit;
  text-decoration:underline;cursor:pointer;color:inherit;
}
.pb-link.danger{color:#F04438}

/* ============ 余额充值 ============ */
.bl-head{
  margin:0 12px 14px;padding:20px 18px;border-radius:18px;
  background:linear-gradient(120deg,#1B1F24,#2C323B);color:#fff;
  box-shadow:0 8px 22px rgba(27,31,36,.16);
}
.bl-head-t{font-size:11.5px;opacity:.7}
.bl-head-v{font-size:31px;font-weight:800;letter-spacing:-1px;margin-top:5px;color:var(--brand)}
.bl-head-sub{display:flex;gap:18px;margin-top:13px;padding-top:13px;border-top:1px solid rgba(255,255,255,.14)}
.bl-head-sub div{font-size:12px;opacity:.85}
.bl-head-sub b{display:block;font-size:15px;font-weight:800;color:#fff;margin-top:2px}

.bl-plans{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin:0 12px 14px}
.bl-plan{
  background:#fff;border:1.5px solid var(--line);border-radius:14px;padding:13px 6px;text-align:center;
  transition:.15s;cursor:pointer;
}
.bl-plan:active{transform:scale(.96)}
.bl-plan.on{border-color:var(--brand);background:rgba(255,228,17,.08)}
.bl-plan-v{font-size:17px;font-weight:800;color:var(--ink)}
.bl-plan-g{font-size:11px;color:var(--err);font-weight:700;margin-top:2px;min-height:15px}
.bl-plan.on .bl-plan-g{color:#8A6100}

/* 列表通用标签切换 */
.tag{cursor:pointer;user-select:none}

/* ============ 发布文章表单 ============ */
.pf-imgs{display:grid;grid-template-columns:repeat(3,1fr);gap:9px}
.pf-img{position:relative;aspect-ratio:1/1;border-radius:12px;overflow:hidden;background:var(--bg-2)}
.pf-img img{width:100%;height:100%;object-fit:cover;display:block}
.pf-del{
  position:absolute;right:5px;top:5px;width:21px;height:21px;border-radius:50%;
  background:rgba(0,0,0,.55);color:#fff;display:flex;align-items:center;justify-content:center;
}
.pf-add{
  aspect-ratio:1/1;border-radius:12px;border:1.5px dashed var(--line);background:var(--bg-2);
  color:var(--gray-3);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;
  font-size:11.5px;cursor:pointer;transition:.15s;
}
.pf-add:active{background:var(--brand-16)}
.pf-cates{display:flex;gap:8px;flex-wrap:wrap}
.pf-cate{
  padding:7px 13px;border-radius:11px;background:var(--bg-2);color:var(--gray-1);
  font-size:13px;cursor:pointer;transition:.15s;border:1.5px solid transparent;
}
.pf-cate:active{transform:scale(.96)}
.pf-cate.on{background:var(--brand-16);color:#8A6100;border-color:var(--brand);font-weight:700}

/* ============ 个人中心身份徽章与快捷栏（v1.3.6）============ */
.pc-badges{display:flex;align-items:center;gap:5px;flex-wrap:wrap;margin-top:4px}
.pc-badge{
  display:inline-flex;align-items:center;gap:3px;font-size:10px;font-weight:800;
  padding:1.5px 6px;border-radius:6px;line-height:1.6;white-space:nowrap;
}
.pc-badge.lv{background:var(--brand-16);color:#8A6100}
.pc-badge.vip{background:#FFF3B0;color:#8A6100}
.pc-badge.creator{background:#E4F7D6;color:#3A7D0E}
.pc-badge.admin{background:#D6E9FF;color:#1E5EB8}

/* 昵称行：昵称 + 身份徽章横向排列（徽章紧跟昵称右侧，同一行）
   —— 昵称完整显示、不再省略：
      此前 b 上有 overflow:hidden + text-overflow:ellipsis + nowrap，
      还被 max-width:calc(100% - 140px) 限制，长昵称一律被截成「奶酪…」。
      改为允许换行，并允许徽章组整体折到下一行。 */
.pc-name{
  display:flex;align-items:center;gap:6px;
  /* ⚠️ nowrap 是关键：wrap 会让徽章组整块掉到第二行（v1.7.41 的"太丑"）。
     现在昵称可收缩 + ellipsis，所以空间不够时牺牲的是【昵称尾部】，
     徽章始终留在昵称右侧同一行。 */
  flex-wrap:nowrap;
  min-width:0;width:100%;
}
.pc-name b{
  font-family:var(--font-title);
  font-size:16.5px;font-weight:800;
  letter-spacing:.2px;       /* 略微放开字距，中文更舒展 */
  line-height:1.3;
  /* ⚠️ 变形的真正根因是 white-space:normal，不是「能不能收缩」。
     此前是 flex:0 1 auto + white-space:normal：空间不足时昵称【内部换行】，
     18px 大字每个字占一行 → 卡片被撑高、昵称竖排。
     v1.7.41 改 flex-shrink:0 让徽章整块折行，虽然不变形，但徽章掉到第二行
     很难看（用户反馈"太丑"）。
     v1.7.42 回到同行：昵称允许收缩，但 nowrap + ellipsis 保证它【横向】优雅
     截断，永远不会竖排。徽章组 flex:none 优先保住，先被牺牲的是超长昵称。 */
  flex:0 1 auto;
  min-width:0;               /* 允许收缩到比内容更窄，配合 ellipsis 生效 */
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  max-width:100%;
}
.pc-badges.inline{
  display:inline-flex;align-items:center;gap:5px;
  flex-wrap:nowrap;          /* 徽章组整体不换行：始终紧跟昵称右侧 */
  flex:none;margin-left:2px;
  max-width:100%;
}
/* ⚠️ v1.7.41 曾让徽章数 ≥3 时整块独占一行（flex-basis:100%），
   虽然不变形，但徽章掉到第二行很难看（用户反馈"太丑"）。
   v1.7.42 回到「徽章紧跟昵称同行」，靠【缩小徽章】腾出空间：
   字号 10.5→9.5、内边距 2.5/8→1.5/5、图标 11→9、组间距 7→5，
   三枚徽章总宽从约 176px 降到约 128px，375px 屏上昵称仍可完整显示。
   此规则保留为空实现，防止今后有人误加 .wrap 又掉回第二行。 */
.pc-badges.inline.wrap{
  flex-basis:auto;
  margin-left:2px;
  margin-top:0;
}

/* 昵称行通用规则 —— 个人中心(.pc-name) 与 个人主页(.nick-row) 共用。
   两处都是「昵称 + 若干徽章」横向排列，挤压问题的根因与解法完全一致，
   分开写必然会在某一处漏改。 */
.nick-row{display:flex;align-items:center;gap:5px;flex-wrap:nowrap;min-width:0;width:100%}
.nick-row > b{
  flex:0 1 auto;             /* 允许收缩 */
  min-width:0;               /* 配合 ellipsis：收缩后横向省略，不竖排 */
  max-width:100%;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
/* 徽章缩小版：紧跟昵称右侧时不能喧宾夺主，也不能顶破一行 */
.pc-badges.inline .pc-badge,
.nick-row .pc-badge{
  font-size:9.5px;padding:1.5px 5px;gap:2px;white-space:nowrap;
  line-height:1.3;border-radius:5px;font-weight:700;
}
.pc-badges.inline .pc-badge svg,
.nick-row .pc-badge svg{width:9px;height:9px;flex:none}

/* 昵称 → ID → 签名：三行纵向堆叠，统一左侧对齐（与头像右边缘对齐） */
.pc-info{display:block;min-width:0;width:100%}
.pc-meta{
  display:block;font-size:12.5px;color:var(--gray-2);
  margin-top:3px;opacity:1;text-align:left;
}

/* ID 与称号 */
.pc-meta{font-size:12.5px;color:var(--gray-2);margin-top:3px;opacity:1}

.pc-quick{
  /* 已取消分隔线（原 rgba(27,31,36,.08) 黑线） */
  display:flex;margin-top:14px;padding-top:0;position:relative;z-index:1;border-top:none;
}
.pc-q{flex:1;text-align:center;cursor:pointer}
.pc-q:active{opacity:.7}
.pc-q b{display:block;font-size:15px;font-weight:800;color:var(--ink)}
.pc-q span{display:block;font-size:11px;color:var(--gray-2);margin-top:2px}

/* ============ 转账 ============ */
.tr-head{
  margin:0 12px 14px;padding:20px 18px;border-radius:18px;text-align:center;
  background:linear-gradient(120deg,#1B1F24,#2C323B);color:#fff;
  box-shadow:0 8px 22px rgba(27,31,36,.16);
}
.tr-head-t{font-size:11.5px;opacity:.7}
.tr-head-v{font-size:31px;font-weight:800;letter-spacing:-1px;margin-top:5px;color:var(--brand)}

/* ==========================================================
   我的 · 顶部流体色块背景（弥散渐变 + 模糊 Blob）
   高度 100px，随页面滚动，底部渐隐融入页面背景
   ========================================================== */
.me-hero{
  /* 从页面最顶部开始（含导航栏区域），向下铺展。
     导航栏底部为全透明渐变，色块透过导航可见，视觉上连成一体。
     v1.7.71：铺展高度 100px → 124px。导航栏加白渐变后，
     色块顶部会被压淡一层，整体上移半格做视觉补偿；
     同时四个 blob 的 top 与尺寸同步下移/放大（见下），
     让「弥散」的主体落在导航下方的可见区，而不是被导航吃掉。 */
  position:absolute;left:0;right:0;
  top:0;height:calc(var(--nav-h) + var(--safe-t) + 124px);
  overflow:hidden;pointer-events:none;z-index:0;
}
/* 底部渐隐，避免色块边缘出现生硬切线。
   v1.7.34：44px → 58px。恢复 blur 后色块向下多扩散约 24px，
   原高度盖不住，底部会露出一条被 overflow 切出来的硬边。 */
.me-hero::after{
  /* v1.7.71：58px → 66px。铺展区加高 24px 后色块也跟着变大，
     原来的渐隐长度盖不住，底部会露出被 overflow 切出的硬边。
     （v1.7.34 从 44px 加到 58px 就是同一个原因。） */
  content:"";position:absolute;left:0;right:0;bottom:0;height:66px;
  background:linear-gradient(to bottom,rgba(250,250,250,0) 0%,var(--bg) 100%);
}
/* v1.7.34：恢复高斯模糊 —— 采用「动画层 / 模糊层」分离架构
 *
 * 【为什么要恢复】
 * v1.7.18 为性能优化去掉了 filter:blur(30px)，只留纯 radial-gradient。
 * 实测逐点采样差异仅 1.4%，单看色块确实接近；
 * 但漏掉了 blur 最重要的作用 —— 让相邻色块在交界处【互相渗透融合】。
 * 纯 gradient 各自渐隐，边界互不相干，看上去就是几个独立的气泡，
 * 失去了「弥散流体」应有的融合感。
 *
 * 【为什么不直接加回去】
 * 若把 filter 与 animation 放在同一个元素上，
 * 每帧 transform 都会让 blur 重新光栅化 ——
 * 高斯模糊是移动端最贵的操作之一，4 块、每秒 60 次，必然掉帧。
 *
 * 【分层方案】
 *   .blob        → 只做 transform 动画，提升为合成层（GPU 变换纹理）
 *   .blob::before → 承载渐变 + blur，本身不参与动画
 * 浏览器会把内层光栅化为一张纹理并缓存，
 * 之后外层 transform 只是对这张纹理做 GPU 变换，blur 不再重算。
 * 视觉等同「每帧重算」，成本却接近「只算一次」。
 *
 * ⚠️ 维护提醒：不要把 filter 移回 .blob，否则性能问题会原样回归。
 *    测试 test_me_blob.js 会守住这条线。
 */
.me-hero .blob{
  position:absolute;border-radius:50%;
}
/* v1.7.57【性能优化】will-change 只在页面激活时给。
   原先常驻在 4 个 blob 上，意味着无论用户在哪个 Tab，
   浏览器都要一直维护 4 个合成层（每块含 blur 24px 的外扩，
   实际约 244×244 × 4B ≈ 238KB，四块近 1MB 显存常驻）。
   页面用 visibility:hidden 隐藏时动画虽不绘制，图层却不会释放。
   改挂到 .page.active 之后，只在真的看着个人中心时才占用。
   blob 是 15~24s 的慢速漂浮，切回来时临层提升的首帧抖动看不出来。 */
.page.active .me-hero .blob{will-change:transform}
/* 模糊层：静态，只在首次光栅化时计算一次 */
.me-hero .blob::before{
  content:"";position:absolute;inset:0;border-radius:50%;
  /* 24px 而非原来的 30px：分层后仍有成本，半径每增加一点
     光栅化面积都按平方增长；24px 已足够让相邻色块融合。 */
  filter:blur(24px);
}
/* 主色黄：左上大块 */
.me-hero .b1{
  width:204px;height:204px;left:-58px;top:-72px;opacity:.72;
  animation:blob1 15s ease-in-out infinite;
}
.me-hero .b1::before{
  background:radial-gradient(circle at 35% 35%,rgba(255,228,17,1) 0%,rgba(255,228,17,.82) 34%,rgba(255,228,17,.42) 58%,rgba(255,228,17,0) 82%);
}
/* 暖橙黄：右上 */
.me-hero .b2{
  width:174px;height:174px;right:-44px;top:-56px;opacity:.6;
  animation:blob2 18s ease-in-out infinite;
}
.me-hero .b2::before{
  background:radial-gradient(circle at 55% 45%,rgba(255,217,102,1) 0%,rgba(255,217,102,.8) 36%,rgba(255,217,102,.4) 60%,rgba(255,217,102,0) 83%);
}
/* 天蓝：中间偏右，与主色形成撞色层次 */
.me-hero .b3{
  width:156px;height:156px;left:42%;top:-34px;opacity:.54;
  animation:blob3 21s ease-in-out infinite;
}
.me-hero .b3::before{
  background:radial-gradient(circle at 50% 50%,rgba(214,233,255,1) 0%,rgba(214,233,255,.78) 36%,rgba(214,233,255,.4) 60%,rgba(214,233,255,0) 83%);
}
/* 淡粉紫：底部小面积点缀 */
.me-hero .b4{
  width:126px;height:126px;right:17%;top:40px;opacity:.4;
  animation:blob2 24s ease-in-out infinite reverse;
}
.me-hero .b4::before{
  background:radial-gradient(circle at 50% 50%,rgba(232,224,255,1) 0%,rgba(232,224,255,.74) 37%,rgba(232,224,255,.38) 61%,rgba(232,224,255,0) 84%);
}
/* 流体漂浮：位移 + 缩放，制造不规则流动感 */
@keyframes blob1{
  0%,100%{transform:translate(0,0) scale(1)}
  33%{transform:translate(26px,16px) scale(1.14)}
  66%{transform:translate(-16px,10px) scale(.92)}
}
@keyframes blob2{
  0%,100%{transform:translate(0,0) scale(1)}
  40%{transform:translate(-22px,18px) scale(1.1)}
  70%{transform:translate(14px,-8px) scale(.95)}
}
@keyframes blob3{
  0%,100%{transform:translate(0,0) scale(1.05)}
  50%{transform:translate(20px,-14px) scale(.9)}
}
/* 尊重系统「减弱动效」设置。
   v1.7.34：这里不仅是不晃 —— 动画停止后图层完全静止，
   blur 连「纹理复用」都省了，成本降到和普通背景图一样。
   ⚠️ 选择器必须与上面的 .page.active .me-hero .blob【同等特异性】(0,4,0)：
      若沿用 .me-hero .blob(0,2,0)，会被上面那条压制，
      will-change:auto 失效 —— 动画虽停，4 个合成层仍常驻不释放。
      同特异性 + 位置在后 → 本条胜出。 */
@media (prefers-reduced-motion:reduce){
  .page.active .me-hero .blob{animation:none;will-change:auto}
}

/* 头图在透明背景下的对比度修正：
   原白色元素在浅色流体背景上会消失，统一改为深色 */
.profile-card .pc-top .i span{opacity:.62}
.profile-card .level-bar-track{background:rgba(27,31,36,.10)}
.profile-card .level-bar-fill{background:var(--brand);box-shadow:0 0 8px rgba(255,228,17,.6)}
.profile-card .level-bar-txt{color:var(--gray-1);opacity:1}
/* 快捷栏：白字改深字；分隔线已按需求移除（此前该规则会把 border-top 加回来，
   表现为「签名下面一条黑线」） */
.pc-quick .pc-q b{color:var(--ink)}
.pc-quick .pc-q span{color:var(--gray-2);opacity:1}

/* ============ 个人中心 · 开通会员模块 ============ */
.vip-card{
  margin:0 12px 10px;padding:15px 16px;border-radius:18px;cursor:pointer;
  display:flex;align-items:center;gap:12px;
  background:linear-gradient(118deg,#1B1F24 0%,#2C323B 58%,#3A3220 100%);
  color:#fff;box-shadow:0 8px 22px rgba(27,31,36,.15);
  transition:transform .16s;
}
.vip-card:active{transform:scale(.985)}
.vip-card .vc-l{flex:1;min-width:0;display:flex;align-items:center;gap:11px}
.vip-card .vc-ic{
  width:40px;height:40px;border-radius:13px;flex:none;
  background:rgba(255,228,17,.16);color:var(--brand);
  display:flex;align-items:center;justify-content:center;
}
.vip-card .vc-txt{min-width:0}
.vip-card .vc-txt b{display:block;font-size:15px;font-weight:800}
.vip-card .vc-txt span{
  display:block;font-size:11.5px;opacity:.68;margin-top:3px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.vip-card .vc-btn{
  flex:none;padding:8px 15px;border-radius:20px;font-size:12.5px;font-weight:800;
  background:var(--brand);color:var(--ink);
}
/* 已是会员：改用金色系，弱化"立即开通"的强引导 */
.vip-card.on{background:linear-gradient(118deg,#3A3220 0%,#4A3F18 55%,#2C323B 100%)}
.vip-card.on .vc-ic{background:rgba(255,228,17,.24)}

/* ============ 个人中心顶部导航：初始半透明，上滑变实 ============ */
.me-nav{
  /* v1.7.71：同样是「白 → #FAFAFA」往下，但末端收到【全透明】。
     个人中心的流体色块（.me-hero .blob）就铺在导航正下方，
     导航若是实底，色块顶部会被整条切掉 —— 那就不是「弥散」了。
     所以这里让白色在导航底部衰减到 0，色块从导航下半段就能透出来，
     顶部仍保留一层薄白，保证标题与设置按钮在浅色流体上依然清晰。

     ⚠️ 色标数量与位置必须和下面的 .solid 完全一致（4 个、同百分比）。
        两条渐变结构一致，浏览器才能在它们之间做插值；
        结构不同会退化成「到点直接跳变」，0.22s 的过渡就没了。

     ⚠️ 另：原写法是 transparent → rgba(255,255,255,.97)。
        transparent 等价于 rgba(0,0,0,0)，插值中点是 rgba(127,127,127,.49)，
        即过渡途中会闪一层灰黑。改成两端同为白色系后，
        插值只剩 alpha 在变，这条灰闪顺带消失了。 */
  background:linear-gradient(to bottom,
    rgba(255,255,255,.92) 0%,
    rgba(252,252,252,.62) 42%,
    rgba(250,250,250,.22) 76%,
    rgba(250,250,250,0) 100%);
  border-bottom:1px solid transparent;
  transition:background .22s ease, border-color .22s ease, box-shadow .22s ease;
}
.me-nav .nb-title,
.me-nav .ic-btn{transition:opacity .22s ease}
/* 未滚动：标题淡出，避免与下方流体色块叠字 */
.me-nav:not(.solid) .nb-title{opacity:0}
.me-nav.solid{
  /* v1.7.18：滚动时这个导航要在透明/实底之间持续切换，
     backdrop-filter 会跟着逐帧重算。背景已 97% 实色，模糊无从体现。
     v1.7.71：改用与上方同结构的渐变，只是 alpha 全部拉到 1。
     滚动到这里时色块已基本滚出视野，实底不影响观感，
     同时保持了「白 → #FAFAFA」这条渐变在全站的一致性。 */
  background:linear-gradient(to bottom,
    rgba(255,255,255,1) 0%,
    rgba(252,252,252,1) 42%,
    rgba(250,250,250,1) 76%,
    rgba(250,250,250,1) 100%);
  border-bottom:1px solid var(--line);
}
.me-nav.solid .nb-title{opacity:1}


.pub-panel .pp-close{
  width:100%;height:46px;margin-top:18px;border-radius:14px;
  background:#F2F4F7;color:var(--gray-1);font-size:15px;font-weight:700;
  display:flex;align-items:center;justify-content:center;transition:.15s;
}
.pub-panel .pp-close:active{background:#E8ECF2;transform:scale(.985)}

/* ============ 动态标题（发布动态时填写，发布鱼塘时无） ============ */
.mcard .mt{
  font-size:15.5px;font-weight:800;line-height:1.45;margin:2px 0 7px;
  color:var(--ink);word-break:break-word;
}
.mcard .mt.big{font-size:18px;margin:4px 0 9px}

/* 分类显示图（后台上传，配置了则优先于 SVG 图标展示）
   与分类标签同步改为方形小圆角（原 50% 圆形会覆盖前面的规则） */
.cate-ic.img{
  background:var(--line-2) center/cover no-repeat;border-radius:5px;
}

/* ============ 动态详情 · 内容块（文字与图片同属一个容器） ============ */
.mcard .md-content{margin-top:2px}
.mcard .md-content .txt{margin-bottom:0}
.mcard .md-content .imgs{margin-top:10px}

/* ============ 资源详情 · 合并后的「资源详情」分段 ============ */
.sec .db{padding:10px 0;border-top:1px solid var(--line-2)}
.sec .db:first-of-type{border-top:none;padding-top:2px}
.sec .db-t{font-size:13px;font-weight:800;color:var(--ink);margin-bottom:5px}
.sec .db p{font-size:13.5px;line-height:1.75;color:var(--gray-1);white-space:pre-wrap}

/* ============ 发布选择面板（参考主流发布面板布局） ============ */
.pub-panel{padding:4px 16px 6px;position:relative}
.pub-panel .pp-h{
  font-size:17px;font-weight:800;margin-bottom:3px;
  display:flex;align-items:baseline;gap:8px;
}
.pub-panel .pp-h-sub{font-size:12px;font-weight:400;color:var(--gray-3)}

/* ---- 推荐话题卡片 ---- */
.pp-topic{
  background:linear-gradient(150deg,#FFFDF0 0%,#FFF9E0 60%,#FFFDF5 100%);
  border:1px solid rgba(255,228,17,.45);
  border-radius:18px;padding:14px 14px 12px;margin:10px 0 16px;
}
.ppt-h{display:flex;align-items:center;gap:10px;margin-bottom:12px}
.ppt-ic{
  width:34px;height:34px;border-radius:12px;flex:none;
  background:var(--brand);color:#1B1F24;
  display:flex;align-items:center;justify-content:center;
}
.ppt-t{min-width:0}
.ppt-t b{display:block;font-size:15px;font-weight:800}
.ppt-t span{display:block;font-size:11.5px;color:#8A6100;opacity:.8;margin-top:2px}
.ppt-list{display:grid;grid-template-columns:1fr 1fr;gap:9px}
.ppt-item{
  text-align:left;padding:10px 11px;border-radius:13px;
  background:rgba(255,255,255,.9);border:1px solid rgba(255,228,17,.4);
  display:flex;flex-direction:column;gap:3px;transition:.15s;
}
.ppt-item:active{transform:scale(.97);background:#fff}
.ppt-n{
  font-size:13.5px;font-weight:700;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.ppt-n i{color:var(--brand);font-style:normal;font-weight:800;margin-left:1px}
.ppt-r{font-size:11px;color:var(--gray-3)}

/* ---- 三个发布入口 ---- */
.pp-acts{display:flex;gap:10px;margin-bottom:12px}
.pp-act{
  flex:1;min-width:0;padding:16px 6px 14px;border-radius:18px;
  background:#F7F9FC;border:1px solid var(--line);
  display:flex;flex-direction:column;align-items:center;gap:7px;transition:.15s;
}
.pp-act:active{transform:scale(.96);background:#F1F4F9}
.pp-act.dis{opacity:.45}
.pp-act .pa-ic{
  width:52px;height:52px;border-radius:17px;
  background:var(--brand);color:#1B1F24;
  display:flex;align-items:center;justify-content:center;
  box-shadow:0 4px 12px rgba(255,228,17,.42);
}
.pp-act.dis .pa-ic{background:var(--line-2);color:var(--gray-3);box-shadow:none}
.pp-act b{font-size:14px;font-weight:800;color:var(--ink)}
.pp-act span{font-size:10.5px;color:var(--gray-3);text-align:center;line-height:1.35}

/* ---- 草稿箱 ---- */
.pp-draft{
  width:100%;height:48px;border-radius:15px;background:#F7F9FC;
  border:1px solid var(--line);color:var(--gray-1);
  font-size:14.5px;font-weight:700;
  display:flex;align-items:center;justify-content:center;gap:8px;
  position:relative;transition:.15s;
}
.pp-draft:active{background:#F1F4F9;transform:scale(.99)}
.pp-draft .pp-dn{
  font-style:normal;min-width:18px;height:18px;padding:0 5px;border-radius:9px;
  background:var(--err);color:#fff;font-size:10.5px;font-weight:800;
  display:flex;align-items:center;justify-content:center;
}

/* 右下角浮动关闭按钮已取消，改用面板底部关闭条 */

/* ---- 草稿箱列表 ---- */
.pp-panel{padding:4px 16px 18px}
.dft-item{
  display:flex;align-items:center;gap:10px;padding:11px 0;
  border-bottom:1px solid var(--line-2);
}
.dft-item:last-of-type{border-bottom:none}
.dft-l{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
.dft-l:active{opacity:.6}
.dft-t{
  font-size:10.5px;font-weight:800;color:#8A6100;
  background:var(--brand-16);padding:1px 7px;border-radius:6px;
  align-self:flex-start;
}
.dft-c{
  font-size:14px;color:var(--ink);font-weight:600;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.dft-d{font-size:11px;color:var(--gray-3)}
.dft-x{
  width:34px;height:34px;border-radius:11px;flex:none;
  background:#FFF3B0;color:#8A6100;
  display:flex;align-items:center;justify-content:center;transition:.14s;
}
.dft-x:active{background:#FFE411;color:#1B1F24}

/* ---- 发布页「存为草稿」按钮 ---- */
.draft-btn{
  width:100%;height:46px;margin-top:18px;border-radius:14px;
  background:#F7F9FC;border:1px solid var(--line);color:var(--gray-1);
  font-size:14.5px;font-weight:700;
  display:flex;align-items:center;justify-content:center;gap:7px;transition:.15s;
}
.draft-btn:active{background:#F1F4F9;transform:scale(.99)}

/* ============ 弹窗锁定：内容不滑动 ============ */
.sheet.locked{overflow:hidden;max-height:none}
.pages.scroll-locked{overflow:hidden}

/* ============ 首页公告条（轮播图下方） ============ */
.home-notice{
  margin:0 12px 10px;padding:9px 12px;border-radius:13px;
  background:linear-gradient(100deg,#FFF9E0 0%,#FFFDF5 100%);
  border:1px solid rgba(255,228,17,.5);
  display:flex;align-items:center;gap:8px;cursor:pointer;transition:.15s;
}
.home-notice:active{transform:scale(.99)}
.hn-ic{
  width:24px;height:24px;border-radius:8px;flex:none;
  background:var(--brand);color:#1B1F24;
  display:flex;align-items:center;justify-content:center;
}
.hn-t{
  flex:1;min-width:0;font-size:13px;font-weight:600;color:#6B5200;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.hn-r{color:#B08A00;flex:none;display:flex}

/* ============ 弹窗公告 ============ */
.anc-pop{padding:6px 16px 4px;text-align:center}
.anc-ic{
  width:56px;height:56px;border-radius:19px;margin:6px auto 12px;
  background:var(--brand);color:#1B1F24;
  display:flex;align-items:center;justify-content:center;
}
.anc-t{font-size:17px;font-weight:800;margin-bottom:10px}
.anc-body{
  font-size:14px;line-height:1.85;color:var(--gray-1);
  text-align:left;white-space:pre-wrap;word-break:break-word;
}

/* ============ 新人红包 ============ */
/* ---- 红包浮层：整屏居中，不再走底部面板 ---- */
.rp-layer{
  position:fixed;inset:0;z-index:120;
  display:none;align-items:center;justify-content:center;
  padding:24px;box-sizing:border-box;
  background:rgba(20,10,8,.52);backdrop-filter:blur(3px);
}
.rp-layer.on{display:flex;animation:rpFade .22s ease both}
@keyframes rpFade{from{opacity:0}to{opacity:1}}
.rp-wrap{
  width:100%;max-width:330px;text-align:center;position:relative;
  animation:rpRise .34s cubic-bezier(.34,1.4,.6,1) both;
}
@keyframes rpRise{
  from{opacity:0;transform:translateY(18px) scale(.94)}
  to  {opacity:1;transform:translateY(0)   scale(1)}
}

/* 卡片用 grid 堆叠：盖子与内容层占同一个格子，
   行高取两者中较高的那个 ——
   此前盖子是 absolute，卡片高度只由内容层决定，
   盖子内容一多就会被 overflow:hidden 裁掉底部文字。 */
.rp-card{
  position:relative;display:grid;border-radius:20px;
  perspective:1000px;
}
.rp-card.shaking{animation:rpShake .8s ease-in-out}
@keyframes rpShake{
  0%,100%{transform:rotate(0deg) scale(1)}
  20%    {transform:rotate(-2.5deg) scale(1.02)}
  45%    {transform:rotate(2.5deg)  scale(1.02)}
  70%    {transform:rotate(-1.5deg) scale(1.01)}
}

/* ---- 内容层（初始被盖子遮住）---- */
.rp-front{
  grid-area:1/1;position:relative;z-index:1;
  border-radius:20px;overflow:hidden;
  padding:34px 20px 26px;
  background:linear-gradient(165deg,#FF5A4E 0%,#E8382B 55%,#C62A1F 100%);
  box-shadow:0 12px 30px rgba(230,56,43,.32);
  display:flex;flex-direction:column;align-items:center;
}
.rp-tt{font-size:14.5px;color:#FFE9B8;font-weight:700;letter-spacing:1px}
.rp-amt{
  font-size:46px;font-weight:900;color:#FFE411;line-height:1.2;
  margin:8px 0 6px;text-shadow:0 2px 8px rgba(0,0,0,.18);
}
.rp-amt i{font-size:22px;font-style:normal;font-weight:800;margin-right:2px}
.rp-desc{
  font-size:12.5px;color:rgba(255,255,255,.78);line-height:1.6;
  margin-bottom:18px;white-space:normal;word-break:break-word;
}
.rp-open{
  min-width:132px;height:46px;border-radius:23px;padding:0 26px;
  background:linear-gradient(180deg,#FFE411 0%,#FFD400 100%);
  color:#8A2B00;font-size:15.5px;font-weight:900;letter-spacing:1px;
  box-shadow:0 4px 12px rgba(0,0,0,.2);transition:.16s;
}
.rp-open:active{transform:scale(.95)}
.rp-open[disabled]{opacity:.65}

/* ---- 红包盖 ---- */
.rp-lid{
  grid-area:1/1;position:relative;z-index:3;
  perspective:800px;border-radius:20px;
  display:flex;flex-direction:column;align-items:center;
  padding:30px 22px 24px;box-sizing:border-box;
  background:
    radial-gradient(120% 60% at 50% -10%,rgba(255,255,255,.22) 0%,rgba(255,255,255,0) 60%),
    linear-gradient(180deg,#FF6A5E 0%,#F04A3D 45%,#DC3A2E 100%);
  box-shadow:0 12px 30px rgba(230,56,43,.32),inset 0 1px 0 rgba(255,255,255,.3);
  transform-origin:top center;
  transition:transform .55s cubic-bezier(.3,.8,.4,1),opacity .45s ease-in;
}
.rp-lid-tt{
  font-size:15px;color:#FFE9B8;font-weight:800;letter-spacing:1px;
  text-shadow:0 1px 4px rgba(0,0,0,.18);
}
.rp-lid-sub{font-size:12px;color:rgba(255,255,255,.8);margin-top:5px}
/* 封印与上下文字留足间距，彻底避免遮挡 */
.rp-seal{
  width:74px;height:74px;border-radius:50%;margin:22px 0 18px;
  flex:none;position:relative;
  background:
    radial-gradient(circle at 34% 30%,rgba(255,255,255,.6) 0%,rgba(255,255,255,0) 42%),
    linear-gradient(180deg,#FFE411 0%,#F5C400 100%);
  color:#8A2B00;font-size:30px;font-weight:900;line-height:1;
  display:flex;align-items:center;justify-content:center;
  box-shadow:0 5px 16px rgba(0,0,0,.28),inset 0 2px 0 rgba(255,255,255,.5);
  transform-style:preserve-3d;transition:transform .15s;
}
.rp-seal:active{transform:scale(.94)}
.rp-seal.spinning{animation:sealSpin .8s cubic-bezier(.35,.05,.2,1) forwards}
@keyframes sealSpin{
  0%  {transform:rotateY(0deg)    scale(1)}
  70% {transform:rotateY(760deg)  scale(1.16)}
  100%{transform:rotateY(1080deg) scale(1)}
}
.rp-lid-tip{
  font-size:12.5px;color:rgba(255,255,255,.82);line-height:1.6;
  white-space:normal;word-break:break-word;
}
.rp-lid-hint{
  margin-top:auto;padding-top:14px;
  font-size:11.5px;color:rgba(255,255,255,.62);
}
/* 掀盖 */
.rp-card.opened .rp-lid{
  transform:rotateX(-112deg);opacity:0;pointer-events:none;
}
.rp-card.opened .rp-amt{animation:amtPop .5s cubic-bezier(.34,1.56,.64,1) .3s both}
@keyframes amtPop{
  from{transform:scale(.5);opacity:0}
  to  {transform:scale(1);opacity:1}
}

/* 关闭按钮放在卡片外面，避免占用盖子空间把文字挤掉 */
.rp-close{
  width:100%;height:42px;margin-top:16px;border-radius:21px;
  background:rgba(255,255,255,.16);color:#fff;font-size:13.5px;font-weight:700;
  display:flex;align-items:center;justify-content:center;transition:.15s;
  backdrop-filter:blur(4px);
}
.rp-close:active{background:rgba(255,255,255,.26)}
/* 右上角 X */
.rp-x{
  position:absolute;top:6px;right:6px;width:30px;height:30px;border-radius:50%;
  border:none;background:rgba(0,0,0,.18);color:#fff;cursor:pointer;
  display:flex;align-items:center;justify-content:center;
}
.rp-x:active{background:rgba(0,0,0,.32)}

/* ---- 领取成功态 ---- */
.rp-done{
  padding:42px 20px 34px;color:#fff;border-radius:20px;
  background:linear-gradient(165deg,#FF5A4E 0%,#E8382B 55%,#C62A1F 100%);
  box-shadow:0 12px 30px rgba(230,56,43,.32);
}
.rp-done-ic{
  width:64px;height:64px;border-radius:50%;margin:0 auto 14px;
  background:rgba(255,255,255,.18);color:#FFE411;
  display:flex;align-items:center;justify-content:center;
}
.rp-done-t{font-size:15px;color:rgba(255,255,255,.85);font-weight:700}
.rp-done-a{
  font-size:44px;font-weight:900;color:#FFE411;line-height:1.3;margin:4px 0;
  text-shadow:0 2px 8px rgba(0,0,0,.2);
}
.rp-done-d{font-size:12.5px;color:rgba(255,255,255,.65)}

@media (prefers-reduced-motion:reduce){
  .rp-layer.on,.rp-wrap,.rp-card.shaking,.rp-seal.spinning{animation:none}
}

/* ============ 聊天页：输入框固定底部 + 随输入法起伏 ============ */
/* .page 是 absolute + overflow-y:auto。
   聊天页改为纵向 flex：消息区 flex:1 自己滚动，输入框 flex:none 固定在底部，
   不再用 sticky（sticky 在内容不足一屏时会停在内容末尾）。 */
.page#pg-chat{display:flex;flex-direction:column;overflow:hidden}
.page#pg-chat .navbar{flex:none}
.chat-body{
  flex:1 1 auto;min-height:0;overflow-y:auto;overflow-x:hidden;
  -webkit-overflow-scrolling:touch;
  display:flex;flex-direction:column;gap:12px;
  padding:12px 14px 14px;
}
.chat-input{
  flex:none;position:relative;left:auto;right:auto;bottom:auto;
  /* v1.7.18：同上，聊天输入框常驻且随键盘/滚动移动，
     backdrop-filter 的逐帧重算在聊天页尤其明显，改为实色 */
  background:rgba(255,255,255,.98);
  border-top:1px solid var(--line);
  padding:9px 12px calc(9px + var(--safe-b));
  display:flex;align-items:flex-end;gap:9px;
  transition:transform .22s ease, padding-bottom .22s ease;
}
/* 发消息显示头像：双方气泡都带头像，底部对齐不拉伸 */
.bubble-row{gap:8px;align-items:flex-end}
/* avatar() 生成的是 .avatar，聊天内统一放大为 34px */
.bubble-row .avatar{
  width:34px;height:34px;font-size:13px;font-weight:700;
  background:var(--brand-16);color:#8A6100;
  /* v1.7.22：不能 overflow:hidden —— 这条规则特异性高于 .avatar{overflow:visible}，
     会把对方头像右下角的认证标裁掉。改为 visible，
     圆形由下方 img 自身的 border-radius 保证，效果一致。 */
  flex:none;overflow:visible;
}
.bubble-row.mine .avatar{background:var(--brand);color:var(--ink)}
.bubble-row .avatar img{width:100%;height:100%;object-fit:cover;display:block;border-radius:50%}

/* ============ 认证标识（头像右下角，v1.7.32 按类型渲染） ============

   造型：一个纯色实心圆 + 里面一个白色对勾。
   颜色是什么就是什么（当前统一认证蓝 #1E9BFF），
   【不再有】外圈白边、也不再有投影 —— 之前是
     蓝色底 + 1.5px 白边 + 深色投影，
   而图标用的又是 check-circle（图形里自带一个 r=9 的圆圈），
   两层圆叠在一起就成了「一圈白、一圈蓝、又一圈白」的同心圆，很脏。

   ⚠️ 改动时注意两点，否则「圈中圈」会复现：
   1. 图标必须是 ic('check')，不能用 ic('check-circle')。
   2. 这里不要再给 border / box-shadow。
*/
.avatar{position:relative}
.v-badge{
  /* v1.7.22：从「外溢 2px」改为「完全内嵌在头像边界内」。
     之前是 right:-2px;bottom:-2px，靠 .avatar{overflow:visible} 才能显示；
     但凡有任意一个祖先容器带 overflow:hidden，或者某条高特异性规则
     把 .avatar 的 overflow 覆盖回 hidden，认证标就整个消失 ——
     这类位置散落在十几个页面里，逐个排查既漏又快失效。
     改成内嵌后，认证标完全落在头像盒子内部，
     无论祖先怎么裁剪都不会被切掉，从根上消除这一类问题。 */
  position:absolute;right:0;bottom:0;
  /* 尺寸随头像缩放：约头像的 40%，最小 10px 最大 22px。
     v1.7.31：由 38%/9px 微调到 40%/10px —— 去掉白边后视觉上会显得
     小一圈（原先 content-box 的 1.5px 边框也占视觉面积），补回一点。
     下限 10px（v1.7.22 定 9px）：内嵌后认证标完全落在头像盒子里，
     20px 的小头像上再大的标会占掉大半个头像，显得很笨重。 */
  width:40%;height:40%;min-width:10px;min-height:10px;max-width:22px;max-height:22px;
  border-radius:50%;
  /* 纯色实心，颜色由 vBadge() 按认证类型内联注入（style="background:…"）。
   这里只放兜底的认证蓝，未指定类型时用。
   ⚠️ 不要再给 border / box-shadow（v1.7.31 才去掉的外圈白边）。 */
  background:#1E9BFF;color:#fff;
  display:flex;align-items:center;justify-content:center;
  box-sizing:content-box;z-index:2;
  border:none;box-shadow:none;
}
/* ⚠️ 76% 而不是 100%：认证图标的图形大致占 viewBox 的 70%，
   若 svg 铺满整个圆（100%），图形的对角线长度约为
   0.7 × 1.414 ≈ 0.99 倍直径 —— 半对角线几乎等于半径，
   盾牌的尖角、星星的星芒会顶到圆边甚至溢出圆外。
   缩到 76% 后对角线约 0.75 倍直径，四周留白均匀，视觉也更像一枚徽章。 */
.v-badge svg{width:76%;height:76%;display:block}
/* 头像本身有 overflow:hidden，会裁掉溢出的认证标，这里放开 */
.avatar:has(.v-badge){overflow:visible}
/* 不支持 :has() 的浏览器兜底：整体放开不影响，圆形由 img 自身圆角保证 */
.avatar{overflow:visible}
.avatar > img{border-radius:50%;width:100%;height:100%;object-fit:cover;display:block}

/* ============ 认证类型选择（v1.7.32）============
 *
 * 两列网格，每张卡 = 彩色圆形图标 + 类型名 + 一句话说明。
 * 选中态用品牌色描边 + 淡黄底，不用背景色强对比 ——
 * 卡片本身已有各自的类型色，再叠一层重色会显得脏。
 */
.vft-pick{display:grid;grid-template-columns:1fr 1fr;gap:9px}
.vft-card{
  display:flex;flex-direction:column;align-items:center;gap:5px;
  padding:13px 8px 11px;border-radius:14px;cursor:pointer;
  background:var(--bg-2);border:1.5px solid transparent;
  transition:.15s;text-align:center;
}
.vft-card:active{transform:scale(.97)}
.vft-card.on{
  border-color:var(--brand);
  background:var(--brand-16);
}
/* 圆形图标底：直接是该类型的认证色，和头像上的徽标长得一样，
   所见即所得 —— 用户选之前就能看到最终效果。 */
.vft-ic{
  width:38px;height:38px;border-radius:50%;flex:none;
  display:flex;align-items:center;justify-content:center;color:#fff;
}
/* 图标 76% —— 与 .v-badge svg 保持同一比例，预览和实物一致 */
.vft-ic svg{width:76%;height:76%;display:block}
.vft-card b{font-size:13px;font-weight:800;color:var(--ink);line-height:1.3}
.vft-card em{
  font-size:11px;font-style:normal;color:var(--gray-3);line-height:1.45;
}
/* 窄屏（≤360px）两列会挤，说明文字强制单行省略 */
@media (max-width:360px){
  .vft-card em{
    display:block;max-width:100%;
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  }
}

/* ============ 身份认证页 ============ */
.vf-card{
  margin:12px;padding:26px 18px;border-radius:18px;text-align:center;
}
.vf-card.ok{background:linear-gradient(150deg,#E3F2FF,#F3F9FF);border:1px solid #B8DCFF}
.vf-card.wait{background:linear-gradient(150deg,#FFF9E0,#FFFDF5);border:1px solid rgba(255,228,17,.5)}
.vf-card.bad{background:#FFF1F0;border:1px solid #FFCCC7}
.vf-ok-ic{
  width:62px;height:62px;border-radius:50%;margin:0 auto 12px;
  display:flex;align-items:center;justify-content:center;
  background:#fff;
}
.vf-card.ok .vf-ok-ic{color:#1E9BFF;box-shadow:0 4px 14px rgba(30,155,255,.22)}
.vf-card.wait .vf-ok-ic{color:#8A6100;box-shadow:0 4px 14px rgba(255,190,0,.22)}
.vf-card.bad .vf-ok-ic{color:#D4380D;box-shadow:0 4px 14px rgba(212,56,13,.16)}
.vf-ok-t{font-size:16px;font-weight:800;margin-bottom:5px}
.vf-ok-d{font-size:12.5px;color:var(--gray-2);line-height:1.7}

.panel-card{
  margin:12px;background:#fff;border:1px solid var(--line);border-radius:16px;
  padding:4px 14px 14px;
}
.pc-h{
  font-size:13.5px;font-weight:800;padding:12px 0 10px;
  border-bottom:1px solid var(--line-2);margin-bottom:10px;
}
.vf-row{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:9px 0;font-size:13.5px;border-bottom:1px solid var(--line-2);
}
.vf-row:last-child{border-bottom:none}
.vf-row span{color:var(--gray-3);flex:none}
.vf-row b{font-weight:700;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.vf-cond{display:flex;align-items:center;gap:9px;padding:9px 0;font-size:13.5px}
.vfc-ic{
  width:20px;height:20px;border-radius:50%;flex:none;
  display:flex;align-items:center;justify-content:center;
}
.vfc-ic.ok{background:#E4F7D6;color:#3A7D0E}
.vfc-ic.no{background:#FFF1F0;color:#D4380D}
.vfc-k{flex:1;color:var(--gray-1);font-weight:600}
.vfc-v{font-size:12px;color:var(--gray-3);flex:none}

.vf-miss{display:flex;flex-direction:column;gap:9px;padding:4px 0 12px}
.vf-miss-i{
  display:flex;align-items:flex-start;gap:7px;font-size:13px;color:#AD4E00;
  background:#FFF7E6;border:1px solid #FFE7BA;border-radius:11px;padding:9px 11px;line-height:1.6;
}
.vf-miss-i span{flex:1}

/* 表单 */
.frm{margin-bottom:12px}
.frm label{
  display:block;font-size:12.5px;color:var(--gray-2);margin-bottom:6px;font-weight:600;
}
.frm label i{color:var(--err);font-style:normal;margin-left:2px}
.frm input,.frm textarea{
  width:100%;border:1px solid var(--line);border-radius:11px;
  padding:10px 12px;font-size:14px;font-family:inherit;outline:none;background:#fff;
}
.frm input:focus,.frm textarea:focus{border-color:var(--brand)}

.vf-sub{
  display:block;width:calc(100% - 24px);margin:4px 12px 0;height:48px;border-radius:15px;
  background:var(--brand);color:var(--ink);font-size:15px;font-weight:800;
  font-family:inherit;transition:.15s;
}
.vf-sub:active{transform:scale(.99);opacity:.9}
.vf-sub.gray{background:var(--line-2);color:var(--gray-1)}
.vf-tip{
  display:flex;align-items:flex-start;gap:7px;margin:14px 12px 0;
  font-size:12px;color:var(--gray-3);line-height:1.7;
}

/* ============ 通知类型标签（系统消息 / 互动消息） ============ */
.nt-tag{
  display:inline-block;margin-top:6px;padding:2px 8px;border-radius:7px;
  font-size:10.5px;font-weight:800;line-height:1.6;
  background:var(--line-2);color:var(--gray-2);
}
.nt-tag.sys{background:#E3F2FF;color:#1E5EB8}

/* ============ 发布面板：弹簧入场动画 ============ */
/* 面板主体 */
.sheet.on{animation:sheetPop .34s cubic-bezier(.34,1.56,.64,1)}
@keyframes sheetPop{
  0%{transform:translateY(26px) scale(.97);opacity:.6}
  100%{transform:translateY(0) scale(1);opacity:1}
}
/* 面板内各区块依次弹入 */
.sheet.on .pp-head,
.sheet.on .pp-acts,
.sheet.on .pp-draft,
.sheet.on .pp-close{animation:ppRise .42s cubic-bezier(.34,1.56,.64,1) both}
.sheet.on .pp-head{animation-delay:.02s}
.sheet.on .pp-acts{animation-delay:.08s}
.sheet.on .pp-draft{animation-delay:.14s}
.sheet.on .pp-close{animation-delay:.18s}
@keyframes ppRise{
  0%{transform:translateY(14px) scale(.96);opacity:0}
  100%{transform:translateY(0) scale(1);opacity:1}
}
/* 三个发布入口卡片逐个弹入 */
.sheet.on .pp-act{animation:ppPop .46s cubic-bezier(.34,1.56,.64,1) both}
.sheet.on .pp-act:nth-child(1){animation-delay:.12s}
.sheet.on .pp-act:nth-child(2){animation-delay:.19s}
.sheet.on .pp-act:nth-child(3){animation-delay:.26s}
@keyframes ppPop{
  0%{transform:translateY(18px) scale(.86);opacity:0}
  60%{transform:translateY(-3px) scale(1.04)}
  100%{transform:translateY(0) scale(1);opacity:1}
}
/* 话题卡片依次弹入 */
.sheet.on .ppt-item{animation:ppFade .38s cubic-bezier(.34,1.56,.64,1) both}
.sheet.on .ppt-item:nth-child(1){animation-delay:.10s}
.sheet.on .ppt-item:nth-child(2){animation-delay:.15s}
.sheet.on .ppt-item:nth-child(3){animation-delay:.20s}
.sheet.on .ppt-item:nth-child(4){animation-delay:.25s}
@keyframes ppFade{
  0%{transform:translateY(10px) scale(.95);opacity:0}
  100%{transform:translateY(0) scale(1);opacity:1}
}
/* 按下回弹 */
.pp-act:active{transform:scale(.93) !important;transition:transform .1s}
.ppt-item:active{transform:scale(.95) !important;transition:transform .1s}
/* 系统开启「减弱动效」时关闭全部动画 */
@media (prefers-reduced-motion:reduce){
  .sheet.on,.sheet.on .pp-head,.sheet.on .pp-acts,.sheet.on .pp-draft,
  .sheet.on .pp-close,.sheet.on .pp-act,.sheet.on .ppt-item{animation:none}
}

/* 发布面板：话题骨架占位 */
/* v1.7.18：发布面板的话题骨架，同样改走 GPU 合成。
   这里只覆盖 .sk-line 的尺寸与配色，动画统一由骨架基础样式提供。 */
.ppt-item.sk{pointer-events:none}
.ppt-item.sk .sk-line{
  height:13px;border-radius:6px;margin:0;
}

/* ============ 板块详情（v1.5.7 重做） ============ */

/* ================= 板块头部（v1.7.29） =================
 *
 * 结构：沉浸式头图（背景图 + 遮罩 + 滚动渐变的导航 + 底部信息行）
 *     → 人物槽（板主 + 2 位成员，固定三格）
 *     → 公告（折叠）→ 排序胶囊 → 帖子列表
 *
 * 相比 v1.7.26：
 *  · 去掉头图下方那张白色信息卡（含 -46px 负 margin 层叠、头像 -33px 悬浮）。
 *    头像与板块名改为直接压在头图底部，省下约 60px 高度。
 *  · 加入按钮由全宽大按钮改为小胶囊，放在信息行右侧，不再独占一行。
 *  · 成员头像堆叠改为三格人物槽，常驻显示，缺位用灰圈预留。
 *
 * 图片处理方式的三版演进（重要，别再走回头路）：
 *  · v1.7.27 取消白卡后，信息行直接压在头图上，白字需要靠遮罩压暗才可读。
 *  · v1.7.28 用「高斯模糊整张图」来保证文字可读 —— 代价是把背景图糊掉了，
 *    看不清图里是什么，而且必须配 scale 放大补偿虚边。
 *  · v1.7.29 改为【底部渐变遮罩（Bottom Gradient Fade）】：
 *    图片保持清晰，只在底部做一段渐变压暗来托住白字。
 *    图看得清、文字也读得清，且不需要任何 filter（零渲染开销）。
 *
 * 帖子卡片 .mc2 未改动。
 */

/* ---- 沉浸式头图 ---- */
.cir2-hero{position:relative;height:190px;overflow:hidden;background:var(--bg-2)}
/* 背景图：v1.7.29 恢复清晰，不再做高斯模糊。
   ⚠️ 不要再加 filter:blur —— 那是 v1.7.28 的做法，已按反馈取消：
      模糊后看不清图里是什么，而且 blur 会虚化边缘、必须配 scale 补偿。
   ⚠️ 也更不要用 backdrop-filter：它是滚动时常驻元素上的毛玻璃，
      要逐帧重算背景，是中低端机掉帧的主因（v1.7.18 专门去掉过）。
   现在文字的可读性完全交给 .cir2-veil 的底部渐变遮罩，零渲染开销。 */
.cir2-bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
/* 没上传背景图时的兜底渐变（黄橙粉），不会显得空 */
.cir2-bg.ph{background:linear-gradient(135deg,#FFE411 0%,#FFB43D 42%,#FF7A9C 100%)}

/* ---- 底部渐变遮罩（Bottom Gradient Fade，v1.7.30）----
 *
 * 四段式：
 *   0~18%    顶部压暗（黑）—— 导航是半透明深色圆钮，压暗后白图标更清晰
 *   18~40%   淡出到全透明 —— 中段留给图片本身，不遮挡细节
 *   40~52%   仍全透明 —— 过渡带的起点，图片主体完整可见
 *   52~100%  【底部渐隐到背景色】—— 图片底部淡淡地融进页面底色
 *
 * 底部这段是本版的核心，和 v1.7.29 的做法不同：
 *  · v1.7.29 用的是「压暗」（黑色 rgba(0,0,0,.78)）—— 底部会明显发黑，
 *    和下方页面之间形成一条看得见的深色分界，不够自然。
 *  · v1.7.30 改用「渐隐到背景色」（var(--bg) 同色）—— 图片底部
 *    逐渐化为页面底色，视觉上不再有分界线，像图片自己淡出去了。
 *
 * ⚠️ 因此文字颜色必须跟着改：底部现在是浅色（--bg），
 *    .cir2-name / .cir2-sub 的白字 + 阴影在这里反而看不清，
 *    已改为深色（见下方 .cir2-head 内）。
 *
 * 停靠点用多档（0 → .30 → .68 → .92 → 1）而不是简单两段：
 * 让过渡足够平滑，避免出现一条能看出边界的色带。
 *
 * ⚠️ 底部【不能】用 rgba(0,0,0,...) 压暗了 —— 那正是 v1.7.29 被否掉的做法。
 */
.cir2-veil{position:absolute;inset:0;
  background:linear-gradient(180deg,
    rgba(0,0,0,.34) 0%,
    rgba(0,0,0,.08) 18%,
    rgba(0,0,0,0)   40%,
    rgba(var(--bg-rgb),0)    52%,
    rgba(var(--bg-rgb),.30) 66%,
    rgba(var(--bg-rgb),.68) 80%,
    rgba(var(--bg-rgb),.92) 92%,
    rgba(var(--bg-rgb),1)   100%)}

/* ---- 头图上的导航：随滚动由透明变实底 ---- */
.cir2-nav{
  position:absolute;top:0;left:0;right:0;z-index:3;
  height:calc(var(--nav-h) + var(--safe-t));
  padding:calc(7px + var(--safe-t)) 12px 0;
  display:flex;align-items:center;gap:10px;color:#fff;
  --op:0;
  background:rgba(255,255,255,var(--op));
  transition:background .16s linear;
}
/* 滚动过半后切成实底白条（文字与图标同时转深色） */
.cir2-nav.solid{background:#fff;box-shadow:0 1px 0 rgba(16,24,40,.06)}
.cir2-nav.solid,.cir2-nav.solid .cir2-nav-t{color:var(--ink)}
.cir2-nav.solid .cir2-rb{background:transparent;color:var(--ink)}
.cir2-rb{
  flex:none;width:32px;height:32px;border-radius:50%;border:none;
  background:rgba(16,24,40,.30);color:#fff;
  display:flex;align-items:center;justify-content:center;
  transition:.16s;
  /* ⚠️ 这里【不能】加 backdrop-filter：导航在滚动时常驻，
     毛玻璃要逐帧重算背景模糊，是中低端机掉帧的主因（v1.7.18 专门去掉过）。 */
}
.cir2-rb:active{transform:scale(.92)}
.cir2-nav-t{
  flex:1;min-width:0;text-align:center;font-size:15.5px;font-weight:800;
  color:transparent;transition:color .16s linear;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}

/* ---- 信息行：直接压在头图底部（v1.7.27 取消白卡）---- */
.cir2-head{
  position:absolute;left:0;right:0;bottom:0;z-index:2;
  display:flex;align-items:center;gap:11px;
  padding:0 14px 15px;
}
.cir2-ava{
  width:56px;height:56px;border-radius:17px;flex:none;
  background:linear-gradient(135deg,var(--brand),#FFB800);color:var(--ink);
  display:flex;align-items:center;justify-content:center;
  font-size:23px;font-weight:800;overflow:hidden;
  /* v1.7.30：底部已是背景色，白边改为纯白即可（原为 .92 半透明白，
     那是为压在图片上准备的）。 */
  box-shadow:0 0 0 2.5px #fff,0 6px 16px rgba(16,24,40,.16);
}
.cir2-ava img{width:100%;height:100%;object-fit:cover;display:block}
.cir2-meta{flex:1;min-width:0}
.cir2-namerow{display:flex;align-items:center;gap:6px}
/* v1.7.30：底部渐变遮罩改为「渐隐到背景色」后，头图下沿已是浅色，
   白字 + 阴影反而看不清。改为深色，看起来就像文字直接写在页面底色上。 */
.cir2-name{
  font-size:19px;font-weight:800;line-height:1.25;max-width:100%;
  color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.cir2-hot{
  flex:none;display:flex;align-items:center;gap:2px;
  font-size:10.5px;font-weight:800;padding:2px 7px;border-radius:7px;
  background:linear-gradient(135deg,#FF6B3D,#FF3D71);color:#fff;
}
/* 一行说完：互动 / 帖子 / 成员（v1.7.30 同样改深色） */
.cir2-sub{font-size:12.5px;margin-top:4px;color:var(--gray-2)}
/* 加入按钮：小胶囊，右侧（v1.7.27 由全宽大按钮改小） */
.cir2-join{
  flex:none;height:31px;padding:0 16px;border-radius:16px;
  font-family:inherit;font-size:13px;font-weight:800;
  background:var(--brand);color:var(--ink);transition:.15s;
  box-shadow:0 2px 8px rgba(0,0,0,.18);
}
.cir2-join:active{transform:scale(.95)}
/* v1.7.30：底部已是背景色，「已加入」态改回浅灰底（原先的半透明白
   是为压在深色图上准备的，现在会和背景糊在一起分不出层次）。 */
.cir2-join.on{background:var(--line-2);color:var(--gray-2);box-shadow:none}
.cir2-join:disabled{opacity:.6}

/* ---- 人物槽：板主 + 2 位成员，固定三格（v1.7.27）----
   缺位用灰圈预留，避免板块刚建好时这块塌成一行空白。 */
.cir2-people{
  display:flex;margin:12px 12px 0;
  background:#fff;border-radius:16px;padding:14px 4px;
  box-shadow:0 2px 12px rgba(16,24,40,.05);
}
.cir2-p{
  flex:1;min-width:0;
  display:flex;flex-direction:column;align-items:center;gap:5px;
  padding:0 4px;cursor:pointer;
}
.cir2-p:not(.empty):active{transform:scale(.96)}
.cir2-p-ava{
  width:44px;height:44px;border-radius:50%;flex:none;
  background:linear-gradient(135deg,#FFE9A8,#FFC93C);color:#7A5A00;
  display:flex;align-items:center;justify-content:center;
  font-size:17px;font-weight:800;overflow:hidden;
}
.cir2-p-ava img{width:100%;height:100%;object-fit:cover;display:block}
/* 灰圈预留位 */
.cir2-p-ava.ph{background:#F0F2F6;color:#C2C8D2}
.cir2-p b{
  max-width:100%;font-size:12.5px;font-weight:700;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.cir2-p.empty b{color:var(--gray-3);font-weight:600}
.cir2-p-tag{
  font-size:10.5px;font-weight:700;color:var(--gray-3);
  padding:1.5px 7px;border-radius:6px;background:var(--bg-2);
}
/* 板主标签用品牌色，和其它成员区分开 */
.cir2-p-tag.own{background:rgba(255,193,7,.20);color:#8A6100}

/* ---- 公告（折叠）---- */
.cir2-info{
  margin:10px 12px 0;border-radius:14px;
  background:#fff;border:1px solid var(--line);overflow:hidden;
}
.c2i-row{
  display:flex;align-items:center;padding:11px 14px;cursor:pointer;
}
.c2i-lab{
  flex:1;display:flex;align-items:center;gap:5px;
  font-size:12.5px;font-weight:700;color:var(--gray-1);
}
.c2i-more{
  flex:none;display:flex;align-items:center;gap:2px;
  font-size:12px;color:var(--gray-3);
}
.c2i-bd{padding:0 14px 12px;border-top:1px solid var(--line)}
.c2i-notice{
  display:flex;gap:7px;padding-top:11px;
  font-size:12.5px;line-height:1.82;color:var(--gray-1);word-break:break-word;
}
.c2i-notice svg{flex:none;margin-top:3px;color:#C2870B}

/* ---- 排序 Tab（v1.7.24：下划线指示器 → 胶囊组）----
   胶囊组比下划线更能表达「这是一组互斥选项」，视觉上也更聚焦。
   外层 .cir2-tabbar 负责 sticky 与整条背景，内层 .cir2-tabs 负责胶囊本身 ——
   分开是因为 sticky 元素需要撑满整行，而胶囊组要居中且留两侧留白。 */
.cir2-tabbar{
  position:sticky;top:0;z-index:10;
  padding:9px 12px;background:var(--bg);
}
.cir2-tabs{
  display:flex;gap:5px;
  padding:4px;border-radius:14px;
  background:rgba(16,24,40,.045);
}
.cir2-tab{
  flex:1;padding:8px 0;border-radius:11px;
  font-family:inherit;font-size:13.5px;font-weight:600;color:var(--gray-2);
  background:transparent;transition:.18s;
}
.cir2-tab:active{opacity:.7}
.cir2-tab.on{
  color:var(--ink);font-weight:800;background:#fff;
  box-shadow:0 1px 5px rgba(16,24,40,.10);
}

#cirList{padding:10px 12px 4px}

/* ---- 帖子卡片（v1.7.24 重做）----
 *
 * 回到卡片式（v1.7.23 的气泡版已按反馈撤销）：
 * 气泡适合一对一对话，帖子流信息密度优先，卡片更合适。
 *
 * 这一版相对更早的卡片改动：
 *  · 卡片加 1px 极浅描边 + 更柔的阴影，边缘更干净（纯阴影在浅色背景上会发灰）
 *  · 底部操作栏改为三等分并去掉 margin-left:auto 的箭头推挤，
 *    三个操作按钮等宽，点击热区更大也更整齐
 *  · 图片整体统一圆角
 *  · 增加按下微缩反馈
 */
.mc2{
  background:#fff;border-radius:18px;
  border:1px solid rgba(16,24,40,.045);
  padding:14px 15px 0;
  margin-bottom:12px;
  box-shadow:0 2px 10px rgba(16,24,40,.05);
  transition:transform .16s ease, box-shadow .16s ease;
}
.mc2:active{transform:scale(.993);box-shadow:0 1px 5px rgba(16,24,40,.05)}
.mc2-hd{display:flex;align-items:center;gap:10px}
.mc2-hd .avatar{width:40px;height:40px;font-size:15px;cursor:pointer}
.mc2-u{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
.mc2-u b{
  font-size:14.5px;font-weight:700;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.mc2-u span{font-size:11.5px;color:var(--gray-4)}
.mc2-more{
  flex:none;width:30px;height:30px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  color:var(--gray-4);transition:background .16s;
}
.mc2-more:active{background:var(--bg-2)}
.mc2-bd{margin-top:11px;cursor:pointer}
.mc2-t{font-size:16px;font-weight:800;line-height:1.5;color:var(--ink)}
.mc2-c{
  font-size:14px;line-height:1.75;color:var(--gray-1);margin-top:6px;
  display:-webkit-box;-webkit-line-clamp:6;-webkit-box-orient:vertical;overflow:hidden;
}
.mc2-bd .imgs{margin-top:10px;border-radius:12px;overflow:hidden}
.mc2-tags{display:flex;gap:6px;flex-wrap:wrap;margin:11px 0 0}
.mc2-tag{
  font-size:11.5px;font-weight:600;padding:4px 11px;border-radius:9px;
  color:#1E5EB8;background:#EFF6FF;
}
/* 底部操作栏：三等分。
   此前最后一个按钮用 margin-left:auto 顶到最右，前两个挤在左边，
   三个按钮宽度不一致、点击热区也一大一小。改为等分后整齐且好按。 */
.mc2-ft{
  display:flex;align-items:center;
  margin-top:12px;border-top:1px solid var(--line);
}
.mc2-ft button{
  flex:1;display:flex;align-items:center;justify-content:center;gap:6px;
  padding:11px 0;font-family:inherit;font-size:13px;color:var(--gray-2);
  border-radius:11px;transition:background .16s,color .16s;
}
.mc2-ft button:active{background:var(--bg-2)}
.mc2-ft button.on{color:var(--err)}
.mc2-ft button.on svg{fill:currentColor}
/* 点赞后图标填充有个过渡，生硬切换会显得跳 */
.mc2-ft button svg{transition:fill .18s}

/* ---- 悬浮发帖 ----
   实体节点位于 .pages 之外（见 index.php 的 #cirFab）。
   .page 带 transform，会给 fixed 后代创建包含块，
   放在页面内会让 fixed 退化成跟随内容滚动，钉不住。 */
.cir2-fab{
  position:fixed;right:16px;flex:none;
  /* 抬高到 Tab 栏之上：板块页 Tab 栏是显示的，
     原来的 22px 会让按钮正好压在最右侧的「我的」上。 */
  bottom:calc(var(--tab-h) + var(--safe-b) + 16px);
  width:52px;height:52px;border-radius:50%;
  background:var(--brand);color:var(--ink);
  display:none;align-items:center;justify-content:center;
  box-shadow:0 6px 20px rgba(255,180,0,.46);z-index:40;
  transition:transform .15s,opacity .18s;
  opacity:0;transform:scale(.8);
  pointer-events:none;
}
.cir2-fab.on{display:flex;opacity:1;transform:scale(1);pointer-events:auto}
.cir2-fab:active{transform:scale(.9)}
/* 键盘弹出时收起，避免压住输入框 */
body.kbd-open .cir2-fab{opacity:0;pointer-events:none;transform:scale(.8)}

/* 头像尺寸补充 */
.avatar.sm{width:26px;height:26px;font-size:11px}
.avatar.md{width:36px;height:36px;font-size:14.5px}

/* ============ 板块广场（v1.5.7 重做） ============ */
.plz-sec{padding:14px 12px 0}
.plz-hd{
  display:flex;align-items:center;gap:5px;margin-bottom:11px;
}
.plz-hd b{font-size:15px;font-weight:800}
.plz-hd svg{color:#FF6B3D}
.plz-hd span{font-size:12px;color:var(--gray-3);margin-left:auto}

/* 我的板块：横向滚动 */
.plz-mine{
  display:flex;gap:10px;overflow-x:auto;padding-bottom:4px;
  -webkit-overflow-scrolling:touch;
}
.plz-mine::-webkit-scrollbar{display:none}
.plz-mine-item{
  flex:none;width:70px;display:flex;flex-direction:column;align-items:center;gap:6px;
}
.pmi-ava{
  width:50px;height:50px;border-radius:16px;overflow:hidden;flex:none;
  background:linear-gradient(135deg,var(--brand),#FFB800);color:var(--ink);
  display:flex;align-items:center;justify-content:center;font-size:21px;font-weight:800;
  box-shadow:0 3px 9px rgba(16,24,40,.10);
}
.pmi-ava img{width:100%;height:100%;object-fit:cover;display:block}
.plz-mine-item b{
  font-size:12px;font-weight:600;max-width:100%;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}

/* 热门榜 */
.plz-rank{
  background:#fff;border:1px solid var(--line);border-radius:15px;overflow:hidden;
}
.plz-row{
  display:flex;align-items:center;gap:10px;padding:11px 12px;cursor:pointer;
}
.plz-row + .plz-row{border-top:1px solid var(--line)}
.plz-row:active{background:var(--bg-2)}
.pr-no{
  flex:none;width:19px;text-align:center;
  font-size:13px;font-weight:800;color:var(--gray-4);font-style:italic;
}
.pr-no.top{color:#FF6B3D}
.pr-ava{
  width:40px;height:40px;border-radius:13px;overflow:hidden;flex:none;
  background:linear-gradient(135deg,#FFE9A8,#FFC93D);color:#8A6100;
  display:flex;align-items:center;justify-content:center;font-size:17px;font-weight:800;
}
.pr-ava img{width:100%;height:100%;object-fit:cover;display:block}
.pr-i{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
.pr-i b{font-size:13.8px;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pr-i span{font-size:11.5px;color:var(--gray-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pr-r{flex:none;display:flex;flex-direction:column;align-items:flex-end;gap:2px}
.pr-r b{font-size:13px;font-weight:800;color:#FF6B3D}
.pr-r span{font-size:10.5px;color:var(--gray-4)}
.pr-btn{
  flex:none;height:28px;padding:0 13px;border-radius:14px;
  font-family:inherit;font-size:12px;font-weight:700;
  background:var(--brand);color:var(--ink);transition:.15s;
}
.pr-btn:active{transform:scale(.94)}
.pr-btn.on{background:var(--line-2);color:var(--gray-2)}
.pr-btn:disabled{opacity:.6}

/* ============ 板块网格（广场 / 鱼塘页） ============ */
.plaza-hd{
  display:flex;align-items:center;justify-content:space-between;margin-bottom:10px;
}
.plaza-t{font-size:14px;font-weight:800}
.plaza-more{
  display:flex;align-items:center;gap:2px;
  font-size:12px;color:var(--gray-3);font-family:inherit;
}
.cir-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:10px}
.cir-grid.full{grid-template-columns:repeat(3,1fr);padding:12px;gap:12px}
.cir-grid-item{
  display:flex;flex-direction:column;align-items:center;gap:6px;
  background:#fff;border:1px solid var(--line);border-radius:14px;
  padding:12px 6px 10px;cursor:pointer;transition:.15s;
}
.cir-grid-item:active{transform:scale(.96)}
.cgi-ava{
  width:44px;height:44px;border-radius:14px;overflow:hidden;flex:none;
  background:var(--brand);color:var(--ink);
  display:flex;align-items:center;justify-content:center;
  font-size:19px;font-weight:800;
}
/* v1.7.18：已设置板块图时不再铺品牌黄底 ——
   图片加载完成前会先闪一块黄色，与最终画面反差大。
   有图改用浅灰，图片淡入过渡自然 */
.cgi-ava.has-img,.pc-ava.has-img{
  background:#F2F4F7;
}
.cgi-ava img{width:100%;height:100%;object-fit:cover;display:block}
.cir-grid-item b{
  font-size:12.5px;font-weight:700;max-width:100%;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.cir-grid-item span{font-size:10.5px;color:var(--gray-3)}

/* 鱼塘页板块区：横向滚动卡片（v1.5.7） */
.pond-cates{
  display:flex;gap:9px;overflow-x:auto;padding:2px 0 4px;
  -webkit-overflow-scrolling:touch;
}
.pond-cates::-webkit-scrollbar{display:none}
.pc-item{
  flex:none;width:66px;
  background:#fff;border:1px solid var(--line);border-radius:14px;
  padding:10px 5px 9px;
  display:flex;flex-direction:column;align-items:center;gap:5px;
  cursor:pointer;transition:.15s;
}
.pc-item:active{transform:scale(.95)}
.pc-ava{
  width:38px;height:38px;border-radius:13px;overflow:hidden;flex:none;
  background:linear-gradient(135deg,var(--brand),#FFB800);color:var(--ink);
  display:flex;align-items:center;justify-content:center;font-size:17px;font-weight:800;
}
.pc-ava img{width:100%;height:100%;object-fit:cover;display:block}
.pc-item b{
  font-size:11.5px;font-weight:700;max-width:100%;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.pc-item span{font-size:9.5px;color:var(--gray-4)}

/* 鱼塘页板块区：底部留出与帖子列表的间距 */
#pondPlaza{padding:10px 12px 0;margin-bottom:16px}

/* ============ 统一支付（v1.7.0） ============ */
/* 支付金额头部 */
.pay-hd{padding:6px 0 16px;text-align:center}
.pay-amt{font-size:30px;font-weight:900;color:var(--ink);line-height:1.2}
.pay-tt{font-size:13px;color:var(--gray-2);margin-top:5px}
/* 支付方式列表 */
.pay-list{display:flex;flex-direction:column;gap:9px}
.pay-item{
  display:flex;align-items:center;gap:11px;width:100%;
  padding:13px 13px;border-radius:14px;text-align:left;
  background:#F7F8FA;border:1px solid var(--line);transition:.15s;
}
.pay-item:active{transform:scale(.985);background:#F0F2F6}
.pay-ic{
  width:38px;height:38px;flex:none;border-radius:11px;
  display:flex;align-items:center;justify-content:center;
  background:#fff;color:var(--gray-1);
}
/* 各通道品牌色 */
.pay-ic.alipay{background:#E8F3FF;color:#1677FF}
.pay-ic.wxpay,
.pay-ic.wechat{background:#E7F8EE;color:#07C160}
.pay-ic.epay{background:#FFF3E0;color:#F79009}
.pay-ic.balance{background:var(--brand-16);color:#8A6100}
.pay-nm{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.pay-nm b{font-size:14.5px;font-weight:700}
.pay-nm i{font-style:normal;font-size:11.5px;color:var(--gray-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pay-ar{flex:none;display:flex;color:var(--gray-4)}
.pay-tip{margin-top:14px;font-size:11.5px;color:var(--gray-3);text-align:center;line-height:1.6}

/* 扫码支付 */
.pay-qr{padding:4px 0 8px;text-align:center}
.pay-qr-t{font-size:13px;color:var(--gray-2)}
.pay-qr-a{font-size:28px;font-weight:900;color:var(--ink);margin:4px 0 14px;line-height:1.2}
.pay-qr-box{
  width:220px;height:220px;margin:0 auto;padding:10px;
  background:#fff;border:1px solid var(--line);border-radius:16px;
  display:flex;align-items:center;justify-content:center;
}
.pay-qr-box img{width:200px;height:200px;display:block;image-rendering:pixelated}
.pay-qr-s{font-size:13px;color:var(--gray-1);margin-top:14px;font-weight:600}
.pay-qr-h{font-size:11.5px;color:var(--gray-3);margin-top:5px}
.pay-qr-btn{
  width:100%;height:45px;margin-top:16px;border-radius:22px;
  background:var(--brand);color:var(--ink);font-size:15px;font-weight:800;
}
.pay-qr-btn:active{transform:scale(.98)}
.pay-qr-cancel{
  width:100%;height:42px;margin-top:9px;border-radius:21px;
  background:#F4F6F9;color:var(--gray-2);font-size:13.5px;font-weight:600;
}

/* 登录/注册：邮箱验证码输入行 */
.code-row{display:flex;gap:8px;align-items:center}
.code-row input{flex:1;min-width:0}
.code-btn{
  flex:none;padding:0 13px;height:38px;border-radius:10px;
  background:var(--brand);color:var(--ink);font-size:12.5px;font-weight:800;
  white-space:nowrap;transition:.15s;
}
.code-btn:active{transform:scale(.96)}
.code-btn[disabled]{opacity:.55}

/* ================= 排行榜 ================= */
/* 入口在首页顶部导航栏（原「刷新」按钮） */
.rank-tabs{
  display:flex;gap:8px;padding:2px 12px 12px;position:sticky;top:0;z-index:5;
  background:var(--bg,#F7F8FA);
}
.rank-tab{
  flex:1;display:flex;align-items:center;justify-content:center;gap:5px;
  padding:9px 6px;border:none;border-radius:12px;cursor:pointer;
  background:#fff;color:#7A869A;font-size:13.5px;font-weight:600;
  border:1px solid var(--line,#EDF0F5);transition:.16s;
}
.rank-tab svg{opacity:.75}
.rank-tab.on{
  background:var(--brand,#FFE411);color:#1B1F24;
  border-color:var(--brand,#FFE411);
  box-shadow:0 4px 12px rgba(255,180,0,.24);
}
.rank-tab.on svg{opacity:1}

.rank-list{padding:0 12px}
.rank-row{
  display:flex;align-items:center;gap:10px;
  padding:11px 12px;margin-bottom:8px;border-radius:14px;
  background:#fff;border:1px solid var(--line,#EDF0F5);cursor:pointer;
  transition:transform .14s;
}
.rank-row:active{transform:scale(.985)}
/* 前三名：加一圈对应色，一眼看出冠亚季 */
.rank-row.top1{border-color:#FFD84D;background:linear-gradient(90deg,#FFFBE6 0%,#fff 62%)}
.rank-row.top2{border-color:#D8DEE9;background:linear-gradient(90deg,#F6F8FB 0%,#fff 62%)}
.rank-row.top3{border-color:#F0C89B;background:linear-gradient(90deg,#FFF6EE 0%,#fff 62%)}

.rk-no{
  flex:none;width:24px;height:24px;border-radius:8px;
  display:flex;align-items:center;justify-content:center;
  font-size:12.5px;font-weight:800;color:#98A2B3;
  background:var(--line-2,#F2F4F7);
}
.rk-no.n1{background:linear-gradient(140deg,#FFE055,#F5B800);color:#fff;box-shadow:0 3px 8px rgba(255,184,0,.36)}
.rk-no.n2{background:linear-gradient(140deg,#D9DEE6,#AEB8C6);color:#fff}
.rk-no.n3{background:linear-gradient(140deg,#F0C08A,#D98E4A);color:#fff}

.rk-cover{
  flex:none;width:42px;height:42px;border-radius:11px;
  background-size:cover;background-position:center;background-color:#F2F4F7;
  display:flex;align-items:center;justify-content:center;font-size:17px;
}
.rk-main{flex:1;min-width:0}
.rk-main b{
  display:block;font-size:14.5px;font-weight:700;color:#1B1F24;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.rk-sub{
  display:block;margin-top:3px;font-size:11.5px;color:#98A2B3;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.rk-num{
  flex:none;font-size:13px;font-weight:800;color:var(--brand-2,#F5B800);
  font-variant-numeric:tabular-nums;
}

/* ================= 任务中心（v1.7.11 重做） =================
   原布局把「进度条 + 奖励 + 操作按钮」挤在同一行，窄屏下进度条被压扁。
   现改为纵向分段：标题行 / 描述 / 进度 / 奖励，各自独立，不会互相挤压。 */
.tk-wrap{padding:0 12px 30px}
.tk-level{
  padding:16px 16px 14px;border-radius:18px;margin-bottom:14px;
  background:linear-gradient(128deg,#FFE411 0%,#FFD84D 46%,#FFC53D 100%);
  box-shadow:0 10px 24px rgba(255,180,0,.22);position:relative;overflow:hidden;
}
/* 右上角装饰圆，纯装饰不参与布局 */
.tk-level::after{
  content:'';position:absolute;right:-30px;top:-38px;width:118px;height:118px;border-radius:50%;
  background:rgba(255,255,255,.18);pointer-events:none;
}
.tk-lv-top{display:flex;align-items:center;gap:11px;position:relative;z-index:1}
.tk-lv-badge{
  width:46px;height:46px;border-radius:15px;flex:none;
  background:rgba(255,255,255,.92);color:#7A5B00;
  display:flex;align-items:center;justify-content:center;
  font-size:15px;font-weight:800;letter-spacing:-.3px;
  box-shadow:0 3px 10px rgba(122,91,0,.14);
}
.tk-lv-info{flex:1;min-width:0}
.tk-lv-info b{display:block;font-size:16px;font-weight:800;color:#1B1F24}
.tk-lv-info span{
  display:block;margin-top:3px;font-size:11.5px;color:#7A5B00;opacity:.9;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.tk-lv-next{
  flex:none;padding:4px 10px;border-radius:20px;font-size:11.5px;font-weight:700;
  background:rgba(255,255,255,.9);color:#7A5B00;
}
.tk-lv-bar{
  height:9px;border-radius:9px;margin-top:13px;overflow:hidden;position:relative;z-index:1;
  background:rgba(27,31,36,.13);
}
.tk-lv-bar i{
  display:block;height:100%;border-radius:9px;background:#fff;
  box-shadow:0 1px 4px rgba(255,255,255,.6);
  transition:width .55s cubic-bezier(.4,0,.2,1);min-width:2px;
}
.tk-lv-num{
  display:flex;justify-content:space-between;margin-top:6px;
  font-size:11px;color:#7A5B00;opacity:.85;position:relative;z-index:1;
  font-variant-numeric:tabular-nums;
}

/* 筛选 Tab：真筛选，不再是只弹 toast 的摆设 */
.tk-tabs{display:flex;gap:8px;margin-bottom:12px}
.tk-tabs button{
  flex:1;min-width:0;padding:9px 6px;border-radius:13px;border:1px solid var(--line,#EDF0F5);
  background:#fff;color:#667085;font-size:13px;font-weight:600;
  display:flex;align-items:center;justify-content:center;gap:5px;
  transition:.16s;white-space:nowrap;
}
.tk-tabs button i{
  font-style:normal;font-size:11px;padding:1px 6px;border-radius:20px;
  background:var(--bg-2,#F2F4F7);color:#98A2B3;font-weight:700;
}
.tk-tabs button.on{
  background:var(--brand,#FFE411);border-color:var(--brand,#FFE411);color:#1B1F24;font-weight:700;
  box-shadow:0 4px 12px rgba(255,180,0,.22);
}
.tk-tabs button.on i{background:rgba(27,31,36,.14);color:#1B1F24}
/* 有待领取时高亮提醒 */
.tk-tabs button.alert i{background:var(--err,#F04438);color:#fff}

.tk-card{
  background:#fff;border:1px solid var(--line,#EDF0F5);border-radius:16px;
  padding:13px 14px;margin-bottom:10px;transition:.16s;
}
.tk-card.got{opacity:.6}
.tk-c-hd{display:flex;align-items:center;gap:10px}
.tk-c-ic{
  width:40px;height:40px;border-radius:13px;flex:none;
  background:var(--bg-2,#F2F4F7);color:#98A2B3;
  display:flex;align-items:center;justify-content:center;
}
.tk-card.done .tk-c-ic{background:rgba(255,228,17,.20);color:#8A6100}
.tk-c-tt{flex:1;min-width:0;display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.tk-c-tt b{font-size:14.5px;font-weight:700;color:#1B1F24}
.tk-tag{
  font-style:normal;font-size:10px;padding:1.5px 6px;border-radius:6px;flex:none;
  background:#F2F4F7;color:#667085;font-weight:600;
}
.tk-tag.daily{background:#E8F3FF;color:#1D6FD8}
.tk-btn{
  flex:none;padding:6px 14px;border-radius:20px;border:none;
  background:var(--brand,#FFE411);color:#1B1F24;font-size:12.5px;font-weight:700;
  font-family:inherit;cursor:pointer;white-space:nowrap;transition:.15s;
}
.tk-btn:active{transform:scale(.94)}
.tk-btn.wait{background:#F2F4F7;color:#98A2B3;cursor:default}
.tk-c-desc{font-size:12px;color:#98A2B3;margin-top:8px;line-height:1.5}
.tk-c-prog{display:flex;align-items:center;gap:9px;margin-top:10px}
.tk-bar{flex:1;height:6px;border-radius:6px;background:var(--bg-2,#F2F4F7);overflow:hidden}
.tk-bar i{
  display:block;height:100%;border-radius:6px;background:#C6CDD6;
  transition:width .4s cubic-bezier(.4,0,.2,1);
}
.tk-card.done .tk-bar i{background:var(--brand,#FFE411)}
.tk-pg-t{
  flex:none;font-size:11px;color:#98A2B3;font-weight:600;
  font-variant-numeric:tabular-nums;min-width:34px;text-align:right;
}
.tk-c-rw{display:flex;gap:7px;margin-top:10px;flex-wrap:wrap}
.tk-rw{
  display:inline-flex;align-items:center;gap:3px;
  padding:3px 9px;border-radius:20px;background:#FFFDF0;
  border:1px solid rgba(255,228,17,.5);
  font-size:11px;color:#8A6100;font-weight:700;
}
.tk-empty{text-align:center;padding:34px 16px;color:#98A2B3;font-size:13px}

/* ================= 余额/金币页（v1.7.11 重做） ================= */
.bl2-wrap{padding:0 12px 30px}
.bl2-head{
  padding:20px 18px 18px;border-radius:20px;margin-bottom:16px;position:relative;overflow:hidden;
  background:linear-gradient(128deg,#1B1F24 0%,#2E3540 62%,#3A4350 100%);
  box-shadow:0 12px 28px rgba(16,24,40,.20);
}
/* 右下角大金币装饰，纯视觉，不占布局 */
.bl2-head::after{
  content:'';position:absolute;right:-26px;bottom:-34px;width:128px;height:128px;border-radius:50%;
  background:radial-gradient(circle at 34% 32%,rgba(255,228,17,.30),rgba(255,228,17,.05) 62%,transparent 72%);
  pointer-events:none;
}
.bl2-ttl{
  display:flex;align-items:center;gap:6px;position:relative;z-index:1;
  font-size:12px;color:rgba(255,255,255,.62);
}
.bl2-val{
  display:flex;align-items:center;gap:8px;margin-top:9px;position:relative;z-index:1;
  color:var(--brand,#FFE411);
}
/* 图标按视觉基线微调，与大号数字对齐 */
.bl2-val svg{margin-bottom:2px;flex:none}
.bl2-val b{
  font-size:38px;font-weight:800;letter-spacing:-1.4px;line-height:1.05;
  font-variant-numeric:tabular-nums;
}
.bl2-val span{font-size:14px;font-weight:700;opacity:.9}
.bl2-sub{
  display:flex;gap:16px;margin-top:15px;padding-top:14px;position:relative;z-index:1;
  border-top:1px solid rgba(255,255,255,.13);
}
.bl2-sub div{font-size:11.5px;color:rgba(255,255,255,.55)}
.bl2-sub div b{
  display:block;margin-top:3px;font-size:15px;font-weight:800;color:#fff;
  font-variant-numeric:tabular-nums;
}

/* 档位：卡片化，赠送做成右上角角标 */
.bl2-sec{
  display:flex;align-items:center;justify-content:space-between;
  margin:0 0 10px;font-size:13.5px;font-weight:700;color:#1B1F24;
}
.bl2-sec em{font-style:normal;font-size:11.5px;color:#98A2B3;font-weight:400}
.bl2-plans{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:6px}
.bl2-plan{
  position:relative;padding:14px 8px 12px;border-radius:15px;cursor:pointer;
  background:#fff;border:1.5px solid var(--line,#EDF0F5);text-align:center;transition:.16s;
}
.bl2-plan:active{transform:scale(.96)}
.bl2-plan.on{
  border-color:var(--brand,#FFE411);background:rgba(255,228,17,.09);
  box-shadow:0 5px 16px rgba(255,180,0,.20);
}
.bl2-pv{font-size:19px;font-weight:800;color:#1B1F24;font-variant-numeric:tabular-nums}
.bl2-pv i{font-style:normal;font-size:13px;font-weight:700;margin-right:1px}
.bl2-pg{font-size:11px;color:#98A2B3;margin-top:4px;min-height:15px}
.bl2-plan.on .bl2-pg{color:#8A6100;font-weight:700}
/* 赠送角标 */
.bl2-bonus{
  /* v1.7.22：原 top:-8px/right:-4px 外溢。此处父级 .bl2-plan 有定位基准、
     祖先也无裁剪，实践中是安全的；但为了全站统一「角标一律内嵌」的原则
     （任何一处新增 overflow:hidden 都不会再引发遮挡），改为内嵌。
     视觉上仍是贴在卡片右上角，差别很小。 */
  position:absolute;top:4px;right:4px;padding:2px 7px;border-radius:20px;
  background:var(--err,#F04438);color:#fff;font-size:10px;font-weight:700;
  box-shadow:0 2px 7px rgba(240,68,56,.32);
}
.bl2-pay{margin:12px 0 0}

/* ================= 每日签到（v1.7.12 重做） ================= */
.sg-wrap{padding:0 12px 30px}
.sg-hero{
  position:relative;overflow:hidden;border-radius:20px;padding:22px 18px 20px;margin-bottom:14px;
  background:linear-gradient(135deg,#FFE411 0%,#FFD166 52%,#FFC02E 100%);
  box-shadow:0 12px 28px rgba(255,180,0,.24);
}
/* 装饰圆：右下角亮斑，纯视觉 */
.sg-hero::after{
  content:'';position:absolute;right:-34px;bottom:-42px;width:140px;height:140px;border-radius:50%;
  background:radial-gradient(circle at 36% 34%,rgba(255,255,255,.42),rgba(255,255,255,.06) 64%,transparent 74%);
  pointer-events:none;
}
.sg-top{display:flex;align-items:center;gap:14px;position:relative;z-index:1}
/* 左侧大圆环：连续签到天数 */
.sg-ring{
  width:78px;height:78px;border-radius:50%;flex:none;position:relative;
  background:rgba(255,255,255,.94);display:flex;flex-direction:column;
  align-items:center;justify-content:center;color:#7A5B00;
  box-shadow:0 6px 18px rgba(170,120,0,.20);
}
.sg-ring b{font-size:27px;font-weight:800;line-height:1;letter-spacing:-1px}
.sg-ring i{font-style:normal;font-size:10.5px;font-weight:700;margin-top:3px;opacity:.8}
.sg-info{flex:1;min-width:0;color:#7A5B00}
.sg-info .sg-t{font-size:17px;font-weight:800;color:#1B1F24}
.sg-info .sg-s{font-size:12px;margin-top:5px;opacity:.9;line-height:1.6}
.sg-info .sg-s b{font-weight:800}

/* 签到按钮 */
.sg-btn{
  display:block;width:100%;margin-top:16px;padding:13px 0;border:none;border-radius:26px;
  font-size:15px;font-weight:800;font-family:inherit;cursor:pointer;position:relative;z-index:1;
  background:#1B1F24;color:var(--brand,#FFE411);
  box-shadow:0 6px 16px rgba(27,31,36,.24);transition:.16s;
}
.sg-btn:active{transform:scale(.98)}
.sg-btn.done{background:rgba(255,255,255,.72);color:#8A6100;box-shadow:none;cursor:default}

/* 连签奖励阶梯 */
.sg-steps{display:flex;gap:7px;margin-top:14px;position:relative;z-index:1}
.sg-step{
  flex:1;min-width:0;padding:8px 4px;border-radius:11px;text-align:center;
  background:rgba(255,255,255,.34);border:1px solid rgba(255,255,255,.5);
}
.sg-step.on{background:rgba(255,255,255,.92);border-color:#fff;box-shadow:0 3px 10px rgba(170,120,0,.16)}
.sg-step b{display:block;font-size:12.5px;font-weight:800;color:#1B1F24}
.sg-step span{display:block;font-size:10px;color:#8A6100;margin-top:2px;opacity:.9}
.sg-step.on span{color:#7A5B00;font-weight:700;opacity:1}

/* 日历 */
.sg-cal{background:#fff;border-radius:16px;padding:14px 14px 16px;box-shadow:0 2px 10px rgba(16,24,40,.04)}
.sg-cal-hd{
  display:flex;align-items:center;justify-content:space-between;margin-bottom:12px;
}
.sg-cal-hd b{font-size:14.5px;font-weight:700;color:#1B1F24}
.sg-cal-hd span{font-size:11.5px;color:#98A2B3}
.sg-wk{display:grid;grid-template-columns:repeat(7,1fr);gap:5px;margin-bottom:6px}
.sg-wk div{text-align:center;font-size:11px;color:#98A2B3;font-weight:600}
.sg-days{display:grid;grid-template-columns:repeat(7,1fr);gap:5px}
/* v1.7.13：高度由 JS 的 Signin.fitCal() 按实测列宽精确设置。
   此前只用 aspect-ratio:1 —— 部分 WebView 不支持时格子高度会退回由内容决定，
   于是「空格子高度 0、有对勾的格子更高」，整块日历歪成锯齿状。
   这里保留 aspect-ratio 作为 JS 未执行时的兜底，并加 min-height 防止塌陷。 */
.sg-day{
  aspect-ratio:1;min-height:38px;box-sizing:border-box;
  border-radius:11px;display:flex;flex-direction:column;
  align-items:center;justify-content:center;background:#F7F8FA;color:#98A2B3;
  font-size:12.5px;font-weight:600;transition:.16s;overflow:hidden;
}
.sg-day.empty{background:transparent}
/* v1.7.47：上/下月的补位日期 —— 填满首尾空缺，不再留空白格。
   比 .future 更淡：future 至少是本月的日子，补位格纯粹是占位。
   ⚠️ 不能加 box-shadow：与 .signed 的黄底阴影同处一行会更显眼，
      而它们本该是"退到背景里"的存在。 */
.sg-day.other{
  background:transparent;color:#D5DAE2;font-weight:500;
}
.sg-day.future{background:#FCFCFD;color:#C6CDD6}
.sg-day.today{
  background:#FFF4D5;color:#8A6100;font-weight:800;
  box-shadow:inset 0 0 0 1.5px var(--brand,#FFE411);
}
.sg-day.signed{
  background:var(--brand,#FFE411);color:#1B1F24;font-weight:800;
  box-shadow:0 2px 7px rgba(255,180,0,.28);
}
/* 日期数字与状态点：所有格子的结构统一，避免内容高度不一 */
.sg-day b{font-weight:inherit;line-height:1.1}
.sg-day i{
  display:block;width:4px;height:4px;border-radius:50%;margin-top:3px;
  background:currentColor;opacity:0;
}
.sg-day.signed i{opacity:.55}
.sg-note{
  font-size:11.5px;color:#98A2B3;line-height:1.75;margin-top:12px;
  padding-top:12px;border-top:1px solid var(--line,#EDF0F5);
}

/* ==================================================================
   v1.7.14 统一重做：创作者中心 / 我的勋章 / 会员中心 / 身份认证 / 关于
   共用一套视觉语言：
     · 头部 —— 品牌色或深色渐变大卡，承载核心数字
     · 数据 —— 等分网格，带竖向分隔线
     · 列表 —— 卡片化，与主内容区间距统一（左右 12px）
   ================================================================== */

/* ---------- 通用头部卡 ---------- */
.hd-card{
  position:relative;overflow:hidden;border-radius:20px;margin-bottom:14px;
  padding:20px 18px;
  background:linear-gradient(128deg,#1B1F24 0%,#2E3540 60%,#3A4350 100%);
  box-shadow:0 12px 28px rgba(16,24,40,.20);
}
.hd-card.brand{
  background:linear-gradient(128deg,#FFE411 0%,#FFD84D 48%,#FFC53D 100%);
  box-shadow:0 12px 28px rgba(255,180,0,.24);
}
/* 装饰圆：纯视觉，不参与布局 */
.hd-card::after{
  content:'';position:absolute;right:-30px;top:-40px;width:126px;height:126px;
  border-radius:50%;background:rgba(255,255,255,.14);pointer-events:none;
}
.hd-card.brand::after{background:rgba(255,255,255,.30)}
.hd-top{display:flex;align-items:center;gap:10px;position:relative;z-index:1}
.hd-ic{
  width:44px;height:44px;border-radius:14px;flex:none;
  display:flex;align-items:center;justify-content:center;
  background:rgba(255,255,255,.16);color:#fff;
}
.hd-card.brand .hd-ic{background:rgba(255,255,255,.86);color:#7A5B00}
.hd-tt{flex:1;min-width:0;color:#fff}
.hd-card.brand .hd-tt{color:#1B1F24}
.hd-tt b{display:block;font-size:16px;font-weight:800;letter-spacing:-.2px}
.hd-tt span{display:block;font-size:11.5px;opacity:.72;margin-top:3px}
.hd-tag{
  flex:none;padding:4px 11px;border-radius:20px;font-size:11px;font-weight:700;
  background:rgba(255,255,255,.18);color:#fff;
}
.hd-card.brand .hd-tag{background:rgba(27,31,36,.12);color:#7A5B00}
.hd-tag.ok{background:#ECFDF3;color:var(--ok,#12B76A)}
.hd-tag.warn{background:#FFFAEB;color:#B54708}
.hd-tag.err{background:#FEF3F2;color:var(--err,#F04438)}
.hd-val{
  display:flex;align-items:baseline;gap:5px;margin-top:15px;
  position:relative;z-index:1;color:var(--brand,#FFE411);
}
.hd-card.brand .hd-val{color:#1B1F24}
.hd-val b{font-size:34px;font-weight:800;letter-spacing:-1.2px;line-height:1;font-variant-numeric:tabular-nums}
.hd-val i{font-style:normal;font-size:13px;font-weight:700;opacity:.85}
.hd-sub{
  margin-top:14px;padding-top:14px;position:relative;z-index:1;
  border-top:1px solid rgba(255,255,255,.14);
  font-size:11.5px;color:rgba(255,255,255,.62);line-height:1.7;
}
.hd-card.brand .hd-sub{border-top-color:rgba(27,31,36,.12);color:#7A5B00}

/* ---------- 数据网格 ---------- */
.dt-grid{
  display:grid;grid-template-columns:repeat(4,1fr);background:#fff;
  border-radius:16px;margin-bottom:14px;overflow:hidden;
  box-shadow:0 2px 10px rgba(16,24,40,.04);
}
.dt-cell{padding:15px 4px;text-align:center;position:relative}
/* 分隔线用伪元素，避免影响 grid 列宽 */
.dt-cell + .dt-cell::before{
  content:'';position:absolute;left:0;top:50%;transform:translateY(-50%);
  width:1px;height:24px;background:var(--line,#EDF0F5);
}
.dt-cell b{
  display:block;font-size:17px;font-weight:800;color:#1B1F24;
  font-variant-numeric:tabular-nums;line-height:1.2;
}
.dt-cell span{display:block;font-size:11px;color:#98A2B3;margin-top:4px}
.dt-cell.hi b{color:#8A6100}

/* ---------- 区块标题 ---------- */
.sc-hd{
  display:flex;align-items:center;justify-content:space-between;
  margin:0 0 10px;padding:0 2px;
}
.sc-hd b{font-size:14px;font-weight:800;color:#1B1F24}
.sc-hd em{font-style:normal;font-size:11.5px;color:#98A2B3}

/* ---------- 特权 / 权益卡（两列） ---------- */
.rt-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:10px;margin-bottom:14px}
.rt-item{
  background:#fff;border-radius:15px;padding:14px 12px;
  box-shadow:0 2px 10px rgba(16,24,40,.04);
}
.rt-ic{
  width:36px;height:36px;border-radius:12px;margin-bottom:9px;
  display:flex;align-items:center;justify-content:center;
  background:var(--brand-16,#FFF9E8);color:#8A6100;
}
.rt-item b{display:block;font-size:13px;font-weight:700;color:#1B1F24}
.rt-item span{display:block;font-size:11px;color:#98A2B3;margin-top:4px;line-height:1.55}

/* ---------- 条件清单 ---------- */
.cd-card{
  background:#fff;border-radius:16px;margin-bottom:14px;overflow:hidden;
  box-shadow:0 2px 10px rgba(16,24,40,.04);
}
.cd-hd{
  padding:13px 16px 11px;font-size:13px;font-weight:700;color:#1B1F24;
  border-bottom:1px solid var(--line,#EDF0F5);
}
.cd-row{display:flex;align-items:center;gap:11px;padding:12px 16px}
.cd-row + .cd-row{border-top:1px solid var(--line,#EDF0F5)}
.cd-ic{
  width:30px;height:30px;border-radius:10px;flex:none;
  display:flex;align-items:center;justify-content:center;
  background:var(--bg-2,#F2F4F7);color:#98A2B3;
}
.cd-ic.ok{background:#ECFDF3;color:var(--ok,#12B76A)}
.cd-tx{flex:1;min-width:0}
.cd-tx b{display:block;font-size:13.5px;font-weight:600;color:#1B1F24}
.cd-tx span{display:block;font-size:11.5px;color:#98A2B3;margin-top:2px}
.cd-v{flex:none;font-size:11.5px;font-weight:700;color:#98A2B3;white-space:nowrap}
.cd-v.ok{color:var(--ok,#12B76A)}
/* v1.7.39：值右侧的箭头单独成元素，不再和文字塞进同一个 span。
 *
 * 原因：「<span class="cd-v">2 篇<svg…></span>」里，svg 是 inline 元素，
 * 按【基线】对齐 —— 15px 的箭头底边贴在 11.5px 文字的基线上，
 * 箭头中心因此比文字中心高出约 3px，看起来像飘起来；
 * 而且两者之间没有任何间距，数字和箭头直接贴在一起。
 *
 * 对比：全站其它同类行用 .mi-x（自带 display:flex + gap:5px）所以没这个问题，
 * 创作者中心这几行用了 .cd-v，而 .cd-v 只有字体样式、没有布局。
 * 因此拆成「值 .cd-v」+「箭头 .cd-ar」，而不是给 .cd-v 加 flex ——
 * 后者会连带影响条件进度里那两处纯文本用法（.cd-v 在 3907/4643 行只放文字）。
 */
.cd-ar{
  flex:none;display:flex;align-items:center;
  margin-left:6px;color:var(--gray-4,#C2C9D4);
}
/* svg 默认 inline，会在行盒里留出基线下方的空隙，导致箭头再偏一点 */
.cd-ar svg{display:block}
.cd-bar{
  margin:0 16px 14px;height:8px;border-radius:8px;
  background:var(--bg-2,#F2F4F7);overflow:hidden;
}
.cd-bar i{
  display:block;height:100%;border-radius:8px;
  background:linear-gradient(90deg,#FFE411,#FFC53D);
  transition:width .5s cubic-bezier(.4,0,.2,1);min-width:4px;
}

/* ---------- 勋章 ---------- */
.md-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:14px}
.md-item{
  background:#fff;border:1px solid var(--line,#EDF0F5);border-radius:16px;
  padding:15px 8px 13px;text-align:center;transition:.16s;position:relative;
}
.md-item:active{transform:scale(.97)}
.md-item.on{
  border-color:var(--brand,#FFE411);background:#FFFDF2;
  box-shadow:0 4px 14px rgba(255,180,0,.16);
}
.md-ring{
  width:52px;height:52px;margin:0 auto 9px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:var(--bg-2,#F2F4F7);color:#C6CDD6;position:relative;
}
.md-item.on .md-ring{color:#1B1F24}
/* 未获得时去饱和，已获得时按勋章配色 */
.md-item:not(.on) .md-ring{filter:grayscale(1);opacity:.55}
.md-item b{display:block;font-size:12.5px;font-weight:700;color:#1B1F24;line-height:1.3}
.md-item:not(.on) b{color:#98A2B3}
.md-item i{
  display:block;font-style:normal;font-size:10px;color:#98A2B3;
  margin-top:4px;line-height:1.5;min-height:15px;
}
.md-item em{
  display:block;font-style:normal;font-size:9.5px;color:#C6CDD6;margin-top:5px;
}
.md-item.on em{color:#8A6100}
/* 勋章名称过长时省略，不撑破格子 */
.md-item b,.md-item i{
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.md-item i{white-space:normal;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}

/* ---------- 会员套餐 ---------- */
.vp-item{
  position:relative;width:100%;text-align:left;background:#fff;
  border:1.5px solid var(--line,#EDF0F5);border-radius:16px;
  padding:15px 16px;margin-bottom:10px;display:flex;align-items:center;gap:12px;
  cursor:pointer;transition:.16s;font-family:inherit;
}
.vp-item:active{transform:scale(.985)}
.vp-item.on{border-color:var(--brand,#FFE411);background:#FFFDF2;box-shadow:0 5px 16px rgba(255,180,0,.18)}
.vp-ic{
  width:42px;height:42px;border-radius:13px;flex:none;
  display:flex;align-items:center;justify-content:center;
  background:var(--brand-16,#FFF9E8);color:#8A6100;
}
.vp-tx{flex:1;min-width:0}
.vp-tx b{display:block;font-size:15px;font-weight:800;color:#1B1F24}
.vp-tx span{display:block;font-size:11.5px;color:#98A2B3;margin-top:3px}
.vp-tx span s{color:#C6CDD6;margin-left:5px}
.vp-pr{flex:none;text-align:right}
.vp-pr b{display:block;font-size:20px;font-weight:800;color:#1B1F24;font-variant-numeric:tabular-nums}
.vp-pr b i{font-style:normal;font-size:13px;margin-right:1px}
.vp-pr span{display:block;font-size:10.5px;color:#98A2B3;margin-top:2px}
.vp-tag{
  /* v1.7.22：原 top:-1px/right:-1px 外溢 1px，而祖先 .cd-card 带 overflow:hidden，
     标签的边角会被切掉一小条。改为内嵌，圆角同步调整为纯右上角圆角。 */
  position:absolute;top:0;right:0;padding:3px 10px;
  border-radius:0 15px 0 12px;background:var(--err,#F04438);color:#fff;
  font-size:10.5px;font-weight:800;
}
.vp-tag.rec{background:#1B1F24;color:var(--brand,#FFE411)}
.vp-note{
  font-size:11.5px;color:#C6CDD6;line-height:1.75;text-align:center;margin-top:6px;
}

/* ---------- 关于页 ---------- */
.ab-hero{
  text-align:center;padding:30px 18px 26px;margin-bottom:14px;
}
.ab-logo{display:flex;justify-content:center;margin-bottom:14px}
/* 复用登录页的 .l-logo 造型，但覆盖它的居中 margin 与尺寸。
   注意：.l-logo 的选择器是 `.launch .l-logo`（带父级限定），
   所以在关于页里必须把造型属性重新写一遍，否则只有字号自适应生效。 */
.ab-logo .l-logo{
  position:relative;
  width:78px;height:78px;flex:none;overflow:hidden;margin:0;
  box-sizing:border-box;padding:7px;
  border-radius:22px;
  background:linear-gradient(158deg,rgba(255,255,255,.62) 0%,rgba(255,255,255,0) 56%),var(--brand);
  display:flex;align-items:center;justify-content:center;
  font-size:36px;font-weight:800;line-height:1.05;letter-spacing:0;
  text-align:center;word-break:break-all;
  transform:rotate(-5deg);
  box-shadow:0 13px 26px rgba(255,180,0,.34),inset 0 1px 0 rgba(255,255,255,.55);
  animation:logoIn .5s cubic-bezier(.34,1.5,.5,1) both;
}
@media (prefers-reduced-motion:reduce){ .ab-logo .l-logo{animation:none} }
.ab-nm{
  font-size:19px;font-weight:800;color:#1B1F24;letter-spacing:.4px;
}
.ab-ds{font-size:12.5px;color:#98A2B3;margin-top:7px;letter-spacing:.2px}
.ab-ver{
  display:inline-block;margin-top:13px;padding:5px 15px;border-radius:20px;
  background:var(--brand-16,#FFF9E8);color:#8A6100;
  font-size:12px;font-weight:700;font-variant-numeric:tabular-nums;
}

/* ================= 点赞特效（v1.7.23，v1.7.24 重新加回） =================
 *
 * 【v1.7.24 说明】这段曾在重做帖子卡片时被整块替换误删过一次。
 * 原先它插在「帖子卡片」与「悬浮发帖」两个区块之间，
 * 而那次替换的起止点正好是这两个区块，于是被连带清掉。
 * 教训：不要把自己的代码插在别人的区块边界上 ——
 * 一旦有人按区块整体替换就会被无声删除，且功能表现为「JS 还在跑、
 * 但动画全无」，极难排查。改为独立放在文件末尾。
 *
 * 设计要点：
 *  1) 粒子用 position:fixed + transform 位移，只触发合成，不触发重排；
 *     动画结束后立刻移除节点，不留任何 DOM 残留。
 *  2) 位移/旋转角度通过 CSS 变量传入，避免为每个粒子生成一份 keyframes
 *     （那样会给每张卡片都注入一段 <style>，卡片多了非常浪费）。
 *  3) 只对「点赞」放特效，「取消赞」不放 ——
 *     连点两次时两次都放会显得很吵，也容易让人误以为还在加。
 */
.like-fx{
  position:fixed;left:0;top:0;width:0;height:0;
  pointer-events:none;z-index:300;
}
.like-fx i{
  position:absolute;left:0;top:0;
  width:var(--sz,17px);height:var(--sz,17px);
  margin-left:calc(var(--sz,17px) / -2);margin-top:calc(var(--sz,17px) / -2);
  display:block;color:var(--err,#F04438);
  will-change:transform,opacity;
  animation:like-fly var(--dur,.78s) cubic-bezier(.18,.72,.32,1) forwards;
}
.like-fx i svg{width:100%;height:100%;display:block;fill:currentColor}
@keyframes like-fly{
  0%   { transform:translate(var(--x),var(--y)) scale(.2) rotate(0deg);            opacity:0 }
  14%  { transform:translate(calc(var(--x) + var(--dx) * .18),
                             calc(var(--y) + var(--dy) * .18)) scale(1.15) rotate(calc(var(--rot) * .18)); opacity:1 }
  100% { transform:translate(calc(var(--x) + var(--dx)),
                             calc(var(--y) + var(--dy))) scale(.32) rotate(var(--rot)); opacity:0 }
}
/* 中心那颗心：先放大再缩没，给一个明确的「确认」反馈 */
.like-fx i.core{
  animation:like-core var(--dur,.78s) cubic-bezier(.2,.8,.3,1) forwards;
}
@keyframes like-core{
  0%   { transform:translate(var(--x),var(--y)) scale(.3);  opacity:0 }
  22%  { transform:translate(var(--x),var(--y)) scale(1.5); opacity:1 }
  46%  { transform:translate(var(--x),var(--y)) scale(.95); opacity:1 }
  100% { transform:translate(var(--x),calc(var(--y) - 26px)) scale(.5); opacity:0 }
}
/* 按钮本身弹一下 */
@keyframes like-btn-pop{
  0%{transform:scale(1)} 30%{transform:scale(1.34)} 62%{transform:scale(.9)} 100%{transform:scale(1)}
}
.like-pop{animation:like-btn-pop .44s cubic-bezier(.3,1.5,.5,1)}
/* 数字滚一下 */
@keyframes like-num{
  0%{transform:translateY(0);opacity:1}
  40%{transform:translateY(-7px);opacity:0}
  60%{transform:translateY(7px);opacity:0}
  100%{transform:translateY(0);opacity:1}
}
.like-num{display:inline-block;animation:like-num .34s ease}

/* 系统开启「减弱动效」时关闭粒子动画。
   JS 侧的 likeFx() 会读 reduceMotion() 直接不生成粒子，
   这里再兜一层，防止任何遗漏路径。 */
@media (prefers-reduced-motion:reduce){
  .like-fx i,.like-fx i.core{animation:none;opacity:0}
  .like-pop{animation:none}
  .like-num{animation:none}
}

/* ==========================================================================
   管理中心（v1.7.58）
   手机端管理页，仅管理员与审核员可见。
   样式沿用站内既有的卡片与按钮体系，不新增配色。
   ========================================================================== */

/* 骨架屏：列表加载中的占位
 *
 * ⚠️ 必须用自己的 mg-sk-* 类名，不能直接复用 .sk-box / .sk-line。
 * 那两个是全站通用的骨架样式（首页列表、个人中心、评论、排行榜共 10 余处），
 * 在文件末尾复写会顺带改掉它们的尺寸与外边距——
 * 而 .sk-box 的用法大多是内联指定 width/height 的小方块，
 * 一旦被加上 padding 就会整体变形。这类污染不报错，只能肉眼发现。 */
.mg-sk{padding:16px 16px 20px}
.mg-sk-l{height:13px;border-radius:7px;background:var(--line-2);margin-bottom:11px}
.mg-sk-l:last-child{margin-bottom:0}

/* ---- 区块标题（待处理 / 数据概览 / 内容管理）----
 *
 * ⚠️ 只能给【管理页内部】的 .sc-hd 加边距，不能改全局的 .sc-hd：
 *   它是全站通用标题，认证页、会员页、勋章页、创作者中心共 8 处在用，
 *   那些页面的标题与卡片用的是另外一套边距，改全局会连带错开。
 *
 * .sc-hd 自身是 padding:0 2px，而管理页的卡片（.mg-hero / .mg-todo /
 * .mg-grid / .mg-today / .mg-card）全是 margin:0 12px ——
 * 标题文字会比卡片往左凸出 10px，看着就是没对齐。
 * 这里补齐左右 12px，让标题与卡片共用同一条左边缘。
 *
 * 用 #manageBody 后代选择器而不是新增类名：JS 里管理页的 4 处 .sc-hd
 * 全部自动生效，以后新增区块也不会漏改（改 JS 就得一处一处找）。 */
#manageBody .sc-hd{padding-left:12px;padding-right:12px}

/* ---- 身份卡 ---- */
.mg-hero{
  display:flex;align-items:center;gap:12px;
  margin:0 12px 14px;padding:14px 16px;
  background:linear-gradient(120deg,#FFF9DB,#FFF3B0);
  border-radius:16px;
}
.mg-hero-ic{
  width:40px;height:40px;border-radius:50%;flex:none;
  background:#fff;color:#8A6100;
  display:flex;align-items:center;justify-content:center;
}
.mg-hero b{display:block;font-size:15px;font-weight:800}
.mg-hero span{display:block;font-size:11.5px;color:#8A6100;margin-top:2px}

/* ---- 待办六宫格 ---- */
.mg-todo{
  display:grid;grid-template-columns:repeat(3,1fr);gap:10px;
  margin:0 12px 14px;
}
.mg-todo-i{
  background:#fff;border:1px solid var(--line);border-radius:14px;
  padding:13px 6px 11px;display:flex;flex-direction:column;align-items:center;gap:7px;
  /* v1.7.58：给未处理角标提供定位基准。角标必须挂在【按钮】上而不是图标块上，
     否则就要靠负偏移外溢 —— 那是 v1.7.22 才修掉的老问题（.dot-badge 曾被
     消息列表 .page 的 overflow-x:hidden 横向切掉）。 */
  position:relative;
}
.mg-todo-i:active{background:var(--line-2)}
.mg-todo-ic{
  width:38px;height:38px;border-radius:12px;position:relative;
  display:flex;align-items:center;justify-content:center;
}
/* 未处理数量角标
   ⚠️ 一律【内嵌】在按钮右上角内侧，不许用负偏移向外溢出：
      祖先里有滚动容器（.page 计算后 overflow-x 为 auto），外溢必被裁。
      与 .dot-badge（v1.7.22）同一条规则。 */
.mg-dot{
  position:absolute;top:6px;right:6px;
  min-width:17px;height:17px;padding:0 4px;box-sizing:border-box;
  border-radius:9px;background:var(--err);color:#fff;
  font-size:10px;font-weight:700;font-style:normal;line-height:17px;text-align:center;
}
.mg-todo-tx{font-size:11.5px;color:var(--gray-1);text-align:center;line-height:1.3}

/* ---- 数据四宫格 ---- */
.mg-grid{
  display:grid;grid-template-columns:repeat(4,1fr);
  margin:0 12px 10px;background:#fff;
  border:1px solid var(--line);border-radius:14px;overflow:hidden;
}
.mg-cell{padding:14px 4px;text-align:center}
.mg-cell + .mg-cell{border-left:1px solid var(--line)}
.mg-cell b{display:block;font-size:17px;font-weight:800}
.mg-cell span{display:block;font-size:11px;color:var(--gray-3);margin-top:3px}

/* ---- 今日新增 ---- */
.mg-today{
  display:flex;gap:14px;flex-wrap:wrap;
  margin:0 12px 14px;padding:10px 14px;
  background:#fff;border:1px solid var(--line);border-radius:14px;
  font-size:12px;color:var(--gray-3);
}
.mg-today b{color:var(--ink);font-size:13px;font-weight:800;margin-right:3px}

/* ---- 返回条 ----
 * v1.7.61：已删除。导航栏（.navbar）本身就有返回箭头 + 页面标题，
 * 列表顶部再来一条是重复信息；返回管理中心走列表底部按钮。
 * 对应的样式一并移除，Manage.subHead() 里也不再生成该结构。
 */

/* ---- 状态分段 + 搜索 ---- */
.mg-seg{display:flex;gap:8px;overflow-x:auto;padding:0 12px 12px;-webkit-overflow-scrolling:touch}
.mg-seg::-webkit-scrollbar{display:none}
.mg-seg button{
  flex:none;padding:6px 12px;border-radius:14px;
  border:1px solid var(--line);background:#fff;
  font-size:12px;color:var(--gray-2);white-space:nowrap;
}
.mg-seg button.on{background:var(--ink);border-color:var(--ink);color:#fff;font-weight:700}

.mg-search{
  display:flex;align-items:center;gap:8px;
  margin:0 12px 12px;padding:8px 12px;
  background:#fff;border:1px solid var(--line);border-radius:12px;
}
.mg-search input{
  flex:1;min-width:0;border:0;outline:none;background:transparent;
  font-size:14px;font-family:inherit;color:var(--ink);
}
.mg-search button{
  flex:none;font-size:12.5px;color:var(--brand);font-weight:700;padding:2px 4px;
}
/* 品牌黄 #FFE411 在白底上对比度不足，这里改用深色保证可读 */
.mg-search button{color:#8A6100}

/* ---- 列表卡片 ---- */
.mg-card{
  margin:0 12px 12px;background:#fff;
  border:1px solid var(--line);border-radius:14px;overflow:hidden;
}
/* 卡片内菜单行之间的分隔线。
   写在这里而不是改全局 .menu-item —— 全局的 .menu-item 用在 .menu-group 里，
   那边靠分组圆角区分，加分隔线会连带改掉个人中心等十余处菜单。 */
.mg-card .menu-item + .menu-item{border-top:1px solid var(--line-2)}
.mg-item{display:flex;gap:11px;padding:12px 14px}
.mg-item + .mg-item{border-top:1px solid var(--line-2)}
/* col：无缩略图的条目（举报/认证/创作者申请），内容纵向铺满 */
.mg-item.col{display:block}
.mg-item-b{flex:1;min-width:0}
.mg-thumb{
  width:52px;height:52px;border-radius:10px;flex:none;
  object-fit:cover;background:var(--line-2);
}
.mg-thumb.ph{display:flex;align-items:center;justify-content:center;color:var(--gray-4)}
.mg-ava{width:44px;height:44px;border-radius:50%;flex:none;object-fit:cover;background:var(--line-2)}
.mg-item-t{
  font-size:14px;line-height:1.45;color:var(--ink);font-weight:600;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.mg-item-m{display:flex;flex-wrap:wrap;gap:7px;align-items:center;margin-top:6px;
  font-size:11px;color:var(--gray-3)}
.mg-item-m .tag{padding:2px 7px;border-radius:5px;font-size:10.5px}
.mg-reason{
  margin-top:6px;padding:7px 9px;border-radius:8px;background:var(--line-2);
  font-size:11.5px;color:var(--gray-2);line-height:1.55;word-break:break-word;
}
/* 操作按钮行 */
.mg-ops{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}
.mg-ops .btn-ghost-sm,.mg-ops .btn-brand-sm{padding:5px 12px;font-size:12px}

/* ---- 分页 ---- */
.mg-pager{
  display:flex;align-items:center;justify-content:center;gap:14px;
  padding:4px 12px 14px;font-size:12.5px;color:var(--gray-2);
}

.mg-tip{margin:0 12px;padding:0 4px;font-size:11.5px;color:var(--gray-4);line-height:1.7}

/* ==========================================================================
   资源详情页（v1.7.81 小红书 / 闲鱼风重做）
   --------------------------------------------------------------------------
   全部使用 rd- 前缀，不复用 / 不覆盖详情页旧类（.imgview / .author-row /
   .sec 等仍在动态详情页使用，改它们会连带改掉别处）。

   四处刻意的写法：
   1. .rd-slide 用 aspect-ratio + object-fit:cover
      图集是横向 scroll-snap，若各 slide 高度随图片原始比例变化，
      容器高度会以最高那张为准，滑动时下方内容会跟着跳动。
   2. .rd-main 用负 margin 上叠，而不是给图集加圆角
      图集是 overflow 容器，加 border-radius 会裁掉滚动中的图片。
   3. 缩略图条放在 .rd-gal 内部、主卡上叠区之上
      它属于"图集"这个整体，放外面会被上叠的主卡压住一半。
   4. 缩略图用 scrollbar-width:none 隐藏滚动条
      出现横向滚动条会顶高容器，让整块图集高度在有无溢出时不一致。
   ========================================================================== */
.rd-gal{position:relative;background:#F0F2F6;padding-bottom:10px}
.rd-gv{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;
  scrollbar-width:none;-webkit-overflow-scrolling:touch}
.rd-gv::-webkit-scrollbar{display:none}
.rd-slide{min-width:100%;scroll-snap-align:center;position:relative;
  aspect-ratio:4/3;background:#000}
.rd-slide img{width:100%;height:100%;object-fit:cover;display:block}
/* 无图时的占位块：高度与 4:3 图集接近，避免主卡位置跳变 */
.rd-ph{height:230px;display:flex;align-items:center;justify-content:center;
  color:rgba(27,31,36,.18)}
.rd-gn{position:absolute;right:12px;bottom:66px;padding:2px 9px;border-radius:20px;
  background:rgba(27,31,36,.55);color:#fff;font-size:11px;line-height:1.5;
  z-index:3}
.rd-gn b{font-weight:700}

/* ---- 缩略图条（小红书/闲鱼风的核心：一眼看完全部图）---- */
.rd-thumbs{position:relative;z-index:3;margin:-22px 12px 0;display:flex;gap:6px;
  overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch;
  padding:2px}
.rd-thumbs::-webkit-scrollbar{display:none}
.rd-th{flex:none;width:46px;height:46px;padding:0;border:2px solid transparent;
  border-radius:10px;overflow:hidden;background:#EDEFF3;cursor:pointer;
  transition:border-color .16s,transform .16s}
.rd-th img{width:100%;height:100%;object-fit:cover;display:block}
/* 当前张：品牌黄描边 + 轻微放大，比单纯描边更容易一眼定位 */
.rd-th.on{border-color:var(--brand);transform:scale(1.04)}
.rd-th:active{transform:scale(.94)}

/* 主信息卡：上叠压住图集底边，形成"卡片浮在图上"的层次 */
.rd-main{position:relative;z-index:2;margin:10px 12px 0;padding:16px 15px 14px;
  background:#fff;border-radius:16px}
.rd-badges{display:flex;gap:6px;margin-bottom:9px}
.rd-b{padding:3px 9px;border-radius:7px;font-size:11.5px;font-weight:700}
.rd-b.free{background:#EAFBF1;color:#0A7A45}
.rd-b.unlock{background:#FFF4E5;color:#B54708}
.rd-b.pick{background:#FFFAEB;color:#B54708}
.rd-title{font-size:19px;font-weight:800;line-height:1.42;letter-spacing:-.2px;
  word-break:break-word}
.rd-meta{display:flex;flex-wrap:wrap;align-items:center;gap:14px;
  margin-top:11px;font-size:12px;color:var(--gray-3)}
.rd-meta span{display:flex;align-items:center;gap:4px}
.rd-meta .rd-time{margin-left:auto;color:var(--gray-4)}
.rd-tags{display:flex;flex-wrap:wrap;gap:6px;margin-top:12px}
.rd-tag{padding:3px 10px;border-radius:20px;background:var(--line-2);
  font-size:11.5px;color:var(--gray-2)}

/* 作者条 */
.rd-author{display:flex;align-items:center;gap:11px;margin:10px 12px;
  padding:13px 15px;background:#fff;border-radius:16px}
.rd-au{flex:1;min-width:0}
.rd-au b{display:block;font-size:14.5px}
.rd-au span{display:block;margin-top:2px;font-size:12px;color:var(--gray-3);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rd-au-go{flex:none;display:flex;align-items:center;gap:1px;
  font-size:12.5px;color:var(--gray-3)}

/* 通用区块卡 */
.rd-sec{margin:10px 12px;padding:15px 16px;background:#fff;border-radius:16px}
.rd-sec-h{display:flex;align-items:center;gap:8px;margin-bottom:12px;
  font-size:15px;font-weight:800}
.rd-sec-h i{width:3.5px;height:15px;border-radius:3px;background:var(--brand)}
.rd-sec-n{font-size:12.5px;font-weight:500;color:var(--gray-3)}
.rd-blk+.rd-blk{margin-top:14px;padding-top:14px;border-top:1px solid var(--line)}
.rd-blk-t{font-size:13px;font-weight:700;color:var(--ink);margin-bottom:6px}
.rd-blk p{font-size:14px;color:var(--gray-1);line-height:1.72;
  white-space:pre-wrap;word-break:break-word}

/* ==========================================================================
   关于社区·正文页（v1.7.86）
   --------------------------------------------------------------------------
   dev-card 系列样式随 v1.7.86 一并删除 —— 那个「关于社区开发者」小卡
   原本贴在协议 / 隐私 / 帮助三页底部，用户要求移除，开发者信息改在
   关于社区正文页里以完整区块呈现。
   ========================================================================== */
.ai-wrap{margin:0 0 14px;padding:17px 16px;background:#fff;border-radius:16px}
.ai-lead{font-size:13px;line-height:1.85;color:var(--gray-1)}

/* 开发历程时间线 */
.ai-tl{margin:0 0 14px;padding:17px 16px 6px;background:#fff;border-radius:16px}
.ai-tl-hd{display:flex;align-items:center;gap:7px;font-size:14.5px;font-weight:800;margin-bottom:4px}
.ai-tl-hd span{color:var(--brand)}
.ai-item{position:relative;padding:0 0 18px 26px}
/* 竖线用伪元素而非真实节点：条目数量会变，写死节点必然漏改 */
.ai-item::before{content:'';position:absolute;left:5px;top:15px;bottom:-1px;
  width:2px;background:var(--line)}
.ai-item:last-child{padding-bottom:2px}
.ai-item:last-child::before{display:none}
/* 圆点压在竖线上，z-index 保证不被后续条目的线盖住 */
.ai-dot{position:absolute;left:0;top:5px;width:12px;height:12px;border-radius:50%;
  background:#fff;border:2.5px solid var(--brand);z-index:1}
.ai-yr{font-size:11.5px;font-weight:800;color:var(--brand);letter-spacing:.3px}
.ai-tt{font-size:13.5px;font-weight:700;margin-top:3px}
.ai-ds{font-size:12.5px;line-height:1.8;color:var(--gray-2);margin-top:4px}

/* 核心特性：两列网格，条目多了自动换行 */
.ai-feat{margin:0 0 14px;padding:17px 16px;background:#fff;border-radius:16px}
.ai-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:12px}
.ai-cell{padding:11px 12px;background:#FAFAFA;border-radius:12px}
.ai-cell b{display:block;font-size:12.5px;font-weight:700}
.ai-cell em{display:block;font-style:normal;font-size:11.5px;
  color:var(--gray-3);margin-top:3px;line-height:1.6}

/* 开发者区块 */
.ai-dev{display:flex;align-items:center;gap:12px;
  padding:15px 16px;background:#fff;border-radius:16px}
.ai-dev-ic{flex:none;width:44px;height:44px;border-radius:14px;
  background:#FFFBEB;color:#B54708;
  display:flex;align-items:center;justify-content:center}
.ai-dev-tx{flex:1;min-width:0}
.ai-dev-tx b{display:block;font-size:14px;font-weight:800}
.ai-dev-tx em{display:block;font-style:normal;font-size:12px;
  color:var(--gray-3);margin-top:4px;line-height:1.65}

/* ==========================================================================
   文档页：用户协议 / 隐私政策（v1.7.84）
   ========================================================================== */
.doc-wrap{margin:0 0 14px;padding:17px 16px;background:#fff;border-radius:16px}
.doc-hd b{display:block;font-size:17px;font-weight:800}
.doc-hd span{display:block;margin-top:5px;font-size:11.5px;color:var(--gray-3)}
.doc-lead{margin-top:13px;padding:11px 13px;border-radius:12px;
  background:#FAFAFA;font-size:12.5px;color:var(--gray-1);line-height:1.7}
.doc-sec{margin-top:16px}
.doc-sec+.doc-sec{border-top:1px solid var(--line)}
.doc-st{font-size:13.5px;font-weight:700;margin-bottom:8px}
.doc-sec+.doc-sec .doc-st{padding-top:16px}
.doc-p{font-size:13px;color:var(--gray-1);line-height:1.8;margin-bottom:7px}
.doc-p:last-child{margin-bottom:0}

/* ==========================================================================
   帮助反馈：常见问题展开（v1.7.84）
   折叠用 max-height 过渡而不是 display —— display 无法过渡，会硬跳。
   收起态 height:0 + overflow:hidden，避免出现 0 高度仍占位。
   ========================================================================== */
.faq-a{max-height:0;overflow:hidden;transition:max-height .26s ease;
  padding:0 16px;background:#fff;font-size:12.5px;color:var(--gray-2);line-height:1.8}
.faq-a.on{max-height:320px;padding:0 16px 14px}
.menu-item.faq+.faq-a{border-top:0}

/* ==================================================================
   奶酪小助手（v1.7.93）
   ------------------------------------------------------------------
   ① .asst-entry —— 消息页通知列表的置顶入口
      v1.7.93 放列表底部 → v1.7.94 改置顶但仅「系统消息」分类显示
      → v1.7.95 改为【全部五个分类常驻】（用户明确要求"固定显示"）
   ② .asst-*     —— pg-assistant 独立页
   ⚠️ 前缀统一为 asst-，勿复用 .msg-card / .menu-item：
      那两处规则绑着各自的间距与点击态，改一处会连带改掉消息列表和
      设置页（本项目已多次踩到「改 A 坏 B」）。
   ================================================================== */

/* ① 置顶入口：白卡，与 .msg-list 的 14px 内边距对齐。
   v1.7.94：由列表【之后】移到【之前】，margin 相应从
   「2px 14px 16px」改为「0 14px 10px」—— 现在它的下方就是 .msg-list，
   下边距要给列表留位置但不能太大（列表自身已有 14px 底部内边距）。 */
.asst-entry{
  display:flex;align-items:center;gap:11px;
  margin:0 14px 10px;padding:12px 14px;
  background:#fff;border-radius:16px;
  box-shadow:0 1px 3px rgba(27,31,36,.05);
  cursor:pointer;
}
.asst-entry:active{background:var(--line-2)}
.asst-entry .asst-av{
  width:42px;height:42px;border-radius:50%;flex:none;
  background:var(--line-2);object-fit:cover;
}
.asst-entry .asst-txt{flex:1;min-width:0}
.asst-entry .asst-txt b{display:block;font-size:14.5px;line-height:1.35}
.asst-entry .asst-txt span{display:block;font-size:12px;color:var(--gray-3);margin-top:2px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.asst-entry .asst-go{color:var(--gray-4);flex:none;display:flex}

/* ② 独立页 */
.asst-page{padding:0 14px 24px}
.asst-hero{
  display:flex;flex-direction:column;align-items:center;
  padding:26px 16px 22px;margin-bottom:14px;
  background:#fff;border-radius:20px;
}
.asst-hero .asst-hero-av{
  width:88px;height:88px;border-radius:50%;object-fit:cover;
  background:var(--line-2);
}
.asst-hero .asst-hero-name{font-size:17px;margin-top:13px}
.asst-hero .asst-hero-say{
  font-size:13px;color:var(--gray-2);text-align:center;
  line-height:1.75;margin-top:7px;
}
.asst-cards{display:flex;flex-direction:column;gap:10px}
.asst-card{
  display:flex;align-items:center;gap:12px;
  padding:13px 14px;background:#fff;border-radius:16px;cursor:pointer;
}
.asst-card:active{background:var(--line-2)}
.asst-card .ac-ic{
  width:38px;height:38px;border-radius:12px;flex:none;
  display:flex;align-items:center;justify-content:center;
}
.asst-card .ac-t{flex:1;min-width:0}
.asst-card .ac-t b{display:block;font-size:14.5px}
.asst-card .ac-t span{display:block;font-size:12px;color:var(--gray-3);margin-top:2px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.asst-card .ac-go{color:var(--gray-4);flex:none;display:flex}

/* 联系站长：无联系方式时整行不渲染，故不需要 :empty 兜底 */
.asst-contact{
  display:flex;align-items:center;gap:10px;
  margin-top:12px;padding:13px 14px;
  background:#fff;border-radius:16px;cursor:pointer;
}
.asst-contact:active{background:var(--line-2)}
.asst-contact span{font-size:13.5px;color:var(--gray-2);flex:none}
.asst-contact b{
  flex:1;min-width:0;text-align:right;font-size:13.5px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.asst-contact i{color:var(--gray-4);flex:none;display:flex}

/* ========== 积分商城（v1.7.99） ==========
   类名统一 sp- / so- 前缀：不与 .empty、.sheet-foot 等通用类冲突，
   也不复用资源卡（.rc-*），避免改一处动全身。 */
.sp-hero{
  position:relative;margin:12px 12px 4px;padding:16px 18px;border-radius:18px;
  background:linear-gradient(135deg,#FFC646 0%,#FF9F1A 100%);
  color:#4A3000;overflow:hidden;
}
.sp-hero::after{
  content:'';position:absolute;right:-26px;top:-30px;width:118px;height:118px;
  border-radius:50%;background:rgba(255,255,255,.22);
}
.sp-hero-t{font-size:12.5px;opacity:.85;font-weight:600}
.sp-hero-n{display:flex;align-items:center;gap:6px;margin-top:6px;font-size:27px;font-weight:800;line-height:1.1}
.sp-hero-n svg{opacity:.9}
.sp-hero-btn{
  position:relative;z-index:1;margin-top:12px;
  display:inline-flex;align-items:center;gap:3px;
  height:30px;padding:0 12px;border-radius:15px;
  background:rgba(255,255,255,.9);color:#8A6100;
  font-size:12.5px;font-weight:700;
}
.sp-hero.small{margin-bottom:10px}
.sp-hero.small .sp-hero-n{font-size:22px}

/* 两列网格：与首页瀑布流（.waterfall）同为 1fr 1fr，
   但商城是固定等高卡片，不能复用（瀑布流是 JS 分列插入的） */
.sp-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px;padding:10px 12px 0}
.sp-card{
  background:#fff;border-radius:16px;padding:9px 9px 11px;
  display:flex;flex-direction:column;
}
.sp-card.out{opacity:.62}
.sp-img{
  position:relative;width:100%;aspect-ratio:1/1;border-radius:12px;
  overflow:hidden;background:var(--line-2);
}
.sp-img img{width:100%;height:100%;object-fit:cover;display:block}
.sp-noimg{width:100%;height:100%;display:flex;align-items:center;justify-content:center;color:var(--gray-4)}
.sp-t{
  margin-top:9px;font-size:14px;font-weight:700;color:var(--ink);line-height:1.35;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  min-height:38px;
}
.sp-d{
  margin-top:3px;font-size:11.5px;color:var(--gray-3);line-height:1.4;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.sp-p{display:flex;align-items:center;gap:3px;margin-top:7px;color:#E08A00;font-weight:800}
.sp-p b{font-size:16px}
.sp-p span{font-size:11.5px;font-weight:600;margin-left:1px}
.sp-m{display:flex;justify-content:space-between;font-size:11px;color:var(--gray-3);margin-top:4px}
.sp-btn{
  margin-top:9px;height:33px;border-radius:11px;
  background:var(--brand);color:#4A3000;font-size:13.5px;font-weight:700;
}
.sp-btn:disabled{background:var(--line);color:var(--gray-3)}
.sp-tip{font-size:11.5px;color:var(--gray-3);text-align:center;padding:16px 24px 0;line-height:1.6}

/* 兑换弹窗 */
.sp-ask{display:flex;gap:11px;align-items:center;padding:14px 16px 0}
.sp-ask-i{width:52px;height:52px;border-radius:12px;overflow:hidden;background:var(--line-2);flex:none}
.sp-ask-i img{width:100%;height:100%;object-fit:cover;display:block}
.sp-ask-t{font-size:14.5px;font-weight:700}
.sp-ask-p{display:flex;align-items:center;gap:3px;margin-top:4px;font-size:12.5px;color:#E08A00;font-weight:700}
.sp-row{display:flex;align-items:center;justify-content:space-between;padding:13px 16px 0;font-size:13.5px;color:var(--gray-2)}
.sp-step{display:flex;align-items:center;gap:13px}
.sp-step button{
  width:27px;height:27px;border-radius:50%;background:var(--line-2);
  font-size:17px;line-height:1;color:var(--ink);font-weight:700;
}
.sp-step b{min-width:20px;text-align:center;font-size:15px;color:var(--ink)}
.sp-cost{color:#E08A00;font-weight:800;font-size:14.5px}

/* 我的兑换 */
.so-list{padding:6px 12px 0}
.so-item{
  display:flex;align-items:center;gap:11px;
  background:#fff;border-radius:16px;padding:11px 12px;margin-top:9px;
}
.so-img{width:48px;height:48px;border-radius:12px;overflow:hidden;background:var(--line-2);flex:none}
.so-img img{width:100%;height:100%;object-fit:cover;display:block}
.so-main{flex:1;min-width:0}
.so-t{font-size:14px;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.so-n{font-weight:600;color:var(--gray-3);font-size:12.5px}
.so-c{display:flex;align-items:center;gap:3px;font-size:11.5px;color:var(--gray-3);margin-top:3px}
.so-key{
  margin-top:5px;font-size:12px;color:#8A6100;background:var(--brand-16);
  border-radius:8px;padding:5px 8px;word-break:break-all;line-height:1.5;
}
.so-st{flex:none;font-size:11.5px;font-weight:700;padding:3px 9px;border-radius:20px}
.so-st.s0{background:var(--brand-16);color:#8A6100}
.so-st.s1{background:#E8F7EE;color:#1A9A54}
.so-st.s2{background:var(--line-2);color:var(--gray-3)}

/* ================= 启动页 / 开屏广告（v1.8.2） =================
 *
 * 全部使用 .splash- 前缀，不复用任何既有类：
 *   · .launch / .l-logo 是登录页的，选择器带 .launch 父级限定，
 *     直接改会连带改坏登录页（v1.7.76 的 .empty、v1.7.90 的 --bg-2
 *     都是"改 A 坏 B"的教训）
 *   · .sp-up 是后台的上传区样式，与本页无关
 *
 * z-index 9999 的依据：登录页 .launch 是 90，底部导航与弹窗在 100~900 之间，
 * 启动页要盖住一切（含尚未决定去向的首页/登录页），故取最高。
 */
.splash{
  position:fixed;inset:0;z-index:9999;
  background:#fff;
  display:flex;flex-direction:column;
  overflow:hidden;
  -webkit-user-select:none;user-select:none;
}
.splash.out{
  opacity:0;transform:scale(1.045);
  transition:opacity .34s ease,transform .34s ease;
  pointer-events:none;
}
@media (prefers-reduced-motion:reduce){
  .splash.out{transition:opacity .2s ease;transform:none}
}

/* ---- 右上角「跳过 Ns」 ----
   半透明胶囊，与各类 App 开屏一致。
   ⚠️ 必须始终可点：倒计时只是"自动关闭"的兜底，
      用户愿意等是可以的，但不想等时不能没得选。 */
.splash-skip{
  position:absolute;
  top:calc(14px + var(--safe-t));right:14px;
  z-index:3;
  display:flex;align-items:center;gap:1px;
  padding:7px 13px;
  border:0;border-radius:999px;
  background:rgba(0,0,0,.055);
  color:#333;font-size:12.5px;font-family:inherit;
  line-height:1;cursor:pointer;
  -webkit-tap-highlight-color:transparent;
}
.splash-skip:active{background:rgba(0,0,0,.11)}
.splash-skip b{font-size:13.5px;font-weight:700;font-variant-numeric:tabular-nums;min-width:9px;text-align:center}

/* ---- 中部广告位 ----
   flex:1 吃掉中间全部剩余空间，广告图 contain 居中，
   不铺满整屏：运营图比例不定，cover 会把人脸/文字裁掉。 */
.splash-mid{
  flex:1;min-height:0;
  display:flex;align-items:center;justify-content:center;
  padding:calc(58px + var(--safe-t)) 18px 18px;
  box-sizing:border-box;
}
.splash-mid.tap{cursor:pointer}
.splash-img{
  max-width:100%;max-height:100%;
  object-fit:contain;display:block;
  border-radius:12px;
  animation:splashImgIn .42s cubic-bezier(.22,1,.36,1) both;
}
@keyframes splashImgIn{
  from{opacity:0;transform:scale(.965)}
  to  {opacity:1;transform:scale(1)}
}
@media (prefers-reduced-motion:reduce){ .splash-img{animation:none} }
/* 未配置广告图时的占位：淡灰块 + 图标，不留刺眼空白 */
.splash-ph{
  width:100%;max-width:230px;height:210px;
  border-radius:14px;background:#f6f6f8;
  display:flex;align-items:center;justify-content:center;color:#d3d3d8;
}

/* ---- 底部：Logo + 站名，横向排列 ----
   用 .l-logo 是为了让 index.php 底部的字号自适应脚本接管（多字自动缩小），
   尺寸/配色在这里自己定义，不依赖 .launch .l-logo（那是登录页的）。 */
.splash-foot{
  flex:none;
  display:flex;align-items:center;justify-content:center;gap:10px;
  padding:0 20px calc(46px + var(--safe-b));
  animation:splashFootIn .5s cubic-bezier(.22,1,.36,1) both;
}
@keyframes splashFootIn{ from{opacity:0;transform:translateY(12px)} to{opacity:1;transform:none} }
@media (prefers-reduced-motion:reduce){ .splash-foot{animation:none} }
.splash-logo{
  width:46px;height:46px;flex:none;overflow:hidden;padding:0;
  box-sizing:border-box;border-radius:14px;
  background:linear-gradient(158deg,rgba(255,255,255,.62) 0%,rgba(255,255,255,0) 56%),var(--brand);
  display:flex;align-items:center;justify-content:center;
  font-weight:800;line-height:1.05;letter-spacing:0;text-align:center;
  transform:rotate(-5deg);
  box-shadow:0 8px 16px rgba(255,180,0,.28),inset 0 1px 0 rgba(255,255,255,.55);
}
.splash-name{
  font-size:17px;font-weight:800;letter-spacing:.5px;color:#1a1a1a;
}

/* ==================== 站点品牌字体（v1.8.27） ====================
 * 后台可上传一个字体文件，作用于「Logo 文字」与「社区名」。
 *
 * 为什么只给这几处、不给 body：
 *   中文字体常见 5~10MB，全站正文替换会明显拖慢首屏与渲染；
 *   而品牌感几乎全部集中在站名和 Logo 上，只换这几处收益最大、代价最小。
 *
 * 为什么写 inherit 兜底而不是列一个字体栈：
 *   这些元素原本没有显式 font-family，靠继承 body 的字体栈。
 *   若在这里写死字体栈，就等于替 body 做决定，以后调全站字体时会漏掉这几处
 *   （本项目已经因为「同样规则写两份」出过三次：--bg-2 / .hint / mc2-tag）。
 *   var(--site-font,inherit) 在未配置字体时等同于「没有这条规则」，零副作用。
 *
 * v1.8.28：改用 .l-logo 覆盖全部 Logo 方块。
 * 之前只列了启动页/登录页/关于页三处，后台与登录注册的 Logo 都不在其中，
 * 管理员设完字体看到「只有一处变了」，多半会以为功能坏了。
 * .l-logo 是 Logo 文字的专用类，套上去不会连累别的元素。
 *
 * 站名同理：启动页 .splash-name / 登录注册 .launch h1 / 关于页 .ab-nm。
 */
.l-logo,
.splash-name,
.launch h1,
.ab-nm{
  font-family:var(--site-font,inherit);
}

/* ==================== 等级中心（v1.8.12） ====================
 * 类名统一 lv- 前缀 —— 本项目多次出现「改了共用类连累别的页面」
 * （mc2-tag 被鱼塘动态卡片共用、--bg-2 前后台两套 CSS 各写一份）。
 * lv- 是全文件全新前缀；与「我的」页旧进度条 .level-bar-* 也刻意区分。
 */

/* ① 我的等级卡：品牌黄纵向渐变，白色大字 */
.lv-hero{
  background:linear-gradient(160deg,#FFE411 0%,#FFD166 100%);
  border-radius:18px;padding:20px 16px 18px;text-align:center;
  margin-bottom:16px;box-shadow:0 4px 14px rgba(255,212,102,.28);
}
.lv-ring{
  width:74px;height:74px;margin:0 auto 10px;border-radius:50%;
  background:rgba(255,255,255,.92);display:flex;flex-direction:column;
  align-items:center;justify-content:center;line-height:1;
  box-shadow:0 2px 8px rgba(160,120,0,.14);
}
.lv-ring b{font-size:11px;font-weight:700;color:#B3860B;letter-spacing:.5px}
.lv-ring i{font-size:27px;font-weight:800;font-style:normal;color:#1B1F24;margin-top:2px}
.lv-ttl{font-size:16px;font-weight:800;color:#5A4300}
/* 进度条：白底半透明轨道 + 纯白填充，在黄底上对比度足够 */
.lv-bar{height:7px;border-radius:7px;background:rgba(255,255,255,.55);overflow:hidden;margin:12px 0 7px}
.lv-bar span{display:block;height:100%;border-radius:7px;background:#fff;transition:width .45s}
.lv-bar-tx{display:flex;justify-content:space-between;font-size:11.5px;color:#6B5200;font-weight:600}
.lv-bar-sub{font-size:10.5px;color:#8A6D10;margin-top:5px}
.lv-max{font-size:12.5px;color:#6B5200;font-weight:700;margin-top:10px}

/* ② 分区标题 */
.lv-sec{margin-bottom:16px}
.lv-sec-t{display:flex;align-items:center;gap:5px;font-size:13.5px;font-weight:700;color:var(--ink);margin-bottom:8px}
.lv-card{background:#fff;border:1px solid var(--line);border-radius:15px;overflow:hidden}

/* 规则 */
.lv-formula{font-size:13px;color:var(--ink);padding:13px 14px 9px}
.lv-formula b{color:#8A6100}
.lv-note{font-size:11.5px;color:var(--gray-3);line-height:1.6;padding:0 14px 13px}
.lv-note b{color:var(--gray-1)}

/* ③ 经验获取：可点行 */
.lv-way{display:flex;align-items:center;gap:11px;padding:12px 14px;border-bottom:1px solid var(--line-2);cursor:pointer}
.lv-way.last{border-bottom:none}
.lv-way:active{background:var(--line-2)}
.lv-way-ic{width:32px;height:32px;flex:none;border-radius:10px;background:var(--brand-16);color:#8A6100;display:flex;align-items:center;justify-content:center}
.lv-way-b{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.lv-way-b b{font-size:13.5px;color:var(--ink)}
.lv-way-b span{font-size:11px;color:var(--gray-3)}

/* ④ 特权：达标绿色，未达标灰 */
.lv-perk{display:flex;align-items:center;gap:11px;padding:11px 14px;border-bottom:1px solid var(--line-2)}
.lv-perk.last{border-bottom:none}
.lv-perk-lv{
  flex:none;min-width:34px;height:24px;padding:0 7px;border-radius:7px;
  background:var(--line-2);color:var(--gray-3);font-size:11px;font-weight:700;
  display:flex;align-items:center;justify-content:center;
}
.lv-perk.on .lv-perk-lv{background:rgba(18,183,106,.12);color:var(--ok)}
.lv-perk.on .lv-perk-b b{color:var(--ink)}
.lv-perk-b{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.lv-perk-b b{font-size:13px;color:var(--gray-2)}
.lv-perk-b span{font-size:11px;color:var(--gray-4)}

/* ⑤ 等级一览 */
.lv-fold{display:flex;align-items:center;justify-content:space-between;padding:12px 14px;cursor:pointer;font-size:12.5px;color:var(--gray-2)}
.lv-fold:active{background:var(--line-2)}
.lv-fold-ar{transition:transform .22s;display:flex;color:var(--gray-3)}
.lv-fold-ar.on{transform:rotate(180deg)}
.lv-row{display:flex;align-items:center;gap:10px;padding:9px 14px;border-top:1px solid var(--line-2);font-size:12.5px}
.lv-row.cur{background:var(--brand-16)}
.lv-row-l{flex:none;min-width:36px;font-weight:700;color:var(--gray-3)}
.lv-row-l.cur{color:#8A6100}
.lv-row-t{flex:1;min-width:0;color:var(--gray-1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lv-row.cur .lv-row-t{color:var(--ink);font-weight:600}
.lv-row-n{flex:none;font-size:11px;color:var(--gray-4)}

/* ==================================================================
   v1.8.21：消息页改造
   ------------------------------------------------------------------
   ① .msg-entries —— 四宫格下方的入口列表（系统通知/创作者小助手/活动中心）
   ② .ch-tip      —— 创作者小助手页顶部说明卡
   ③ .act-*       —— 活动中心卡片

   ⚠️ 前缀统一用 me-（msg entry）/ ch-（creator helper）/ act-（activity），
      不要复用 asst-：那是奶酪小助手的（v1.8.21 已从消息页移除，但
      Assistant 模块本身还在，pg-assistant 页面也还在，CSS 不能删）。
   ================================================================== */

/* ① 入口列表 */
.msg-entries{display:flex;flex-direction:column;gap:8px;padding:0 14px 12px}
/* v1.8.22：收进白卡后 —— 去掉 gap（改发丝线）、去掉自身边框圆角 */
.msg-panel .msg-entries{gap:0;padding:0}
.msg-panel .msg-entry{
  border:none;border-radius:0;background:transparent;
  border-bottom:1px solid var(--line-2);
}
.msg-panel .msg-entry:last-child{border-bottom:none}
.msg-panel .msg-entry:active{transform:none;background:var(--line-2)}
.msg-entry{
  display:flex;align-items:center;gap:11px;
  padding:12px 14px;width:100%;
  background:#fff;border:1px solid var(--line);border-radius:16px;
  font-family:inherit;text-align:left;cursor:pointer;transition:.16s;
}
.msg-entry:active{transform:scale(.985);background:var(--line-2)}
.msg-entry .me-ic{
  width:36px;height:36px;border-radius:11px;flex:none;
  display:flex;align-items:center;justify-content:center;
}
.msg-entry .me-txt{flex:1;min-width:0}
.msg-entry .me-txt b{
  display:block;font-size:14.5px;font-weight:700;line-height:1.35;color:var(--gray-1);
}
.msg-entry .me-txt span{
  display:block;font-size:12px;color:var(--gray-3);margin-top:2px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.msg-entry .me-go{color:var(--gray-4);flex:none;display:flex}

/* ② 创作者小助手：顶部说明卡 */
.ch-tip{
  display:flex;align-items:center;gap:10px;
  margin:0 14px 12px;padding:13px 14px;
  background:linear-gradient(135deg,#FFFAEB,#FEF0C7);
  border:1px solid #FDE8B0;border-radius:16px;
}
.ch-tip .ch-tip-ic{
  width:34px;height:34px;border-radius:11px;flex:none;
  background:#F79009;color:#fff;
  display:flex;align-items:center;justify-content:center;
}
.ch-tip b{display:block;font-size:14px;font-weight:700;line-height:1.35;color:#7A4E00}
.ch-tip span{display:block;font-size:12px;color:#A56A00;margin-top:2px;line-height:1.4}

/* ③ 活动中心卡片 */
.act-list{display:flex;flex-direction:column;gap:11px;padding:0 14px 24px}
.act-card{
  display:flex;gap:12px;padding:11px;
  background:#fff;border:1px solid var(--line);border-radius:18px;
  cursor:pointer;transition:.16s;
}
.act-card:active{transform:scale(.985)}
/* 已结束的活动整体降饱和，一眼能区分 */
.act-card.over{opacity:.72}
.act-card .act-img{
  width:82px;height:82px;border-radius:14px;flex:none;
  object-fit:cover;background:var(--line-2);
}
.act-card .act-img.ph{
  display:flex;align-items:center;justify-content:center;color:var(--gray-4);
}
.act-card .act-b{flex:1;min-width:0;display:flex;flex-direction:column;gap:5px;padding:2px 0}
.act-card .act-hd{display:flex;align-items:flex-start;gap:7px}
.act-card .act-hd b{
  flex:1;min-width:0;font-size:14.5px;font-weight:700;line-height:1.35;color:var(--gray-1);
  /* 标题最多两行：活动标题普遍偏长，不截断会把卡片撑得很高 */
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.act-card .act-tag{
  flex:none;padding:2px 7px;border-radius:7px;
  background:var(--line-2);color:var(--gray-3);
  font-size:10.5px;font-weight:800;line-height:1.5;
}
.act-card .act-tag.on{background:#E3F8EE;color:#0E9F6E}
.act-card .act-tx{
  font-size:12.5px;color:var(--gray-3);line-height:1.45;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.act-card .act-ft{font-size:11.5px;color:var(--gray-4);margin-top:auto}

/* 活动卡【无链接】时不该给可点的暗示 */
.act-card[onclick]{cursor:pointer}
