/* ============ 像素溶解转场 ============ */
#dissolve{position:fixed;inset:0;z-index:60;pointer-events:none;display:none;}

/* ============ 桌面 ============ */
#desktop{position:fixed;inset:0;z-index:10;visibility:hidden;}
#desktop.on{visibility:visible;}
.wallpaper{position:absolute;inset:0;
  background:linear-gradient(180deg,#cdd1d8 0%,#b9bec6 34%,#9aa0a9 68%,#7f858e 100%);}
.wallpaper::after{content:'';position:absolute;inset:0;
  background:radial-gradient(90% 60% at 30% 20%, rgba(255,255,255,.35), transparent 60%),
             radial-gradient(70% 50% at 80% 85%, rgba(0,0,0,.18), transparent 65%);
  animation:wallLight 14s ease-in-out infinite alternate;}
#wall-fx{position:absolute;inset:0;width:100%;height:100%;}
@keyframes wallLight{from{opacity:.75;transform:translateX(-1.5%)}to{opacity:1;transform:translateX(1.5%)}}

/* ---- 菜单栏 ---- */
#menubar{position:absolute;top:0;left:0;right:0;height:30px;z-index:300;
  background:rgba(10,10,12,.92);backdrop-filter:blur(16px);
  display:flex;align-items:center;padding:0 12px;gap:2px;color:#fff;font-size:13px;}
#menubar .mb-logo{width:17px;height:17px;margin:0 8px 0 4px;object-fit:contain;border-radius:4px;}
#menubar .mb-item{padding:3px 10px;border-radius:5px;cursor:default;font-weight:400;white-space:nowrap;}
#menubar .mb-item.bold{font-weight:700;}
/* 版本号跟在品牌名后面，弱化处理：不加粗、降透明度，不抢品牌名的视觉重量 */
#menubar .mb-item.bold .mb-version{margin-left:6px;font-weight:400;font-size:11.5px;color:rgba(255,255,255,.45);}
#menubar .mb-item:hover,#menubar .mb-item.open{background:rgba(255,255,255,.18);}
/* 在线客服菜单项前的状态点：绿=有客服在线，灰=离线或状态未知 */
#menubar .mb-item-support,#lg-menubar .mb-item-support{display:inline-flex;align-items:center;gap:6px;}
/* 两条规则权重必须一致，否则离线态会被在线态覆盖 */
#menubar .mb-support-dot,#lg-menubar .mb-support-dot{
  flex:none;width:6px;height:6px;border-radius:50%;
  background:#8a929c;box-shadow:0 0 0 1px rgba(255,255,255,.14);
  transition:background .2s,box-shadow .2s;
}
#menubar .mb-support-dot[data-online="1"],#lg-menubar .mb-support-dot[data-online="1"]{
  background:#47b04b;
  /* 在线时加一圈柔光，弱光环境下也能一眼看出 */
  box-shadow:0 0 0 1px rgba(255,255,255,.14),0 0 6px rgba(71,176,75,.85);
}
#menubar .mb-right{margin-left:auto;display:flex;align-items:center;gap:14px;font-size:12.5px;}
#menubar .mb-right svg{display:block;opacity:.9}

/* 顶部会员状态：放在用户图标左侧，点击进入购买/续费窗口。 */
/* 到期时间移入下拉面板后徽章只剩一个标签，宽度回到 230px 即够用，
   不再占掉菜单栏右侧空间。 */
#menubar .mb-membership{
  flex:none;height:22px;max-width:230px;padding:0 7px;
  display:flex;align-items:center;gap:5px;
  border:1px solid transparent;border-radius:6px;
  background:transparent;color:rgba(255,255,255,.88);
  font:500 11.5px/1 inherit;white-space:nowrap;cursor:pointer;
  transition:background .15s,border-color .15s,color .15s;
}
#menubar .mb-membership:hover{
  background:rgba(255,255,255,.14);border-color:rgba(255,255,255,.08);color:#fff;
}

#menubar .mb-membership:focus{outline:none;}
#menubar .mb-membership:focus-visible{outline:2px solid rgba(255,255,255,.55);outline-offset:1px;}
/* 头像图标与文字同属一个按钮，整体点击、整体高亮。
   .mb-right 的 svg 全局 opacity 会让图标偏灰，这里恢复为跟随文字颜色。 */
/* 整个小人图标按会员状态上色，图标本身即状态指示，不再额外挂圆点。
   SVG 用 stroke="currentColor"，所以只需改这里的 color。 */
#menubar .mb-membership .mb-membership-avatar{
  flex:none;display:block;opacity:1;
  color:#8a929c;stroke:#8a929c;
  transition:color .15s,stroke .15s;
}
#menubar .mb-membership-level{font-weight:400;}
/* 徽章展开时与其他菜单项一致地高亮 */
#menubar .mb-membership.open{background:rgba(255,255,255,.14);border-color:rgba(255,255,255,.08);}
/* 小人颜色代表会员状态，与卡片角标同色便于分辨。
   各状态选择器权重相同，靠书写顺序决定优先级：
   未开通（橙）写在前，具体等级写在后，避免橙色反向覆盖蓝/绿/红。 */
#menubar .mb-membership[data-state="guest"] .mb-membership-avatar,
#menubar .mb-membership[data-state="none"] .mb-membership-avatar{color:#f0b84b;stroke:#f0b84b;}
/* 只有一种会员，advanced 是停售前的历史等级值，与 super 同色同权限。
   绿色不再表示「更高等级」，只是会员生效的统一标识。 */
#menubar .mb-membership[data-state="advanced"] .mb-membership-avatar,
#menubar .mb-membership[data-state="super"] .mb-membership-avatar{color:#7cf01b;stroke:#7cf01b;}
#menubar .mb-membership[data-state="advanced"] .mb-membership-level,
#menubar .mb-membership[data-state="super"] .mb-membership-level{color:#7cf01b;}
/* 只有游戏会员生效时用 Steam 蓝，与修改器会员的绿区分开。
   漏了这条会让已付费的游戏会员用户看到灰色图标，像是没开通。 */
#menubar .mb-membership[data-state="game"] .mb-membership-avatar{color:#66c0f4;stroke:#66c0f4;}
#menubar .mb-membership[data-state="game"] .mb-membership-level{color:#66c0f4;}
#menubar .mb-membership[data-state="expired"] .mb-membership-avatar{color:#e46a6a;stroke:#e46a6a;}
#menubar .mb-membership[data-state="expired"] .mb-membership-level{color:#e46a6a;}

/* ---- 自绘标题栏 ---- */
/* 客户端为无边框窗口，菜单栏兼任标题栏。拖动时不应选中文字。 */
html[data-frameless="1"] #menubar{-webkit-user-select:none;user-select:none;}
/* 按登录界面小窗口复用 Apple 交通灯：12px 圆点，默认暗灰，悬停显示红/黄/绿 */
#menubar .mb-winctl,#lg-menubar .mb-winctl{display:flex;align-items:center;align-self:center;gap:8px;margin:0 0 0 4px;padding:0 2px;}
#menubar .mb-winctl[hidden],#lg-menubar .mb-winctl[hidden]{display:none;}
#menubar .mb-wc.circle,#lg-menubar .mb-wc.circle{flex:none;width:12px;height:12px;min-width:12px;padding:0;border:none;border-radius:50%;
  background:rgba(255,255,255,.16);color:transparent;cursor:pointer;box-sizing:border-box;
  transition:background .12s,filter .12s,transform .12s;}
#menubar .mb-wc.circle:hover,#lg-menubar .mb-wc.circle:hover{transform:scale(1.04);}
#menubar .mb-winctl:hover .mb-wc.circle.red,#lg-menubar .mb-winctl:hover .mb-wc.circle.red{background:#ff5f57;}
#menubar .mb-winctl:hover .mb-wc.circle.yellow,#lg-menubar .mb-winctl:hover .mb-wc.circle.yellow{background:#febc2e;}
#menubar .mb-winctl:hover .mb-wc.circle.green,#lg-menubar .mb-winctl:hover .mb-wc.circle.green{background:#28c840;}
#menubar .mb-wc.circle:active,#lg-menubar .mb-wc.circle:active{filter:brightness(.88);transform:scale(.94);}
#menubar .mb-wc.circle:focus,#lg-menubar .mb-wc.circle:focus{outline:none;}
#menubar .mb-wc.circle:focus-visible,#lg-menubar .mb-wc.circle:focus-visible{outline:2px solid rgba(255,255,255,.5);outline-offset:3px;}

/* 缩放热区：decorations:false 后系统 resize 边框消失，只能自绘。
   z-index 高于窗口层（.window 是 100+），否则贴边的应用窗口会挡住热区。 */
.win-resize-zones{position:fixed;inset:0;z-index:9000;pointer-events:none;}
.win-resize-zones[hidden]{display:none;}
.win-resize-zones .wrz{position:absolute;pointer-events:auto;}
/* 最大化时拖边缘缩放无意义，且会与屏幕边缘冲突，直接禁用 */
html[data-maximized="1"] .win-resize-zones{display:none;}
.wrz-n{top:0;left:6px;right:6px;height:4px;cursor:n-resize;}
.wrz-s{bottom:0;left:6px;right:6px;height:4px;cursor:s-resize;}
.wrz-e{right:0;top:6px;bottom:6px;width:4px;cursor:e-resize;}
.wrz-w{left:0;top:6px;bottom:6px;width:4px;cursor:w-resize;}
.wrz-ne{top:0;right:0;width:8px;height:8px;cursor:ne-resize;}
.wrz-nw{top:0;left:0;width:8px;height:8px;cursor:nw-resize;}
.wrz-se{bottom:0;right:0;width:8px;height:8px;cursor:se-resize;}
.wrz-sw{bottom:0;left:0;width:8px;height:8px;cursor:sw-resize;}

/* 全局运行指示器：播放图标 + 游戏名，点击回到该修改器。任何窗口下均可见 */
.mb-running{display:flex;align-items:center;gap:6px;max-width:220px;height:20px;padding:0;
  border:none;background:transparent;
  font:500 12.5px/1 inherit;cursor:pointer;}
/* display:flex 会覆盖 HTML 的 hidden 属性，需显式声明 */
.mb-running[hidden]{display:none;}
/* 三角保持绿色表示运行中，游戏名用白色与菜单栏其他文字一致 */
.mb-running svg{flex:none;display:block;color:#47b04b;transition:color .15s;}
.mb-running:hover svg{color:#5fcc63;}
.mb-running-name{color:#fff;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.mb-running:focus{outline:none;}
.mb-running:focus-visible .mb-running-name{text-decoration:underline;}

/* ---- 界面音效：菜单栏图标 + 弹出面板 ---- */
#menubar .mb-sound{
  flex:none;width:28px;height:24px;padding:0;
  display:flex;align-items:center;justify-content:center;
  border:none;border-radius:6px;background:transparent;
  color:rgba(255,255,255,.9);cursor:pointer;
  transition:background .15s,color .15s;
}
#menubar .mb-sound:hover{background:rgba(255,255,255,.14);color:#fff;}
#menubar .mb-sound[aria-expanded="true"]{background:rgba(255,255,255,.18);color:#fff;}
/* 静音时压暗，一眼能看出当前没有声音 */
#menubar .mb-sound[data-level="muted"]{color:rgba(255,255,255,.5);}
#menubar .mb-sound:focus{outline:none;}
#menubar .mb-sound:focus-visible{outline:2px solid rgba(255,255,255,.55);outline-offset:1px;}
#menubar .mb-sound svg{display:block;opacity:1;}

/* 面板复用 .menu-drop 的浅色毛玻璃规格，位置由 JS 按图标计算 */
.mb-sound-panel{
  position:absolute;top:32px;z-index:400;width:210px;padding:10px 12px 11px;
  background:rgba(242,242,246,.9);color:#1d1d1f;
  border:1px solid rgba(0,0,0,.12);border-radius:10px;
  box-shadow:0 12px 34px rgba(0,0,0,.25);
  backdrop-filter:blur(24px) saturate(1.4);-webkit-backdrop-filter:blur(24px) saturate(1.4);
  display:none;
}
.mb-sound-panel.on{display:block;animation:dropIn .16s ease-out;}
.mb-sound-panel[hidden]{display:none;}
.mb-sound-head{display:flex;align-items:center;justify-content:space-between;gap:10px;}
.mb-sound-title{font-size:12.5px;font-weight:600;}
.mb-sound-switch{
  flex:none;width:34px;height:18px;padding:2px;
  display:flex;align-items:center;
  border:1px solid rgba(0,0,0,.16);border-radius:9px;
  background:rgba(0,0,0,.12);cursor:pointer;
  transition:background .15s,border-color .15s,justify-content .15s;
}
.mb-sound-switch.on{justify-content:flex-end;background:var(--blue);border-color:var(--blue);}
.mb-sound-nob{width:12px;height:12px;border-radius:50%;background:#8a8f96;transition:background .15s;}
.mb-sound-switch.on .mb-sound-nob{background:#fff;}
.mb-sound-switch:focus{outline:none;}
.mb-sound-switch:focus-visible{outline:2px solid var(--blue);outline-offset:2px;}
.mb-sound-row{margin-top:10px;display:flex;align-items:center;gap:9px;}
/* 自绘轨道与滑块：浏览器默认的 range 在滑块上带一圈描边，这里全部重置 */
.mb-sound-slider{
  flex:1;min-width:0;height:14px;margin:0;
  -webkit-appearance:none;appearance:none;
  background:transparent;cursor:pointer;
}
.mb-sound-slider:focus{outline:none;}
.mb-sound-slider:focus-visible{outline:2px solid var(--blue);outline-offset:3px;border-radius:8px;}
/* Chrome 无 range-progress，已填充部分用 JS 写入的 --mb-sound-fill 做渐变 */
.mb-sound-slider::-webkit-slider-runnable-track{
  height:4px;border:none;border-radius:2px;
  background:linear-gradient(to right,
    var(--blue) 0%,var(--blue) var(--mb-sound-fill,100%),
    rgba(0,0,0,.16) var(--mb-sound-fill,100%),rgba(0,0,0,.16) 100%);
}
.mb-sound-slider::-moz-range-track{
  height:4px;border:none;border-radius:2px;background:rgba(0,0,0,.16);
}
.mb-sound-slider::-moz-range-progress{height:4px;border-radius:2px;background:var(--blue);}
.mb-sound-slider::-webkit-slider-thumb{
  -webkit-appearance:none;appearance:none;
  width:14px;height:14px;margin-top:-5px;
  border:none;border-radius:50%;background:var(--blue);
  box-shadow:0 1px 3px rgba(0,0,0,.3);
}
.mb-sound-slider::-moz-range-thumb{
  width:14px;height:14px;
  border:none;border-radius:50%;background:var(--blue);
  box-shadow:0 1px 3px rgba(0,0,0,.3);
}
.mb-sound-slider:disabled{cursor:not-allowed;}
.mb-sound-slider:disabled::-webkit-slider-runnable-track{
  background:linear-gradient(to right,
    #a8adb4 0%,#a8adb4 var(--mb-sound-fill,100%),
    rgba(0,0,0,.12) var(--mb-sound-fill,100%),rgba(0,0,0,.12) 100%);
}
.mb-sound-slider:disabled::-webkit-slider-thumb{background:#a8adb4;box-shadow:none;}
.mb-sound-slider:disabled::-moz-range-thumb{background:#a8adb4;box-shadow:none;}
.mb-sound-slider:disabled::-moz-range-progress{background:#a8adb4;}
/* 百分比用等宽数字，拖动时宽度不跳动 */
.mb-sound-value{
  flex:none;min-width:34px;text-align:right;
  font-size:11.5px;color:rgba(0,0,0,.5);font-variant-numeric:tabular-nums;
}

.menu-drop{position:absolute;top:32px;min-width:200px;background:rgba(242,242,246,.82);
  backdrop-filter:blur(24px) saturate(1.4);-webkit-backdrop-filter:blur(24px) saturate(1.4);
  border:1px solid rgba(0,0,0,.12);border-radius:10px;
  box-shadow:0 12px 34px rgba(0,0,0,.25);
  padding:5px;z-index:400;display:none;
  /* 面板从 top:32px 展开，留 40px 余量避免贴到窗口底边。
     内容多的面板（如「购买」有 4 段说明）在小窗口下会超出可视区，
     没有这个约束时底部内容完全够不着。 */
  max-height:calc(100vh - 72px);overflow-y:auto;
  animation:dropIn .16s ease-out;}
@keyframes dropIn{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}
.menu-drop.on{display:block;}
.menu-drop .mi{padding:6px 12px;border-radius:6px;color:#1d1d1f;font-size:13px;cursor:default;}
.menu-drop .mi:hover{background:var(--blue);color:#fff;}
.menu-drop .sep{height:1px;margin:5px 8px;background:rgba(0,0,0,.12);}
/* 带图标的菜单项：图标 + 文字 + 右侧箭头，明确传达“这一行可点击” */
.menu-drop .mi-action{display:flex;align-items:center;gap:8px;cursor:pointer;}
.menu-drop .mi-action .mi-icon{flex:none;color:var(--blue);}
.menu-drop .mi-action .mi-arrow{flex:none;margin-left:auto;opacity:.45;}
.menu-drop .mi-action:hover .mi-icon,
.menu-drop .mi-action:hover .mi-arrow{color:#fff;opacity:1;}
/* 菜单内的纯说明文字：不可点击、不参与 .mi 的悬停高亮与命令绑定。
   写成短要点而不是整段长句：菜单是扫读场景，句子一长就没人看。
   宽度给足让每条尽量单行，行内不折行才扫得快。 */
.menu-drop .mi-note{padding:2px 12px 6px;width:max-content;max-width:320px;
  color:#6e6e73;font-size:11.5px;line-height:1.45;
  cursor:default;pointer-events:none;white-space:normal;}
.menu-drop .mi-note ul{list-style:none;margin:0;padding:0;
  display:flex;flex-direction:column;gap:4px;}
/* 不加项目符号：菜单本身已经是列表语境，再加圆点只是视觉噪音 */
.menu-drop .mi-note li{padding:0;}
/* 关键信息（时间限制、版本名、依赖项）加重，扫一眼就能抓到 */
.menu-drop .mi-note b{color:#1d1d1f;font-weight:600;}
/* 蓝标 / 绿标沿用修改器来源配色（蓝 #38b6ff / 绿 #7cf01b），与购买卡片角标、
   Steam 列表圆点保持同一套色。菜单是浅底，原色直接上去对比度不足，
   这里按同色相压暗取值，保证可读又不引入新色系。 */
.menu-drop .mi-note .tag-blue{color:#0a84c8;font-weight:600;}
.menu-drop .mi-note .tag-green{color:#4f9c0a;font-weight:600;}
/* 小节标题：并列两种商品后，下面的说明必须标明归属哪一个，
   否则蓝绿标那段紧跟在会员列表下面，会被当成在讲两种会员的关系。
   字号比正文更小、加字距，做成弱化的分类标签而不是抢眼的标题。 */
.menu-drop .mi-note-title{padding:6px 12px 2px;
  color:#8e8e93;font-size:10.5px;font-weight:600;letter-spacing:.04em;
  cursor:default;pointer-events:none;}
/* 会员面板：右对齐定位（见 menu-bar.js 的 positionMenu），最小宽度保证
   「修改器会员 —— 至 2026-01-01」这类两列不折行 */
.menu-drop.menu-drop-right{min-width:212px;}
/* 名称与到期时间两端对齐，比堆在一行更易扫读 */
.menu-drop .mb-mship-row{display:flex;align-items:center;justify-content:space-between;gap:14px;}
.menu-drop .mb-mship-name{color:#1d1d1f;font-weight:600;}
/* 到期时间按状态上色：生效绿、过期红、未开通保持弱化灰，
   让用户一眼看出哪个需要续费 */
.menu-drop .mb-mship-val{font-variant-numeric:tabular-nums;}
.menu-drop .mb-mship-val[data-status="active"]{color:#2f8c1f;font-weight:600;}
.menu-drop .mb-mship-val[data-status="expired"]{color:#c8452f;font-weight:600;}
.menu-drop .mb-mship-val[data-status="none"]{color:#8e8e93;}
#context-menu{position:fixed;display:none;min-width:210px;max-width:280px;padding:5px;z-index:10000;
  background:rgba(242,242,246,.88);color:#1d1d1f;border:1px solid rgba(0,0,0,.14);border-radius:10px;
  box-shadow:0 16px 42px rgba(0,0,0,.32);backdrop-filter:blur(26px) saturate(1.45);-webkit-backdrop-filter:blur(26px) saturate(1.45);}
#context-menu.on{display:block;animation:dropIn .12s ease-out}
.ctx-item{display:flex;align-items:center;gap:18px;min-height:28px;padding:4px 10px;border-radius:6px;font-size:13px;cursor:default;white-space:nowrap}
.ctx-item .ctx-key{margin-left:auto;color:rgba(0,0,0,.42);font-size:11px}.ctx-item:hover{background:var(--blue);color:#fff}.ctx-item:hover .ctx-key{color:rgba(255,255,255,.75)}
.ctx-item.disabled{opacity:.4;pointer-events:none}.ctx-sep{height:1px;margin:5px 7px;background:rgba(0,0,0,.13)}

/* ---- 桌面图标 ---- */
.desk-icons{position:absolute;top:52px;left:18px;bottom:110px;z-index:20;
  display:flex;flex-direction:column;flex-wrap:wrap;align-content:flex-start;gap:6px 14px;}
.dicon{width:78px;display:flex;flex-direction:column;align-items:center;gap:4px;
  padding:7px 3px;border-radius:10px;cursor:default;}
.dicon img{width:46px;height:46px;object-fit:contain;filter:drop-shadow(0 6px 10px rgba(0,0,0,.25));
  transition:transform .18s cubic-bezier(.34,1.56,.64,1);}
.dicon:hover img{transform:translateY(-3px) scale(1.06);}
.dicon .dlabel{font-size:11.5px;color:#1c1e22;text-align:center;line-height:1.25;
  padding:1px 6px;border-radius:5px;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
#desk-icons .dicon .dlabel{max-width:none;overflow:visible;text-overflow:clip;white-space:nowrap;color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.9),0 0 5px rgba(0,0,0,.58);}
.dicon.sel .dlabel{background:var(--blue);color:#fff;}
.dicon.sel img{transform:scale(1.04);}

/* 首次登录引导：很多用户找不到修改器入口，给图标加呼吸光圈 + 右侧气泡。
   点击图标后写 localStorage 永久移除，不再打扰。 */
.dicon.dicon-hint{position:relative;}
/* 光圈用 ::before 画在图标下层，不影响图标本身的 hover 位移 */
.dicon-hint::before{
  content:'';position:absolute;top:5px;left:50%;width:54px;height:54px;
  margin-left:-27px;border-radius:50%;pointer-events:none;z-index:-1;
  background:radial-gradient(circle,rgba(88,180,255,.55) 0%,rgba(88,180,255,.18) 45%,transparent 70%);
  animation:dicon-hint-pulse 2.1s ease-in-out infinite;
}
@keyframes dicon-hint-pulse{
  0%,100%{transform:scale(.82);opacity:.45;}
  50%{transform:scale(1.18);opacity:1;}
}
/* 两个引导同时存在时错开节拍，避免光圈整齐闪烁显得机械 */
.dicon-hint ~ .dicon-hint::before{animation-delay:.7s;}
.dicon-hint ~ .dicon-hint .dicon-hint-tip{animation-delay:.14s,1.14s;}

/* 气泡挂在图标右侧，绝对定位所以不会挤动其他桌面图标。
   配色沿用 #context-menu 的浅色毛玻璃，保持系统一致性。 */
.dicon-hint-tip{
  /* 顶部对齐图标图像：.dicon 有 7px 内边距，图像顶边在 7px 处；气泡自身还有
     7px 内边距，所以 top 取 0 让气泡内的首行文字正好与图像顶部齐平。
     固定 top 而不是垂直居中 —— 气泡向下生长，加几行内容都不会整体偏移。 */
  position:absolute;left:calc(100% + 14px);top:0;z-index:30;
  display:flex;align-items:flex-start;gap:10px;
  padding:7px 9px 7px 11px;border-radius:10px;white-space:nowrap;
  background:rgba(242,242,246,.88);color:rgba(0,0,0,.75);
  border:1px solid rgba(0,0,0,.14);
  box-shadow:0 16px 42px rgba(0,0,0,.32);
  backdrop-filter:blur(26px) saturate(1.45);-webkit-backdrop-filter:blur(26px) saturate(1.45);
  /* 从图标左侧「长」出来，所以原点贴着三角那一侧（与 ::before 的 top 一致） */
  transform-origin:0 15px;
  animation:dicon-hint-pop .62s cubic-bezier(.34,1.56,.64,1) both,
            dicon-hint-sway 3.4s ease-in-out 1s infinite;
}
/* flex 子项默认 min-width:auto 但会被父级 flex 压缩，导致 nowrap 的文字被
   ellipsis 截断（「若无效，联系客服原路退…」）。这里让文本列不参与收缩，
   气泡按最长一行自然撑开 —— 实测最宽约 173px，桌面空间充足。 */
.dicon-hint-text{display:flex;flex-direction:column;gap:2px;flex:0 0 auto;min-width:max-content;}
.dicon-hint-tip strong{font-size:12px;font-weight:600;line-height:1.3;white-space:nowrap;}
.dicon-hint-tip span{font-size:10.5px;color:rgba(0,0,0,.5);line-height:1.3;white-space:nowrap;}
/* 关闭按钮：气泡整体 pointer-events:none 会连按钮一起禁用，故只在按钮上放开 */
.dicon-hint-close{
  flex:none;width:17px;height:17px;margin-top:-1px;padding:0;
  display:flex;align-items:center;justify-content:center;
  border:none;border-radius:50%;background:rgba(0,0,0,.07);
  color:rgba(0,0,0,.45);font-size:13px;line-height:1;cursor:pointer;
  transition:background .15s,color .15s;
}
.dicon-hint-close:hover{background:rgba(0,0,0,.16);color:rgba(0,0,0,.75);}
.dicon-hint-close:focus-visible{outline:2px solid var(--blue);outline-offset:1px;}
/* 演示视频入口。同样要单独放开 pointer-events（气泡整体是 none）。
   做成蓝色文字按钮而不是实心块：气泡本身很小，实心按钮会盖住说明文字。 */
.dicon-hint-action{
  align-self:flex-start;margin-top:5px;padding:3px 8px 3px 6px;
  display:inline-flex;align-items:center;gap:4px;
  pointer-events:auto;
  border:none;border-radius:6px;background:rgba(0,0,0,.08);
  /* 气泡是浅色底，黑色加粗比蓝字更抓眼，也和标题的深色字统一 */
  color:#1d1d1f;font:700 11px/1 inherit;cursor:pointer;white-space:nowrap;
  transition:background .15s;
}
.dicon-hint-action:hover{background:rgba(0,0,0,.15);}
.dicon-hint-action:focus-visible{outline:2px solid var(--blue);outline-offset:1px;}
/* 气泡里的 span 统一是灰色小字，按钮内的图标不受这条影响 */
.dicon-hint-action svg{flex:none;}
/* 指向图标的小三角：对齐首行标题的垂直中心
   （气泡 padding 7px + 标题行高约 16px 的一半 ≈ 15px，减去三角半高 6px = 9px） */
.dicon-hint-tip::before{
  content:'';position:absolute;right:100%;top:9px;
  border:6px solid transparent;border-right-color:rgba(242,242,246,.88);
}
/* 弹出：缩着冒出来 → 冲过头 → 回弹坐稳 */
@keyframes dicon-hint-pop{
  0%{opacity:0;transform:scale(.4) translateX(-14px);}
  45%{opacity:1;transform:scale(1.08) translateX(3px);}
  70%{transform:scale(.97) translateX(-1px);}
  100%{opacity:1;transform:scale(1) translateX(0);}
}
/* 坐稳后持续轻微摆动，避免静止后显得死板 */
@keyframes dicon-hint-sway{
  0%,100%{transform:scale(1) translateX(0);}
  50%{transform:scale(1) translateX(3px);}
}
/* 窄屏时气泡会顶出屏幕，直接隐藏，光圈仍然保留 */
@media (max-width:640px){.dicon-hint-tip{display:none;}}

/* ---- 全局气泡提示（替代浏览器原生 title tooltip）----
   配方与 .dicon-hint-tip / #context-menu 一致：浅色毛玻璃 + 小三角，
   由 src/shell/tooltip.js 接管所有带 title 的元素。 */
.ui-tooltip{
  position:fixed;left:0;top:0;z-index:11000;
  max-width:300px;padding:7px 11px;border-radius:8px;
  background:rgba(245,245,248,.95);color:#666666 !important;
  border:1px solid rgba(0,0,0,.12);
  box-shadow:0 10px 28px rgba(0,0,0,.22);
  backdrop-filter:blur(26px) saturate(1.45);-webkit-backdrop-filter:blur(26px) saturate(1.45);
  font-size:12px;font-weight:450;line-height:1.45;white-space:normal;
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
  pointer-events:none;opacity:0;
  /* 收起时缩回箭头那一侧，与弹出方向相反 */
  /* 起始态：轻微缩小 + 贴着箭头一侧的小位移。幅度刻意做小，
     位移越短、越不过冲，观感才越顺，不会有「弹一下」的顿挫。 */
  transform:scale(.96) translateY(-4px);
  transform-origin:var(--tooltip-arrow-x,50%) 0;
  /* 收起比展开快一档，手感更利落 */
  transition:opacity .1s linear,transform .1s cubic-bezier(.4,0,1,1);
}
/* 展开用标准缓出曲线（Material 的 decelerate）：起步快、尾段长而缓，
   不过冲，全程无速度突变，是最「顺滑」的一档。 */
.ui-tooltip.on{
  opacity:1;transform:none;
  transition:opacity .16s cubic-bezier(0,0,.2,1),transform .22s cubic-bezier(0,0,.2,1);
}
/* 气泡已亮着又换了目标：位置本身也做过渡，直接滑过去而不是重新淡入。
   宽度会随文案变化，一起过渡才不会有跳变。 */
.ui-tooltip.on.sliding{
  transition:opacity .16s cubic-bezier(0,0,.2,1),
             transform .22s cubic-bezier(0,0,.2,1),
             left .2s cubic-bezier(.2,0,0,1),
             top .2s cubic-bezier(.2,0,0,1);
}
/* 翻到目标上方时，原点与初始位移都改到底边，方向随之翻转 */
.ui-tooltip.above{
  transform:scale(.96) translateY(4px);
  transform-origin:var(--tooltip-arrow-x,50%) 100%;
}
.ui-tooltip.above.on{transform:none;}
/* 系统关闭动效时直接显示，不做位移与缩放 */
@media (prefers-reduced-motion:reduce){
  .ui-tooltip,.ui-tooltip.above{transform:none;transition:opacity .1s linear;}
  .ui-tooltip.on.sliding{transition:opacity .1s linear;}
}
/* 指向目标的小三角，水平位置由 JS 写入 --tooltip-arrow-x */
.ui-tooltip::before{
  content:'';position:absolute;bottom:100%;
  left:var(--tooltip-arrow-x,50%);transform:translateX(-50%);
  border:5px solid transparent;border-bottom-color:rgba(242,242,246,.92);
}
/* 翻到目标上方时三角改朝下 */
.ui-tooltip.above::before{
  bottom:auto;top:100%;
  border-bottom-color:transparent;border-top-color:rgba(242,242,246,.92);
}
