/* ============================================================================
 * source/css/site-inject.css —— 站点注入样式合集
 * ----------------------------------------------------------------------------
 * 本文件由 _config.fomalhaut.yml 的 inject.head 段抽出（2026-10-03 屎山重构）。
 * 抽出来的原因：在 YAML 里写 CSS 没有语法高亮、没有补全、缩进错一位就会被静默吞掉；
 * 在一个两千行的配置文件里翻样式更是折磨。现在样式集中在这个文件里，配置里只留一行 <link>。
 *
 * 【层叠顺序 = 本文件从上到下的顺序，与抽取前完全一致，不要随意重排】
 *   配置里那条 <link> 的位置，就是原先第一个 <style> 块的位置，所以它相对于
 *   主题样式表 / 其它注入块的优先级没有变。
 *
 * 【唯一的位置变化（已评估，无影响）】
 *   原 scroll-gap-css（锚点 scroll-padding-top:70px）在 YAML 里排在 aside-show /
 *   aside-pos 两个「运行时空槽」之前，现在排到了它们之后。两者管的属性完全不搭界
 *   （滚动容器锚点定位 vs 侧栏显隐/左右位置），不会互相覆盖。
 *
 * 【注意】配置里那些空标签 <style id="themeColor"></style>、#rightSide、#transPercent、
 *   #bgFilterParam、#defineBg、#menu_shadow、#nav-display、#aside-show、#aside-pos
 *   是「运行时空槽」：由右下角美化面板的 JS 在运行时写入内容，不能删、不能挪。
 *
 * 【本文件目录】共 17 块（后面的优先级更高）
 *    1. scroll-gap-css     ← 原 _config.fomalhaut.yml:1209-1212
 *    2. annoV2             ← 原 _config.fomalhaut.yml:1216-1295
 *    3. pcLightTheme       ← 原 _config.fomalhaut.yml:1306-1344
 *    4. asideWider         ← 原 _config.fomalhaut.yml:1364-1379
 *    5. listPagination     ← 原 _config.fomalhaut.yml:1437-1437
 *    6. pageWidthLimit     ← 原 _config.fomalhaut.yml:1438-1438
 *    7. rightMenuState     ← 原 _config.fomalhaut.yml:1444-1452
 *    8. webinfoCard        ← 原 _config.fomalhaut.yml:1492-1518
 *    9. ft-hide-self       ← 原 _config.fomalhaut.yml:1522-1526
 *   10. aplayerVolumeFix   ← 原 _config.fomalhaut.yml:1538-1542
 *   11. readModeIconGuard  ← 2026-10-04 新增（阅读模式标题风车兜底）
 *   12. letterBoard        ← 2026-10-04 新增（留言板 / 信封页改版）
 *   13. cardAnimPerf       ← 2026-10-04 新增（首页卡片箭头 / 置顶角标流光改走 transform）
 *   14. loadingIdle        ← 2026-10-04 新增（加载动画在遮罩隐藏后停掉）
 *   15. cardGlassOff       ← 2026-10-04 新增（关闭卡片毛玻璃特效）
 *   16. searchPanelUX      ← 2026-10-11 新增（搜索加载提示位置修正 + 搜索历史）
 *   17. darkModeSpeed      ← 2026-10-11 新增（昼夜切换动画时长调整：覆盖天空/星球/日月互换时长，整屏遮挡 ~1.5s）
 * ========================================================================== */

/* ── 1/12  #scroll-gap-css  ← 原 _config.fomalhaut.yml:1209-1212 ── */
/* 锚点跳转兜底：给常驻顶栏留出高度。scroll-padding-top 作用于滚动容器的锚点定位， */
/* 使得「JS 完全没跑 / pjax 换页后点击处理丢失」时，原生锚点跳转也不会把标题顶到常驻顶栏底下。 */
/* 实测注意：不要再给目标元素加 scroll-margin-top，两者会叠加（70+70=140px）造成偏移过大。 */
/* JS 版补偿见 inject.bottom 的 scroll-gap-fix（实测落点 70px）。 */
html { scroll-padding-top: 70px !important; }

/* ── 2/12  #annoV2  ← 原 _config.fomalhaut.yml:1216-1295 ── */
/* 公告栏 · 信息板改版样式（配合 card_announcement.content 的新结构，纯 CSS + 变量） */
/* 公告栏 · 信息板改版（配合 _config.fomalhaut.yml 的 card_announcement.content）
 * 只作用于侧栏 .card-announcement 这一张卡；配色跟着 --theme-color 走，
 * 由它派生三档，每个变量第一行是「不支持 color-mix() 的老浏览器」回退值：
 *   --anno-accent  主题色原色
 *   --anno-strong  原色压深(浅色)/提亮(深色)一档 → 当文字用的胶囊、下载按钮、欢迎信息里的高亮
 *   --anno-chip-* / --anno-soft-*  胶囊与软底的底色/描边
 * 深色适配只覆盖变量，规则本体一套。
 */
.card-announcement {
  --anno-accent: var(--theme-color, #39c5bb);

  --anno-strong: #25706b;
  --anno-strong: color-mix(in srgb, var(--anno-accent) 62%, #000);

  --anno-muted: rgba(60, 60, 67, .55);
  --anno-muted: color-mix(in srgb, var(--font-color, #1f2937) 55%, transparent);

  --anno-chip-bg: rgba(57, 197, 187, .075);
  --anno-chip-bg: color-mix(in srgb, var(--anno-accent) 7.5%, transparent);
  --anno-chip-bd: rgba(57, 197, 187, .22);
  --anno-chip-bd: color-mix(in srgb, var(--anno-accent) 22%, transparent);

  --anno-soft-bg: rgba(57, 197, 187, .06);
  --anno-soft-bg: color-mix(in srgb, var(--anno-accent) 6%, transparent);
  --anno-soft-bd: rgba(57, 197, 187, .16);
  --anno-soft-bd: color-mix(in srgb, var(--anno-accent) 16%, transparent);
}
[data-theme="dark"] .card-announcement {
  --anno-strong: #7fe3da;
  --anno-strong: color-mix(in srgb, var(--anno-accent) 78%, #fff);
  --anno-chip-bg: rgba(57, 197, 187, .14);
  --anno-chip-bg: color-mix(in srgb, var(--anno-accent) 14%, transparent);
  --anno-chip-bd: rgba(57, 197, 187, .32);
  --anno-chip-bd: color-mix(in srgb, var(--anno-accent) 32%, transparent);
  --anno-soft-bg: rgba(57, 197, 187, .12);
  --anno-soft-bg: color-mix(in srgb, var(--anno-accent) 12%, transparent);
  --anno-soft-bd: rgba(57, 197, 187, .26);
  --anno-soft-bd: color-mix(in srgb, var(--anno-accent) 26%, transparent);
}
.card-announcement .anno2 { font-size: 13.5px; line-height: 1.75; text-align: left; }
.card-announcement .anno2 a { text-decoration: none; }
.card-announcement .a-row { display: flex; align-items: center; gap: 6px; padding: 7px 0; flex-wrap: nowrap;}
.card-announcement .a-row + .a-row { border-top: 1px dashed rgba(127, 127, 127, .18); flex-wrap: nowrap;}
.card-announcement .a-row.a-sub { border-top: 0; padding-top: 0; }
.card-announcement .a-row.a-flat { border-top: 0; padding: 0; }
.card-announcement .a-lb { flex: 0 0 56px; font-size: 12px; letter-spacing: .4px; color: var(--anno-muted); font-weight: 700; white-space: nowrap; }
.card-announcement .a-chip { display: inline-flex; align-items: center; gap: 6px; font-weight: 700; font-size: 13px;
  color: var(--anno-strong); background: var(--anno-chip-bg); border: 1px solid var(--anno-chip-bd);
  border-radius: 999px; padding: 4px 9px; line-height: 1.7; transition: .25s; flex: 0 0 auto;}
.card-announcement .a-chip:hover { background: var(--anno-accent); border-color: var(--anno-accent); color: var(--on-theme); }
.card-announcement .a-chip .a-dot { width: 5px; height: 5px; border-radius: 50%; background: currentColor; opacity: .75; }
.card-announcement .a-note { font-size: 12.5px; color: var(--anno-muted); font-weight: 500; margin-left: auto;
  white-space: nowrap; flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis;}
/* 排版规则（2026-10-04 修正）：.a-row 一律 flex-wrap:nowrap —— 一行装不下时只允许两种结果：
   ① .a-note 自己省略成「Cloudfl…」（flex:0 1 auto + min-width:0 + text-overflow:ellipsis）；
   ② 容器查询按宽度逐档收起注记/徽标。绝不把注记挤到第二行把行撑高（用户实测反馈过）。
   胶囊与徽标是 flex:0 0 auto，不会被压缩，保证域名与延时完整可读。 */
/* ── 线路延时徽标（2026-10-04 新增）────────────────────────────────────────
   由 source/js/inject/ping-route.js 在每条线路胶囊后面插入 <span class="a-ms">，
   显示「本机 → 该线路」的一次网络往返（如 82ms）。等宽数字 + 最小宽度锁死，
   状态：wait/load → ok（主题色）/ slow ≥400ms（琥珀）/ bad ≥1s（红）/ fail（—，删除线）。
   从 — → ··· → 82ms 的长度变化都不会引起布局位移（min-width 锁住）；ok 的配色由主题色派生。
   位置说明：徽标在 DOM 里紧跟胶囊，靠 .a-note 的 margin-left:auto 被推到右侧、与「Vercel」
   这类注记相邻（用户圈的是「线路名后面那块空位」）。宽 42px 是内测值：narrow 断点下
   「胶囊 + 82ms」仍能排在同一行，超时最长显示「999ms」也不会撑宽。 */
.card-announcement .a-ms { flex: 0 0 auto; min-width: 42px; text-align: center;
  font-size: 11.5px; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: .2px;
  color: var(--anno-muted); background: transparent; border: 1px solid transparent;
  border-radius: 999px; padding: 2px 6px; line-height: 1.6; cursor: pointer;
  transition: color .25s, background .25s, border-color .25s; user-select: none; }
.card-announcement .a-ms:hover { border-color: var(--anno-chip-bd); }
.card-announcement .a-ms[data-state="load"] { color: var(--anno-muted); opacity: .7; }
.card-announcement .a-ms[data-state="ok"] { color: var(--anno-strong);
  background: var(--anno-chip-bg); border-color: var(--anno-chip-bd); }
.card-announcement .a-ms[data-state="slow"] { color: #e8a33d; border-color: rgba(232, 163, 61, .34);
  background: rgba(232, 163, 61, .10); }
/* ≥1s：红色（很慢）。浅色卡片用深一点的红，深色卡片覆盖成亮红 —— 与 slow 同一种写法 */
.card-announcement .a-ms[data-state="bad"] { color: #d23b3b; border-color: rgba(210, 59, 59, .34);
  background: rgba(210, 59, 59, .10); }
[data-theme="dark"] .card-announcement .a-ms[data-state="bad"] { color: #ff7a7a; border-color: rgba(255, 122, 122, .38);
  background: rgba(255, 122, 122, .12); }
.card-announcement .a-ms[data-state="fail"] { color: var(--anno-muted); text-decoration: line-through;
  text-decoration-thickness: 1px; opacity: .6; }
/* 卡片更窄时（窗口变小 / 侧栏收窄）用容器查询自动降一档，保证「Cloudflare」这类注记永远排在同一行。 */
/* 降档只收「行间距 + 标签列 + 胶囊内边距 + 胶囊内圆点间距」这四种尺寸，字号一律不动 —— */
/* 用户两次要求过胶囊/线路注记的字要更大（13px / 12px 就是这个结论），这里绝不能再缩回去。 */
.card-announcement .anno2 { container-type: inline-size; }
@container (max-width: 320px) {
  .card-announcement .a-row { gap: 3px; }
  /* 标签列改成「按内容、最小 44px」并禁止换行：「手机 App」在 48px 定宽里会折成两行（用户反馈）。
     主线路/备用线路内容约 38px，被 min-width 抬到 44px，三行胶囊仍对齐。 */
  .card-announcement .a-lb { flex: 0 0 auto; min-width: 44px; font-size: 12px; }
  .card-announcement .a-chip { padding: 3px 6px; gap: 4px; font-size: 13px; }
  .card-announcement .a-ms { min-width: 34px; padding: 2px 4px; font-size: 11.5px; }
}
/* 320 这一档同时收四处（行间距 6→3、标签列 56→48、胶囊内边距 9→6、徽标 min-width 42→32），
   字号一律不动。阈值必须是 320 而不是 285：线上桌面卡片内容宽正好 272px，
   而「备用线路 + github.example.com + 999ms + Github」在原尺寸下要 279px —— 286-320 这段
   如果不收，注记就会掉到第二行。收完之后最宽的一行 ≈269px，272px 下仍有 3px 余量。 */
/* 卡片再窄时先让出「线路注记」，保住延时徽标（用户要的是能看见延时）。
   268 是实测值：最宽的「netlify.example.com + 999ms + Netlify + 标签」在容器 269px 时刚好 266px。 */
@container (max-width: 268px) { .card-announcement .a-note { display: none; } }
/* 最窄一档：放不下徽标，连同它一起收起，绝不换行。
   230 是实测值：容器 231px 时「标签 48 + 最长胶囊 120 + 徽标 44 + 间距」= 223px 刚好排下。 */
@container (max-width: 230px) { .card-announcement .a-ms { display: none; } }
/* 再窄（手机抽屉等）：注记与徽标都已收起，只剩「标签 + 胶囊」，此时恢复换行兜底，避免横向裁切。 */
@container (max-width: 230px) { .card-announcement .a-row { flex-wrap: wrap; } }
.card-announcement .a-sect { margin-top: 11px; padding-bottom: 18px; }
.card-announcement .a-approw { display: flex; align-items: center; gap: 8px; margin-top: 7px; }
.card-announcement .a-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; font-weight: 700;
  font-size: 13.5px; color: var(--on-theme);
/* 渐变方向改成「往远离前景色的方向」（浅色预设 → 提亮、深色预设 → 压暗）。
   原来是从主题色渐到 --anno-strong（= 主题色 62% + 黑），深色那头配深字只有 2.2~3.4:1，
   就是「字被渐变吃掉」的原因；现在两端都 ≥5.6:1。第一行是不支持 color-mix 时的回退。 */
background: linear-gradient(135deg, var(--anno-accent), var(--anno-strong));
background: linear-gradient(135deg, color-mix(in srgb, var(--anno-accent) 88%, var(--on-theme-away, #ffffff)), color-mix(in srgb, var(--anno-accent) 66%, var(--on-theme-away, #ffffff)));
  border-radius: 10px; padding: 8px 16px; line-height: 1.6; transition: .25s;
  box-shadow: 0 3px 10px rgba(57, 197, 187, .35);
  box-shadow: 0 3px 10px color-mix(in srgb, var(--anno-accent) 35%, transparent); flex: 0 0 auto;}
.card-announcement .a-btn:hover { color: var(--on-theme); filter: brightness(1.06); transform: translateY(-1px);
  box-shadow: 0 6px 16px color-mix(in srgb, var(--anno-accent) 45%, transparent); }
.card-announcement .a-btn svg { width: 13px; height: 13px; fill: currentColor; }
/* 欢迎信息块：改成左对齐的「小标签 + 正文」，并让 fomal.js 写死的内联蓝色跟随主题色 */
.card-widget.card-announcement #welcome-info { background: var(--anno-soft-bg); border: 1px solid var(--anno-soft-bd);
  border-radius: 14px; padding: 10px 13px; margin-top: 0; text-align: left; font-weight: 500; line-height: 1.9; font-size: 13.5px; }
.card-widget.card-announcement #welcome-info b { font-weight: 500; }
.card-widget.card-announcement #welcome-info center { text-align: left; margin: 0 0 2px; font-size: 12px;
  letter-spacing: .5px; color: var(--anno-muted); font-weight: 700; }
.card-widget.card-announcement #welcome-info span { color: var(--anno-strong) !important; font-weight: 800; }

/* ── 3/12  #pcLightTheme  ← 原 _config.fomalhaut.yml:1306-1344 ── */
/* 版权卡片 · 白天配色（2026-10-05）：原文那套粉-青-米渐变是主题作者写死的固定值，跟主题色无关； */
/* 更要紧的是两处彩色小字白天几乎看不见：文章链接 #99a9bf 只有 1.89:1、值行用主题色原色只有 1.71:1 */
/* （实测自用户截图，WCAG AA 小字要 4.5:1）。注意 #39c5bb 放在纯白上也只有 2.13:1 —— 所以光换底色没用， */
/* 必须把文字按同色系压深一档，才有现在这套： */
/*   值行/许可协议  color-mix(主题色 50%, #0d1f22) → 5.1~5.5:1（13 种主题色全验过，最差的黄色 4.69:1） */
/*   文章链接        保留它那支灰蓝压深 → ≈6:1 */
/*   卡片底色        主题色 14% / 3% / 18% 混白的三档渐变，跟着右下角主题色选择器联动 */
/* 只作用于 html[data-theme="light"]；暗色模式的 #07080a + flashlight 观感完全不动。 */
/* 每处 color-mix() 的上一行是不支持它的老浏览器回退值（沿用上方 annoV2 的写法）。 */
/* 主题源码 post.styl 里的原渐变仍在，这里按「优先改配置」的约定从配置层覆盖。 */
/* 版权卡片 · 白天配色（主题色系淡渐变 + 同色系深墨字） */
html[data-theme="light"] #post .post-copyright {
  background: linear-gradient(45deg, #e3f7f5, #f9fdfd, #d1eeef) !important;
  background: linear-gradient(45deg,
      color-mix(in srgb, var(--theme-color, #39c5bb) 14%, #fff),
      color-mix(in srgb, var(--theme-color, #39c5bb) 3%, #fff),
      color-mix(in srgb, var(--theme-color, #39c5bb) 18%, #f2f7fa)) !important;
  border-color: #c9e7e8 !important;
  border-color: color-mix(in srgb, var(--theme-color, #39c5bb) 18%, #e9eef2) !important;
  /* 原 box-shadow 是 currentColor（深灰实心偏移影），浅底上会显得脏，压到 10% 黑 */
  box-shadow: 2px 2px 5px rgba(0, 0, 0, .1) !important;
}
/* 值行（作者 / 发表日期 / 更新日期 / 许可协议）：主题色压深一档当墨色用 */
html[data-theme="light"] #post .post-copyright .post-copyright-cc-info,
html[data-theme="light"] #post .post-copyright .post-copyright-cc-info a {
  color: #23726f !important;
  color: color-mix(in srgb, var(--theme-color, #39c5bb) 50%, #0d1f22) !important;
}
/* 文章链接：保留它自己那支灰蓝，只压深（1.89:1 → ≈6:1） */
html[data-theme="light"] #post .post-copyright__type .post-copyright-info a {
  color: #586575 !important;
  color: color-mix(in srgb, #99a9bf 50%, #16202b) !important;
}
/* 白天别再用主题色原色当悬停色（浅底上同样看不清）：改成压深 + 下划线 */
html[data-theme="light"] #post .post-copyright-info a:hover,
html[data-theme="light"] #post .post-copyright-cc-info a:hover {
  color: #23726f !important;
  color: color-mix(in srgb, var(--theme-color, #39c5bb) 50%, #0d1f22) !important;
  text-decoration: underline !important;
  text-underline-offset: 3px;
}
/* 右下角那枚 CC 水印：由原来的灰改成跟着主题色染一点（仍由 opacity 保持很淡） */
html[data-theme="light"] #post .post-copyright:before {
  color: #61a0a4;
  color: color-mix(in srgb, var(--theme-color, #39c5bb) 40%, #7b8794);
}

/* ── 4/12  #asideWider  ← 原 _config.fomalhaut.yml:1364-1379 ── */
/* 侧栏宽度（第三轮，2026-10-04）：第二轮把侧栏顶到 .layout 最右边，结果撞上了右侧悬浮工具条， */
/* 所以这一轮同时处理「宽度」和「右边留够工具条的位置」两件事。 */
/* 两个必须知道的上游事实： */
/*  1) 站点自定义 CSS `.aside-content { max-width: 318px; min-width: 300px }`（类选择器）会把侧栏锁死在 318px； */
/*     元素本身是 #aside-content.aside-content（themes/fomalhaut/layout/includes/widget/index.pug:1）， */
/*     所以要用 ID+类 的选择器才压得住它。站点还有 `.layout { max-width: 1400px }`（覆盖主题的 1200px）。 */
/*  2) 右侧悬浮工具条 #rightside 是 position: fixed（themes/fomalhaut/source/css/_layout/rightside.styl:1-4 */
/*     是 right: -48px，custom.css:2284-2288 再 translateX(-58px)，按钮宽 38px，见 custom.css:1087-1096）—— */
/*     换算下来按钮左边缘大约在「窗口右边 −48px」处，所以布局内容必须在它左边收住，不能贴到窗口最右。 */
/* 第三轮做法：① 压缩整个布局宽度（max-width 取 min(1400px, 100vw - 140px)）；② 侧栏固定 380px， */
/* 主列 flex-grow 吃满剩余。结果：卡片确实离开按钮了，但左右两侧被压出两条空隙，看着没铺满 —— 已废弃。 */
/* 第四轮做法（当前，2026-10-04）：**不压缩布局宽度**，只把 .layout 的右侧内边距加大到 78px， */
/* 让右列内容在工具条左边收住、左列仍然贴到窗口左边（左右都铺满）；窗口比 1400px 布局上限更宽时， */
/* 布局居中本身就会离右边越来越远，所以右侧内边距按 (100vw - 1400px)/2 逐步回收，最少 15px。 */
/* 宽度上限测算（窗口 1440 CSS、扣 15px 滚动条）：布局 1400、右内边距 58 → 内容区 ≈ [27.5, 1354.5]， */
/* 卡片右边缘 1349.5，工具条按钮左边缘 1377 → 留约 27px 间隙。 */
/* 只在小屏以上生效：901px 以下主题自己的 +maxWidth900() 会把两者都设成 100%，不能被覆盖（见 aside.styl:10-11）。 */
/* 用 :not(.hide-aside) 避开「收纳侧栏」时主题的 `.layout.hide-aside > div { width: 100% !important }`。 */
/* 样式自 2026-10-03 起集中在 source/css/site-inject.css（配置里只留一行 <link>），不动主题源码； */
/* 本块的上一版备份 bak/announcement-20261004-v8-fill/before/，本次备份 bak/announcement-20261004-v9-narrow340/before/。 */
/* 左右都铺满：不动布局宽度，只把右侧内边距加大，让内容在悬浮工具条左边收住 */
@media screen and (min-width: 901px) and (max-width: 1400px) {
  .layout:not(.hide-aside) { padding-right: 78px; }
}
/* 窗口比布局上限 1400px 更宽时，布局居中已自带右侧余量，内边距按差额逐步收回（最少 15px） */
@media screen and (min-width: 1401px) {
  .layout:not(.hide-aside) { padding-right: max(15px, calc(78px - (100vw - 1400px) / 2)); }
}
/* 第五轮（2026-10-04 晚）：侧栏 360 → 340px —— 用户原话「侧栏又有点太宽了，稍微弄窄一点点」。 */
/* 340px 时卡片内容宽 = 340 − 20（#aside-content padding 0 5px 0 15px）− 48（.card-widget padding 20px 24px）= 272px； */
/* 最紧的是「cloudflare.example.com + Cloudflare」那行（衬底值约 265px），靠上面 @container ≤285px 的降档刚好排得下。 */
/* 再往下窄（≤335px 左右）这行就要换行，那时必须继续降档或改行结构。 */
@media screen and (min-width: 1200px) {
  #aside-content.aside-content { width: 340px; max-width: 340px; flex: 0 0 auto; }
  .layout:not(.hide-aside) > div:first-child { flex: 1 1 auto; width: auto; min-width: 0; }
}

/* ── 5/12  #listPagination  ← 原 _config.fomalhaut.yml:1437-1437 ── */
/* 归档 / 标签 / 分类等列表页的翻页按钮：样式对齐首页（卡片圆角 + 悬浮反馈 + 统一尺寸） */
.layout > div:not(.recent-posts) #pagination .pagination > *{display:inline-block;margin:0 6px;width:2.5em;height:2.5em;line-height:2.5em;text-align:center}.layout > div:not(.recent-posts) #pagination .pagination > *:not(.space){border-radius:8px;background:var(--card-bg);box-shadow:var(--card-box-shadow);transition:all .3s}.layout > div:not(.recent-posts) #pagination .pagination > *:not(.space):hover{background:var(--btn-hover-color);color:var(--btn-color);box-shadow:var(--card-hover-box-shadow)}

/* ── 6/12  #pageWidthLimit  ← 原 _config.fomalhaut.yml:1438-1438 ── */
.layout:has(#page),.layout:has(#archive),.layout:has(#tag),.layout:has(#category){max-width:1200px}

/* ── 7/12  #rightMenuState  ← 原 _config.fomalhaut.yml:1444-1452 ── */
/*  */
/* 侧边栏「右键模式」按钮：显示"站点自定义右键"当前是开还是关 */
/*   开 = 跟随主题色（主题默认外观，不动）；关 = 灰色 + 图标上一道斜杠 */
/*   状态源与 source/js/fomal.js 的 mouseMode 完全一致（localStorage 键 "mouse"，缺省视为开） */
/*   纯 HTML/CSS/JS 注入实现，不改主题源码（rightside.pug 的 button 原样保留） */
html[data-rm="off"] #rightside button:has(> i.fa-mouse){position:relative;background-color:#909090 !important;color:#fff !important;}
html[data-rm="off"] #rightside button:has(> i.fa-mouse):hover{background-color:#a8a8a8 !important;}
html[data-theme="dark"][data-rm="off"] #rightside button:has(> i.fa-mouse){background-color:#787878 !important;}
html[data-theme="dark"][data-rm="off"] #rightside button:has(> i.fa-mouse):hover{background-color:#8d8d8d !important;}
html[data-rm="off"] #rightside button:has(> i.fa-mouse) > i{opacity:.4;}
html[data-rm="off"] #rightside button:has(> i.fa-mouse)::after{content:"";position:absolute;left:50%;top:50%;width:20px;height:2px;border-radius:2px;background:#fff;opacity:.95;transform:translate(-50%,-50%) rotate(-45deg);}

/* ── 8/12  #webinfoCard  ← 原 _config.fomalhaut.yml:1492-1518 ── */
/* （2026-10-03）不蒜子已弃用，统计源改为 Vercount（见 additional-js.pug）。 */
/* 原先这两段（bsz-guard 拦截器 / bsz-lazy 延迟兜底）是专为 busuanzi.ibruce.info 写的； */
/* 其中 bsz-lazy 的 6 秒超时会把 Vercount 已经写好的数字覆盖成「—」，故整段删除。 */
/* 原文与备份见 bak/20261003-webinfo/。 */
/* 小站资讯卡（2026-10-03 改版）样式 */
/* 小站资讯卡 2026-10-03 改版 */
.card-webinfo .wi{margin-top:2px;container-type:inline-size}
.card-webinfo .wi-kpi{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin:10px 0 12px}
.card-webinfo .wi-kpi-item{display:block;text-align:center;border-radius:10px;padding:10px 2px 8px;color:inherit;text-decoration:none;background:rgba(128,128,128,.09);background:color-mix(in srgb,var(--theme-color) 9%,transparent);transition:background .3s,transform .3s}
.card-webinfo a.wi-kpi-item:hover{transform:translateY(-2px);background:rgba(128,128,128,.16);background:color-mix(in srgb,var(--theme-color) 16%,transparent)}
.card-webinfo .wi-kpi-num{font-size:22px;line-height:1.1;font-weight:700;color:var(--theme-color);font-variant-numeric:tabular-nums}
.card-webinfo .wi-kpi-label{font-size:11px;opacity:.6;margin-top:4px;letter-spacing:.3px}
.card-webinfo .wi-time{display:flex;align-items:center;justify-content:center;gap:5px;flex-wrap:wrap;font-size:12px;padding:8px 0 2px;border-top:1px solid rgba(128,128,128,.2)}
.card-webinfo .wi-time-item{display:inline-flex;align-items:baseline;gap:3px}
.card-webinfo .wi-time-k{opacity:.55}
.card-webinfo .wi-time-v{font-weight:600;color:var(--theme-color);font-variant-numeric:tabular-nums}
.card-webinfo .wi-time-sep{opacity:.3}
/* 「更新」= 站点最后更新时间（最近一次部署）。构建时先渲染 MM-DD 兜底，
   页面加载后由 source/js/inject/webinfo-card.js 换成「N 分钟前 / N 小时前 / N 天前」。 */
.card-webinfo .wi-deploy{cursor:default}
/* 三项一行（已运行 / 距上次发文 / 更新）。实测（2026-10-04，无头 Chrome）：
   · 侧栏 340px → 卡片内容宽 288px，12px 字号下三项 + 4 个 5px 间距 ≈ 280px，刚好一行；
   · 901~1199px 侧栏只有 300px → 内容宽 248px（两栏布局下的地板值，再窄就没有了，
     <901px 时侧栏变整列反而更宽），12px 会挤成两行，故 ≤284px 时降字号一档。
   284 这个界值是算出来的：12px 档最少要 280px 才不换行，界值必须大于它、又要小于 288。 */
@container (max-width: 284px) {
  .card-webinfo .wi-time{font-size:10.5px;gap:4px}
  .card-webinfo .wi-time-item{gap:2px}
}
.card-webinfo .wi-chart{margin-top:10px;border-top:1px solid rgba(128,128,128,.2);padding-top:9px}
.card-webinfo .wi-chart-head{display:flex;justify-content:space-between;align-items:baseline;font-size:11px;opacity:.6;margin-bottom:6px}
.card-webinfo .wi-bars{display:flex;align-items:flex-end;gap:6px;height:50px}
.card-webinfo .wi-bar{flex:1 1 0;min-width:0;height:100%;display:flex;flex-direction:column;justify-content:flex-end;align-items:center}
.card-webinfo .wi-bar-n{font-size:10px;opacity:.5;line-height:1.2;margin-bottom:2px;font-variant-numeric:tabular-nums}
.card-webinfo .wi-bar-fill{width:100%;max-width:22px;border-radius:4px 4px 2px 2px;background:var(--theme-color);background:linear-gradient(180deg,var(--theme-color),color-mix(in srgb,var(--theme-color) 30%,transparent))}
.card-webinfo .wi-years{display:flex;gap:6px;margin-top:4px}
.card-webinfo .wi-year{flex:1 1 0;min-width:0;text-align:center;font-size:10px;opacity:.45}
.card-webinfo .wi-visit{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:10px;border-top:1px solid rgba(128,128,128,.2);padding-top:9px}
.card-webinfo .wi-visit-item{text-align:center}
.card-webinfo .wi-visit-num{font-size:16px;font-weight:600;line-height:1.3;font-variant-numeric:tabular-nums}
.card-webinfo .wi-visit-label{font-size:11px;opacity:.55;margin-top:2px}

/* ── 9/12  #ft-hide-self  ← 原 _config.fomalhaut.yml:1522-1526 ── */
/* 页脚「推荐友链⌛」隐藏本站自己那一项（2026-10-03） */
/* 该列表硬编码在 themes/fomalhaut/layout/includes/footer.pug:33-58，没有任何配置项可管； */
/* 按 href 精准隐藏（:has() 现代 Chrome 生效，老浏览器不支持时优雅降级为仍显示）。 */
/* 页脚推荐友链：去掉指向本站（example.com）的那一项 */
.ft-img-group .img-group-item:has(> a[href*="example.com"]) { display: none !important; }

/* ── 10/12  #aplayerVolumeFix  ← 原 _config.fomalhaut.yml:1538-1542 ── */
/* 八音盒 APlayer 音量条「点了看不出变化」修复（2026-10-03） */
/* 根因：APlayer 渲染出的 .aplayer-volume 自带内联 style="background:<data-theme 的颜色>"， */
/*   内联样式优先级高于样式表，于是 themes/fomalhaut/source/css/_custom/custom.css:1492 那句 */
/*   不带 !important 的 background: var(--theme-color) 从来没生效过——填充色一直是 */
/*   source/life/music/index.md 里 data-theme="#e3f2f5" 的浅灰蓝； */
/*   而槽色（custom.css:1488）是 color-mix(--theme-color 18%, #fff)，也是接近白的浅色， */
/*   两段肉眼几乎同色 → 拖动/点击音量条、点喇叭静音时只有声音变，看不出任何变化。 */
/* 修法照主题对 .aplayer-played / .aplayer-thumb 的既有做法（custom.css 里那两句都带 !important）， */
/*   这里补 !important 把填充色拉回主题色；再补夜间模式的槽色（custom.css 只给 */
/*   .aplayer-bar / .aplayer-loaded 写了夜间色，漏了音量条）。 */
/* 回滚：删掉下面这一整段即可（纯样式，不碰播放逻辑）。 */
#article-container .aplayer .aplayer-volume { background: var(--theme-color) !important; }
[data-theme="dark"] #article-container .aplayer .aplayer-volume-bar { background: color-mix(in srgb, var(--theme-color) 25%, #242424); }

/* ── 11/12  #readModeIconGuard  ← 2026-10-04 新增（站点级兜底） ── */
/* 阅读模式下的标题小风车兜底。
 * 主题在阅读模式里会把标题内边距整个清空（编译产物 public/css/index.css 里）：
 *   .read-mode #article-container h1 ~ h6 { padding: 0 }   —— 还有一份 :hover 版
 * 但标题前风车图标的负 margin 依然生效（themes/fomalhaut/source/css/_custom/custom.css:925-960，
 *   h1~h6 依次是 -1.55 / -1.35 / -1.22 / -1.05 / -0.9 / -0.9rem），
 * 于是图标被顶到标题盒左侧：桌面端卡片左右各有 40px 内边距还能兜住，
 * 窄屏卡片只剩 14px（.layout > div:first-child:not(.recent-posts) { padding: 36px 14px }），
 * 图标就会顶出卡片、在手机视口边缘被裁掉 —— 和友人帐 / 网址导航那两页是同一个毛病。
 * 这里只在窄屏补回左内边距（= 该级负 margin + 约 0.25rem 间隙），图标就稳定落在标题盒内；
 * 桌面端阅读模式保持原样，不改观感。
 * 特异性：#content-inner.layout #article-container h2 = (2,0,1) ＞ 主题的 .read-mode #article-container h2 = (1,1,1)，
 *   所以不需要 !important 也能压过（本文件在 /css/index.css 之后加载，顺序上也占优）。
 * 回滚：删掉下面这一整段即可（纯样式，不涉及任何 JS / 模板 / 主题源码）。 */
@media screen and (max-width: 768px) {
  .read-mode #content-inner.layout #article-container h1 { padding-left: 1.8rem; }
  .read-mode #content-inner.layout #article-container h2 { padding-left: 1.6rem; }
  .read-mode #content-inner.layout #article-container h3 { padding-left: 1.5rem; }
  .read-mode #content-inner.layout #article-container h4 { padding-left: 1.3rem; }
  .read-mode #content-inner.layout #article-container h5,
  .read-mode #content-inner.layout #article-container h6 { padding-left: 1.15rem; }
}

/* ── 12/12  #letterBoard  ← 2026-10-04 新增（留言板 / 信封页改版） ── */
/* /comments/ 页面由 hexo-butterfly-envelope 插件生成，主题源码 themes/ 不动，样式按站点约定放这里。
 * 为什么不能只靠配置：插件把信封构图写死在 node_modules/hexo-butterfly-envelope/lib/html.pug 的内联
 *   <style> 里（#form-wrap 447px 裁剪、hover 才展开、#beforeimg/#afterimg 绝对定位），配置项只能换图片与文案。
 * 做法：
 *   ① 解除 447px 裁剪与 hover 联动 → 4 条留言提示默认可见（原来要悬停才露出来）；
 *   ② 给插件内容套一层主题色「信笺台」#maincontent（点阵 + 顶部主题色渐变）；
 *   ③ 信封正面口袋 after.png 从绝对定位改回正常流元素 + 负 margin，让信纸底边稳定插进袋口；
 *      #beforeimg（信封背页）隐藏，避免它的白/蓝底与信纸的白底在袋口透明区打架；
 *   ④ 重排标题 / 提示面板 / 签名，并把评论区上方分隔线、评论图标改成主题色。
 * 作用域 #page:has(#maincontent)：只有这个插件页生效；:has() 不支持时整块失效，页面回落到插件原样。
 * 回滚：删掉本块即可（纯样式，不涉及 JS / 模板 / 主题源码）。 */
#page:has(#maincontent) {
  --lt-accent: var(--theme-color, #39c5bb);
  --lt-soft: rgba(57, 197, 187, .07);
  --lt-soft: color-mix(in srgb, var(--lt-accent) 7%, transparent);
  --lt-soft2: rgba(57, 197, 187, .15);
  --lt-soft2: color-mix(in srgb, var(--lt-accent) 15%, transparent);
  --lt-line: rgba(57, 197, 187, .22);
  --lt-line: color-mix(in srgb, var(--lt-accent) 22%, transparent);
  --lt-ink: #1f6b67;
  --lt-ink: color-mix(in srgb, var(--lt-accent) 52%, #10201f);
  --lt-muted: rgba(60, 60, 67, .55);
  --lt-muted: color-mix(in srgb, var(--font-color, #1f2937) 55%, transparent);
  --lt-pocket: 680px;
}
[data-theme="dark"] #page:has(#maincontent) {
  --lt-soft: rgba(57, 197, 187, .12);
  --lt-soft: color-mix(in srgb, var(--lt-accent) 12%, transparent);
  --lt-soft2: rgba(57, 197, 187, .22);
  --lt-soft2: color-mix(in srgb, var(--lt-accent) 22%, transparent);
  --lt-line: rgba(57, 197, 187, .32);
  --lt-line: color-mix(in srgb, var(--lt-accent) 32%, transparent);
  --lt-ink: #7fe3da;
  --lt-ink: color-mix(in srgb, var(--lt-accent) 78%, #fff);
  --lt-muted: color-mix(in srgb, var(--font-color, #e6e6e6) 62%, transparent);
}
/* ① 解除插件折叠 */
#page:has(#maincontent) #form-wrap,
#page:has(#maincontent) #form-wrap:hover {
  height: auto !important; top: 0 !important;
  overflow: visible !important; transition: none !important;
}
/* ② 信笺台 */
#page:has(#maincontent) #maincontent {
  width: 100%; max-width: 100%; box-sizing: border-box;
  margin: 0 auto; padding: 27px 22px 0;
  position: relative; border-radius: 20px;
  border: 1px solid var(--lt-line);
  background-image:
    radial-gradient(rgba(57, 197, 187, .26) 1px, transparent 1px),
    radial-gradient(120% 70% at 50% -8%, rgba(57, 197, 187, .15), transparent 62%),
    linear-gradient(180deg, rgba(57, 197, 187, .07), transparent 58%);
  background-image:
    radial-gradient(color-mix(in srgb, var(--lt-accent) 34%, transparent) 1px, transparent 1px),
    radial-gradient(120% 70% at 50% -8%, var(--lt-soft2), transparent 62%),
    linear-gradient(180deg, var(--lt-soft), transparent 58%);
  background-size: 16px 16px, auto, auto;
  animation: lt-board-in .55s ease-out both;
}
@keyframes lt-board-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  #page:has(#maincontent) #maincontent { animation: none; }
}
/* ③ 信纸 */
#page:has(#maincontent) #beforeimg { display: none !important; }
#page:has(#maincontent) #envelope { width: 600px; max-width: 100%; padding-top: 4px; position: relative; z-index: 2; }
#page:has(#maincontent) .formmain {
  background: var(--card-bg, #fff); width: 100% !important; max-width: none !important;
  border: 1px solid var(--lt-line) !important; border-radius: 14px !important;
  box-shadow: 0 22px 46px -26px rgba(0, 0, 0, .5) !important;
  overflow: hidden !important;
}
#page:has(#maincontent) img.headerimg {
  display: block; width: 100% !important; height: 214px; margin: 0 !important;
  object-fit: cover; object-position: center 16%;
  -webkit-mask-image: linear-gradient(180deg, #000 74%, transparent);
  mask-image: linear-gradient(180deg, #000 74%, transparent);
}
#page:has(#maincontent) #maincontent .comments-main { padding: 8px 30px 28px; }
#page:has(#maincontent) #maincontent h3.title3 {
  margin: 0 0 15px !important; padding: 0 0 12px !important; position: relative;
  font-size: 19px !important; font-weight: 700; letter-spacing: 1px;
  color: var(--lt-ink) !important; text-align: center !important;
}
#page:has(#maincontent) #maincontent h3.title3::after {
  content: ""; position: absolute; left: 50%; bottom: 0; width: 46px; height: 3px;
  border-radius: 3px; transform: translateX(-50%);
  background: linear-gradient(90deg, var(--lt-accent), color-mix(in srgb, var(--lt-accent) 28%, transparent));
}
#page:has(#maincontent) #maincontent .comments {
  margin: 15px 0 0 !important; padding: 14px 22px !important;
  background: var(--lt-soft) !important; border: 1px solid var(--lt-line) !important;
  border-radius: 14px !important; text-align: left !important;
}
#page:has(#maincontent) #maincontent .comments > div {
  display: flex; gap: 10px; align-items: baseline;
  font-size: 14.5px; line-height: 2; color: var(--font-color, #1f2937);
}
#page:has(#maincontent) #maincontent .comments > div::before {
  content: "✦"; flex: 0 0 auto; font-size: 11px; color: var(--lt-accent); opacity: .9;
}
#page:has(#maincontent) #maincontent .comments > div + div { border-top: 1px dashed var(--lt-line); }
#page:has(#maincontent) #maincontent .bottomcontent { margin-top: 20px !important; }
#page:has(#maincontent) #maincontent .bottomcontent img.bottomimg {
  display: block; width: auto !important; max-width: 100%; height: auto; max-height: 54px;
  margin: 0 auto !important; opacity: .85;
}
#page:has(#maincontent) #maincontent p.bottomhr {
  margin: 2px 6px 0 0 !important; text-align: right !important;
  font-size: 12.5px !important; font-style: italic; letter-spacing: .5px;
  color: var(--lt-muted) !important;
}
#page:has(#maincontent) #maincontent p.bottomhr::before { content: "—— "; }
/* ④ 信封口袋 after.png：脱离绝对定位，用负 margin 咬住信纸底边 */
#page:has(#maincontent) #afterimg {
  position: relative !important; left: auto !important; right: auto !important;
  top: auto !important; bottom: auto !important;
  display: block !important; z-index: 3 !important;
  width: var(--lt-pocket) !important; max-width: 100%; height: auto !important;
  margin: -38px auto 0 !important; pointer-events: none;
  filter: drop-shadow(0 14px 20px rgba(0, 0, 0, .16));
  /* after.png 的左上 / 右上被硬切成平口（原设计靠 #beforeimg 背页压住，本块把背页隐藏了），
   * 顶部 20px 渐隐后平口没入信笺台点阵，不再出现两条横向断线。 */
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 20px);
  mask-image: linear-gradient(180deg, transparent 0, #000 20px);
}
/* ⑤ 评论区 */
#page:has(#maincontent) #article-container + hr {
  border: 0 !important; height: 1px !important; max-width: 460px; margin: 30px auto !important;
  background: linear-gradient(90deg, transparent, var(--lt-line), transparent) !important;
}
#page:has(#maincontent) #post-comment .comment-headline { letter-spacing: 1px; }
#page:has(#maincontent) #post-comment .comment-headline i { color: var(--lt-accent); }
@media screen and (max-width: 768px) {
  #page:has(#maincontent) #maincontent { padding: 16px 10px 20px; border-radius: 16px; }
  #page:has(#maincontent) #envelope { width: 100%; padding-top: 0; }
  #page:has(#maincontent) img.headerimg { height: 148px; }
  #page:has(#maincontent) #maincontent .comments-main { padding: 6px 16px 20px; }
  #page:has(#maincontent) #maincontent .comments { padding: 12px 15px !important; }
  #page:has(#maincontent) #maincontent .comments > div { font-size: 13.5px; }
  #page:has(#maincontent) #afterimg { display: none !important; }
}

/* ── 13/13  cardAnimPerf  ← 2026-10-04 新增（首页卡片动画改走合成层）────────────
 * 背景：首页每张卡片里的小箭头 .recent-post-arrow 用 @keyframes ddd 动 top，
 *   置顶角标的流光 .post-sticky-shine 动 left。top / left 都是「非合成属性」，
 *   浏览器每帧要重算布局 + 重绘：首页 9 个箭头 + 3 个角标 = 每帧 12 次布局失效，
 *   页面静止不动也一直在跑 —— 属于「静置帧率不高 / 机身发热」的直接来源。
 * 做法：同名重声明 @keyframes（后声明者胜，主题 /css/index.css 在本文件之前），
 *   把动画属性换成 transform（合成层动画，不触发布局）；箭头原来的 top 静态值
 *   补上（动画在跑时 top 恒为 20~30px，见 custom.css 的 ddd 关键帧），位移交给
 *   translateY，观感与原来逐帧一致。
 * 注意：.recent-post-arrow 是 position: absolute + top: auto，必须显式补 top，
 *   否则动画一撤它会掉回 static 位置。主题里没有任何规则给这个元素设过 top
 *   （只有 @keyframes ddd 设过），因此补 top 不会跟别的规则打架。
 * 回滚：删掉本块即可（备份 bak/20261004-perf-idle-frame/before/source/css/site-inject.css）。
 * ──────────────────────────────────────────────────────────────────────────── */
.recent-post-arrow {
  top: 20px;
}

@keyframes ddd {
  0%   { transform: translateY(10px); }
  10%  { transform: translateY(0); }
  20%  { transform: translateY(10px); }
  30%  { transform: translateY(0); }
  60%  { transform: translateY(2px); }
  90%  { transform: translateY(0); }
  100% { transform: translateY(0); }
}

/* 置顶角标流光：left -60% → 118% 换成 translateX。
   元素自身宽度是角标宽度的 45%，所以 178% 的角标宽度 = 178/45 ≈ 395% 的元素宽度；
   角标是 overflow: hidden，多出来的部分本来也看不见。 */
@keyframes post-sticky-shine {
  0%,
  62% {
    transform: skewX(-18deg) translateX(0);
  }
  86%,
  100% {
    transform: skewX(-18deg) translateX(395%);
  }
}

/* ── 14/14  loadingIdle  ← 2026-10-04 新增（加载遮罩隐藏后停掉内部动画）────────
 * 背景：#loading-box（heo 版加载遮罩）加载完只是被加上 .loaded，让 .loading-bg
 *   变成 opacity: 0 / z-index: -1000 —— 元素并没有离开渲染树。里面的 .loading-img
 *   还挂着 animation: loadingAction 0.3s infinite（动的是 opacity），于是首页
 *   永远有一条「看不见但在跑」的动画，浏览器也就永远有活干。
 * 做法：只在 .loaded 状态下停掉内部动画。遮罩真正显示时（加载中 / pjax 换页，
 *   preloader 会移除 .loaded）规则不生效，动画照常。隐藏后的 0.3s 淡出是父层
 *   opacity 过渡，与本条无关，观感零变化。
 * 回滚：删掉本块即可（备份 bak/20261004-perf-idle-frame/before/source/css/site-inject.css）。
 * ──────────────────────────────────────────────────────────────────────────── */
#loading-box.loaded .loading-img {
  animation: none;
}

/* ── 15/15  cardGlassOff  ← 2026-10-04 新增（作者卡去掉实时背景模糊）─────────────
 * 背景：themes/fomalhaut/source/css/_custom/custom.css:3787-3793 在 ≥1200px 给作者卡
 *   的 ::before 加了 backdrop-filter: blur(11px) saturate(1.45)。卡片本身是随页面滚动的，
 *   而它背后的 #web_bg 是 position: fixed 不动的 —— 于是浏览器每一帧都要对「卡片此刻
 *   盖住的那块背景」重做一次高斯模糊。这是侧栏滚动时最贵的一项，弱 GPU 上直接掉帧。
 * 做法：用同样特异性的选择器（本文件在 /css/index.css 之后加载，后声明者胜）把
 *   backdrop-filter 置 none。渐变一个字没动 → 卡片的白色罩层、顶部渐隐、整体明度
 *   完全不变；唯一差别是卡片上半部分背后的背景图不再是磨砂的，而是清晰原图。
 * 如果觉得清晰背景图太花、压不住文字：把下面「备用」那段注释取消即可
 *   （整体比原渐变白 8% 左右，只影响 ≥1200px 的桌面端），一行就能调。
 * 想恢复玻璃拟态：删掉本块即可。
 * 回滚备份：bak/20261004-perf-idle-frame/before/source/css/site-inject.css
 * ──────────────────────────────────────────────────────────────────────────── */
#aside-content > .card-widget.card-info::before,
[data-theme="dark"] #aside-content > .card-widget.card-info::before {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

/* 备用：觉得背景图太抢时启用（取消这行的注释符号即可）
@media (min-width: 1200px) {
  #aside-content > .card-widget.card-info::before {
    background: linear-gradient(180deg, rgba(255,255,255,.14) 0%, rgba(255,255,255,.56) 30%, rgba(255,255,255,.82) 64%, rgba(255,255,255,.92) 100%);
  }
  [data-theme="dark"] #aside-content > .card-widget.card-info::before {
    background: linear-gradient(180deg, rgba(6,22,30,.14) 0%, rgba(6,22,30,.56) 30%, rgba(6,22,30,.82) 64%, rgba(6,22,30,.92) 100%);
  }
}
*/

/* 背景滤镜：仅面板内生效，原生滑条本身有 44px 触摸区域。 */
.settings .bf-panel { margin:18px 10px 24px; max-width:600px; padding:20px; border:1px solid rgba(128,128,128,.25); border-radius:16px; }
.settings .bf-heading,.settings .bf-value-row { display:flex; align-items:center; justify-content:space-between; gap:12px; }
.settings .bf-heading { font-weight:700; }
.settings .bf-heading input { margin:0; flex-shrink:0; }
.settings .bf-hint { margin:8px 0 18px; font-size:.8em; opacity:.8; line-height:1.6; }
.settings .bf-control { margin:18px 0; }
.settings .bf-value-row>label { font-weight:600; }
.settings .bf-number { display:flex; align-items:center; gap:8px; }
/* 卡片不透明度与背景滤镜共用数字框样式；覆盖主题滤镜输入框的 max-width:50px，避免三位数裁切与 flex 压缩。 */
.settings .bf-panel .bf-number input:is(#transNumber, #blurRad, #saturation, #contrast) { box-sizing:border-box; flex:0 0 76px; width:76px; min-width:76px; max-width:none; height:44px; margin:0; padding:6px 8px; border:1px solid rgba(128,128,128,.45); border-radius:8px; background:rgba(128,128,128,.08); color:inherit; font:inherit; font-size:16px; text-align:center; }
.settings .bf-panel input:focus-visible,.settings .bf-panel button:focus-visible { outline:2px solid var(--theme-color); outline-offset:3px; }
.settings .bf-panel .bf-slider { --bf-fill:0%; box-sizing:border-box; display:block; width:100%; height:44px; margin:2px 0 0; padding:0; border:0; border-radius:0; background:linear-gradient(to right,var(--theme-color) var(--bf-fill),rgba(128,128,128,.35) var(--bf-fill)) center / 100% 5px no-repeat; touch-action:pan-y; cursor:pointer; }
.settings .bf-slider::-webkit-slider-thumb { width:22px; height:22px; border:3px solid var(--theme-color); background:var(--theme-color); border-radius:50%; }
.settings .bf-slider::-moz-range-thumb { width:18px; height:18px; border:2px solid var(--theme-color); background:var(--theme-color); border-radius:50%; }
.settings .bf-slider::-moz-range-track { background:transparent; border:0; }
.settings .bf-limits { display:flex; justify-content:space-between; gap:8px; font-size:.72em; line-height:1.5; opacity:.75; }
.settings .bf-limits span:nth-child(2) { text-align:center; }
.settings .bf-footer { display:flex; justify-content:flex-end; margin-top:20px; }
.settings .bf-footer button { min-height:44px; padding:8px 12px; border:1px solid rgba(128,128,128,.45); border-radius:8px; color:inherit; background:transparent; font:inherit; font-size:.85em; cursor:pointer; }
.settings .bf-panel input:disabled,.settings .bf-panel button:disabled { opacity:.4; cursor:not-allowed; }
@media(max-width:480px) { .settings .bf-panel { margin:16px 0; padding:14px 12px; } }

/* FPS 轻量状态条：不阻挡点击，不加模糊或动画；预留数值与状态宽度，避免刷新抖动。
   配色按观感优先（2026-10-15 作者确认）：小字对比度有意不按 4.5:1 收紧，
   浅底压在深色壁纸上约 3.2–4.3:1；曾按对比度压深过一版，观感变闷、状态色也难区分，
   已回退 —— 不要再"优化"回去。背景滤镜那套数字框的对比度结论不适用于这里。
   状态色由 data-state（good/warn/low）交给 CSS 定义，不反查内联 style。
   状态色间距（2026-10-15）：原来 amber(#94600d) 与 red(#b13b42) 的 L* 与彩度几乎相同、
   色相只差 48°，12px 下很难一眼分开 —— 现在把 amber 推向金黄、red 推向纯红，
   Lab ΔE 从 43 提到 64（深色 44 → 60）。*/
html #fps, html[data-theme] #fps {
  --fps-bg:rgba(232,242,246,.88); --fps-fg:#283c45; --fps-muted:#65757b;
  --fps-border:rgba(61,91,104,.18); --fps-good:#267d72; --fps-warn:#a0740d; --fps-low:#df2039;
  box-sizing:border-box; position:fixed; left:12px; bottom:12px;
  left:calc(12px + env(safe-area-inset-left,0px)); bottom:calc(12px + env(safe-area-inset-bottom,0px));
  z-index:1000; width:max-content; height:30px; padding:0 9px;
  border:1px solid var(--fps-border); border-radius:9px; background:var(--fps-bg); color:var(--fps-fg);
  font-size:13px; line-height:28px; font-weight:500; white-space:nowrap;
  box-shadow:0 2px 8px rgba(15,35,45,.06); pointer-events:none; user-select:none;
}
html[data-theme="dark"] #fps {
  --fps-bg:rgba(18,29,35,.88); --fps-fg:#dce9ef; --fps-muted:#9aacb6;
  --fps-border:rgba(192,219,232,.16); --fps-good:#75d2c5; --fps-warn:#f0cb68; --fps-low:#ff8a95;
}
#fps:empty { visibility:hidden; }
#fps > span { display:inline-block; vertical-align:middle; line-height:18px; }
#fps .fps-label { font-size:10px; letter-spacing:.6px; color:var(--fps-muted); }
#fps .fps-value { width:3ch; margin:0 6px; font-family:ui-monospace,SFMono-Regular,Consolas,monospace; font-variant-numeric:tabular-nums; font-weight:600; text-align:right; }
#fps .fps-state { min-width:3.5em; font-size:12px; }
#fps .fps-state::before { content:"·"; margin-right:5px; color:var(--fps-muted); }
#fps .fps-state[data-state="good"] { color:var(--fps-good); }
#fps .fps-state[data-state="warn"] { color:var(--fps-warn); }
#fps .fps-state[data-state="low"] { color:var(--fps-low); }
@media(max-width:600px) {
  html #fps, html[data-theme] #fps { height:28px; line-height:26px; padding:0 8px; border-radius:8px; }
}

/* 互动挂件与功能分区：沿用 bf-panel 的边框、留白与圆角，不改主题源码。 */
.beauty-neko-off .neko,
.beauty-neko-off #myscoll { display:none !important; }
.settings { container-type:inline-size; }
.settings .feature-grid { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:8px 22px; }
.settings .feature-opt { display:flex; align-items:center; justify-content:space-between; gap:12px; min-width:0; min-height:64px; padding:8px 0; cursor:pointer; }
.settings .feature-opt > span { min-width:0; font-weight:600; line-height:1.5; }
.settings .feature-opt small { display:block; margin-top:3px; font-size:.72em; font-weight:400; opacity:.75; line-height:1.5; }
.settings .feature-opt input[type="checkbox"] { flex-shrink:0; margin:0; }
@container (max-width:560px) { .settings .feature-grid { grid-template-columns:minmax(0,1fr); gap:4px; } }
@media(max-width:600px) { .settings .feature-grid { grid-template-columns:minmax(0,1fr); gap:4px; } }

/* 点击涟漪（第 4 个互动挂件，默认关闭 · 和猫咪/听话鼠标同一区）
   层是 0×0 且 pointer-events:none，不参与命中测试：链接、按钮、文字选择照常先拿到点击，
   所以不需要"只在空白处画"那种每次点击跑一遍命中测试的写法；关掉开关时连监听都不挂。
   z-index:9998 —— 高于正文/侧栏/美化面板（winbox 的 z-index 是个位数），
   低于光标圆点 #cursor-position(10086)、猫咪 .neko(99990)、右键菜单(19198)，也低于昼夜过场 .dm-stage。
   颜色全部从 --theme-color 派生，换主题色或自定义取色时自动跟随。 */
.ripple-layer { position:fixed; left:0; top:0; width:0; height:0; pointer-events:none; z-index:9998; }
.ripple-burst { position:absolute; left:0; top:0; width:0; height:0; }
.ripple-ring { box-sizing:border-box; position:absolute; left:0; top:0; width:46px; height:46px; margin:-23px 0 0 -23px; border-radius:50%; border:1.5px solid color-mix(in srgb, var(--theme-color, #39c5bb) 55%, transparent); opacity:0; animation:ripple-out .52s cubic-bezier(.22,.61,.36,1) forwards; }
/* 第二环错开 60ms、更细更淡：两圈同心速度略不同，一眼是水波不是单圈涟漪。 */
.ripple-ring.is-late { border-width:1px; border-color:color-mix(in srgb, var(--theme-color, #39c5bb) 30%, transparent); animation-delay:.06s; animation-duration:.56s; }
@keyframes ripple-out { from { transform:scale(.16); opacity:.9; } to { transform:scale(2.6); opacity:0; } }

/* 十色预设色板：站点注入覆盖主题变量，不改主题源码。
   青绿、珊瑚红、紫罗兰、樱花粉保持原色；与 boot/cursor 的 RGB 完全对应。 */
:root {
  --color-orange: rgb(215, 146, 77); /* 暖杏橙 #D7924D */
  --color-yellow: rgb(196, 166, 74); /* 蜂蜜金 #C4A64A */
  --color-puregreen: rgb(77, 175, 135); /* 玉石绿 #4DAF87 */
  --color-blue: rgb(74, 156, 199); /* 晴空蓝 #4A9CC7 */
  --color-heoblue: rgb(97, 106, 209); /* 柔靛蓝 #616AD1 */
  --color-darkblue: rgb(113, 133, 156); /* 雾蓝灰 #71859C */
  --color-matcha: rgb(102, 179, 77); /* 抹茶绿 #66B34D（2026-10-14 新增：补 80°–150° 的黄绿区） */
}

/* 主题色「实底上的前景色」--on-theme（2026-10-14 新增）
   由来：主题的按钮/标签/分页/右栏图标/气泡/选中底色全是白字压在 --theme-color 上，
   而 10 个预设里只有紫罗兰的白字过 WCAG AA（默认青绿只有 2.13:1，蜂蜜金 2.36:1）。
   前景色由站点脚本按主题色亮度算：
     · source/js/inject/beauty-boot.js —— 首帧前写（浅色预设不会先闪一下白字）
     · source/js/modules/settings.js 的 setColor() —— 换色时写
   亮度高的预设给近黑 #141a1c（实测最低 4.8:1），亮度低的给纯白（最低 4.4:1）。
   下面这段只做三件事：① 脚本没跑时的兜底；② 把主题里 var(--btn-color)=#fff 接到同一条链；
   ③ 把主题 CSS 里带 !important、没法靠变量覆盖的两处（TOC 当前项、作者卡按钮 hover）抄一遍。 */
:root { --on-theme: #ffffff; }
/* ── 实底图标块：右侧工具条那排 38×38（2026-10-15 第三版）────────────────────────
   这三轮试下来的结论：颜色越压深越"稳"，但越没活泼感；站点主人要的是亮。
   所以最终取「主题色原色 + 白图标 + 一层极轻的暗投影」：
     · 填充回到主题色原色（青绿 rgb(57,197,187)），不再压深 —— 这是最亮、最接近原设计的状态；
     · 白图标在原色底上名义对比只有 2.13:1（WCAG 不把投影算进对比度），
       但 0 1px 1px 的深色投影把字形边缘压出来，实际观感不糊（和改之前的样子基本一致，只是更清晰）。
   如果要回到"压深一档"的版本（白图标 3.45:1 但偏暗）：把下面两行的 background-color 换成
   color-mix(in srgb, var(--theme-color) 75%, #0b1416) 即可（备份见 bak/theme-ink-20261014/before/）。
   hover 仍是主题自带的 --btn-hover-color（浅橙 #FF7242），保持不变。 */
#rightside > div > a,
#rightside > div > button {
  background-color: var(--theme-color);
  color: #fff;
  text-shadow: 0 1px 1px rgba(6, 32, 34, .45);
}
#rightside > div > a svg,
#rightside > div > button svg { filter: drop-shadow(0 1px 1px rgba(6, 32, 34, .45)); }
/* 主题 var.styl:70 的 $button-color = #fff，所有 var(--btn-bg)（=主题色）面上的字与图标 */
:root { --btn-color: var(--on-theme) !important; }
/* 选中文字：Chrome 侧主题只设了底色，Firefox 侧写死白字（custom.css:274 / 2106） */
*::selection { color: var(--on-theme); }
::-moz-selection { color: var(--on-theme); }
/* TOC 当前项（custom.css:2109-2114） */
#aside-content #card-toc .toc-content .toc-link.active,
#aside-content #card-toc .toc-content .toc-link.active:hover { color: var(--on-theme) !important; }
/* 主题 CSS 里写死 white、但底色就是主题色/渐变主题色的几处（custom.css:1473 作者卡按钮、
   3812 设置面板保存按钮、3813 切换背景按钮、4013 恢复默认按钮）：统一接到 --on-theme。
   标签外挂按钮（_tags/button.styl:11 的 $btn-color=#fff）hover 时底色换成 --btn-hover-color，也要跟着走。 */
#aside-content > .card-widget.card-info > #card-info-btn { color: var(--on-theme) !important; }
.settings .bgp-save, .settings .picbtn, #reset_btn { color: var(--on-theme); }
#article-container .btn-beautify:hover { color: var(--on-theme); }
/* tag-hide 的折叠按钮：底色是 $tag-hide-bg、字是 var(--white)，hover 换成 --btn-hover-color */
#article-container .hide-button:hover { color: var(--on-theme); }
/* 音乐卡标签 + 作者卡按钮 hover（custom.css:1705 / 3889 / 3950，主题里带 !important） */
#article-container .music-note-id { color: var(--on-theme); }
#aside-content > .card-widget.card-info > #card-info-btn:hover,
[data-theme="dark"] #aside-content > .card-widget.card-info > #card-info-btn:hover { color: var(--on-theme) !important; }
/* 新增档位的圆点样式：主题 CSS 里没有 #matcha 这条规则（它是站点新增的档位），
   所以边框/选中态在这里补齐，配色引用上面同一份色板变量。 */
#matcha { border: 3px solid var(--color-matcha); }
#matcha:checked { box-shadow: 0 0 0 2px #fff inset; border-radius: 50%; border: 3px solid var(--color-matcha); background-color: var(--color-matcha); }
/* 主题色：24px 可见圆环 / 44px 热区；按面板宽度换行，不依赖屏幕宽度。 */
.settings .content.colorRow { display:flex; flex-wrap:wrap; justify-content:flex-start; align-items:center; gap:4px 2px; padding:4px 0 0 8px; margin:0; }
.settings .colorRow .theme-choice { position:relative; display:inline-flex; align-items:center; justify-content:center; flex:0 0 44px; width:44px; height:44px; border-radius:50%; cursor:pointer; }
.settings .colorRow .theme-choice input[name="colors"] { box-sizing:border-box; flex:none; min-width:24px; width:24px; height:24px; margin:0; padding:0; border-width:3px; cursor:pointer; transition:transform .18s ease; }
.settings .colorRow .theme-choice:hover input[name="colors"],.settings .theme-custom:hover .theme-rainbow { transform:scale(1.08); }
.settings .colorRow .theme-choice input:focus-visible { outline:2px solid currentColor; outline-offset:5px; }
.settings .colorRow .theme-custom { margin-left:6px; }
.settings .theme-rainbow { display:block; position:relative; width:24px; height:24px; flex:none; border-radius:50%; background:conic-gradient(var(--color-red),var(--color-orange),var(--color-yellow),var(--color-matcha),var(--color-puregreen),var(--color-green),var(--color-blue),var(--color-darkblue),var(--color-heoblue),var(--color-purepurple),var(--color-pink),var(--color-red)); transition:transform .18s ease; }
.settings .theme-rainbow::before { content:""; position:absolute; inset:3px; border-radius:50%; background:#f5f5f5; }
[data-theme="dark"] .settings .theme-rainbow::before { background:#333; }
.settings .theme-rainbow::after { content:""; position:absolute; inset:7px; border-radius:50%; background:var(--custom-theme-color,#c74bd0); opacity:0; }
.settings .theme-custom.is-selected .theme-rainbow::after { opacity:1; }
.settings .colorRow .theme-custom input[type="color"] { position:absolute; inset:0; box-sizing:border-box; width:44px; height:44px; margin:0; padding:0; border:0; opacity:0; cursor:pointer; }
.settings .colorRow .theme-custom:has(input:focus-visible) { outline:2px solid currentColor; outline-offset:0; }
.settings .theme-color-hint { margin:8px 12px 22px; font-size:.75em; line-height:1.7; opacity:.8; }
@media(prefers-reduced-motion:reduce) { .settings .theme-rainbow,.settings .colorRow .theme-choice input[name="colors"] { transition:none; } }

/* 字体/背景预览：站点模块专用，保持首屏字体和壁纸默认策略。 */
.settings .ap-panel { --ap-border:rgba(40,55,65,.16); --ap-surface:rgba(255,255,255,.52); --ap-soft:rgba(255,255,255,.32); margin:12px 0 24px; padding:20px; border:1px solid var(--ap-border); border-radius:16px; min-width:0; }
[data-theme="dark"] .settings .ap-panel { --ap-border:rgba(255,255,255,.16); --ap-surface:rgba(255,255,255,.055); --ap-soft:rgba(255,255,255,.025); }
.settings .ap-section-head { display:flex; justify-content:space-between; align-items:flex-start; gap:16px; margin-bottom:16px; }
.settings .ap-eyebrow { font-weight:700; margin:0 0 4px!important; font-size:1.05em; }
.settings .ap-hint,.settings .ap-bg-meta { margin:4px 0 12px!important; opacity:.78; font-size:.85em; line-height:1.7; overflow-wrap:anywhere; }
.settings #article-container .ap-subtitle { margin:18px 0 10px; padding:0; font-size:1.05em; font-weight:600; }
.settings #article-container .ap-subtitle::before { display:none; }
.settings .ap-btn,.settings .ap-font-option,.settings .ap-bg-option { font:inherit; color:inherit; background:var(--ap-surface); border:1px solid var(--ap-border); border-radius:10px; box-shadow:none; cursor:pointer; transition:border-color .16s,background-color .16s; }
.settings .ap-btn { min-height:44px; padding:8px 14px; line-height:1.5; flex-shrink:0; }
.settings .ap-btn:hover,.settings .ap-font-option:hover,.settings .ap-bg-option:hover { border-color:var(--theme-color); }
.settings .ap-btn:focus-visible,.settings .ap-font-option:focus-visible,.settings .ap-bg-option:focus-visible,.settings .ap-details>summary:focus-visible,.settings .ap-bg-advanced>summary:focus-visible,.settings #pic-link:focus-visible { outline:2px solid var(--theme-color); outline-offset:3px; }
.settings .ap-btn:disabled { opacity:.45; cursor:not-allowed; }
.settings #swfs,.settings #swfs_code,.settings .ap-font-grid { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:10px; }
.settings .ap-font-option { position:relative; min-height:72px; padding:12px 32px 12px 14px; text-align:left; min-width:0; }
.settings .ap-font-name { display:block; font-weight:600; line-height:1.5; overflow-wrap:anywhere; }
.settings .ap-font-option small { display:block; margin-top:4px; opacity:.78; font-size:.78em; line-height:1.6; }
.settings .ap-check { position:absolute; right:12px; top:12px; color:var(--theme-color); display:none; }
.settings .ap-font-option[aria-pressed="true"],.settings .ap-bg-option[aria-pressed="true"],.settings .ap-tabs .ap-btn[aria-pressed="true"] { border-color:var(--theme-color); background:color-mix(in srgb,var(--theme-color) 12%,var(--ap-surface)); box-shadow:inset 0 0 0 1px var(--theme-color); }
.settings .ap-font-option[aria-pressed="true"] .ap-check { display:block; }
.settings .ap-preview { margin-top:16px; padding:16px 18px; border:1px solid var(--ap-border); border-radius:12px; background:var(--ap-soft); min-width:0; }
.settings .ap-current { margin:0 0 10px!important; font-size:.8em; opacity:.78; font-family:system-ui,sans-serif; }
.settings .ap-text-sample { font-size:18px; line-height:1.85; margin:0!important; overflow-wrap:anywhere; }
.settings #article-container .ap-code-sample { margin:0; padding:0; background:transparent; color:inherit; font-size:14px; line-height:1.8; white-space:pre-wrap; overflow-wrap:anywhere; border-radius:0; }
.settings .ap-status { min-height:1.7em; margin:10px 0 0!important; font-size:.8em; line-height:1.7; opacity:.82; overflow-wrap:anywhere; }
.settings .ap-status[data-state="error"] { opacity:1; font-weight:600; }
.settings .ap-details,.settings .ap-bg-advanced { margin:14px 0; border-top:1px solid var(--ap-border); }
.settings .ap-details>summary,.settings .ap-bg-advanced>summary { min-height:44px; line-height:1.6; padding:12px 0; cursor:pointer; font-size:.88em; }
.settings .ap-license { margin-bottom:0; }
.settings .ap-bg-current { display:grid; grid-template-columns:150px minmax(0,1fr); align-items:center; gap:12px 18px; margin-bottom:10px; }
.settings .ap-bg-current>.ap-btn { grid-column:2; justify-self:start; }
.settings .ap-bg-thumb { margin:0!important; display:block; width:100%; aspect-ratio:16/9; object-fit:cover; border-radius:8px; background:var(--ap-soft); }
.settings .ap-bg-current>.ap-bg-thumb { grid-row:span 2; position:relative; overflow:hidden; }
.settings .ap-bg-current>.ap-bg-thumb img { width:100%; height:100%; object-fit:cover; }
.settings .ap-bg-placeholder { border:1px dashed var(--ap-border); }
.settings .ap-bg-name { display:block; line-height:1.55; font-size:.9em; overflow-wrap:anywhere; }
.settings .ap-tabs,.settings .ap-bg-actions { display:flex; flex-wrap:wrap; gap:8px; margin:14px 0; }
.settings .ap-tabs .ap-btn { flex:0 1 auto; }
.settings .ap-bg-grid { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:12px; margin:14px 0; }
.settings .ap-panel [hidden] { display:none!important; }
.settings .ap-bg-option { position:relative; overflow:hidden; min-width:0; padding:6px; text-align:left; }
.settings .ap-bg-option .ap-bg-name { padding:6px 3px 2px; }
.settings .ap-bg-option .ap-bg-meta { padding:0 3px; margin:0 0 3px!important; font-size:.72em; }
.settings #ap-bg-category-mobile .ap-bg-thumb { aspect-ratio:3/4; }
.settings .ap-bg-check { position:absolute; top:12px; right:12px; display:grid; place-items:center; width:24px; height:24px; background:var(--theme-color); color:var(--on-theme); border-radius:50%; box-shadow:0 1px 5px rgba(0,0,0,.2); }
.settings .ap-bg-swatch { min-height:54px; }
.settings #define_colors { box-sizing:border-box; width:72px; height:44px; margin:0 0 8px; vertical-align:middle; border:1px solid var(--ap-border); border-radius:8px; cursor:pointer; }
.settings #pic-link { box-sizing:border-box; width:100%; min-height:44px; padding:10px 12px; margin:8px 0 0; border:1px solid var(--ap-border); border-radius:10px; background:var(--ap-surface); color:inherit; font:inherit; font-size:.85em; }
.settings #ap-bg-custom-preview { width:100%; max-height:230px; position:relative; overflow:hidden; margin-top:12px; }
.settings #ap-bg-custom-preview img { width:100%; height:100%; max-height:230px; object-fit:contain; }
@container(max-width:560px) { .settings .ap-panel { padding:14px; } .settings #swfs,.settings #swfs_code,.settings .ap-font-grid { grid-template-columns:minmax(0,1fr); } .settings .ap-bg-grid { grid-template-columns:repeat(2,minmax(0,1fr)); } .settings .ap-section-head { flex-direction:column; gap:8px; } .settings .ap-bg-current { grid-template-columns:100px minmax(0,1fr); } .settings .ap-bg-current>.ap-btn { grid-column:1 / -1; } }
@media(max-width:600px) { .settings .ap-panel { padding:14px; } .settings #swfs,.settings #swfs_code,.settings .ap-font-grid { grid-template-columns:minmax(0,1fr); } .settings .ap-bg-grid { grid-template-columns:repeat(2,minmax(0,1fr)); } .settings .ap-section-head { flex-direction:column; gap:8px; } .settings .ap-bg-current { grid-template-columns:100px minmax(0,1fr); } .settings .ap-bg-current>.ap-btn { grid-column:1 / -1; } }
@media(prefers-reduced-motion:reduce) { .settings .ap-btn,.settings .ap-font-option,.settings .ap-bg-option { transition:none; } }

/* 萤火虫微光：只在下方背景层漂浮，位于正文/弹窗之后，不拦截点击。 */
#fireflies-stage {
  position:fixed; left:0; right:0; bottom:0;
  height:44vh; min-height:180px; max-height:440px;
  z-index:-1; overflow:hidden; pointer-events:none; user-select:none;
  contain:layout paint; margin:0; padding:0;
}
#fireflies-stage[hidden] { display:none!important; }
#fireflies-stage .ff-mote {
  position:absolute; display:block; width:34px; height:34px;
  margin:0; padding:0; pointer-events:none;
  animation:ff-drift var(--ff-drift-time) ease-in-out var(--ff-delay) infinite alternate;
}
#fireflies-stage .ff-glow {
  position:relative; display:block; width:100%; height:100%; border-radius:50%;
  background:radial-gradient(circle,rgba(var(--ff-color),.5) 0,rgba(var(--ff-color),.16) 20%,rgba(var(--ff-color),0) 70%);
  animation:ff-breathe var(--ff-breathe-time) ease-in-out var(--ff-delay) infinite;
}
#fireflies-stage .ff-glow::after {
  content:''; position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
  width:var(--ff-size); height:var(--ff-size); border-radius:50%;
  background:rgb(var(--ff-color)); box-shadow:0 0 6px 1px rgba(var(--ff-color),.65);
}
#fireflies-stage[data-paused="true"] .ff-mote,
#fireflies-stage[data-paused="true"] .ff-glow { animation-play-state:paused!important; }
@keyframes ff-drift {
  0% { transform:translate(-12px,10px); }
  45% { transform:translate(8px,-14px); }
  100% { transform:translate(22px,-32px); }
}
@keyframes ff-breathe {
  0%,100% { opacity:.18; }
  45% { opacity:.95; }
  70% { opacity:.5; }
}
@media(prefers-reduced-motion:reduce) {
  #fireflies-stage { display:none!important; }
  #fireflies-stage .ff-mote,#fireflies-stage .ff-glow { animation:none!important; }
  #snow { display:none!important; }
}

/* ── 16/16  #searchPanelUX  ← 2026-10-11 新增（搜索加载提示位置修正 + 搜索历史） ── */
/* 配套 JS：source/js/inject/search-lazy.js（inject.bottom 里带 ?v=20261011）。
   加载提示 .search-lazy-tip 由 JS 插在 #algolia-search-results 的首位（即 #algolia-hits 的前一个兄弟）：
   这样 hits 组件整块替换自己容器的内容时不会连带删掉它，也避开了 #algolia-hits > div 的滚动条样式。 */
#algolia-search-results > .search-lazy-tip { padding: 22px 0 26px; text-align: center; font-size: 14px; opacity: .6; }
#algolia-search-results > .search-lazy-tip i { margin-right: 6px; }

/* 搜索历史：插在 #algolia-search-input 之后（.search-wrap 内），随面板一起显隐。
   显隐由 JS 控制 hidden 属性（没有记录 / 已发起搜索 / 输入框里有内容时收起）。 */
.search-history { margin: 0 0 4px; }
.search-history[hidden] { display: none !important; }
.search-history-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; font-size: 13px; opacity: .72; }
.search-history-title i { margin-right: 5px; }
.search-history-clear { padding: 2px 6px; border: 0; border-radius: 6px; background: none; color: inherit; font-size: 12px; line-height: 1.4; cursor: pointer; transition: opacity .2s, background .2s; }
.search-history-clear:hover { background: rgba(0,0,0,.06); opacity: 1; }
.search-history-list { display: flex; flex-wrap: wrap; gap: 6px; max-height: 56px; overflow-y: auto; }
.search-history-item { display: inline-flex; align-items: center; gap: 4px; max-width: 100%; padding: 3px 8px; border-radius: 999px; background: rgba(0,0,0,.05); font-size: 12px; line-height: 1.5; cursor: pointer; transition: background .2s; }
.search-history-item:hover { background: rgba(0,0,0,.09); }
.search-history-text { max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.search-history-del { font-size: 11px; opacity: .45; transition: opacity .2s, color .2s; }
.search-history-del:hover { opacity: 1; color: #f56c6c; }

[data-theme="dark"] .search-history-item { background: rgba(255,255,255,.08); }
[data-theme="dark"] .search-history-item:hover { background: rgba(255,255,255,.14); }
[data-theme="dark"] .search-history-clear:hover { background: rgba(255,255,255,.1); }

/* 桌面端面板是「内容撑高 + top:10%」，而 #algolia-hits > div 的 max-height 按 80vh-240px 算，
   历史条最多再占约 90px。这里在历史可见时把结果区收窄 100px，避免面板顶出视口底部；
   @supports 兜底：不认识 :has() 的浏览器直接忽略这条，退回原样（不会比现在更差）。 */
@supports selector(:has(*)) {
  #algolia-search .search-wrap:has(.search-history:not([hidden])) #algolia-hits > div { max-height: calc(80vh - 340px); }
}

/* ── 17/17  #darkModeSpeed  ← 2026-10-11 新增（昼夜切换动画提速：整屏遮挡 ~3s → ~1.5s） ── */
/* 主题 _layout/sun_moon.styl 里天空交叉淡化 2s、星球转一圈 2s，太阳月亮互换是硬切；这里覆盖掉这些时长。
   数字与 source/js/modules/shell.js 的 NIGHT_SKY_FADE_MS / NIGHT_PLANET_MS / NIGHT_ICON_MS 对齐，改一边记得改另一边。
   本文件在 /css/index.css 之后加载，同特异性后加载者胜；这里仍加 !important，是为了以后主题换选择器或
   给元素加内联样式时不至于失效（这块就是专门用来盖主题值的）。 */
.Cuteen_DarkSky:before { transition: .75s ease all !important; }
.Cuteen_DarkPlanet { animation-duration: 1s !important; -webkit-animation-duration: 1s !important; }
.Cuteen_DarkSky #sun, .Cuteen_DarkSky #moon { transition: opacity .4s ease !important; }

/* 系统开了「减少动态效果」时不要动画（JS 侧已经不会插遮罩了，这里是兜底） */
@media (prefers-reduced-motion: reduce) {
  .Cuteen_DarkSky:before { transition: none !important; }
  .Cuteen_DarkPlanet { animation: none !important; }
  .Cuteen_DarkSky #sun, .Cuteen_DarkSky #moon { transition: none !important; }
}
/* ── 18/18  #darkModeStage  ← 2026-10-11 新增（昼夜切换「黄昏落幕」：三拍剧本 + 圆形揭幕；「轻」档仍走第 17 块的老转盘）──
   与 source/js/modules/shell.js 的 DM_* 常量一一对应，两边要一起改：
     DM_BEAT1_MS 450（日落/日出） → DM_BEAT2_MS 450（暮色 + 第一批星） → DM_BEAT3_MS 600（星夜 + 揭幕，合计 1500）
     DM_REVEAL_AT_MS 1150 起揭幕  DM_REVEAL_MS 350 揭完  转昼整体 ×0.8（--dm-k: .8 → 1200ms）
   视线层次（DOM 顺序，从下到上）：夜空 → 夜色层 → 暮色 → 星星 → 太阳 → 月亮 → 云 → 远山 → 山脚辉光 → 流星
   只动 opacity / transform / mask；没有 canvas、没有 rAF；手机 ≤600px 由 shell.js 把星星减半、这里把云关掉 */
@property --dm-r { syntax: '<length>'; inherits: false; initial-value: 0px; }

.dm-stage { position: fixed; inset: 0; z-index: 88888890; overflow: hidden; pointer-events: none;
  --dm-x: 50%; --dm-y: 42%; --dm-r: 0px; --dm-k: 1;
  -webkit-mask-image: radial-gradient(circle var(--dm-r) at var(--dm-x) var(--dm-y), transparent 99%, #000 100%);
          mask-image: radial-gradient(circle var(--dm-r) at var(--dm-x) var(--dm-y), transparent 99%, #000 100%);
  transition: --dm-r 350ms cubic-bezier(.22,.61,.36,1), opacity 140ms linear 210ms; }
.dm-stage[data-to="light"] { --dm-k: .8; }
.dm-stage.is-reveal { --dm-r: 160vmax; opacity: 0; }

/* ① 天空：底子（暖橙→紫） + 夜色层（慢慢吃掉） + 暮色层（中间站，先亮后灭） */
.dm-stage .dm-sky, .dm-stage .dm-dusk, .dm-stage .dm-stars { position: absolute; inset: 0; }
.dm-stage .dm-sky { background: linear-gradient(to top, #ffb26b 0%, #ef7d67 26%, #6d4b90 62%, #241f45 100%); }
.dm-stage .dm-sky::after { content: ''; position: absolute; inset: 0; opacity: 0;
  background: linear-gradient(to top, #0b1030 0%, #16244f 34%, #2b3a6b 62%, #4a3567 100%);
  animation: dm-night-fall calc(1100ms * var(--dm-k)) ease-in forwards; }
.dm-stage .dm-dusk { opacity: 0;
  background: linear-gradient(to top, #ffb26b 0%, #d4588f 42%, #4b2a6b 78%, #1a1638 100%);
  animation: dm-dusk-glow calc(900ms * var(--dm-k)) ease-out forwards; }
@keyframes dm-night-fall { 0% { opacity: 0 } 45% { opacity: .45 } 100% { opacity: 1 } }
@keyframes dm-dusk-glow { 0% { opacity: 0 } 32% { opacity: .9 } 100% { opacity: 0 } }

/* ② 太阳 / 月亮：同一条弧线，一个下去另一个上来；月亮带环形山 */
.dm-stage .dm-sun, .dm-stage .dm-moon { position: absolute; left: 50%; top: 34%; width: 92px; height: 92px; margin: -46px 0 0 -46px; border-radius: 50%; }
.dm-stage .dm-sun { background: radial-gradient(circle at 38% 34%, #fff7cf 0 16%, #ffe07a 44%, #ffb43d 76%, #f08a1e 100%);
  box-shadow: 0 0 60px 18px rgba(255,190,90,.45), 0 0 150px 44px rgba(255,150,60,.16);
  animation: dm-sun-set calc(950ms * var(--dm-k)) cubic-bezier(.4,.1,.3,1) forwards; }
@keyframes dm-sun-set { 0% { opacity: 1; transform: translate3d(0,-14px,0) scale(1) } 55% { opacity: .92; transform: translate3d(-18px,52px,0) scale(.96) } 100% { opacity: 0; transform: translate3d(-34px,168px,0) scale(.8) } }
.dm-stage .dm-moon { opacity: 0; background: radial-gradient(circle at 34% 30%, #fff 0 30%, #e9eefc 62%, #c3ccdf 100%);
  box-shadow: 0 0 44px 10px rgba(206,224,255,.35), inset -14px -10px 26px rgba(150,163,190,.35);
  animation: dm-moon-rise calc(950ms * var(--dm-k)) cubic-bezier(.4,.1,.3,1) forwards; }
@keyframes dm-moon-rise { 0% { opacity: 0; transform: translate3d(64px,150px,0) scale(.78) } 42% { opacity: .9 } 100% { opacity: 1; transform: translate3d(0,0,0) scale(1) } }
/* 转昼时反过来：月亮沉下去、太阳升上来（两端的帧与上面互为倒放，接得上） */
.dm-stage[data-to="light"] .dm-sun { opacity: 0; animation-name: dm-sun-rise; }
.dm-stage[data-to="light"] .dm-moon { opacity: 1; animation-name: dm-moon-set; }
@keyframes dm-sun-rise { 0% { opacity: 0; transform: translate3d(-34px,168px,0) scale(.8) } 45% { opacity: .9 } 100% { opacity: 1; transform: translate3d(0,-14px,0) scale(1) } }
@keyframes dm-moon-set { 0% { opacity: 1; transform: translate3d(0,0,0) scale(1) } 55% { opacity: .85 } 100% { opacity: 0; transform: translate3d(64px,150px,0) scale(.78) } }
.dm-stage .dm-moon::after { content: ''; position: absolute; inset: 0; border-radius: 50%;
  background: radial-gradient(circle at 66% 34%, rgba(148,161,188,.5) 0 11%, transparent 12%),
              radial-gradient(circle at 40% 62%, rgba(148,161,188,.42) 0 8%, transparent 9%),
              radial-gradient(circle at 71% 69%, rgba(148,161,188,.36) 0 6%, transparent 7%); }

/* ③ 星星：两批亮（第一批在暮色里先冒头，剩下的在第三拍铺满），之后轻轻闪 */
.dm-stage .dm-star { position: absolute; left: var(--dm-sx,50%); top: var(--dm-sy,30%); width: var(--dm-ss,2px); height: var(--dm-ss,2px);
  border-radius: 50%; background: #fff; opacity: 0; box-shadow: 0 0 7px rgba(214,232,255,.92);
  animation: dm-star-in calc(900ms * var(--dm-k)) ease-out calc(var(--dm-sd,0ms) * var(--dm-k)) forwards,
             dm-star-flicker calc(1400ms * var(--dm-k)) ease-in-out calc((var(--dm-sd,0ms) + 700ms) * var(--dm-k)) infinite alternate; }
@keyframes dm-star-in { 0% { opacity: 0; transform: translate3d(0,5px,0) scale(.5) } 55% { opacity: 1; transform: translate3d(0,0,0) scale(1) } 100% { opacity: var(--dm-so,.95); transform: translate3d(0,0,0) scale(1) } }
@keyframes dm-star-flicker { 0% { opacity: var(--dm-so,.95) } 100% { opacity: .55 } }

/* ④ 云（只有华丽档）：掠过日月时短暂遮一下再让开 */
.dm-stage[data-tier="standard"] .dm-clouds { display: none; }
.dm-stage .dm-clouds { position: absolute; inset: 0; }
.dm-stage .dm-clouds i { position: absolute; display: block; border-radius: 50%; filter: blur(9px); opacity: 0; background: radial-gradient(58% 100% at 50% 62%, rgba(255,238,218,.9) 0 44%, rgba(248,222,208,.5) 64%, transparent 100%); box-shadow: 7vw 1.1vw 0 -1.7vw rgba(255,238,218,.55), -6.5vw 1.5vw 0 -2.1vw rgba(246,220,206,.45); }
  background: radial-gradient(60% 60% at 40% 45%, rgba(255,255,255,.55), rgba(215,225,255,.18) 70%, transparent 72%); }
.dm-stage .dm-clouds i:nth-child(1) { left: -14%; top: 44%; width: 34vw; height: 9vw; animation: dm-cloud-a calc(1500ms * var(--dm-k)) linear calc(120ms * var(--dm-k)) forwards; }
.dm-stage .dm-clouds i:nth-child(2) { right: -16%; top: 26%; width: 26vw; height: 7vw; animation: dm-cloud-b calc(1600ms * var(--dm-k)) linear calc(60ms * var(--dm-k)) forwards; }
@keyframes dm-cloud-a { 0% { opacity: 0; transform: translate3d(0,0,0) } 25% { opacity: .85 } 100% { opacity: 0; transform: translate3d(58vw,10px,0) } }
@keyframes dm-cloud-b { 0% { opacity: 0; transform: translate3d(0,0,0) } 30% { opacity: .7 } 100% { opacity: 0; transform: translate3d(-48vw,-6px,0) } }

/* ⑤ 远山剪影 + 山脚辉光：有了地平线，日月才有「落下去 / 升起来」的参照 */
.dm-stage .dm-horizon { position: absolute; left: 0; right: 0; bottom: 0; height: 34%; background-repeat: no-repeat; background-position: bottom center; background-size: 100% 100%;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 200' preserveAspectRatio='none'><path fill='%230d1226' d='M0 200V152l126-24 132 30 138-44 148 36 140-30 152 34 158-26 150 32 152-20 144 24V200Z'/></svg>"); }
.dm-stage .dm-horizon::after { content: ''; position: absolute; inset: 0; opacity: .62; background-repeat: no-repeat; background-position: bottom center; background-size: 100% 100%;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 200' preserveAspectRatio='none'><path fill='%23272c52' d='M0 200V116l150-34 132 44 156-62 138 48 152-66 152 56 160-38 142 46 158-28 100 22V200Z'/></svg>"); }
.dm-stage .dm-glow { position: absolute; left: 0; right: 0; bottom: 0; height: 46%; opacity: 0;
  background: radial-gradient(70% 100% at 50% 108%, rgba(255,176,94,.72) 0 22%, rgba(255,120,80,.26) 46%, transparent 72%);
  animation: dm-glow-pulse calc(1000ms * var(--dm-k)) ease-out calc(60ms * var(--dm-k)) forwards; }
@keyframes dm-glow-pulse { 0% { opacity: .12 } 34% { opacity: .95 } 100% { opacity: .1 } }

/* ⑥ 流星：标准档一颗；华丽档 ::after 再来一颗（转昼不放，免得「天亮还掉流星」） */
.dm-stage[data-to="light"] .dm-meteor { display: none; }
.dm-stage .dm-meteor { position: absolute; left: 66%; top: 14%; width: 190px; height: 2px; border-radius: 2px; opacity: 0; transform-origin: right center;
  background: linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(214,232,255,.25) 45%, #fff 100%);
  filter: drop-shadow(0 0 6px rgba(206,228,255,.9));
  animation: dm-meteor-run calc(720ms * var(--dm-k)) cubic-bezier(.35,.5,.5,1) calc(940ms * var(--dm-k)) forwards; }
@keyframes dm-meteor-run { 0% { opacity: 0; transform: rotate(-20deg) translate3d(0,0,0) scaleX(.25) } 14% { opacity: 1 } 62% { opacity: 1 } 100% { opacity: 0; transform: rotate(-20deg) translate3d(-340px,120px,0) scaleX(1) } }
.dm-stage[data-tier="flourish"] .dm-meteor::after { content: ''; position: absolute; left: -30%; top: 38%; width: 140px; height: 2px; border-radius: 2px; opacity: 0;
  background: linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(214,232,255,.25) 45%, #fff 100%);
  animation: dm-meteor-run calc(720ms * var(--dm-k)) cubic-bezier(.35,.5,.5,1) calc(1180ms * var(--dm-k)) forwards; }

/* ⑦ 设置面板里的档位下拉：跟 feature-opt 的排版对齐 */
/* ⑦′ 昼夜档位：四个胶囊按钮 + 一句跟着变的说明（原来用下拉，选项文字会被截断、也看不出能点） */
.settings .feature-opt.dm-wide { grid-column: 1 / -1; flex-wrap: wrap; align-items: flex-start; padding: 10px 0; }
.settings .dm-seg { display: flex; flex-shrink: 0; gap: 6px; padding: 4px; border: 1px solid rgba(128,128,128,.22); border-radius: 999px; background: rgba(128,128,128,.12); }
.settings .dm-seg button { min-height: 34px; padding: 5px 14px; border: 1px solid transparent; border-radius: 999px; background: transparent; color: inherit; font: inherit; font-size: .84em; font-weight: 600; line-height: 1; cursor: pointer; transition: background .18s, color .18s, border-color .18s, box-shadow .18s; }
.settings .dm-seg button:hover { background: rgba(128,128,128,.18); }
.settings .dm-seg button.is-on { background: var(--theme-color); border-color: var(--theme-color); color: var(--on-theme); box-shadow: 0 2px 10px rgba(0,0,0,.14); }
.settings .dm-seg button:focus-visible { outline: 2px solid var(--theme-color); outline-offset: 3px; }
.settings .feature-opt .dm-seg-note { flex: 1 0 100%; margin: 6px 0 0; font-size: .76em; font-weight: 400; line-height: 1.6; opacity: .82; }
@media (max-width: 600px) { .settings .feature-opt.dm-wide { flex-direction: column; align-items: stretch; } .settings .dm-seg { width: 100%; } .settings .dm-seg button { flex: 1 1 0; padding: 5px 6px; } .settings .feature-opt .dm-seg-note { flex: 0 0 auto; width: 100%; } }

/* ⑧ 兜底：手机缩小日月、关掉云；系统要求减少动态就不放这块幕布 */
@media (max-width: 600px) {
  .dm-stage .dm-sun, .dm-stage .dm-moon { width: 74px; height: 74px; margin: -37px 0 0 -37px; }
  .dm-stage .dm-clouds { display: none; }
  .dm-stage .dm-horizon { height: 17%; background-position: bottom left; background-size: 150% 100%; }
  .dm-stage .dm-horizon::after { background-position: bottom left; background-size: 150% 100%; }
  .dm-stage .dm-glow { height: 22%; }
}
@media (prefers-reduced-motion: reduce) { .dm-stage { display: none !important; } }
