/* ===================== 主题变量 =====================
   深色是默认值（抖音视频页本身就是深色底）。
   浅色由 <html theme-mode="light"> 覆盖 —— 具体用哪套
   在 <head> 那段早期脚本里决定，避免闪屏。 */
:root{
  /* 抖音真实 token（取自 creator.douyin.com 的 Semi Design 变量）
     grey-9=#252632 grey-5=#5c5d66 grey-4=#929399 grey-1=#f2f2f4 brand-5=#fe2c55 */
  --outside:#08080a;      /* 列两侧留白（桌面端列外侧留白，比页面更深） */
  /* ★★★ 暗色下【内容区底色 = 底部 nav 底色】（用户 2026-10-08 要求）。
     原来每页一个微妙不同的蓝灰（下面这几行），而 nav 是纯黑 --footer-color:#000
     → nav 比内容深，接缝处一条色差，看着"不一致"。
     现在统一成 #000，和 nav 完全同色。
     ⚠️ 这意味着暗色下「页面底色分层」没有了 —— 这是用户的明确选择，
        **别当成 bug 改回蓝灰**。层次感改由「卡片 --panel / 输入框 --field / 分隔线 --line」提供。 */
  --bg:#000;              /* 应用列底色（同 nav） */
  --main-bg:#000;         /* 默认页底（同 nav） */
  --color-message:#000;   /* 消息/聊天页底（同 nav） */
  --color-me:#000;        /* 我的页底（同 nav） */
  --color-user:#000;      /* 他人主页底（同 nav） */
  --footer-color:#000;    /* 底栏 */
  /* ★ 深色下必须和 --field2 同族（蓝黑）。
     原来 #1c1f23 = rgb(28,31,35) 是【中性绿灰】，而页面 --main-bg 是 rgb(21,23,36) 蓝黑
     → 深色下卡片/抽屉发灰、页面发蓝，「样式不一致」就是这么来的。浅色下两边都是白，看不出。 */
  --panel:rgb(28,30,43);  /* 卡片 / 抽屉 */
  --field:#252632;        /* = grey-9 */
  --field2:#33343f;       /* = grey-8 */
  --line:#2a2b33;
  --hairline:rgba(255,255,255,.07);
  --text:#fff;
  --sub:#929399;          /* = grey-4 */
  --dim:#5c5d66;          /* = grey-5 */
  --accent:#fe2c55;       /* = brand-5 ✓ */
  --mask:rgba(0,0,0,.55);
  --glow:rgba(0,0,0,.9);
  --switch:#3a3c4a;       /* 蓝黑系（原 #3a3a42 是中性灰，同上面 --panel 的问题） */
  --switchknob:#fff;
  --sugactive:#141418;
  --segsurf:#3a3c4a;      /* 分段控件滑块（同上，归到蓝黑系） */
  --segshadow:0 1px 3px rgba(0,0,0,.35);

  /* 叠在视频上的元素 —— 视频底永远是黑的，这两组不随主题变 */
  --onvideo:#fff;
  --onvideo-sub:rgba(255,255,255,.60);
  --onvideo-shadow:0 1px 4px rgba(0,0,0,.55);

  --tabbar-h:56px;        /* 抖音 --footer-height:56rem（1rem=1px） */
  /* 功能色（订单状态 / 钱包金额 / 「本地」角标）—— 浅色主题下会覆盖成更深的色 */
  --ok:#3ddc84;
  --warn:#ffb020;
  --info:#7aa2ff;
  --app-w:540px;
}

/* 浅色 —— 机制同抖音/Semi：用 [theme-mode] 属性（不是 prefers-color-scheme，抖音也不自动跟随）
   浅色 token 取自 creator.douyin.com 的 Semi 变量（--grey-*） */
[theme-mode="light"]{
  /* ★ 浅色下绿色系要加深：暗色主题用的 #3ddc84 压在白底上对比度只有 ~1.6:1。
     抖音浅色模式的功能色也是深一档（白底/深字才立得住）。 */
  --ok:#0a9950;
  --warn:#c47f00;
  --info:#3d6fd8;
  --bg:#fff;
  --main-bg:#fff;
  --color-message:#fff;
  --color-me:#fff;
  --color-user:#fff;
  --footer-color:#fff;
  --outside:#f7f8fa;
  --panel:#fff;
  --mask:rgba(0,0,0,.4);
  --glow:rgba(0,0,0,.14);
  --switch:#d8d8de;
  --switchknob:#fff;
  --sugactive:#f0f0f4;
  --segsurf:#fff;
  --segshadow:0 1px 3px rgba(0,0,0,.16);
  --field:#f2f2f4;        /* = grey-1 */
  --field2:#e4e4e6;       /* = grey-2 */
  --line:#f2f2f4;         /* = grey-1，抖音边框就是用底色 */
  --hairline:rgba(0,0,0,.06);
  --text:#252632;         /* = grey-9（抖音的主文字色，不是纯黑） */
  --sub:#5c5d66;          /* = grey-5 */
  --dim:#929399;          /* = grey-4 */
}
/* 抖音自有字体 Douyin Sans（Bold）—— 自托管，font-weight:700 时才用
   来源：creator.douyin.com 的 @font-face（真实文件，非近似） */
@font-face{
  font-family:"Douyin Sans";
  font-style:normal;
  font-weight:700;
  font-display:swap;
  src:url("DouyinSansBold.ttf") format("truetype");
}

*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;height:100%;background:var(--outside);color:var(--text);
  /* ★ 字体栈对齐抖音：它把 PingFang SC 放第一位，**没有** -apple-system。
     原来的 -apple-system 会让 iOS 用 SF Pro（不是苹方）→ 看着就是不一样。 */
  /* ★ 补上日文/韩文/西里尔字体回退（多语言需要，否则日韩字形会走中文fallback、俄文可能缺字） */
  font:14px/1.5 "Douyin Sans","PingFang SC","Hiragino Sans","Yu Gothic","Meiryo",
       "Malgun Gothic","Apple SD Gothic Neo","Noto Sans KR","Noto Sans JP",Arial,
       "Microsoft YaHei","Apple Color Emoji","Segoe UI Emoji",sans-serif;
  overscroll-behavior:none}
body{overflow:hidden;display:flex;justify-content:center;align-items:stretch}

/* ★★★ 全站不显示滚动条（用户 2026-10-08 硬要求：本站任何地方都不能有滚动条）。
   注意：**隐藏 ≠ 不能滚** —— 手指/滚轮照常滑，只是不画那条灰杠。
   用通配符兜底：`*` 特异性为 0，只会补漏，不会盖掉下面那些具体容器的规则。
   以前是逐个容器手写（.feed/.sp-body/.pf-scroll/.me-body/…），
   结果 .sub-body（观看记录/订单/钱包/离线缓存都在里面）就漏了 → 用户看到滚动条。 */
*{scrollbar-width:none;-ms-overflow-style:none}
*::-webkit-scrollbar{width:0;height:0;display:none}

.app{position:relative;width:100%;max-width:var(--app-w);
  height:100vh;height:100dvh;
  display:flex;flex-direction:column;overflow:hidden;background:var(--main-bg);
  border-left:1px solid var(--hairline);
  border-right:1px solid var(--hairline);
  box-shadow:0 0 60px var(--glow)}
.stage{position:relative;flex:1;min-height:0}
.page{position:absolute;inset:0;display:none;flex-direction:column}
.page.active{display:flex}
/* ★ 页面底色分层（同抖音）：视频页永远纯黑，其余页各用自己的 token */
#page-home{background:#000}
#page-chat{background:var(--color-message)}
#page-me{background:var(--color-me)}
#page-ext{background:var(--main-bg)}

/* ============ 底部 Tab（纯文字） ============ */
.tabbar{height:calc(var(--tabbar-h) + env(safe-area-inset-bottom));
  padding-bottom:env(safe-area-inset-bottom);
  display:flex;background:var(--footer-color);border-top:1px solid var(--line);flex:none}
.tabbar button{flex:1;background:none;border:0;color:var(--sub);
  font-size:16px;                       /* 抖音 .l-button{font-size:16rem} */
  font-family:inherit;font-weight:500;
  display:flex;align-items:center;justify-content:center;
  padding:0;cursor:pointer;position:relative;transition:color .15s}
.tabbar button.on{color:var(--text);font-weight:600}
/* ★★★ 首页是【视频页】—— 底栏永远暗色，浅色模式下也是（用户 2026-10-08 要求）。
   依据（zyronon/douyin 源码，不是我猜的）：
     · less/index.less :root 里 `--footer-color: black`（默认就是黑，且仓库没写浅色覆盖）
     · BaseFooter.vue <style>：.footer{background:var(--footer-color);color:white}
       文字固定 white，未选中 opacity:.7 / 选中 opacity:1
     · `.isWhite{background:white!important;color:#000!important}` 是**按页显式 opt-in** 的 prop，
       全仓库**只有商城页**传了 → 说明「默认黑、非视频页才转白」才是抖音的模型
   所以：底栏默认走 --footer-color（浅色=白），**首页例外，永远黑**。 */
/* 只改背景色：边框【不要】在这里单独覆盖，否则首页底栏的线和其它页不一样。
   统一走 .tabbar 的 border-top:1px solid var(--line)。 */
.app.on-home .tabbar{background:#000}
.app.on-home .tabbar button{color:#fff;opacity:.7}
.app.on-home .tabbar button.on{color:#fff;opacity:1;font-weight:600}
.app.on-home .tabbar button.on::after{background:#fff}
.tabbar button.on::after{content:"";position:absolute;bottom:6px;left:50%;
  transform:translateX(-50%);width:18px;height:2.5px;border-radius:2px;background:var(--text)}
.tabbar button .dot{position:absolute;top:6px;right:calc(50% - 26px);min-width:16px;
  height:16px;border-radius:8px;background:var(--accent);color:#fff;font-size:10px;
  line-height:16px;padding:0 4px;display:none;font-weight:400}
.tabbar button.has-dot .dot{display:block}


/* ============ 顶部频道条（横向可滑动） ============ */
/* 频道条与搜索按钮同一行（同抖音）：左边频道可滑，右边图标固定 */
/* ★ 顶部频道要【真居中】（2026-10-09 用户要求）。
   只给 .chans 加 justify-content:center 只能让它在「搜索按钮左边的剩余空间」里居中，
   会整体偏左约半个图标宽。所以左边放一个和搜索按钮【等宽的配重】，
   两边对称 → 频道文字的中心才真正落在屏幕中线。 */
.topbar{--topbar-ic:20px;                 /* 搜索图标宽 = 配重宽，一个来源 */
  position:absolute;top:0;left:0;right:0;z-index:5;
  padding:calc(env(safe-area-inset-top) + 12px) 12px 10px;
  display:flex;align-items:center;gap:10px;pointer-events:none}
.topbar-balance{flex:none;width:var(--topbar-ic)}   /* 纯配重，无内容 */
.chans{display:flex;gap:22px;pointer-events:auto;flex:1;min-width:0;
  flex-wrap:nowrap;align-items:center;
  justify-content:center;                /* ★ 居中（配合左边的 .topbar-balance 配重） */
  /* ⚠️ 现在只有 3 个频道、放得下，所以不会碰到这个已知问题：
     flex 容器 overflow:auto + justify-content:center 时，内容一旦溢出，左侧会滚不到。
     以后频道多到溢出，要把这里换回 flex-start（或改用 safe center）。 */
  overflow-x:auto;overflow-y:hidden;
  scrollbar-width:none;-webkit-overflow-scrolling:touch;
  padding:0;
  /* 左右渐隐，暗示还能滑 */
  mask-image:linear-gradient(90deg,transparent 0,#000 12px,#000 calc(100% - 8px),transparent 100%);
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 12px,#000 calc(100% - 8px),transparent 100%)}
.chans::-webkit-scrollbar{display:none}
/* 频道条叠在视频上 —— 用 on-video 色，不随主题变 */
/* ★ 关键：下划线用绝对定位，不给 span 增加高度。
   之前用 ::after{display:block;margin-top:4px} 会把「选中项」撑高，
   而 .topbar 是 align-items:center → 搜索图标被带着一起下移，
   看着就像「搜索按钮和分类不在同一排」。 */
/* ★ 上下内边距必须对称，文字才会落在盒子正中。
   之前只加 padding-bottom:7px（上 0 下 7），文字被顶高 3.5px，
   而搜索图标是按父级 align-items:center 居中的 → 图标看着就「偏下面」。
   对称内边距既能给下划线留位置，又能让文字严格居中。 */
.chans span{position:relative;flex:none;white-space:nowrap;font-size:16px;
  font-weight:600;line-height:1.2;padding:5px 0;
  color:var(--onvideo-sub);transition:color .15s,font-size .15s;
  cursor:pointer;text-shadow:var(--onvideo-shadow)}
.chans span.on{color:var(--onvideo);font-size:17.5px}
.chans span.on::after{content:"";position:absolute;left:50%;bottom:0;
  transform:translateX(-50%);height:2.5px;width:16px;
  border-radius:2px;background:var(--onvideo)}
/* 搜索按钮不再绝对定位、不再带暗色渐变（那层渐变就是看着像「另一条横条」的原因） */
.topbar .magnify{flex:none;align-self:center;pointer-events:auto;
  background:none;border:0;color:var(--onvideo);cursor:pointer;
  padding:4px 0;line-height:0;
  display:flex;align-items:center;justify-content:center;
  text-shadow:var(--onvideo-shadow)}
.topbar .magnify svg{width:var(--topbar-ic);height:var(--topbar-ic);display:block}

/* ============ 加载：中心环形 + 底部缓冲条 ============ */
/* ★【视频缓冲】也用抖音的双球 —— 原来是我们自己画的 SVG 环形 spinner。
   抖音 BaseVideo.vue 就是 `<Loading v-if="state.loading" style="position:absolute" />`
   （双球的 full 模式，居中）。这里靠 .on 控制透明度，避免频繁闪烁。 */
.loader{position:absolute;left:50%;top:50%;width:22px;height:10px;
  margin:-5px 0 0 -11px;z-index:2;opacity:0;transition:opacity .22s;
  pointer-events:none;display:flex;justify-content:space-between}
.loader.on{opacity:1}
.buf{position:absolute;left:0;right:0;bottom:0;height:2px;z-index:4;
  pointer-events:none;background:transparent}
.buf i{display:block;height:100%;width:0;
  background:rgba(255,255,255,.8);transition:width .25s linear}

/* ==================== 通用「双球」加载指示器 ====================
   严格照抖音 components/Loading.vue（1rem = 1px）：
     .circle{width:10rem;height:10rem;border-radius:50%}
     .blue{background:cadetblue; animation:anim-blue .4s ease-in-out 0s infinite alternate}
     .red {background:var(--primary-btn-color); animation:anim-red .4s ease-in-out 0s infinite alternate}
     @keyframes anim-blue{from{translate3d(0,0,0) scale(1)} to{translate3d(10rem,0,0) scale(1.2)}}
     @keyframes anim-red {from{translate3d(0,0,0) scale(1)} to{translate3d(-10rem,0,0) scale(1.2)}}
   （抖音的 --primary-btn-color = rgb(252,47,86)，我们用 --accent #fe2c55，几乎同色）

   ★ 这是抖音【全站通用】的加载指示器 —— 20+ 个页面在用，连【视频缓冲】也用
     （BaseVideo.vue: `<Loading v-if="state.loading" style="position:absolute" />`）。
     两种尺寸（按场景切换，同抖音的 is-full-screen 参数）：
       full   —— 绝对定位居中（整块内容为空、首次加载）
       inline —— 文档流内、宽 100%、高 40px、居中（加载下一批、在列表底部）

   ★ 用法：元素带 `dyloading dyloading-full|dyloading-inline`，JS 切 `.on` 控制显隐；
     动态插入的场景直接用 loadingHtml(mode)（返回带 .on 的、插入即显示）。 */
.dyc{width:10px;height:10px;border-radius:50%;display:block}
.dyc.blue{background:cadetblue;animation:dy-blue .4s ease-in-out 0s infinite alternate}
.dyc.red{background:var(--accent);animation:dy-red .4s ease-in-out 0s infinite alternate}
@keyframes dy-blue{from{transform:translate3d(0,0,0) scale(1)}
  to{transform:translate3d(10px,0,0) scale(1.2)}}
@keyframes dy-red{from{transform:translate3d(0,0,0) scale(1)}
  to{transform:translate3d(-10px,0,0) scale(1.2)}}

.dyloading{display:none;width:22px;justify-content:space-between}
.dyloading.on{display:flex}
/* ⚠️ 两个修饰类都必须带 .dyloading 前缀（(0,2,0)）——
   只写 .dyloading-inline 的话特异性 (0,1,0) 和 .dyloading 相同，
   而 .dyloading 定义在后 → 定位会被覆盖（这坑踩过一次）。 */
.dyloading.dyloading-full{position:absolute;left:50%;top:50%;z-index:9;
  transform:translate(-50%,-50%);pointer-events:none}
.dyloading.dyloading-inline{position:static;width:100%;height:40px;
  justify-content:center;align-items:center;gap:12px}


/* ============ 播放/暂停大三角 ============ */
.playmark{position:absolute;left:50%;top:50%;z-index:2;pointer-events:none;
  width:76px;height:76px;margin:-38px 0 0 -38px;opacity:0;
  transition:opacity .16s ease;filter:drop-shadow(0 3px 14px rgba(0,0,0,.45))}
.playmark.on{opacity:1}

/* ============ 横屏「全屏观看」 ============ */
.fsbtn{position:absolute;left:12px;bottom:74px;z-index:3;display:none;
  align-items:center;gap:6px;
  background:rgba(255,255,255,.16);-webkit-backdrop-filter:blur(8px);
  backdrop-filter:blur(8px);border:0;border-radius:18px;
  padding:7px 13px 7px 11px;color:var(--onvideo);font-size:12.5px;
  font-family:inherit;cursor:pointer;white-space:nowrap}
.fsbtn.on{display:inline-flex}
.fsbtn:active{background:rgba(255,255,255,.26)}
.fsbtn svg{display:block}

/* ============ 首页视频流 ============ */
.feed{flex:1;min-height:0;overflow-y:scroll;scroll-snap-type:y mandatory;
  scrollbar-width:none;-webkit-overflow-scrolling:touch}
.feed::-webkit-scrollbar{display:none}
.slide{position:relative;height:100%;scroll-snap-align:start;scroll-snap-stop:always;
  overflow:hidden;background:#000}
.slide video{width:100%;height:100%;object-fit:cover;display:block;background:#000}
.slide .shade{position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,rgba(0,0,0,.42) 0,transparent 22%,transparent 58%,rgba(0,0,0,.62) 100%)}

.side{position:absolute;right:10px;bottom:0;
  /* 抖音 .toolbar: absolute / bottom:0 / right:10rem / mb1r(10px) */
  margin-bottom:10px;
  display:flex;flex-direction:column;align-items:center;
  gap:20px;                             /* 抖音每项 mb2r = 20rem */
  color:var(--onvideo);z-index:3}
.side .ava{width:45px;height:45px;border-radius:50%;
  border:3px solid #fff;                /* 抖音 @w:45rem + border:3rem */
  object-fit:cover}
.side .act{background:none;border:0;color:var(--onvideo);font-family:inherit;cursor:pointer;
  display:flex;flex-direction:column;align-items:center;gap:3px;padding:0}
.side .act .g{line-height:1;text-shadow:0 1px 4px rgba(0,0,0,.5)}
/* 抖音图标实测 35rem；SVG 的 width/height 属性优先级低于 CSS，这里统一覆盖 */
.side .act .g svg{width:35px;height:35px}
.side .act .n{font-size:12px;color:var(--onvideo);text-shadow:var(--onvideo-shadow)}
.side .act.liked .g{color:var(--accent)}

.meta{position:absolute;left:0;bottom:0;width:70%;z-index:3;
  /* 抖音 .item-desc: absolute / bottom:0 / width:70% / ml1r+mb1r */
  margin-left:10px;margin-bottom:10px;
  /* ★ 叠在视频上，必须用「视频上的文字色」，不能继承 --text
     （浅色主题下 --text 是深灰，压在黑视频上会看不见） */
  color:var(--onvideo);
  text-shadow:var(--onvideo-shadow)}
/* 位置标签（抖音 .location：12px / padding 4px / radius 3px / bg rgba(58,58,70,.4)） */
.meta .loc{display:inline-flex;align-items:center;gap:7px;
  font-size:12px;padding:4px 5px;border-radius:3px;
  background:rgba(58,58,70,.4);margin-bottom:10px;
  color:var(--onvideo)}
.meta .loc svg{width:18px;height:18px;flex:none;opacity:.95}
.meta .loc .gang{height:8px;width:1.5px;background:rgba(255,255,255,.5)}

.meta .author{font-weight:700;font-size:18px;margin-bottom:10px;cursor:pointer;
  color:var(--onvideo)}                 /* 抖音 .name mb1r f18 fb */
.citem .cav,.citem .cnick{cursor:pointer}
.meta .desc{font-size:13.5px;line-height:1.45;max-height:3.9em;overflow:hidden;
  color:var(--onvideo)}
.meta .music{font-size:12.5px;color:var(--onvideo-sub);margin-top:7px;display:flex;
  align-items:center;gap:5px;opacity:.92}
.meta .music .mi{animation:spin 4s linear infinite;display:inline-block}
@keyframes spin{to{transform:rotate(360deg)}}

/* ============ 搜索页（整页，同抖音） ============ */
/* z-index 层级：pf/dm 44 < mmenu 46(我的右侧抽屉) < sheet 50(设置)
   < vd 52(作品详情) < csheet 56(评论) < searchpage 60(最顶)
   ★★ 【从高层的浮层里打开低层的浮层】必须先收起高层那个，否则看起来「点了没反应」。
      踩过（2026-10-08）：从作品详情页(vd 52)点作者 → openProfile 只给主页(pf 44)加 .on，
      主页在 vd 底下打开了、用户完全看不见，而 openProfile 里的 pauseAll() 又把视频停了
      → 用户报「为什么不能进主页而是暂停」。修法：openProfile 开头先收 vd。
   ★ sheet 从 30 提到 50：否则从抽屉点「系统设置」时，设置面板会被抽屉(46)压住 */
/* 整页搜索（同抖音）。用户明确要求：全局搜索就保持整页，别做成抽屉。
   只有【博主主页】那个🔍不同 —— 它走 profile 模式，搜的是这个博主自己的作品。 */
.searchpage{position:absolute;inset:0;z-index:60;background:var(--main-bg);
  color:var(--text);display:none;flex-direction:column}
.searchpage.on{display:flex}
.sp-top{display:flex;align-items:center;gap:10px;flex:none;
  height:52px;box-sizing:content-box;padding-top:env(safe-area-inset-top);
  padding-left:48px;padding-right:12px}
.sp-back{background:none;border:0;color:var(--text);font-size:22px;line-height:1;
  cursor:pointer;padding:2px 4px;font-family:inherit;flex:none}
.sp-field{flex:1;min-width:0;display:flex;align-items:center;gap:7px;
  background:var(--field);border-radius:18px;padding:8px 13px;color:var(--sub)}
.sp-field svg{flex:none;opacity:.75}
.sp-field input{flex:1;min-width:0;background:none;border:0;outline:none;
  color:var(--text);font-size:14.5px;font-family:inherit;padding:0}
.sp-field input::placeholder{color:var(--dim)}
.sp-go{background:none;border:0;color:var(--text);font-size:14.5px;font-weight:600;
  cursor:pointer;padding:4px 2px;font-family:inherit;flex:none}
.sp-body{flex:1;min-height:0;overflow-y:auto;padding:4px 0 30px;
  scrollbar-width:none;-webkit-overflow-scrolling:touch}
.sp-body::-webkit-scrollbar{display:none}
/* ★ 博主主页搜索：搜索框下面【间隔 50px】，然后是一行「搜索 XXX 发布过的作品」（居中） */
.sp-pgap{height:50px}
/* 有搜索记录时，记录块就贴着搜索框下面（.sp-cap 默认上边距 16px 太松） */
.sp-cap.hist-first{padding-top:8px}
.sug .pwho{justify-content:center}
.sug .pwho .tx{flex:none;text-align:center}
.sp-cap{display:flex;align-items:center;justify-content:space-between;
  padding:16px 16px 10px;color:var(--sub);font-size:13px}
.sp-cap .clr{background:none;border:0;color:var(--dim);font-size:13px;
  cursor:pointer;font-family:inherit;padding:2px}
.tags{display:flex;flex-wrap:wrap;gap:9px;padding:0 16px}
.tags span{background:var(--field);border-radius:15px;padding:7px 14px;font-size:13px;
  color:var(--text);cursor:pointer;max-width:100%;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.tags span:active{background:var(--field2)}
.sug{padding:0 4px}
.sug div{display:flex;align-items:center;gap:11px;padding:11px 16px;
  cursor:pointer;font-size:14.5px;color:var(--text)}
.sug div:active{background:var(--sugactive)}
.sug .rk{color:var(--dim);font-size:13.5px;width:16px;flex:none;text-align:center}
.sug .tx{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sug .tx em{color:var(--accent);font-style:normal}
.sp-empty{color:var(--dim);font-size:13px;text-align:center;padding:34px 20px}

/* ============ 搜索历史（对齐抖音 SearchPage.vue）============ */
/* 抖音是「一行一条 + 右侧 × 单独删除」，不是标签墙 */
.hist{display:flex;flex-direction:column}
.hrow{display:flex;align-items:center;gap:10px;padding:9px 16px;cursor:pointer}
.hrow:active{background:var(--sugactive)}
.hrow .ht{flex:none;display:flex;width:16px;height:16px;color:var(--dim)}
.hrow .ht svg{width:16px;height:16px}
.hrow .hx{flex:1;min-width:0;font-size:14px;color:var(--text);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.hrow .hdel{flex:none;background:none;border:0;color:var(--dim);font-size:13px;
  line-height:1;padding:4px 2px;cursor:pointer;font-family:inherit}
.hrow .hdel:active{color:var(--text)}
/* 一个按钮两态：展开全部 / 清除全部搜索记录 */
.hmore{display:flex;align-items:center;justify-content:center;
  padding:9px;font-size:13px;color:var(--dim);cursor:pointer}
.hmore:active{color:var(--text)}
/* 「换一换」（抖音 .guess .right） */
.sp-refresh{display:flex;align-items:center;gap:4px;background:none;border:0;
  color:var(--dim);font-size:13px;cursor:pointer;font-family:inherit;padding:0}
.sp-refresh svg{width:14px;height:14px}
.sp-refresh:active{color:var(--text)}

/* ============ 评论面板 ============ */
.csheet{position:absolute;inset:0;z-index:56;display:none}
.csheet.on{display:block}
/* ★ 从评论区点作者头像进主页时，把评论面板压到主页(44)之下。
   为什么不用调 z-index 顺序：作品详情页(52)要压主页、评论(56)要压作品详情页、
   主页又要压评论 —— 静态层级自相矛盾，只能动态降层。 */
.csheet.sunk{z-index:34}
.csheet .mask{position:absolute;inset:0;background:var(--mask);opacity:0;transition:opacity .22s}
.csheet.on .mask{opacity:1}
.csheet .body{position:absolute;left:0;right:0;bottom:0;height:68%;background:var(--panel);
  color:var(--text);border-radius:14px 14px 0 0;display:flex;flex-direction:column;
  transform:translateY(100%);transition:transform .26s cubic-bezier(.2,.8,.3,1)}
.csheet.on .body{transform:translateY(0)}
.csheet .hd{display:flex;align-items:center;justify-content:space-between;
  padding:13px 16px 11px;border-bottom:1px solid var(--line);flex:none}
.csheet .hd .t{font-size:14px;color:var(--sub)}
.csheet .hd .x{background:none;border:0;color:var(--sub);font-size:19px;line-height:1;
  cursor:pointer;padding:2px 6px;font-family:inherit}
.csheet .list{flex:1;min-height:0;overflow-y:auto;padding:6px 0 10px;
  scrollbar-width:none;-webkit-overflow-scrolling:touch;overscroll-behavior:contain}
.csheet .list::-webkit-scrollbar{display:none}
.citem{display:flex;gap:10px;padding:11px 16px}
.citem .cav{width:34px;height:34px;border-radius:50%;flex:none;object-fit:cover}
.citem .cmain{flex:1;min-width:0}
.citem .cnick{font-size:12.5px;color:var(--sub);margin-bottom:3px;
  display:flex;align-items:center;gap:6px}
.citem .ctag{font-size:10px;border:1px solid var(--accent);color:var(--accent);
  border-radius:3px;padding:0 4px;line-height:14px}
.citem .ctext{font-size:14.5px;line-height:1.5;word-break:break-word}
.citem .cmeta{font-size:12px;color:var(--dim);margin-top:5px}
.citem .clike{flex:none;display:flex;flex-direction:column;align-items:center;
  gap:2px;color:var(--dim);font-size:11px;background:none;border:0;
  font-family:inherit;cursor:pointer;padding:0;min-width:28px}
.citem .clike .hg{font-size:15px;line-height:1}
.citem .clike.liked{color:var(--accent)}
.csheet .ft{flex:none;display:flex;align-items:center;gap:9px;padding:9px 14px;
  padding-bottom:calc(9px + env(safe-area-inset-bottom));border-top:1px solid var(--line)}
.csheet .ft input{flex:1;min-width:0;background:var(--field);border:0;border-radius:17px;
  padding:9px 14px;color:var(--text);font-size:14px;outline:none;font-family:inherit}
.csheet .ft input::placeholder{color:var(--dim)}
.csheet .ft .send{background:none;border:0;color:var(--accent);font-size:14px;
  font-weight:600;cursor:pointer;font-family:inherit;padding:4px 2px;flex:none}
.csheet .ft .send:disabled{color:var(--dim);cursor:default}
.cempty{color:var(--dim);font-size:13.5px;text-align:center;padding:40px 20px}

/* ============ 空态（同 zyronon/douyin 的 .no-result）============
   1rem = 1px：img 高 150px、主文案 16px/上距40px、副文案 12px/上距20px */
.no-result{display:flex;flex-direction:column;align-items:center;
  padding-bottom:40px}
.no-result img{height:150px;width:auto;margin-top:150px;
  display:block;pointer-events:none;user-select:none}
.no-result .n1{margin-top:40px;font-size:16px;color:var(--text);line-height:1}
.no-result .n2{margin-top:20px;font-size:12px;color:var(--sub);
  text-align:center;line-height:1.5;padding:0 30px}
/* 黑底（视频区）里的空态：文字必须白色，配图别顶那么远 */
.no-result.on-black{width:100%}
.no-result.on-black .n1{color:#fff}
.no-result.on-black .n2{color:rgba(255,255,255,.66)}
.no-result.on-black img{margin-top:0;height:120px;opacity:.95}
.no-result .n3{margin-top:16px;font-size:13px;color:var(--accent);
  background:none;border:1px solid var(--line);border-radius:15px;
  padding:6px 16px;cursor:pointer;font-family:inherit}
/* 手机屏幕矮一点时别顶太远 */
@media (max-height:680px){
  .no-result img{margin-top:80px;height:120px}
}
.cmore{color:var(--dim);font-size:12.5px;text-align:center;padding:14px}

/* ============ 作品详情页（同抖音 VideoDetail.vue）============
   上下滑该作者的作品；顶栏浮在视频上（返回 + 搜索框） */
.vd{position:absolute;inset:0;z-index:52;background:#000;color:#fff;
  display:none;flex-direction:column}
.vd.on{display:flex}
.vd-top{position:absolute;top:0;left:0;right:0;z-index:3;
  height:52px;box-sizing:content-box;padding-top:env(safe-area-inset-top);
  padding-left:12px;padding-right:12px;
  display:flex;align-items:center;gap:10px}
.vd-top .icbtn{background:rgba(82,80,80,.5);color:#fff}
.vd-search{flex:1;min-width:0;height:32px;border-radius:16px;
  background:rgba(255,255,255,.14);display:flex;align-items:center;gap:6px;
  padding:0 12px;font-size:13px;color:rgba(255,255,255,.82);cursor:pointer}
.vd-search svg{width:15px;height:15px;flex:none;opacity:.8}
.vd-search span{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.vd-search i{width:1px;height:14px;background:rgba(255,255,255,.3);flex:none}
.vd-search b{font-weight:500;color:#fff;flex:none}
.vd-feed{flex:1;min-height:0;overflow-y:scroll;scroll-snap-type:y mandatory;
  scrollbar-width:none;-webkit-overflow-scrolling:touch}
.vd-feed::-webkit-scrollbar{display:none}

/* ★ 播放页底部评论条（同抖音 VideoDetail.vue：头像 + 提示语 + 右侧图标） */
.vd-ft{position:absolute;left:0;right:0;bottom:0;z-index:3;
  display:flex;align-items:center;gap:12px;
  padding:10px 14px calc(10px + env(safe-area-inset-bottom));
  background:linear-gradient(to top,rgba(0,0,0,.72),rgba(0,0,0,0))}
.vd-cm{flex:1;min-width:0;height:34px;border-radius:17px;cursor:pointer;
  background:rgba(255,255,255,.14);display:flex;align-items:center;gap:8px;
  padding:0 12px;font-size:13px;color:rgba(255,255,255,.72)}
.vd-cm .av{width:24px;height:24px;border-radius:50%;flex:none;object-fit:cover;
  background:rgba(255,255,255,.2)}
.vd-cm span{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.vd-ic{display:flex;align-items:center;gap:12px;flex:none}
.vd-ic .icbtn{width:20px;height:20px;padding:0;background:none;color:#fff;
  font-size:17px;line-height:1}

/* ============ 个人主页（值取自 zyronon/douyin UserPanel.vue）============
   顶栏统一规格：高 52px、左右内边距 12px、图标中心 = safe-top + 26px */
.pf{position:absolute;inset:0;z-index:44;background:var(--color-user);color:var(--text);
  display:none;flex-direction:column}
.pf.on{display:flex}

/* 浮动顶栏 —— 抖音 .float{height:52rem;padding:0 15rem;justify-content:space-between} */
/* 顶栏统一规格：高 52px，左右内边距 12px，图标垂直居中（中心 = safe-top + 26px）
   主页 / 私信 / 搜索 三处完全一致 —— 之前主页 15px、私信 10px，且垂直定位方式不同 */
.pf-hdr{position:absolute;top:0;left:0;right:0;z-index:3;
  height:52px;box-sizing:content-box;padding-top:env(safe-area-inset-top);
  padding-left:12px;padding-right:12px;
  display:flex;align-items:center;justify-content:space-between;
  transition:background .2s}
/* ★ 关键：变实之后背景切成主题色，图标颜色必须【同步】切。
   踩过：只改 background 不改 color → 亮色主题 --field=#f2f2f4，白图标压上去＝看不见
   （用户报「主页往下滚，顶部图标变白消失」）*/
.pf-hdr.solid .ic,.pf-hdr.solid .pf-update,.pf-hdr.solid .icbtn{
  background:var(--field);color:var(--text)}
/* 抖音 .icon{border-radius:50%;background:rgba(82,80,80,.5);padding:6rem;font-size:18rem} */
.pf-hdr .ic{width:18px;height:18px;padding:6px;box-sizing:content-box;border-radius:50%;
  background:rgba(82,80,80,.5);color:#fff;border:0;cursor:pointer;
  display:flex;align-items:center;justify-content:center}
.pf-hdr .ic svg{width:18px;height:18px}
/* 搜索页返回键与主页/私信严格同位置 */
.sp-top .sp-back{position:absolute;left:12px;
  top:calc(env(safe-area-inset-top) + 26px);transform:translateY(-50%)}
.pf-hdr .right{display:flex;align-items:center;gap:15px}
/* 求更新 —— 抖音 .request{font-size:12rem;height:26rem;border-radius:20rem;
     background:rgba(82,80,80,.5);padding:0 13rem 0 5rem} */
.pf-update{height:26px;border-radius:20px;background:rgba(82,80,80,.5);
  font-size:12px;color:#fff;border:0;cursor:pointer;font-family:inherit;
  display:inline-flex;align-items:center;padding:0 13px 0 5px;white-space:nowrap}
.pf-update svg{width:18px;height:18px;padding:6px;box-sizing:content-box;flex:none}
.pf-hdr .pf-update.on{color:rgba(255,255,255,.78);background:rgba(82,80,80,.35)}
.pf-hdr.solid .pf-update.on{color:var(--sub);background:var(--field)}

.pf-scroll{flex:1;min-height:0;overflow-y:auto;scrollbar-width:none;
  -webkit-overflow-scrolling:touch;overscroll-behavior:contain}
.pf-scroll::-webkit-scrollbar{display:none}

/* 封面 */
/* ★ 头部按抖音 UserPanel.vue/less 重排（实测源码值）：
   .cover{height:220rem}；.avatar-wrapper{display:flex;align-items:center;
   position:absolute;bottom:35rem;left:20rem}；.avatar{background:white;padding:2.5px;
   border-radius:50%;width:100rem;height:100rem}；.description{color:white;margin-left:15rem} */
.pf-cover{position:relative;width:100%;height:220px;overflow:hidden;flex:none}
.pf-cover>.cover{width:100%;height:100%;object-fit:cover;display:block}
.pf-cover .pf-ava-wrap{position:absolute;left:20px;bottom:35px;display:flex;align-items:center}
.pf-cover .ava{width:100px;height:100px;border-radius:50%;object-fit:cover;
  background:#fff;padding:2.5px;box-sizing:content-box;flex:none}
/* 名字 + 抖音号在头像右边，白字压在封面上（抖音 header{color:white}） */
.pf-cover .pf-desc{margin-left:15px;color:#fff;min-width:0}
.pf-cover .pf-name{color:#fff;font-size:22px}
.pf-cover .pf-name .v{background:rgba(255,255,255,.22)}
.pf-cover .pf-uid{color:rgba(255,255,255,.75);margin-top:6px}
.pf-cover .pf-uid .cp{color:rgba(255,255,255,.75)}

/* 信息卡 —— 抖音 .info{border-radius:10rem 10rem 0 0;margin-top:-20rem;padding:0 20rem} */
.pf-info{position:relative;z-index:1;background:var(--color-user);
  border-radius:10px 10px 0 0;margin-top:-20px;padding:0 20px 0}
.pf-name{font-size:22px;font-weight:700;line-height:1.3;
  display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.pf-name .v{font-size:10px;background:var(--accent);color:#fff;border-radius:3px;padding:1px 5px}
.pf-uid{font-size:12px;color:var(--sub);margin-top:6px;display:flex;align-items:center;gap:5px}
.pf-uid .cp{background:none;border:0;color:var(--sub);cursor:pointer;padding:0;
  line-height:0;display:inline-flex}
.pf-uid .cp svg{width:13px;height:13px}
/* 统计 —— 抖音 .heat{padding:15rem 0} .text{font-size:12rem;margin-right:18rem}
     .num{color:#fff;font-size:16rem;font-weight:bold;margin-right:5rem} */
.pf-heat{padding:15px 0;display:flex;align-items:center;color:var(--sub)}
.pf-heat .t{font-size:12px;margin-right:18px;display:flex;align-items:center}
.pf-heat .num{color:var(--text);font-size:16px;font-weight:700;margin-right:5px}
.pf-sig{color:var(--text);font-size:12px;white-space:pre-wrap;line-height:1.6;margin-bottom:5px}
/* 标签行 —— 抖音 .more .item{font-size:10rem;padding:2rem 5rem;border-radius:2rem} */
.pf-more{display:flex;flex-wrap:wrap;gap:5px;margin-top:10px;margin-bottom:20px}
.pf-more .item{font-size:10px;padding:2px 5px;border-radius:2px;
  background:var(--field);color:var(--sub);display:inline-flex;align-items:center;gap:2px}
.pf-more .item svg{width:10px;height:10px}

/* 按钮 —— 抖音 .my-buttons{margin:20rem;gap:6rem}；关注 height:36rem radius:4rem */
/* 两个按钮始终并排：［关注 / 已关注］［私信］
   未关注也能看到私信，点了会提示「关注后才能私信」（产品要求，非抖音原样） */
.pf-btns{margin:0 20px 20px;display:flex;align-items:center;gap:6px}
.pf-btns button{flex:1;min-width:0;height:36px;border-radius:4px;border:0;
  font-size:14px;font-family:inherit;cursor:pointer;box-sizing:border-box;
  display:flex;align-items:center;justify-content:center;gap:4px;white-space:nowrap}
.pf-btns button svg{width:14px;height:14px;flex:none}
.pf-btns .pf-main{background:var(--accent);color:#fff;font-weight:600}
.pf-btns .pf-main.on{background:var(--field);color:var(--text);font-weight:400}
.pf-btns .pf-dm{background:var(--field);color:var(--text)}

/* 作品网格 */
.pf-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:2px;padding:2px}
/* ★★★ 图片容器【一律不给兜底色】（2026-10-08 用户报「没显示封面时还是不一样的颜色」）。
   抖音全仓库核对结论：Posters 的格子只有 border、UserPanel 的封面/评论头像/聊天头像
   **全都没有 background** —— 图没出来时透出的是【页面底色】。
   我们原来逐个加了 `background:var(--field)`（#252632 灰蓝），
   在纯黑页面上就是一块块"别的颜色"。
   ⚠️ 以后新增图片容器也别加兜底色。检查器有断言锁这几条。 */
.pf-cell{position:relative;aspect-ratio:3/4;overflow:hidden;cursor:pointer}
.pf-cell img{width:100%;height:100%;object-fit:cover;display:block}
/* ★ 看过的作品：压一层暗色 + 标「刚刚看过」（用户要求） */
/* 「缓存到本地」按钮 + 本地标识 */
.pf-cachebtn{margin-left:10px;background:none;border:1px solid var(--line);
  color:var(--sub);font-size:11px;padding:2px 9px;border-radius:11px;
  cursor:pointer;font-family:inherit}
.pf-cachebtn:disabled{opacity:.6;cursor:default}
.pf-flag{color:var(--ok)}

.pf-cell .wmask{position:absolute;inset:0;background:rgba(0,0,0,.45);
  display:flex;align-items:center;justify-content:center;
  color:#fff;font-size:11.5px;font-weight:600;letter-spacing:.5px;
  text-shadow:0 1px 3px rgba(0,0,0,.7);pointer-events:none}
/* 播放量标签要压在暗色层之上，不然被一起压暗看不清 */
.pf-cell.watched .pv{z-index:1}
.pf-cell .pv{position:absolute;left:5px;bottom:4px;color:#fff;font-size:11px;
  text-shadow:0 1px 3px rgba(0,0,0,.7);display:flex;align-items:center;gap:3px}

/* 评论表情 */
.emo{font-size:1.08em;line-height:1;vertical-align:-1px}

/* 统一返回栏（抖音 BaseHeader：--common-header-height:50rem，返回键 20rem，left:10rem） */
.hdr{position:relative;flex:none;height:52px;box-sizing:content-box;
  padding-top:env(safe-area-inset-top);
  display:flex;align-items:center;justify-content:center;
  border-bottom:1px solid rgba(204,204,204,.07);background:var(--color-user);color:var(--text)}
/* 统一的图标按钮：圆形半透明底 + 18px 图标（抖音 .float .icon）
   主页 / 私信 / 搜索 三处返回键都用它，保证位置与观感一致 */
.icbtn{display:inline-flex;align-items:center;justify-content:center;flex:none;
  width:18px;height:18px;padding:6px;box-sizing:content-box;border-radius:50%;
  background:var(--field);border:0;color:var(--text);cursor:pointer;line-height:0}
/* 主页顶栏里的返回键浮在【封面照片】上 —— 照片深浅不定，只能用深底白图标；
   变实后由上面的 .solid 规则切回主题色 */
.pf-hdr .icbtn{background:rgba(82,80,80,.5);color:#fff}
.icbtn svg{width:18px;height:18px;display:block}
.hdr .back{position:absolute;left:12px;
  top:calc(env(safe-area-inset-top) + 26px);transform:translateY(-50%)}
.hdr .ttl{font-size:16px;font-weight:500}
.hdr .right{position:absolute;right:12px;
  top:calc(env(safe-area-inset-top) + 26px);transform:translateY(-50%);
  display:flex;align-items:center;gap:14px}
.hdr .right button{background:none;border:0;color:var(--text);cursor:pointer;
  padding:0;line-height:0}

/* ============ 我的：本地点赞/收藏 ============ */
/* 我的页头部（同抖音 Me.vue：头像 + 昵称 + 抖音号 + 统计一排） */
.me-ava{width:100px;height:100px;border-radius:50%;background:#000;padding:2px;flex:none;
  box-sizing:content-box;display:flex;align-items:center;justify-content:center;
  font-size:40px;color:#fff;overflow:hidden}
.me-ava img{width:100%;height:100%;border-radius:50%;object-fit:cover;display:block}
.me-nick{font-size:16px;font-weight:600;line-height:1.3;color:#fff;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.me-uid{font-size:12px;color:rgba(255,255,255,.75);margin-top:5px}
/* 统计 —— 抖音 .heat{display:flex} 三项一排，数字在标签前 */
.me-heat{padding:14px 0 2px;display:flex;align-items:center;color:var(--sub)}
.me-heat .t{font-size:12px;margin-right:18px;display:flex;align-items:center}
.me-heat .num{color:var(--text);font-size:16px;font-weight:700;margin-right:5px}
.me-tip{font-size:11.5px;color:var(--dim);margin-top:9px;line-height:1.5}
/* ★ 分段栏也【不要分隔线】。
   抖音 Me.vue 用的是 Indicator 组件：
     .indicator-ctn{background:var(--main-bg)}   ← 就是页底色，没有 border-bottom
     .tab{color:gray} / .tab.active{color:white} ← 靠文字色差表选中
   我们那条 1px var(--line) 在纯黑页面上是一条"别的颜色"的横线。
   （选中态仍有下划线 .me-segs span.on::after，那个是白色 --text，属于同族色。） */
.me-segs{display:flex;flex:none}
.me-segs span{flex:1;text-align:center;padding:11px 0;font-size:14.5px;
  color:var(--sub);cursor:pointer;position:relative}
.me-segs span.on{color:var(--text);font-weight:600}
.me-segs span.on::after{content:"";position:absolute;bottom:0;left:50%;
  transform:translateX(-50%);width:22px;height:2.5px;border-radius:2px;background:var(--text)}
/* ★ 「我的」各 Tab 顶部的锁图标说明条（同抖音每个 SlideItem 里的 .notice） */
/* ★ 说明条【不要背景色】。
   抖音 UserPanel.vue 的 .notice 只有 font-size/height/color/display —— 纯文字无背景；
   它的居中也是靠 display:flex + justify-content:center，不靠色块。
   我们原来加的 `background:var(--field)`（#252632 灰蓝）在纯黑页面上就是
   "还有其他颜色"的来源（用户 2026-10-08 报）。 */
.me-note{display:flex;align-items:center;gap:6px;padding:10px 18px;
  font-size:12.5px;color:var(--dim)}
.me-note svg{width:13px;height:13px;flex:none;opacity:.85}

.me-body{flex:1;min-height:0;overflow-y:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}
.me-body::-webkit-scrollbar{display:none}

/* 头像 + 底部「+」关注角标（同抖音） */
.avawrap{position:relative;width:45px;height:45px;display:block}
.avawrap .ava{width:45px;height:45px;display:block}
/* 抖音 .options: 18rem 圆 / background:red / bottom:-5px / 图标 14rem */
.avawrap .plus{position:absolute;bottom:-5px;left:50%;transform:translateX(-50%);
  width:18px;height:18px;border-radius:50%;background:#ff2c55;color:#fff;
  font-size:14px;line-height:17px;text-align:center;font-weight:600;cursor:pointer}

/* 私信：整页（同抖音，不是抽屉） */
.dm{position:absolute;inset:0;z-index:44;background:var(--color-message);color:var(--text);
  display:none;flex-direction:column}
.dm.on{display:flex}
.dm-top{display:flex;align-items:center;gap:8px;flex:none;
  padding:calc(env(safe-area-inset-top) + 8px) 10px 8px}
.dm-back{background:none;border:0;color:var(--text);cursor:pointer;padding:4px;
  display:flex;align-items:center;font-family:inherit;flex:none}
.dm-who{flex:1;min-width:0;text-align:center;font-size:16px;font-weight:600;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dm-more{background:none;border:0;color:var(--text);font-size:20px;line-height:1;
  cursor:pointer;padding:4px 6px;font-family:inherit;flex:none}
.dm-body{flex:1;min-height:0;overflow-y:auto;padding:16px 14px;
  scrollbar-width:none;-webkit-overflow-scrolling:touch}
.dm-body::-webkit-scrollbar{display:none}
.dm-ft{flex:none;display:flex;align-items:center;gap:9px;padding:9px 12px;
  padding-bottom:calc(9px + env(safe-area-inset-bottom));border-top:1px solid var(--line)}
.dm-ft input{flex:1;min-width:0;background:var(--field);border:0;border-radius:18px;
  padding:9px 14px;color:var(--text);font-size:14px;outline:none;font-family:inherit}
.dm-ft input::placeholder{color:var(--dim)}
.dm-ft .send{background:none;border:0;color:var(--accent);font-size:14px;
  font-weight:600;cursor:pointer;font-family:inherit;padding:4px 2px;flex:none}

/* 侧栏新增收藏按钮的高亮色 */
.side .act.collected .g{color:rgb(252,179,3)}   /* 抖音收藏选中色 */

/* ============ 聊天 tab（值取自 zyronon/douyin Message.vue）============ */
.msg-hd{flex:none;height:50px;box-sizing:content-box;
  padding:env(safe-area-inset-top) 20px 0;display:flex;align-items:center;justify-content:space-between}
.msg-hd .ic{width:24px;height:24px;background:none;border:0;color:var(--text);cursor:pointer;
  padding:0;line-height:0;display:flex;align-items:center;justify-content:center}
.msg-hd .ic svg{width:24px;height:24px}
.msg-hd .r{display:flex;gap:22px}
.msg-scroll{flex:1;min-height:0;overflow-y:auto;scrollbar-width:none;
  -webkit-overflow-scrolling:touch;padding-bottom:8px}
.msg-scroll::-webkit-scrollbar{display:none}

/* 横向好友条：.friend 宽 70rem，gap 20rem */
.msg-friends{display:flex;gap:20px;overflow-x:auto;padding:10px 10px 0;
  scrollbar-width:none}
.msg-friends::-webkit-scrollbar{display:none}
.msg-friends .f{width:70px;min-width:70px}
.msg-friends .av{position:relative;width:70px;height:70px;margin-bottom:6px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;overflow:visible}
/* 「工具」按钮例外：抖音 Message.vue 的 .avatar 就是这个背景（--second-btn-color-tran） */
.msg-friends .av.tool{background:var(--field)}
.msg-friends .av img{width:100%;height:100%;border-radius:50%;object-fit:cover}
.msg-friends .av.tool svg{width:35px;height:35px;color:var(--sub)}
/* 在线绿点：18rem 圆 + 4rem 黑边，右下角 */
.msg-friends .av.on::after{content:"";position:absolute;right:0;bottom:0;
  width:18px;height:18px;border-radius:50%;background:rgb(115,254,73);
  border:4px solid var(--color-message);box-sizing:content-box}
.msg-friends .nm{display:block;font-size:12px;color:var(--text);text-align:center;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* 消息行：头像 55rem，margin 左20右15 */
/* 长按删除的提示（聊天列表底部） */
.chat-tip{padding:16px 0 22px;text-align:center;font-size:12px;color:var(--dim)}

.msg-list{margin-top:20px}
.msg-row{display:flex;align-items:center;cursor:pointer}
.msg-row:active{background:var(--sugactive)}
.msg-row .av{margin-left:20px;margin-right:15px;width:55px;height:55px;border-radius:50%;
  flex:none;display:flex;align-items:center;justify-content:center;
  position:relative}
.msg-row .av img{width:100%;height:100%;border-radius:50%;object-fit:cover}
.msg-row .av svg{width:28px;height:28px;color:var(--sub)}
.msg-row .av.on::after{content:"";position:absolute;right:0;bottom:0;width:12px;height:12px;
  border-radius:50%;background:rgb(115,254,73);border:3px solid var(--color-message);box-sizing:content-box}
.msg-row .bd{flex:1;min-width:0;display:flex;justify-content:space-between;align-items:center;
  padding:16px 0}
.msg-row .nm{font-size:16px;color:var(--text);display:flex;align-items:center;gap:5px}
.msg-row .nm .tag{font-size:10px;background:var(--field);color:var(--sub);
  padding:2px 5px;border-radius:2px}
.msg-row .dt{color:var(--sub);font-size:14px;margin-top:4px;display:flex;align-items:center;
  gap:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.msg-row .dt .dot{width:1.5px;height:1.5px;border-radius:50%;background:var(--sub);flex:none}
.msg-row .rt{margin-right:20px;display:flex;align-items:center;gap:6px;flex:none}
.msg-row .rt svg{width:15px;height:15px;color:var(--sub)}
.msg-row .badge{min-width:18px;height:18px;border-radius:9px;background:var(--accent);
  color:#fff;font-size:11px;line-height:18px;text-align:center;padding:0 5px}

/* ==================== 编辑资料页 / 字段子页 ====================
   同抖音 EditUserInfo.vue：整页 + 从右滑入。子页 z-index 比资料页高一层。
   常驻 + transform（display:none 做不了过渡），关闭态 pointer-events:none。 */
.subpage{position:absolute;inset:0;z-index:54;background:var(--main-bg);color:var(--text);
  display:flex;flex-direction:column;transform:translateX(100%);
  pointer-events:none;transition:transform .3s ease;will-change:transform}
/* ★ 阴影【只能在 .on 时挂】！
   踩过：写在 .subpage 基类上，子页推到屏幕外（translateX(100%)）后，
   它自己的左边缘正好落在容器右缘，阴影 -8px 偏移 + 24px 模糊会【回渗】约 32px，
   .app 又是 overflow:hidden → 屏幕右侧就多出一条渐变黑边（用户一眼看到）。 */
.subpage.on{transform:translateX(0);pointer-events:auto;
  box-shadow:-8px 0 24px rgba(0,0,0,.28)}
.subpage.sub2{z-index:55}

/* ★ 子页打开时，底层页面轻微左移一点 —— 抖音的页面切换（App.vue 的 transition）
   是「整页替换 + go/back 过渡」，旧页会跟着动一下，不是干等着被盖住。
   这里只移 24%，够表达"推进"的意思，又不会把底层内容推翻。
   ⚠️ 位移量比抽屉（--mmw:80%）小得多，两者同时在场时也不会跑出画面。 */
.app.sub-open .stage,.app.sub-open .tabbar{transform:translateX(-24%)}
.sub-body{flex:1;min-height:0;overflow-y:auto;scrollbar-width:none;
  -webkit-overflow-scrolling:touch;
  padding-bottom:calc(env(safe-area-inset-bottom) + 30px)}
.sub-body::-webkit-scrollbar{display:none}
.hdr .ttl2{display:flex;flex-direction:column;align-items:center;line-height:1.25}
.hdr .ttl2 .sub{font-size:11px;color:var(--dim)}
.save-btn{background:none;border:0;font-family:inherit;font-size:15px;font-weight:600;
  cursor:pointer;padding:4px 2px;color:var(--dim)}
.save-btn.yes{color:var(--accent)}

/* 头像区：圆形头像 + 相机角标 + 「点击更换头像」 */
.ep-ava-wrap{display:flex;flex-direction:column;align-items:center;padding:26px 0 22px}
.ep-ava{position:relative;width:86px;height:86px;border-radius:50%;overflow:hidden;
  display:flex;align-items:center;justify-content:center;
  font-size:34px;color:var(--dim);cursor:pointer}
.ep-ava img{width:100%;height:100%;object-fit:cover;display:block}
.ep-cam{position:absolute;right:0;bottom:0;width:26px;height:26px;border-radius:50%;
  background:var(--accent);color:#fff;display:flex;align-items:center;justify-content:center;
  border:2px solid var(--main-bg);box-sizing:border-box}
.ep-cam svg{width:14px;height:14px}
.ep-ava-tip{font-size:12px;color:var(--dim);margin-top:9px}

/* 行：左标签 / 右当前值 / 右箭头（同抖音 .row） */
.ep-rows{padding:0 0 10px}
/* 行高对齐抖音 custom.less：.row/.li{min-height:50rem;font-size:14rem} */
.ep-row{display:flex;align-items:center;gap:12px;padding:16px 18px;cursor:pointer;
  min-height:50px;box-sizing:border-box;
  border-top:1px solid var(--line)}
.ep-row:active{background:var(--sugactive)}
.ep-row .lb{flex:none;font-size:15px}
.ep-row .vl{flex:1;min-width:0;text-align:right;color:var(--sub);font-size:14px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ep-row .vl.empty{color:var(--dim)}
.ep-row .ar{flex:none;width:13px;height:13px;color:var(--dim)}

/* 子页的输入区 */
.ei-block{padding:22px 18px 0}
.ei-note{font-size:12px;color:var(--dim);margin-bottom:9px}
.ei-input{width:100%;box-sizing:border-box;background:var(--field);border:0;border-radius:10px;
  color:var(--text);font-family:inherit;font-size:15px;padding:13px 14px;outline:none}
.ei-area{min-height:120px;resize:none;line-height:1.6}
.ei-count{text-align:right;font-size:12px;color:var(--dim);margin-top:7px}
.ei-hint{font-size:12px;color:var(--dim);margin-top:10px;line-height:1.6}
.pick-row{display:flex;align-items:center;justify-content:space-between;
  padding:16px 18px;min-height:50px;box-sizing:border-box;
  border-top:1px solid var(--line);cursor:pointer;font-size:15px}
.pick-row:active{background:var(--sugactive)}
.pick-row .ck{width:20px;height:20px;color:var(--accent);opacity:0}
.pick-row.on .ck{opacity:1}
.ei-two{display:flex;gap:10px}
.ei-two .ei-input{flex:1}

/* ==================== 推广记录 ====================
   顶部余额卡【居中】（用户要求），下面一排两个统计，再下面是记录列表。 */
.pr-card{margin:14px;padding:22px 16px;border-radius:12px;background:var(--panel);text-align:center}
.pr-cap{font-size:12px;color:var(--sub)}
.pr-bal{font-size:34px;font-weight:700;margin-top:8px;letter-spacing:.5px}
.pr-stats{display:flex;margin:0 14px;padding:16px 0;border-radius:12px;background:var(--panel)}
.pr-stats .it{flex:1;text-align:center}
.pr-stats .it+.it{border-left:1px solid var(--line)}
.pr-stats .num{font-size:19px;font-weight:700}
.pr-stats .lb{font-size:12px;color:var(--sub);margin-top:5px}
.pr-cap2{font-size:13px;color:var(--sub);padding:18px 18px 0}
.pr-row{display:flex;align-items:flex-start;gap:10px;padding:13px 18px;
  min-height:50px;box-sizing:border-box;border-bottom:1px solid var(--line)}
.pr-row .dot{flex:none;width:7px;height:7px;border-radius:50%;margin-top:6px}
.pr-row.inv .dot{background:var(--info)}
.pr-row.pay .dot{background:var(--ok)}
.pr-row .bd{flex:1;min-width:0}
.pr-row .tx{font-size:14px;line-height:1.5;word-break:break-word}
.pr-row .tx b{font-weight:600}
.pr-row .tm{font-size:12px;color:var(--dim);margin-top:4px}
.pr-row .am{flex:none;font-size:14.5px;font-weight:700;color:var(--ok);margin-top:1px}

/* ==================== 订单记录 / 钱包 / 离线缓存 ==================== */
/* 订单卡片：抖音的订单/账单是卡片式，按压有反馈（custom.less 的 .active:active） */
.od-item{background:var(--panel);border-radius:10px;padding:13px 14px;margin:10px 14px;
  transition:background .15s ease}
.od-item:active{background:var(--sugactive)}
.od-hd{display:flex;align-items:center;justify-content:space-between;gap:10px}
.od-ty{font-size:13px;font-weight:600}
.od-amt{font-size:15px;font-weight:700}
.od-ti{font-size:13px;color:var(--sub);margin-top:6px}
.od-ft{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:9px}
.od-ft .tm{font-size:12px;color:var(--dim)}
.od-st{font-size:12px;font-weight:600;padding:2px 8px;border-radius:9px}
.od-st.paid{color:var(--ok);background:rgba(61,220,132,.13)}
.od-st.wait{color:var(--warn);background:rgba(255,176,32,.14)}
.od-st.refund{color:var(--info);background:rgba(122,162,255,.14)}
.od-st.closed{color:var(--dim);background:var(--field)}
.od-pt{font-size:12px;color:var(--dim);margin-top:5px}

.wl-card{margin:14px;padding:18px 16px;border-radius:12px;background:var(--panel)}
.wl-cap{font-size:12px;color:var(--sub)}
.wl-bal{font-size:32px;font-weight:700;margin-top:6px;letter-spacing:.5px}
.wl-btn{margin-top:14px;width:100%;height:38px;border:0;border-radius:19px;
  background:var(--accent);color:#fff;font-size:15px;font-weight:600;font-family:inherit;
  cursor:pointer}
.wl-cap2{font-size:13px;color:var(--sub);padding:6px 18px 0}
.rc-row{display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:13px 18px;min-height:50px;box-sizing:border-box;
  border-bottom:1px solid var(--line)}
.rc-row .lt{min-width:0}
.rc-row .nm{font-size:14px}
.rc-row .tm{font-size:12px;color:var(--dim);margin-top:4px}
.rc-row .am{font-size:15px;font-weight:700;color:var(--ok);flex:none}

.dl-row{display:flex;align-items:center;gap:11px;padding:11px 14px;cursor:pointer}
.dl-row:active{background:var(--sugactive)}
.dl-row .cv{width:62px;height:82px;border-radius:6px;object-fit:cover;flex:none}
.dl-row .bd{flex:1;min-width:0}
.dl-row .ti{font-size:13.5px;line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;
  -webkit-box-orient:vertical;overflow:hidden}
.dl-row .sb{font-size:12px;color:var(--dim);margin-top:6px}
.dl-sum{padding:14px 18px 4px;font-size:13px;color:var(--sub)}

/* ★ 「我的」页头部按抖音 Me.less 重排（2026-10-08）：
   header{height:190rem; background-image:url(header-bg.png); color:white}
   .info{position:absolute; bottom:10rem; padding:20rem; display:flex; align-items:center; gap:15rem}
   .avatar{background:black; padding:2px; border-radius:50%; width:100rem; height:100rem}
   .name{font-size:16rem} .number{font-size:12rem}
   .detail{transform:translateY(-10rem); border-radius:14rem 14rem 0 0; padding:15rem 15rem 0} */
.me-head{position:relative;height:190px;flex:none;color:#fff;
  /* ★ 头图直接用抖音自带的那张素材（zyronon/douyin src/assets/img/header-bg.png，
     513×241），不是用户封面 —— 抖音的「我的」页就是这么干的 */
  background-image:url("/header-bg.png");background-size:cover;background-position:center}
.me-hinfo{position:absolute;left:0;right:0;bottom:10px;padding:20px;
  display:flex;align-items:center;gap:15px}
.me-hname{min-width:0}
.me-detail{position:relative;z-index:1;transform:translateY(-10px);
  background:var(--main-bg);border-radius:14px 14px 0 0;padding:15px 15px 0}

/* ============ 设置页（独立整页）============
   用户要求：从抽屉点「系统设置」→ 打开【单独的】设置界面。
   从右侧滑入（.3s ease，和「我的」右侧菜单同一观感）；
   常驻 + transform（display:none 做不了过渡），关闭态 pointer-events:none。
   z-index 50：高于「我的」抽屉(46)；低于作品详情(52)/评论(56)/搜索(60) */
.sheet{position:absolute;inset:0;z-index:50;background:var(--main-bg);color:var(--text);
  display:flex;flex-direction:column;transform:translateX(100%);
  pointer-events:none;transition:transform .3s ease;will-change:transform}
.sheet.on{transform:translateX(0);pointer-events:auto}
/* ==================== 「我的」右上角菜单：右侧滑出的抽屉 ====================
   常驻 + transform 做动画（display:none 做不了过渡）；关闭态 pointer-events:none，
   否则透明抽屉会挡住下面的点击。（尺寸与时长见下方对齐说明） */
/* ★ 整页左移（2026-10-08 用户要求，照抖音做）：
   抖音的菜单不是「面板自己滑进来」，是 SlideRowList 把整个容器
   `translate3d(-70vw, 0, 0)` —— 页面被推走、菜单跟着露出来。
   所以这里把内容区(.stage) 和底栏(.tabbar) 一起推，位移量 = 抽屉宽度，
   页面右边缘始终贴着抽屉左边缘，中间不留缝、也不会各滑各的。
   用同一个变量 --mmw 保证「页面位移」和「抽屉宽度」永远相等。
   ★ 比例可调：改下面这一行即可（页面推多少 = 抽屉多宽，一个数控制两处）。
     2026-10-08 用户反馈「推过去太少了」→ 70% 提到 80%。 */
.app{--mmw:80%}
.stage,.tabbar{transition:transform .3s ease}
.app.me-open .stage,.app.me-open .tabbar{transform:translateX(calc(-1 * var(--mmw)))}

.mmenu{position:absolute;inset:0;z-index:46;pointer-events:none}
.mmenu.on{pointer-events:auto}
.mm-mask{position:absolute;inset:0;background:var(--mask);opacity:0;transition:opacity .3s ease}
.mmenu.on .mm-mask{opacity:1}
/* ★ 对齐抖音（zyronon/douyin Me.less / SlideRowList.vue）：
   - 宽度：抖音 SlideItem 是 `width:70vw`；这里按用户实际观感调到 80%
     （用户看过效果后说「推过去太少了」）
   - 底色：抖音 .ul 用 `var(--main-bg)`（页底），不是卡片色 --panel
   - 时长：抖音 _css(slideList,"transition-duration","300ms") → 300ms（原来 240ms）
   - 列表入场：抖音 Me.less 的 .fade1 → `all 0.3s ease` + `translateY(10rem)` + opacity 0 → 0 */
.mm-pane{position:absolute;right:0;top:0;bottom:0;width:var(--mmw);
  /* ★ 抽屉要直角（用户 2026-10-08 要求：右边这个不要有圆角），
     所以这里【不写】圆角属性 —— 免得 grep 数不干净 */
  background:var(--main-bg);color:var(--text);
  padding-top:env(safe-area-inset-top);overflow-y:auto;
  transform:translateX(100%);transition:transform .3s ease;will-change:transform}
.mmenu.on .mm-pane{transform:translateX(0)}
.mm-list{padding:8px 0 24px;opacity:0;transform:translateY(10px);
  transition:opacity .3s ease,transform .3s ease}
.mmenu.on .mm-list{opacity:1;transform:translateY(0)}
.mm-row{display:flex;align-items:center;gap:12px;padding:15px 16px;cursor:pointer;font-size:15px;
  min-height:50px;box-sizing:border-box}
.mm-row:active{background:var(--sugactive)}
.mm-row .ic{flex:none;display:flex;width:20px;height:20px;color:var(--sub)}
.mm-row .ic svg{width:100%;height:100%}
.mm-row .tx{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mm-row .sb{flex:none;color:var(--dim);font-size:12.5px}
.mm-row .ar{flex:none;width:14px;height:14px;color:var(--dim)}

/* 原来的「底部弹层 + 遮罩」已删掉（整页不需要遮罩）。
   顶部栏直接用全局 .hdr（.hdr .back / .hdr .ttl 已定义）。 */
.sheet .set-body{flex:1;min-height:0;overflow-y:auto;scrollbar-width:none;
  padding-bottom:calc(env(safe-area-inset-bottom) + 30px)}
.sheet .set-body::-webkit-scrollbar{display:none}
.sheet .sec{padding:4px 0}
.sheet .sec .cap{color:var(--sub);font-size:11.5px;padding:14px 18px 5px;letter-spacing:.4px}
.rowset{display:flex;align-items:center;justify-content:space-between;gap:14px;
  padding:14px 18px;font-size:15px}
.rowset .lbl{display:flex;flex-direction:column;gap:4px;min-width:0}
.rowset .lbl .sub{color:var(--sub);font-size:12px;line-height:1.5}
/* 主题选择分段控件 */
.seg{display:flex;background:var(--field);border-radius:8px;padding:2px;
  flex:none;gap:2px}
.seg button{background:none;border:0;color:var(--sub);font-size:12px;
  font-family:inherit;padding:5px 9px;border-radius:6px;cursor:pointer;
  white-space:nowrap;transition:.15s}
.seg button.on{background:var(--segsurf);color:var(--text);font-weight:600;
  box-shadow:var(--segshadow)}

.sw{width:48px;height:28px;border-radius:14px;background:var(--switch);position:relative;
  flex:none;cursor:pointer;transition:background .2s;border:0;padding:0}
.sw::after{content:"";position:absolute;top:2px;left:2px;width:24px;height:24px;
  border-radius:50%;background:var(--switchknob);transition:transform .2s;
  box-shadow:0 1px 3px rgba(0,0,0,.35)}
.sw.on{background:#07c160}
.sw.on::after{transform:translateX(20px)}

.gear{background:none;border:0;color:var(--sub);font-size:20px;cursor:pointer;
  padding:2px 4px;line-height:1;font-family:inherit}
/* ☰ 是内联 SVG（原来是 ⚙ 字体字符），给个固定尺寸 */
.gear svg{width:22px;height:22px;display:block}

/* ============ 状态 / 占位 ============ */
/* 叠在视频流上 —— 底永远是黑的，文字固定白色 */
.hint{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;
  justify-content:center;color:var(--onvideo-sub);gap:12px;padding:30px;text-align:center;
  font-size:13.5px;line-height:1.7}
.hint .big{font-size:38px;opacity:.5}
.placeholder{flex:1;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:14px;color:var(--sub);padding:30px;text-align:center}
.placeholder .big{font-size:44px;opacity:.4}
.placeholder .t{font-size:16px;color:var(--text);font-weight:600}
.placeholder .d{font-size:13px;line-height:1.8;max-width:290px}
.placeholder .tag{font-size:11px;border:1px solid var(--line);border-radius:20px;
  padding:3px 11px;color:var(--dim)}
/* ★「我的」页顶栏（2026-10-08 用户要求）：无标题文字、背景透明、只留 ☰，
   绝对定位浮在头图上（抖音的「我的」就是这样，头图一直顶到状态栏）。 */
.me-topbar{position:absolute;left:0;right:0;top:0;z-index:3;
  display:flex;justify-content:flex-end;
  padding:calc(env(safe-area-inset-top) + 12px) 14px 0;
  background:transparent;border:0}
.me-topbar .gear{color:#fff;filter:drop-shadow(0 1px 3px rgba(0,0,0,.45))}
.me-topbar{gap:16px}                        /* 三个入口之间留 16px */

/* ==================== 语言选择面板 ====================
   同 .subpage 一样用「常驻 + transform + pointer-events」做过渡（display:none 做不了）。 */
/* ★ overflow:hidden —— 让「收起」真的不可见。
   只写 translateY(100%) 不够：容器不裁切时，挪出去的部分会画在父级之外
   （踩过：面板藏在 #page-me 里时，那条「语言 ✕」标题栏露在底栏上一直显示）。 */
.langsheet{position:absolute;inset:0;z-index:62;pointer-events:none;overflow:hidden}
.langsheet.on{pointer-events:auto}
.langsheet .mask{position:absolute;inset:0;background:var(--mask);opacity:0;transition:opacity .22s}
.langsheet.on .mask{opacity:1}
.langsheet .body{position:absolute;left:0;right:0;bottom:0;background:var(--panel);color:var(--text);
  border-radius:14px 14px 0 0;padding-bottom:env(safe-area-inset-bottom);
  transform:translateY(100%);transition:transform .24s cubic-bezier(.2,.8,.3,1);
  max-height:70%;overflow-y:auto;scrollbar-width:none}
.langsheet .body::-webkit-scrollbar{display:none}
.langsheet.on .body{transform:translateY(0)}
.langsheet .hd{display:flex;align-items:center;justify-content:space-between;
  padding:15px 18px 13px;border-bottom:1px solid var(--line)}
.langsheet .hd .t{font-size:16px;font-weight:600}
.langsheet .hd .x{background:none;border:0;color:var(--sub);font-size:20px;line-height:1;
  cursor:pointer;padding:2px 6px;font-family:inherit}
.langsheet .opt{display:flex;align-items:center;justify-content:space-between;
  padding:15px 18px;min-height:50px;box-sizing:border-box;cursor:pointer;font-size:15px;
  border-top:1px solid var(--line)}
.langsheet .opt:active{background:var(--sugactive)}
.langsheet .opt .nm{flex:1;min-width:0}
.langsheet .opt .sub{color:var(--dim);font-size:12px;margin-left:8px}
.langsheet .opt .ck{width:18px;height:18px;color:var(--accent);opacity:0;flex:none}
.langsheet .opt.on .ck{opacity:1}
.langsheet .opt.on .nm{color:var(--accent);font-weight:600}

.pagetitle{padding:calc(env(safe-area-inset-top) + 16px) 18px 12px;
  font-size:17px;font-weight:600;border-bottom:1px solid var(--line);flex:none;
  display:flex;align-items:center;justify-content:space-between}


/* ============================================================================
   AI 创作（发现 Tab）—— 2026-10-09
   约束（照既有硬规矩办）：
     · 深色 token 只走蓝黑系（用 --panel / --accent，不新造中性灰）；
     · 图片容器不给兜底色（.ai-work img / .ai-res-item img 都没有 background）；
     · 滚动只放 .ai-scroll 与 .sub-body（全站不能出滚动条）；
     · 白字只允许配 var(--accent)（审计 H 类），其余一律用 --text / --dim。
   ============================================================================ */

/* ---------- 发现页 = AI 创作中心（模型广场） ----------
   ⚠️ 浅色主题下的坑（2026-10-09 装了无头 Chrome 截图才看见，之前全是盲写）：
      · --panel 在浅色下是【纯白】→ 白卡叠白底，看不出卡片边界；
        --field 浅色 #f2f2f4 / 暗色 #252632，正好等于参考图里那种「深色小卡」，两边都立得住。
      · 白底图标按钮（.ci.txt-ico 原来是 rgba(255,255,255,.1) + 白图标）在浅色下等于隐形。
      · 占位图/emoji 一律不许用（用户：「一看就是 ai 做的」）。 */
.ai-hist-btn{position:absolute;right:10px;top:calc(env(safe-area-inset-top) + 12px);z-index:2;
  background:var(--panel);color:var(--text)}
.ai-scroll{flex:1;min-height:0;overflow-y:auto;scrollbar-width:none;
  padding:0 14px 26px;box-sizing:border-box}
.ai-scroll::-webkit-scrollbar{display:none}

/* 横幅：真实底图 + 暗色蒙版（不用纯色渐变块）。
   白字压在图上 → 底色写字面量深色，不写 var()（审计 H 类会判成亮色白底白字） */
.ai-banner{position:relative;display:flex;align-items:center;margin-top:6px;
  height:86px;border-radius:16px;overflow:hidden;background:#141026;cursor:default}
.ai-banner .bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center}
.ai-banner .sc{position:absolute;inset:0;
  background:linear-gradient(90deg,rgba(8,6,22,.88) 6%,rgba(8,6,22,.42) 58%,rgba(8,6,22,.10))}
.ai-banner .tx{position:relative;z-index:2;padding:0 16px;min-width:0}
.ai-banner .bt{font-size:16.5px;font-weight:700;line-height:1.2;color:#fff}
.ai-banner .bs{margin-top:6px;font-size:11.5px;line-height:1.4;color:rgba(255,255,255,.84);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bn-b{margin-top:16px}

.ai-plaza{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:10px}
.ai-card{position:relative;display:flex;align-items:center;gap:11px;padding:13px;
  border-radius:14px;background:var(--field);color:var(--text);cursor:pointer;
  min-height:74px;box-sizing:border-box}
.ai-card .ci{flex:none;width:44px;height:44px;border-radius:12px;object-fit:cover;display:block}
.ai-card .ci.txt-ico{display:flex;align-items:center;justify-content:center;
  background:var(--field2);color:var(--text)}
.ai-card .ci.txt-ico svg{width:22px;height:22px}
.ai-card .tx{min-width:0}
.ai-card .nm{font-size:14.5px;font-weight:600;line-height:1.25;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ai-card .ds{margin-top:5px;font-size:11.5px;line-height:1.4;color:var(--dim);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 大卡：配图铺上半、标题压下半。
   ★ background 用【配图底边那一条的实际颜色】—— 否则图片和卡片之间会露出一条色差（紫条）。
   ★ 圆角交给 .thumb 包一层，卡片本身【不能】overflow:hidden（HOT 角标要露在圆角外） */
.ai-card.big{display:block;padding:0;grid-row:span 2;overflow:visible;background:linear-gradient(180deg,#696eea,#8c77ee)}
.ai-card.big .thumb{display:block;overflow:hidden;border-radius:14px 14px 0 0;
  aspect-ratio:229 / 127}
.ai-card.big .thumb img{display:block;width:100%;height:100%;object-fit:cover;object-position:center}
.ai-card.big .tx{display:block;padding:12px 14px 14px}
.ai-card.big .nm{font-size:17.5px;white-space:normal;color:#fff}
.ai-card.big .ds{font-size:11.5px;white-space:normal;color:rgba(255,255,255,.78)}
.ai-card.wide{grid-column:1 / -1}
.ai-card.grad-a{background:linear-gradient(180deg,#696eea,#8c77ee);color:#fff}
.ai-card.grad-b{background:linear-gradient(135deg,#6a3fd8,#9a4fe0);color:#fff}
.ai-card.grad-c{background:linear-gradient(135deg,#ef8a1c,#f2b13a);color:#fff}
.ai-card.grad-b .ds,.ai-card.grad-c .ds{color:rgba(255,255,255,.86)}
.ai-bdg{position:absolute;top:-7px;right:8px;padding:1px 7px;border-radius:8px;
  background:#ff2c55;color:#fff;font-size:10px;font-weight:600;line-height:1.6}

.ai-sec{display:flex;align-items:center;justify-content:space-between;
  margin:24px 2px 10px;font-size:14px;font-weight:600;color:var(--text)}
.ai-more{padding:0;border:0;background:none;font-size:12px;color:var(--dim);cursor:pointer;font-family:inherit}
.ai-works{display:grid;grid-template-columns:repeat(4,1fr);gap:6px}
.ai-works.empty{display:block}
.ai-work{position:relative;border-radius:8px;overflow:hidden;cursor:pointer}
.ai-work img{display:block;width:100%;aspect-ratio:3 / 4;object-fit:cover}
/* 空态统一用 .no-result，但发现页这块是窄条 → 局部压掉大留白 */
.ai-works .no-result{padding-bottom:6px}
.ai-works .no-result img{margin-top:18px;height:104px}
.ai-works .no-result .n1{margin-top:18px}
.ai-note{margin:16px 2px 0;font-size:11px;line-height:1.7;color:var(--dim)}
/* 子页里的空态：默认 150px 图 + 150px 上边距在输入区下面太空，局部压一压 */
.ai-out .no-result img{margin-top:56px;height:128px}
.ai-out .no-result{padding-bottom:0}
/* ---------- AI 创作子页（5 功能共用） ---------- */
.ai-tips{display:flex;flex-wrap:wrap;gap:8px;padding:14px 16px 0}
.ai-tip{max-width:100%;padding:6px 12px;border:0;border-radius:999px;background:var(--field);
  color:var(--text);font-size:12px;line-height:1.4;cursor:pointer;font-family:inherit;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ai-input{display:block;width:calc(100% - 32px);margin:12px 16px 0;box-sizing:border-box;
  padding:12px;border:0;border-radius:10px;background:var(--field);color:var(--text);
  font-size:14px;line-height:1.6;font-family:inherit;resize:none}
.ai-input:focus{outline:none}
.ai-opts{padding:0 16px}
.ai-opt{margin-top:16px}
.ai-opt-h{margin-bottom:8px;font-size:12px;color:var(--dim)}
.ai-chips{display:flex;flex-wrap:wrap;gap:8px}
.ai-chip{padding:6px 14px;border:0;border-radius:999px;background:var(--field);
  color:var(--text);font-size:12px;cursor:pointer;font-family:inherit}
.ai-chip.on{background:var(--accent);color:#fff}
.ai-gen{display:block;width:calc(100% - 32px);margin:22px 16px 0;padding:13px;border:0;
  border-radius:10px;background:var(--accent);color:#fff;font-size:15px;font-weight:600;
  cursor:pointer;font-family:inherit}
.ai-gen:disabled{opacity:.6}
.ai-out{padding:18px 16px 28px}
.ai-res-hd{margin-bottom:10px;font-size:12px;color:var(--dim)}
.ai-res{display:grid;grid-template-columns:repeat(2,1fr);gap:8px}
.ai-res-item{position:relative;border-radius:10px;overflow:hidden;cursor:pointer}
.ai-res-item img{display:block;width:100%}
.ai-res-item .dur{right:6px;bottom:6px}
.ai-res-item .play{position:absolute;left:50%;top:50%;width:44px;height:44px;margin:-22px 0 0 -22px;
  border-radius:50%;background:rgba(0,0,0,.42);
  display:flex;align-items:center;justify-content:center;color:#fff;font-size:16px}
.ai-text-res{font-size:14px;line-height:1.85;color:var(--text);white-space:pre-wrap}
.ai-copy{margin-top:16px;padding:9px 18px;border:0;border-radius:8px;background:var(--field);
  color:var(--text);font-size:13px;cursor:pointer;font-family:inherit}

/* ============================================================================
   桌面端（宽屏）表现：应用列固定 540px 居中
   - body 已是 flex + justify-content:center，这里只保证宽度与高度行为一致
   - 窄屏（手机）不受影响：width:100% 会被 max-width 之外的规则接管
   ★ 用户 2026-10-09 要求：电脑端宽度 540
   ============================================================================ */
@media (min-width: 561px){
  .app{max-width:540px}
}
