/**
 * 移动端性能降温：暂停不可见层动画、降低 GPU 合成开销，不影响功能与交互。
 * 配合 html.is-mobile / html.is-low-end（index.html 注入）分级生效。
 */

/*
 * 切后台只暂停已知持续动画。禁止 html.karin-tab-hidden * 全量选择器：
 * 切回前台时会对整棵 DOM（含 ::before/::after）做样式重算，容易卡数秒。
 */
html.karin-tab-hidden :is(
  .wg-player__orb,
  .wg-player__scan,
  .wg-player__ring,
  .wg-player__disc,
  .wg-player__eq span,
  .wg-player__marquee span,
  .wg-polaroid__card--1,
  .ins-atelier-orb,
  .mdl__aurora,
  .mdl__scan,
  .mdl__frame::before,
  .mdl__cover-ring,
  .mc-room-deco__grain,
  .fr-orb,
  .fr-ticker,
  .ncm-vinyl,
  .ncm-mini-player__disc,
  .lt-vinyl__disc,
  .qq-card-voice__bar,
  .phone__snow,
  .phone__curtain,
  .wg-4x2-glass__orb,
  .wg-4x2-glass__spark,
  .splash-logo,
  .karin-auth__loader span
) {
  animation-play-state: paused !important;
}

.karin-mode-layer:not(.is-active) *,
.karin-mode-layer:not(.is-active) *::before,
.karin-mode-layer:not(.is-active) *::after {
  animation-play-state: paused !important;
}

body.karin-app-open .phone__wall,
body.karin-app-open .phone__wall *,
body.karin-app-open .desk-shell,
body.karin-app-open .desk-shell * {
  animation-play-state: paused !important;
}

[hidden] *,
[hidden] *::before,
[hidden] *::after {
  animation-play-state: paused !important;
}

/* 【sw-151】非活跃玩法层跳过绘制 —— 限定作用范围，不再命中 .phone。
 *
 * 原选择器：.karin-mode-layer:not(.is-active):not(.is-leaving)
 * 该规则写于「三模式时代」（模拟器 / 大世界 / 小手机），当时确实存在
 * 多个可互相切换的层，跳过非活跃层能省下可观的绘制开销。
 *
 * 但现在全项目**只剩一个** .karin-mode-layer，就是 #karin-phone-layer
 * （承载壁纸 + 整个桌面 + 所有 App）。这条规则于是变成一颗地雷：
 *
 *   · content-visibility: hidden 的语义是「完全跳过该元素的渲染」。
 *     一旦某个内核在视口变化（小窗放大/缩回）时判定该层「非活跃」，
 *     浏览器会直接丢弃已绘制内容 —— 表现就是用户描述的
 *     「从正常壁纸**突然闪出**一大块白」。
 *   · is-active 目前由 JS 在启动时添加且从不移除，在标准 Chromium 里
 *     确实不会命中（实测 cv=visible）；但旧内核（Via 的套壳 WebView）
 *     对 content-visibility / contain 的支持与判定时机差异很大，
 *     把它挂在整个应用的最外层是纯粹的风险敞口，换不来任何收益。
 *
 * 处理：加 :not(#karin-phone-layer) 把手机层排除在外。
 * 保留规则本体，以便日后重新引入真正的多模式层时仍然生效。 */
.karin-mode-layer:not(.is-active):not(.is-leaving):not(#karin-phone-layer) {
  content-visibility: hidden;
  contain: layout style paint;
}

/* ── 移动端：降低合成与毛玻璃开销 ── */

html.is-mobile .glass,
html.is-mobile .foot__dock.glass,
html.is-mobile .modal__card.glass {
  backdrop-filter: blur(10px) saturate(1.06) !important;
  -webkit-backdrop-filter: blur(10px) saturate(1.06) !important;
}

/* 主屏空闲：图标区毛玻璃降级为轻量 blur（sw-147 / sw-148 修正）
 *
 * 原实现把 backdrop-filter 设为 none，本意是「十余个 blur 叠加是主要发热源」。
 * 但底板颜色是 rgba(255,255,255,0.55)（--karin-icon-plate-a），失去 blur 后
 * 就变成一块 55% 白实心方块 —— 在小窗 + 深色壁纸场景下表现为
 * 「每个图标下面一个白块」，与壁纸完全脱节。
 *
 * 改为保留一层轻量 blur（6px）：
 *   · 有 blur  → 底板透出壁纸色调，白块感消失，与设计原意一致；
 *   · 6px 远低于默认 32px，合开销仍远小于原版，省电目标基本保留；
 *   · 同时把底板透明度从 0.55 降到 0.34，进一步减轻白色存在感。
 * 低端机（is-low-end）仍走下方更激进的降级策略，不受此条影响。
 *
 * 【sw-148 重要】本文件不是最终生效者！karin-desk-custom.css（第 27 行加载）
 * 与 karin-apps.css（第 35 行加载）里存在同权重、更靠后的 !important 规则，
 * 会把这里的值覆盖回去。真正的主屏图标底板样式必须同步改那两处，
 * 本文件只是同源兜底。 */

body.karin-mode-phone :is(
  .ic__box.glass,
  .foot__dock.glass
) {
  backdrop-filter: blur(6px) saturate(1.05) !important;
  -webkit-backdrop-filter: blur(6px) saturate(1.05) !important;
  background: rgba(var(--karin-icon-plate-c, 255, 255, 255), 0.34) !important;
  box-shadow:
    0 0 0 1px rgba(120, 130, 145, 0.14) inset !important;
}

html.is-mobile .wg-player:not(.has-custom-player-bg) {
  backdrop-filter: blur(12px) saturate(1.05) !important;
  -webkit-backdrop-filter: blur(12px) saturate(1.05) !important;
}

html.is-mobile .phone__snow,
html.is-mobile .phone__curtain {
  filter: none !important;
}

html.is-mobile .wg-player__grain {
  display: none !important;
}

html.is-mobile .wg-player__orb {
  filter: blur(16px) !important;
}

html.is-mobile .qq-room__head,
html.is-mobile .qq-room__foot {
  background: rgba(248, 249, 251, 0.96) !important;
  backdrop-filter: blur(8px) saturate(1.08) !important;
  -webkit-backdrop-filter: blur(8px) saturate(1.08) !important;
}

html.is-mobile :is(
  .fr-back,
  .fr-nav__bar,
  .fr-compose__veil,
  .fr-note-editor__head
) {
  backdrop-filter: blur(10px) saturate(1.08) !important;
  -webkit-backdrop-filter: blur(10px) saturate(1.08) !important;
}

html.is-mobile :is(
  .ins-atelier-rail,
  .ins-vault-topbar,
  .ncm-mini-player,
  .karin-dialog-backdrop,
  .karin-dialog-card
) {
  backdrop-filter: blur(10px) saturate(1.06) !important;
  -webkit-backdrop-filter: blur(10px) saturate(1.06) !important;
}

html.is-mobile .desk--p1,
html.is-mobile .desk--p2,
html.is-mobile .desk--p3,
html.is-mobile .qq-room__scroll,
html.is-mobile #qq-room-scroll,
html.is-mobile .ncm-scroll {
  contain: layout style;
}

/* ── 主屏空闲：关闭纯装饰无限动画 ── */

html.is-mobile body.karin-mode-phone:not(.karin-app-open) .wg-polaroid__card--1 {
  animation: none !important;
}

html.is-mobile body.karin-mode-phone:not(.karin-app-open) :is(
  .wg-player__orb,
  .wg-player__scan,
  .wg-player__ring,
  .wg-player__marquee span,
  .wg-polaroid__card--1,
  .ins-atelier-orb,
  .mdl__aurora,
  .mdl__scan,
  .mdl__frame::before,
  .mc-room-deco__grain,
  .fr-orb,
  .fr-ticker
) {
  animation: none !important;
}

/* ── 主屏分页：仅跳过距当前页 2 页以上的桌面，相邻页保持绘制以保证横滑流畅 ── */

html.is-mobile .desk-viewport[data-desk-page="0"] .desk--p3,
html.is-mobile .desk-viewport[data-desk-page="2"] .desk--p1 {
  content-visibility: hidden;
  contain: strict;
}

html.is-mobile .desk-viewport[data-desk-page="0"] .desk--p3 *,
html.is-mobile .desk-viewport[data-desk-page="2"] .desk--p1 * {
  animation-play-state: paused !important;
}

/* 移动端关闭 SVG 噪点纹理（feTurbulence 持续占 GPU） */
html.is-mobile :is(
  .p2f-board__grain,
  .wg-folio__grain,
  .wg-ledger__grain,
  .mc-room-deco__grain,
  .qq-card-xfer__grain,
  .qq-card-txtimg__grain,
  .mc-hv__deco-grain,
  .qq-journal__grain,
  .qq-card-to__grain,
  .qq-card-gift__grain,
  .qq-card-cpinv__grain
) {
  display: none !important;
}

html.is-mobile .mc-room-deco {
  opacity: 0.35;
}

html.is-mobile .fr-orb {
  filter: blur(20px);
  opacity: 0.7;
}

/* ── 低端机：进一步降级 ── */

html.is-mobile.is-low-end .wg-player__orb,
html.is-mobile.is-low-end .wg-player__scan,
html.is-mobile.is-low-end .wg-player__ring,
html.is-mobile.is-low-end .wg-player__marquee span,
html.is-mobile.is-low-end .wg-polaroid__card--1,
html.is-mobile.is-low-end .ins-atelier-orb,
html.is-mobile.is-low-end .mdl__aurora,
html.is-mobile.is-low-end .mdl__scan,
html.is-mobile.is-low-end .mdl__frame::before,
html.is-mobile.is-low-end .mc-room-deco__grain {
  animation: none !important;
}

html.is-mobile.is-low-end .glass,
html.is-mobile.is-low-end .wg-player:not(.has-custom-player-bg),
html.is-mobile.is-low-end .foot__dock.glass {
  backdrop-filter: blur(6px) saturate(1.02) !important;
  -webkit-backdrop-filter: blur(6px) saturate(1.02) !important;
}

html.is-mobile.is-low-end .qq-room__head,
html.is-mobile.is-low-end .qq-room__foot {
  background: rgba(248, 249, 251, 0.98) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

html.is-mobile.is-low-end .fr-orb {
  filter: blur(14px);
  opacity: 0.55;
}

/* ── 自定义桌面：小组件毛玻璃降级（主屏空闲） ── */

html.is-mobile body.karin-mode-phone:not(.karin-app-open) :is(
  .desk-custom__wg,
  .wg-4x2-glass,
  .wg-4x2-glass__frame,
  .wg-4x2-glass__panel,
  .desk-custom__wg--glassdeck
) {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

html.is-mobile.is-low-end body.karin-mode-phone:not(.karin-app-open) :is(
  .desk-custom__wg,
  .wg-4x2-glass__orb,
  .wg-4x2-glass__spark
) {
  filter: none !important;
  animation: none !important;
}

/* 自定义桌面：远离当前页 2 页以上跳过绘制 */
html.is-mobile .desk-custom__page[data-desk-far] {
  content-visibility: hidden;
  contain: strict;
}

html.is-mobile .desk-custom__page[data-desk-far] * {
  animation-play-state: paused !important;
}

/* 拖拽/编辑繁忙窗口：临时关闭实时 blur（DOM 属性直改，不触发重渲染） */
html[data-glass-busy="1"] :is(
  .glass,
  .foot__dock.glass,
  .desk-custom__wg,
  .wg-4x2-glass,
  .wg-4x2-glass__frame,
  .wg-4x2-glass__panel,
  .wg-player:not(.has-custom-player-bg)
) {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

html[data-glass-busy="1"] :is(
  .desk-custom__wg,
  .wg-4x2-glass__frame,
  .wg-4x2-glass__panel
) {
  background: linear-gradient(135deg,
    rgba(255, 255, 255, 0.42),
    rgba(255, 255, 255, 0.24) 55%,
    rgba(255, 255, 255, 0.32)) !important;
}

/* glass-pass：双 RAF 切换 blur 小数位，强制 WebKit/Chromium 重合成毛玻璃 */
html[data-glass-pass="1"] .glass,
html[data-glass-pass="1"] .foot__dock.glass {
  backdrop-filter: blur(10.01px) saturate(1.06) !important;
  -webkit-backdrop-filter: blur(10.01px) saturate(1.06) !important;
}

html.is-mobile[data-glass-pass="1"] .qq-room__head,
html.is-mobile[data-glass-pass="1"] .qq-room__foot {
  backdrop-filter: blur(8.01px) saturate(1.08) !important;
  -webkit-backdrop-filter: blur(8.01px) saturate(1.08) !important;
}

html.is-mobile.is-low-end[data-glass-pass="1"] .qq-room__head,
html.is-mobile.is-low-end[data-glass-pass="1"] .qq-room__foot {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

/* App 打开：壁纸瞬时隐藏，避免透明帧 bleed-through */
body.karin-app-open .phone__wall.has-custom-wall {
  opacity: 0 !important;
  transition: opacity 0s !important;
}

body.karin-app-open.karin-mode-phone .phone__wall.has-custom-wall {
  pointer-events: none;
}

/* ── P4：真机全屏与滚动 hygiene ── */

html.is-mobile,
html.is-mobile body {
  overscroll-behavior: none;
  overscroll-behavior-y: none;
}

html.is-mobile .phone {
  /* 【sw-161】height 由 var(--app-height, 100vh) 改为 100vh。
   *
   * 这条规则的特异性高于 style.css 的 .phone，所以它是移动端的**生效者**：
   *   只要这里还写着 var(--app-height)，下面那条 100vh 就会被覆盖，
   *   白块照旧 —— 所以必须同步改。
   *
   * 沿用 sw-154 的结论（min-height 优先级高于 max-height，故已删除），
   * 但把高度来源从「JS 变量」换成「纯视口单位」：
   *   变量写小 → 原来会塌 → 下方露白（探针实测白带起点 = 变量值）
   *   用 100vh → 与变量无关，永不塌。 */
  height: 100vh;
  /* 【sw-154】删掉原先的 min-height: var(--app-height, 100vh)。
   *
   *   致命点：按 CSS 规范，**min-height 的优先级高于 max-height**。
   *   实测：--app-height 被写成 844、真实视口 700 时，
   *     max-height: 100vh → 700px    （算出来了）
   *     min-height: 844px            （把结果又顶回 844）
   *   最终 .phone 实际高 = 844，max-height 形同虚设。
   *
   *   这条 min-height 是在「担心 .phone 塌缩」的年代加的，
   *   但现在 .phone 是 absolute + 四条边 0 + height:100vh，
   *   高度有确定性来源，根本不会塌缩。删掉它，max-height 才能当刹车。 */
}

/* 【sw-154】.phone 的视口硬上限 —— 刻意**不带** html.is-mobile 前缀。
 *
 *   带前缀的坏处：一旦 is-mobile 这个类没加上（UA 判定失败、
 *   或某些套壳内核 navigator 信息异常），整条规则静默失效，
 *   而它恰恰是最后一道防线。硬上限属于「无论如何都该成立」的约束，
 *   不应该有条件。
 *
 *   为什么是 100vh 而不是 100%：html 的 max-height 百分比在
 *   实测内核里无法解析成视口高度（Chrome 145 实测仍按 844 生效），
 *   而 vh 是绝对可靠的。 */
.phone {
  max-height: 100vh;
}

html.is-mobile .phone__snow,
html.is-mobile .phone__curtain,
html.is-mobile .phone__haze {
  display: none !important;
}

/* ── P2：App 内打开时进一步降 blur（移动端） ── */

html.is-mobile body.karin-app-open :is(
  .karin-dialog-backdrop,
  .karin-dialog-card,
  .ncm-mini-player,
  .ins-atelier-rail,
  .ins-vault-topbar
) {
  backdrop-filter: blur(8px) saturate(1.04) !important;
  -webkit-backdrop-filter: blur(8px) saturate(1.04) !important;
}

html.is-mobile.is-low-end body.karin-app-open :is(
  .glass,
  .foot__dock.glass,
  .karin-dialog-card,
  .ncm-mini-player
) {
  backdrop-filter: blur(4px) saturate(1.01) !important;
  -webkit-backdrop-filter: blur(4px) saturate(1.01) !important;
}

html.is-mobile.is-low-end body.karin-app-open :is(
  .qq-room__head,
  .qq-room__foot
) {
  background: rgba(248, 249, 251, 0.98) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

html.is-mobile.is-low-end #cp-ripple-canvas {
  opacity: 0.45;
}

html.is-mobile.is-low-end .karin-chat-app.is-open,
html.is-mobile.is-low-end #karin-couple-app.is-open {
  contain: layout style;
}

/* 滚动中暂时关闭毛玻璃，松手后恢复 —— 不改布局与可点区域 */
html.karin-is-scrolling :is(
  .glass,
  .qq-room__head,
  .qq-room__foot,
  .foot__dock.glass,
  .fr-back,
  .fr-nav__bar,
  .ncm-mini-player,
  .karin-dialog-backdrop,
  .karin-dialog-card
) {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

/* ── 生图等待省电（sw-194）：图片生成在途时全局限负载 ──
 *
 * 生图一挂 1~5 分钟（垫图兜底链更长），用户就停在生图界面等，
 * 这段时间里全 App 的「持续装饰动画 + 实时毛玻璃」都是白烧的
 * GPU/CPU 开销。js2/karin-image-gen.js 的 imggenBusyEnter/Leave
 * 在请求在途期间给 <html> 挂 karin-imggen-busy / data-imggen-busy，
 * 这里据此整段停掉；出图（或失败/中止）后属性摘除、立即恢复。
 *
 * 不动任何反馈型动画：生成转圈（karin-ig-test__spin、qq-card-gen-spin、
 * mm-feed-spin）、打字点、语音播放条进度等照常 —— 用户要靠它们确认
 * 「还在生成」。停的只是与等待无关的纯装饰。
 *
 * 不复用 data-glass-busy：那是桌面拖拽的繁忙窗口，两套状态各自
 * 挂/摘会互相踩；独立属性互不干扰。
 */

/* 纯装饰持续动画：与 karin-tab-hidden 同一份策展清单 */
html.karin-imggen-busy :is(
  .wg-player__orb,
  .wg-player__scan,
  .wg-player__ring,
  .wg-player__disc,
  .wg-player__eq span,
  .wg-player__marquee span,
  .wg-polaroid__card--1,
  .ins-atelier-orb,
  .mdl__aurora,
  .mdl__scan,
  .mdl__frame::before,
  .mdl__cover-ring,
  .mc-room-deco__grain,
  .fr-orb,
  .fr-ticker,
  .ncm-vinyl,
  .ncm-mini-player__disc,
  .lt-vinyl__disc,
  .qq-card-voice__bar,
  .phone__snow,
  .phone__curtain,
  .wg-4x2-glass__orb,
  .wg-4x2-glass__spark
) {
  animation-play-state: paused !important;
}

/* 实时毛玻璃：结构与 data-glass-busy 同构（桌面小组件 + 常驻玻璃件） */
html[data-imggen-busy="1"] :is(
  .glass,
  .foot__dock.glass,
  .desk-custom__wg,
  .wg-4x2-glass,
  .wg-4x2-glass__frame,
  .wg-4x2-glass__panel,
  .wg-player:not(.has-custom-player-bg)
) {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

html[data-imggen-busy="1"] :is(
  .desk-custom__wg,
  .wg-4x2-glass__frame,
  .wg-4x2-glass__panel
) {
  background: linear-gradient(135deg,
    rgba(255, 255, 255, 0.42),
    rgba(255, 255, 255, 0.24) 55%,
    rgba(255, 255, 255, 0.32)) !important;
}

/* 移动端：聊天页常驻玻璃件（thermal 上文给了它们 blur(8~10px)，这里按同权重后置规则关掉） */
html[data-imggen-busy="1"] :is(
  .qq-room__head,
  .qq-room__foot,
  .fr-back,
  .fr-nav__bar,
  .ncm-mini-player,
  .karin-dialog-backdrop,
  .karin-dialog-card,
  .ins-atelier-rail,
  .ins-vault-topbar
) {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

html.is-mobile[data-imggen-busy="1"] :is(
  .qq-room__head,
  .qq-room__foot
) {
  background: rgba(248, 249, 251, 0.98) !important;
}

/* App 内打开的弹层/迷你件：对齐 thermal 上文 (0,3,2) 的 app-open 规则权重 */
html[data-imggen-busy="1"] body.karin-app-open :is(
  .karin-dialog-backdrop,
  .karin-dialog-card,
  .ncm-mini-player,
  .ins-atelier-rail,
  .ins-vault-topbar
) {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

