diff --git a/README.md b/README.md
index b67d2e2..e53fe5f 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@
## 特点
1. **响应式设计** — 适配桌面端与移动端,支持暗色模式,移动端使用动态视口单位适配地址栏
-2. **插件兼容性** — 适配 11 款常用 Halo 插件,安装即用;提供页面布局契约,插件前台页面自动复用主题外观
+2. **插件兼容性** — 适配 10 款常用 Halo 插件,安装即用;提供页面布局契约,插件前台页面自动复用主题外观
3. **内置灯箱** — 主题内置 LightGallery 灯箱(GPLv3,随主题自托管打包),支持 EXIF 信息展示;安装 lightgallery.js 插件后自动禁用
4. **可配置性** — 17 个设置分组、126 个配置项,几乎所有模块可独立开关
5. **性能优化** — 服务端字数统计(API 扩展包)、图片懒加载与响应式缩略图、首屏整屏吸附(仅首屏边界接管,内容区保留原生滚动)、Hero 离屏停绘、CSS/HTML 压缩;详见[开发指南 - 性能与滚动顺滑](https://nxxy335.top/WarmIsland/customize/development.html)
@@ -38,29 +38,33 @@
| 服务 / 资源 | 用途 | 涉及的数据类型 | 默认状态 | 关闭 / 替换方法 |
| --- | --- | --- | --- | --- |
| 主题自身静态资源 `/themes/warm-island/assets/*` | 样式、脚本、字体、图标、Logo、内置句子库 | 无(同域请求,不含用户数据) | 始终启用,渲染必需 | 不可关闭;均为随包自托管文件 |
-| 自定义一言 API `hero_hitokoto_api` | Hero 首屏随机句子 | 无请求体;发起 GET 时第三方可见访客 IP / User-Agent | **默认不启用**:「描述文案来源」默认「无」,一言元素不渲染,零请求;选择「一言」时自动填入 `https://v1.hitokoto.cn/` | 主题设置 → Hero 首屏 → 描述来源改为「无」或「自定义」,或清空该字段回退到 `assets/data/hitokoto.json` 内置本地句子库 |
+| 自定义一言 API `hero_hitokoto_api` | Hero 首屏随机句子 | 无请求体;发起 GET 时第三方可见访客 IP / User-Agent | **默认不启用**:「描述文案来源」默认「无」,一言元素不渲染,零请求;该字段默认预填 `https://v1.hitokoto.cn/`,仅在「一言」模式生效 | 主题设置 → Hero 首屏 → 描述来源改为「无」或「自定义」,或清空该字段回退到 `assets/data/hitokoto.json` 内置本地句子库 |
| 自定义 IP 定位主 / 备选 API `welcome_popup_api` / `welcome_popup_fallback_api` | 欢迎弹窗显示「欢迎来自 XX 的朋友」 | **访客 IP** 与第三方返回的粗略地理位置 | **关闭**:两项均留空,弹窗只显示本地欢迎语;且欢迎弹窗开关本身默认关闭。可选接口见下方清单 | 主题设置 → 欢迎弹窗 → 关闭开关,或清空两个 API 字段 |
| 分享按钮:QQ / 微博 / X / Facebook / Telegram | 分享文章到对应平台 | 文章 URL 与标题(写在目标站 URL 参数中) | 默认开启 `qq,wechat,weibo`;**仅在访客点击后**跳转,页面加载时不请求 | 主题设置 → 文章 → 关闭「显示分享按钮」,或在「分享渠道」取消勾选 |
| 微信分享弹层 | 生成并复制文章链接 | 文章 URL(浏览器本地字符串,不发送) | 与分享按钮一致 | 同上;已移除二维码远程库,改为「复制链接」 |
| 页脚备案 / Halo / 应用市场外链 | 备案信息、致谢、插件安装提示 | 无(访客主动点击才跳转) | 由站点配置决定,默认仅显示 Halo 致谢 | 主题设置 → 页脚 → 关闭对应显示项 |
-| 插件前台页面(豆瓣、Steam、朋友圈、微信读书等) | 展示插件提供的数据 | 由对应插件决定,主题不发起请求 | 安装并启用对应插件后才出现 | 卸载 / 停用对应插件;主题自动降级隐藏 |
+| 插件前台页面(豆瓣、Steam、微信读书、订阅动态等) | 展示插件提供的数据 | 由对应插件决定,主题不发起请求 | 安装并启用对应插件后才出现 | 卸载 / 停用对应插件;主题自动降级隐藏 |
| 内置 LightGallery 灯箱 | 图片放大预览、EXIF 展示 | 无(本地打包,不联网) | 默认启用 | 安装 lightgallery.js 插件后主题自动让位 |
#### 可选第三方接口地址(均为候选值,主题不预置请求)
| 能力 | 设置项 | 可选地址 |
| --- | --- | --- |
-| Hero 一言 | `hero_hitokoto_api` | `https://v1.hitokoto.cn/`(选择「一言」时自动填入;清空则使用内置本地句子库) |
+| Hero 一言 | `hero_hitokoto_api` | `https://v1.hitokoto.cn/`(默认预填,仅「一言」模式生效;清空则使用内置本地句子库) |
| IP 定位主接口 | `welcome_popup_api` | `https://myip.ipip.net/json` 或 `https://r.inews.qq.com/api/ip2city?otype=json` |
| IP 定位备选接口 | `welcome_popup_fallback_api` | 同上两个地址任选其一,主接口失败时兜底 |
-**描述文案来源默认为「无」**,可选「一言」「自定义」,此时不渲染一言元素、不发起任何请求。选择「一言」后自动填入
-`https://v1.hitokoto.cn/`;选择「一言」或「自定义」后若把 API 留空,则使用主题内置的本地句子库(零外部请求)。
+**描述文案来源默认为「无」**,可选「一言」「自定义」,此时不渲染一言元素、不发起任何请求。API 字段默认预填
+`https://v1.hitokoto.cn/`(仅「一言」模式生效);选择「一言」或「自定义」后若把 API 留空,则使用主题内置的本地句子库(零外部请求)。
**只有填写后才会向该地址发起请求**,需自行在站点隐私说明中披露,详见本章节「逐项说明」与下方「隐私说明(5.1)」。
IP 定位接口同样默认留空;**填写后会把访客 IP 发送给该第三方服务换取地理位置**,
需自行在站点隐私说明中披露,详见本章节「逐项说明」与下方「隐私说明(5.1)」。主题不会代替站点做这项声明。
+> 三个可选 API 配置项的 `help` 只保留功能说明(候选地址、留空回退规则);完整的第三方数据流向与
+> 隐私披露统一在 README「外部资源与隐私」章节和配置文档中说明,主题设置界面不重复展示冗长文案。
+> 字段是否显示由对应功能开关决定,且字段可见不等于发起请求:默认值与模板的条件渲染共同保证默认零外部请求。
+
> 自定义 API 属于**站点管理员主动配置**的可选能力:一旦填写,浏览器会按设置向该第三方发起请求。请自行评估服务商的隐私政策,并在站点隐私说明中补充披露;主题不会代替站点做这项声明。
### 隐私说明(5.1)
@@ -107,8 +111,7 @@ IP 定位接口同样默认留空;**填写后会把访客 IP 发送给该第
|----------|---------|-------------|------|
| [瞬间](https://halo.run/store/apps/app-SnwWD) | `PluginMoments` | `/moments` | 瞬间动态页面,支持点赞、评论、标签筛选、顶部封面 |
| [图库](https://halo.run/store/apps/app-BmQJW) | `PluginPhotos` | `/photos` | 图片展示页面,支持分组、灯箱预览 |
-| [友情链接](https://halo.run/store/apps/app-hfbQg) | `PluginLinks` | `/links` | 友链展示页面,支持随机排列、随机传送门、评论区开关 |
-| [朋友圈](https://www.halo.run/store/apps/app-yISsV) | `plugin-friends` | `/friends` | RSS 订阅朋友圈页面 |
+| [友情链接(链接管理)](https://halo.run/store/apps/app-hfbQg) | `PluginLinks` | `/links` | 友链展示页面,支持随机排列、随机传送门、评论区开关;同一插件的 RSS 订阅驱动「订阅」页面 |
| [装备管理](https://github.com/chengzhongxue/plugin-equipment) | `equipment` | `/equipments` | 装备展示页面,按分组展示,支持封面图 |
| [豆瓣](https://github.com/chengzhongxue/plugin-douban) | `plugin-douban` | `/douban` | 豆瓣记录页面,支持类型/状态/标签筛选,默认音乐;需插件 **v1.2.6+**(SQLite 数据结构) |
| [Steam 信息展示](https://github.com/Tim0x0/halo-plugin-steam) | `PluginSteam` | `/steam` | Steam 游戏库页面,含用户资料、统计数据、最近游玩、游戏库分页 |
@@ -118,22 +121,27 @@ IP 定位接口同样默认留空;**填写后会把访客 IP 发送给该第
| [API 扩展包](https://github.com/HowieHz/halo-plugin-extra-api) | `extra-api` | 全站 | 服务端字数统计、中英文混排排版、可选服务端代码高亮 |
> **注意**:插件需要单独安装,安装后主题会自动适配对应页面。若未安装某插件,对应页面或功能自动隐藏/降级,不会报错。
+>
+> **「朋友圈」(`plugin-friends`)插件已不再提供**:原先的 feed / RSS 聚合能力由官方
+> **「链接管理」(PluginLinks)插件的订阅**取代,对应下方的「订阅」自定义页面模板。
+> 主题保留 `friends.html` 与「朋友圈」设置分组仅用于兼容旧站点,新站点请勿再依赖;
+> 插件不可用时会显示空状态,不会报错。
## 自定义页面模板
-在 Halo 后台「页面 → 新建 → 自定义模板」中选择使用:
+在 Halo 后台「页面 → 新建 → 自定义模板」中选择使用(页面地址由 slug 决定,无固定路由):
| 模板名 | 模板文件 | 说明 |
|--------|---------|------|
| 留言板 | `page_messageboard.html` | 留言墙页面,标题与副标题可配置 |
-| 订阅 | `page_subscriptions.html` | 博友文章订阅动态,依赖链接管理插件的 RSS 订阅,支持分页/下滑加载与列表/网格布局 |
+| 订阅 | `page_subscriptions.html` | 博友文章订阅动态,由官方链接管理插件的 RSS 订阅提供,支持分页 / 下滑加载与列表 / 网格布局 |
| 微信读书 | `weread.html` | 微信读书书架展示,依赖微信读书插件,访客免登录查看 |
## 主要功能
### 首页
-- Hero 首屏:明暗双背景图、大标题/副标题独立配色、描述文案(默认「无」;选「一言」自动填入 `https://v1.hitokoto.cn/`,清空则使用内置本地句子库;可选自定义文案与自动刷新)、下滑箭头平滑滚动
+- Hero 首屏:明暗双背景图、大标题/副标题独立配色、描述文案(默认「无」;API 字段默认预填 `https://v1.hitokoto.cn/`,仅「一言」模式生效,清空则使用内置本地句子库;可选自定义文案与自动刷新)、下滑箭头平滑滚动
- 欢迎弹窗:默认显示纯本地静态欢迎语,支持 5 种位置、会话去重开关;仅在显式配置自定义 IP 定位 API 时才显示访客所在地(见[外部资源与隐私](#外部资源与隐私))
- 滚动吸附:首屏与内容区之间滚轮/触摸自动吸附,进入内容区后恢复原生自由滚动
- 文章卡片:可配置显示字数(依赖 API 扩展包)、阅读量、分类、标签、摘要行数
@@ -278,12 +286,12 @@ pnpm smoke
| 页面 | 检查要点 |
| --- | --- |
-| 首页 | Hero(描述文案默认「无」)、切换「一言」后的自动填充与清空回退、滚动吸附、文章卡片、欢迎弹窗(默认本地文案) |
+| 首页 | Hero(描述文案默认「无」)、三个可选 API 设置项(help 仅功能说明,隐私披露见 README)、一言 API 清空回退、滚动吸附、文章卡片、欢迎弹窗(默认本地文案) |
| 文章 | 正文 / 代码块配色、目录、分享按钮与微信复制链接、灯箱、点赞 |
| 分类 / 标签 / 归档 | 列表、分页、空状态、暗色模式 |
| 搜索 / 错误页 | 搜索页与空结果状态、404 / 500 兜底页、暗色模式(4.4.1) |
| 内容与表单 | 标题 / 瞬间正文含尖括号时不执行脚本、JSON-LD 合法、评论与表单校验(4.4.2) |
-| 友链 / 留言板 / 订阅 | 空字段兜底(作者为空不报错)、表单与分页 |
+| 友链 / 留言板 / 订阅 | 空字段兜底(作者为空不报错)、表单与分页、订阅动态空状态与插件未安装提示 |
| 全局 | 导航栏、页脚、移动端抽屉、深浅色切换、键盘可达主要导航与搜索、正文对比度、控制台无报错 / 无外部请求(4.4.3 / 4.4.4) |
## 技术栈
diff --git a/compat/assets/Layout.BzCkWxur.css b/compat/assets/Layout.BzCkWxur.css
new file mode 100644
index 0000000..a0f2d73
--- /dev/null
+++ b/compat/assets/Layout.BzCkWxur.css
@@ -0,0 +1 @@
+@charset "UTF-8";:root{--bg: #faf7f2;--bg-raised: #f3ede5;--bg-overlay: color-mix(in srgb, var(--bg) 85%, transparent);--ink: #2c2420;--ink-2: #7a6e64;--ink-3: #b5a99e;--rule: #e8e0d6;--accent: #d4764e;--accent-hover: #c4613a;--accent-bg: #fdf0e8;--mist-pink: #f0e4de;--sea-salt: #e8e0d6;--caramel: #8b6f5e;--glass-bg: color-mix(in srgb, var(--bg) 72%, transparent);--glass-border: color-mix(in srgb, var(--rule) 50%, transparent);--shadow-sm: 0 1px 3px color-mix(in srgb, var(--ink) 6%, transparent);--shadow-md: 0 4px 16px color-mix(in srgb, var(--ink) 8%, transparent);--shadow-lg: 0 8px 32px color-mix(in srgb, var(--ink) 12%, transparent);--shadow-glow: 0 0 40px color-mix(in srgb, var(--accent) 15%, transparent)}html.dark{--bg: #1e1c1a;--bg-raised: #292623;--bg-overlay: color-mix(in srgb, var(--bg) 85%, transparent);--ink: #e9e4dd;--ink-2: #aaa096;--ink-3: #7c7268;--rule: #3b362f;--accent: #e89a64;--accent-hover: #f2ad79;--accent-bg: #2c231b;--mist-pink: #2e2823;--sea-salt: #302b26;--caramel: #a38b7b;--glass-bg: color-mix(in srgb, var(--bg) 72%, transparent);--glass-border: color-mix(in srgb, var(--rule) 50%, transparent);--shadow-sm: 0 1px 3px rgba(0, 0, 0, .24);--shadow-md: 0 4px 16px rgba(0, 0, 0, .3);--shadow-lg: 0 8px 32px rgba(0, 0, 0, .4);--shadow-glow: 0 0 40px rgba(232, 154, 100, .12)}html[data-palette=matcha]{--bg: #f6f8f1;--bg-raised: #ecf1e3;--ink: #26302a;--ink-2: #6d7a6e;--ink-3: #a8b3a4;--rule: #dde5d4;--accent: #6f9d52;--accent-hover: #5d8943;--accent-bg: #ecf3e2;--mist-pink: #e7eddc;--sea-salt: #dfe8d3;--caramel: #7d8a68}html[data-palette=matcha].dark{--bg: #1b1f1a;--bg-raised: #252b22;--ink: #e6e9e0;--ink-2: #a3ab9c;--ink-3: #767e70;--rule: #363d33;--accent: #9cc47f;--accent-hover: #aed493;--accent-bg: #242c1f;--mist-pink: #262d22;--sea-salt: #282f24;--caramel: #98a387}html[data-palette=indigo]{--bg: #f5f7fa;--bg-raised: #eaeff5;--ink: #232a33;--ink-2: #66707d;--ink-3: #a3adb8;--rule: #dce2ea;--accent: #4a6fa5;--accent-hover: #3d5d8c;--accent-bg: #e9eff8;--mist-pink: #e2e8f0;--sea-salt: #dbe4ee;--caramel: #707c8e}html[data-palette=indigo].dark{--bg: #191d23;--bg-raised: #222831;--ink: #e4e7ec;--ink-2: #9aa4b1;--ink-3: #6d7683;--rule: #323a45;--accent: #7fa3d1;--accent-hover: #93b4dc;--accent-bg: #1f2632;--mist-pink: #232830;--sea-salt: #252b34;--caramel: #8b95a6}html[data-palette=sakura]{--bg: #faf5f6;--bg-raised: #f3eaec;--ink: #322a2c;--ink-2: #7d6e72;--ink-3: #b4a6aa;--rule: #ecdfe2;--accent: #d97387;--accent-hover: #c85d72;--accent-bg: #fbeef1;--mist-pink: #f2e2e6;--sea-salt: #eddfe3;--caramel: #96757e}html[data-palette=sakura].dark{--bg: #201b1c;--bg-raised: #2a2425;--ink: #ece5e6;--ink-2: #b0a4a7;--ink-3: #7f7276;--rule: #3c3436;--accent: #e89aab;--accent-hover: #f0aec0;--accent-bg: #2d2225;--mist-pink: #2f2729;--sea-salt: #31282a;--caramel: #a88d94}html[data-palette=violet]{--bg: #f7f5fa;--bg-raised: #eeeaf5;--ink: #2b2733;--ink-2: #6f6a7c;--ink-3: #aaa5b6;--rule: #e2ddeb;--accent: #8a6fc0;--accent-hover: #7759ae;--accent-bg: #f0eaf9;--mist-pink: #e8e2f0;--sea-salt: #e3dcee;--caramel: #7f7590}html[data-palette=violet].dark{--bg: #1c1a21;--bg-raised: #26222f;--ink: #e8e5ee;--ink-2: #a49eaf;--ink-3: #746e80;--rule: #373241;--accent: #b49ae0;--accent-hover: #c3ace8;--accent-bg: #262033;--mist-pink: #292434;--sea-salt: #2b2536;--caramel: #948caa}html[data-palette=sea]{--bg: #f3f8f7;--bg-raised: #e8f0ee;--ink: #21302d;--ink-2: #647872;--ink-3: #9fb1ac;--rule: #d9e6e3;--accent: #3d9c8f;--accent-hover: #2f8578;--accent-bg: #e5f3f0;--mist-pink: #dee9e6;--sea-salt: #d6e5e1;--caramel: #6c8680}html[data-palette=sea].dark{--bg: #181f1e;--bg-raised: #212a28;--ink: #e3eae8;--ink-2: #9aaba6;--ink-3: #6d7d79;--rule: #2f3b39;--accent: #6cc3b4;--accent-hover: #82d0c2;--accent-bg: #1d2a27;--mist-pink: #222c2a;--sea-salt: #242e2c;--caramel: #869894}html[data-palette=amber]{--bg: #faf7ef;--bg-raised: #f3eddc;--ink: #322b1e;--ink-2: #7d7360;--ink-3: #b5ab94;--rule: #eae1cb;--accent: #b97f1c;--accent-hover: #9f6a0e;--accent-bg: #f9efd8;--mist-pink: #f0e8d2;--sea-salt: #ebe2ca;--caramel: #96835c}html[data-palette=amber].dark{--bg: #201d16;--bg-raised: #2a261d;--ink: #ebe6d9;--ink-2: #b0a893;--ink-3: #7f7866;--rule: #3c3729;--accent: #e0a83e;--accent-hover: #ebba5c;--accent-bg: #2c251a;--mist-pink: #2f2a1e;--sea-salt: #312c20;--caramel: #a89a76}html[data-palette=plum]{--bg: #f9f4f5;--bg-raised: #f1e8ea;--ink: #2f2427;--ink-2: #796a6f;--ink-3: #b1a2a7;--rule: #e9dde0;--accent: #a4506b;--accent-hover: #8d3f59;--accent-bg: #f7e9ee;--mist-pink: #ecdee2;--sea-salt: #e5d8db;--caramel: #8d6f77}html[data-palette=plum].dark{--bg: #1f1a1b;--bg-raised: #292223;--ink: #eae2e4;--ink-2: #ada0a4;--ink-3: #7c6e73;--rule: #3a3133;--accent: #d98aa3;--accent-hover: #e39fb5;--accent-bg: #2b2023;--mist-pink: #2d2527;--sea-salt: #2f2729;--caramel: #a08890}html[data-palette=graphite]{--bg: #f7f7f6;--bg-raised: #eeedeb;--ink: #262626;--ink-2: #6e6e6c;--ink-3: #ababa8;--rule: #e0e0de;--accent: #3f3f3e;--accent-hover: #262626;--accent-bg: #ececea;--mist-pink: #e9e9e7;--sea-salt: #e5e5e3;--caramel: #7b7b78}html[data-palette=graphite].dark{--bg: #1b1b1a;--bg-raised: #252524;--ink: #e8e8e6;--ink-2: #a5a5a2;--ink-3: #757572;--rule: #353534;--accent: #c9c9c5;--accent-hover: #d8d8d4;--accent-bg: #262625;--mist-pink: #2a2a29;--sea-salt: #2c2c2b;--caramel: #8f8f8c}html[data-palette=cocoa]{--bg: #f8f4f0;--bg-raised: #f0e8e1;--ink: #2e2722;--ink-2: #786c62;--ink-3: #b3a89d;--rule: #e7ddd3;--accent: #9a6b4f;--accent-hover: #835539;--accent-bg: #f5e9e0;--mist-pink: #ecdfd4;--sea-salt: #e6d9cd;--caramel: #8a6f5b}html[data-palette=cocoa].dark{--bg: #1e1a17;--bg-raised: #282320;--ink: #eae4dd;--ink-2: #aca199;--ink-3: #7b7169;--rule: #3a332e;--accent: #cd9878;--accent-hover: #daa98c;--accent-bg: #2a211c;--mist-pink: #2d2721;--sea-salt: #2f2923;--caramel: #a08d7c}html[data-palette=azure]{--bg: #f4f8fb;--bg-raised: #e9f1f7;--ink: #223038;--ink-2: #62737e;--ink-3: #a0b0ba;--rule: #dbe7ee;--accent: #3b82c4;--accent-hover: #2e6ba5;--accent-bg: #e7f1f9;--mist-pink: #e0ebf2;--sea-salt: #d8e6ef;--caramel: #6d8090}html[data-palette=azure].dark{--bg: #172026;--bg-raised: #202a31;--ink: #e3eaef;--ink-2: #99a8b3;--ink-3: #6b7a85;--rule: #2e3a42;--accent: #74b3e0;--accent-hover: #88c1e8;--accent-bg: #1d2830;--mist-pink: #222c34;--sea-salt: #243038;--caramel: #8496a3}:root{--font-sans: "LXGW WenKai", "Noto Serif SC", "Source Han Serif SC", Georgia, serif;--font-body: "LXGW WenKai", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;--font-mono: "JetBrains Mono", "Fira Code", monospace;--text-xs: clamp(.75rem, .7rem + .2vw, .8rem);--text-sm: clamp(.875rem, .82rem + .2vw, .95rem);--text-base: clamp(1rem, .94rem + .25vw, 1.05rem);--text-md: clamp(1.1rem, 1.02rem + .3vw, 1.2rem);--text-lg: clamp(1.2rem, 1.1rem + .45vw, 1.3rem);--text-xl: clamp(1.35rem, 1.2rem + .7vw, 1.6rem);--text-2xl: clamp(1.65rem, 1.4rem + 1.05vw, 2rem);--text-3xl: clamp(1.95rem, 1.6rem + 1.65vw, 2.4rem);--text-4xl: clamp(2.3rem, 1.8rem + 2.25vw, 3.2rem);--text-5xl: clamp(2.8rem, 2rem + 3.5vw, 4rem);--leading-none: 1;--leading-tight: 1.2;--leading-snug: 1.35;--leading-normal: 1.6;--leading-relaxed: 1.75;--leading-loose: 2;--tracking-tight: -.02em;--tracking-normal: 0;--tracking-wide: .04em;--tracking-wider: .08em;--tracking-widest: .12em}h1,h2,h3,h4,h5,h6{font-family:var(--font-sans);font-weight:700;line-height:var(--leading-tight);letter-spacing:var(--tracking-tight);color:var(--ink);margin-bottom:var(--space-sm)}h1{font-size:var(--text-3xl);margin-bottom:var(--space-lg)}h2{font-size:var(--text-2xl);padding-left:var(--space-md);border-left:3px solid var(--accent);margin-bottom:var(--space-sm)}h3{font-size:var(--text-xl);position:relative;padding-left:var(--space-lg)}h3:before{content:"";display:block;position:absolute;left:0;top:50%;transform:translateY(-50%);width:6px;height:6px;border-radius:50%;background:var(--accent);opacity:.6}h4{font-size:var(--text-md);color:var(--ink-2)}h5{font-size:var(--text-base);color:var(--ink-2)}h6{font-size:var(--text-sm);color:var(--ink-3)}.wi-post__body :is(h1,h2,h3,h4,h5,h6),.wi-page__body :is(h1,h2,h3,h4,h5,h6),.wi-messageboard__body :is(h1,h2,h3,h4,h5,h6){font-family:var(--font-sans);font-weight:700;line-height:1.35;letter-spacing:-.01em;color:var(--ink);scroll-margin-top:88px;text-wrap:balance;padding-left:0;border-left:0}.wi-post__body :is(h1,h2,h3,h4,h5,h6):before,.wi-post__body :is(h1,h2,h3,h4,h5,h6):after,.wi-page__body :is(h1,h2,h3,h4,h5,h6):before,.wi-page__body :is(h1,h2,h3,h4,h5,h6):after,.wi-messageboard__body :is(h1,h2,h3,h4,h5,h6):before,.wi-messageboard__body :is(h1,h2,h3,h4,h5,h6):after{content:none}.wi-post__body h1,.wi-page__body h1,.wi-messageboard__body h1{font-size:clamp(1.6rem,1.4rem + 1vw,2rem);margin-top:2em;margin-bottom:.7em}.wi-post__body h2,.wi-page__body h2,.wi-messageboard__body h2{font-size:clamp(1.42rem,1.3rem + .6vw,1.68rem);margin-top:1.9em;margin-bottom:.65em}.wi-post__body h3,.wi-page__body h3,.wi-messageboard__body h3{font-size:clamp(1.24rem,1.16rem + .4vw,1.4rem);margin-top:1.7em;margin-bottom:.6em}.wi-post__body h4,.wi-page__body h4,.wi-messageboard__body h4{font-size:clamp(1.1rem,1.05rem + .25vw,1.2rem);margin-top:1.5em;margin-bottom:.5em}.wi-post__body h5,.wi-page__body h5,.wi-messageboard__body h5{font-size:1.04rem;margin-top:1.4em;margin-bottom:.45em}.wi-post__body h6,.wi-page__body h6,.wi-messageboard__body h6{font-size:.98rem;font-weight:600;color:var(--ink-3);margin-top:1.4em;margin-bottom:.45em}.wi-post__body :is(h1,h2,h3,h4,h5,h6)+:is(h1,h2,h3,h4,h5,h6),.wi-page__body :is(h1,h2,h3,h4,h5,h6)+:is(h1,h2,h3,h4,h5,h6),.wi-messageboard__body :is(h1,h2,h3,h4,h5,h6)+:is(h1,h2,h3,h4,h5,h6){margin-top:.6em}.wi-post__body>:is(h1,h2,h3,h4,h5,h6):first-child,.wi-page__body>:is(h1,h2,h3,h4,h5,h6):first-child,.wi-messageboard__body>:is(h1,h2,h3,h4,h5,h6):first-child{margin-top:0}.wi-post__body p,.wi-page__body p,.wi-messageboard__body p{margin-block-end:1.2em}.wi-post__body *,.wi-page__body *,.wi-messageboard__body *{max-width:100%}.wi-post__body :is(pre,code,table),.wi-page__body :is(pre,code,table),.wi-messageboard__body :is(pre,code,table){overflow-x:auto}.wi-post__body pre,.wi-page__body pre,.wi-messageboard__body pre{margin-block:1.5em;padding:1.25em;border-radius:12px;border:1px solid var(--rule);background:var(--bg-raised);font-size:.875em;line-height:1.6}.wi-post__body pre code,.wi-page__body pre code,.wi-messageboard__body pre code{background:none;padding:0;border:none;border-radius:0;font-size:inherit}.wi-post__body code,.wi-page__body code,.wi-messageboard__body code{background:var(--bg-raised);padding:.15em .4em;border-radius:8px;font-size:.875em;border:1px solid var(--rule)}.wi-post__body blockquote,.wi-page__body blockquote,.wi-messageboard__body blockquote{margin-block:1.25em;padding-block:.7em;padding-inline:1.25em}.wi-post__body blockquote>:is(p,ul,ol,pre,figure,table,h1,h2,h3,h4,h5,h6),.wi-page__body blockquote>:is(p,ul,ol,pre,figure,table,h1,h2,h3,h4,h5,h6),.wi-messageboard__body blockquote>:is(p,ul,ol,pre,figure,table,h1,h2,h3,h4,h5,h6){margin-block:0}.wi-post__body blockquote>:is(p,ul,ol,pre,figure,table,h1,h2,h3,h4,h5,h6)+*,.wi-page__body blockquote>:is(p,ul,ol,pre,figure,table,h1,h2,h3,h4,h5,h6)+*,.wi-messageboard__body blockquote>:is(p,ul,ol,pre,figure,table,h1,h2,h3,h4,h5,h6)+*{margin-block-start:.55em}.wi-post__body blockquote>p:empty,.wi-page__body blockquote>p:empty,.wi-messageboard__body blockquote>p:empty{display:none}.wi-post__body blockquote>p:has(>br:only-child),.wi-page__body blockquote>p:has(>br:only-child),.wi-messageboard__body blockquote>p:has(>br:only-child){display:none}.wi-post__body :is(ul,ol),.wi-page__body :is(ul,ol),.wi-messageboard__body :is(ul,ol){padding-inline-start:1.5em;margin-block-end:1.2em}.wi-post__body li,.wi-page__body li,.wi-messageboard__body li{margin-block-end:.6em}.wi-post__body a,.wi-page__body a,.wi-messageboard__body a{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:.2em}.wi-post__body :is(.ai-summary,.abstract),.wi-post__body [class*=ai-summary],.wi-post__body [class*=ai-abstract],.wi-post__body [class*=likcc-article-summary],.wi-page__body :is(.ai-summary,.abstract),.wi-page__body [class*=ai-summary],.wi-page__body [class*=ai-abstract],.wi-page__body [class*=likcc-article-summary],.wi-messageboard__body :is(.ai-summary,.abstract),.wi-messageboard__body [class*=ai-summary],.wi-messageboard__body [class*=ai-abstract],.wi-messageboard__body [class*=likcc-article-summary]{margin-bottom:15px}.wi-post__body img,.wi-post__body video,.wi-page__body img,.wi-page__body video,.wi-messageboard__body img,.wi-messageboard__body video{display:block;max-width:100%;height:auto;margin-inline:auto}.wi-post__body img,.wi-post__body video,.wi-page__body img,.wi-page__body video,.wi-messageboard__body img,.wi-messageboard__body video{border-radius:12px;margin-block:1.5em}.wi-post__body img[role=presentation],.wi-post__body img[aria-hidden=true],.wi-post__body :is(.emoji,.icon,.avatar,.badge),.wi-page__body img[role=presentation],.wi-page__body img[aria-hidden=true],.wi-page__body :is(.emoji,.icon,.avatar,.badge),.wi-messageboard__body img[role=presentation],.wi-messageboard__body img[aria-hidden=true],.wi-messageboard__body :is(.emoji,.icon,.avatar,.badge){display:inline;margin-inline:0;border-radius:0}.wi-post__body [align=center],.wi-post__body [style*="text-align:center"],.wi-post__body [style*="text-align: center"],.wi-page__body [align=center],.wi-page__body [style*="text-align:center"],.wi-page__body [style*="text-align: center"],.wi-messageboard__body [align=center],.wi-messageboard__body [style*="text-align:center"],.wi-messageboard__body [style*="text-align: center"]{text-align:center}.wi-post__body iframe,.wi-page__body iframe,.wi-messageboard__body iframe{display:block;max-width:100%;margin-inline:auto;border:none}.wi-post__body figure,.wi-page__body figure,.wi-messageboard__body figure{display:block;max-width:100%;margin-inline:auto;margin-block:1.5em;text-align:center}.wi-post__body figure :is(img,video),.wi-page__body figure :is(img,video),.wi-messageboard__body figure :is(img,video){margin-block:0}.wi-post__body figcaption,.wi-page__body figcaption,.wi-messageboard__body figcaption{color:var(--ink-3);font-size:.875rem;line-height:1.6;text-align:center;margin-top:.6em}.wi-post__body .wi-lightgallery-item,.wi-page__body .wi-lightgallery-item,.wi-messageboard__body .wi-lightgallery-item{display:block;width:fit-content;max-width:100%;margin-inline:auto;border-radius:12px;line-height:0}.wi-post__body .wi-lightgallery-item>img,.wi-page__body .wi-lightgallery-item>img,.wi-messageboard__body .wi-lightgallery-item>img{margin-block:0}.wi-post__body .wi-embed,.wi-page__body .wi-embed,.wi-messageboard__body .wi-embed{position:relative;width:100%;max-width:100%;margin-inline:auto;margin-block:1.5em;overflow:hidden;border-radius:12px;background:var(--bg-raised)}.wi-post__body .wi-embed>:is(iframe,video,embed,object),.wi-page__body .wi-embed>:is(iframe,video,embed,object),.wi-messageboard__body .wi-embed>:is(iframe,video,embed,object){position:absolute;inset:0;width:100%;height:100%;margin:0;border-radius:0;border:0}.wi-post__body .wi-media-loading,.wi-page__body .wi-media-loading,.wi-messageboard__body .wi-media-loading{filter:blur(20px);opacity:.6}.wi-post__body .wi-media-loaded,.wi-page__body .wi-media-loaded,.wi-messageboard__body .wi-media-loaded{filter:blur(0);opacity:1}@media(max-width:768px){.wi-post__body h1,.wi-page__body h1,.wi-messageboard__body h1{font-size:1.4rem}.wi-post__body h2,.wi-page__body h2,.wi-messageboard__body h2{font-size:1.28rem}.wi-post__body h3,.wi-page__body h3,.wi-messageboard__body h3{font-size:1.16rem}.wi-post__body h4,.wi-page__body h4,.wi-messageboard__body h4{font-size:1.05rem}.wi-post__body h5,.wi-page__body h5,.wi-messageboard__body h5{font-size:1rem}.wi-post__body h6,.wi-page__body h6,.wi-messageboard__body h6{font-size:.95rem}.wi-post__body p,.wi-page__body p,.wi-messageboard__body p{margin-block-end:1.35em}.wi-post__body pre,.wi-page__body pre,.wi-messageboard__body pre{font-size:.9em;padding:1em}.wi-post__body code,.wi-page__body code,.wi-messageboard__body code{font-size:.9em}.wi-post__body img,.wi-post__body video,.wi-page__body img,.wi-page__body video,.wi-messageboard__body img,.wi-messageboard__body video{margin-block:1.2em}.wi-post__body img,.wi-post__body video,.wi-post__body .wi-lightgallery-item,.wi-post__body figure,.wi-page__body img,.wi-page__body video,.wi-page__body .wi-lightgallery-item,.wi-page__body figure,.wi-messageboard__body img,.wi-messageboard__body video,.wi-messageboard__body .wi-lightgallery-item,.wi-messageboard__body figure{max-width:100%}}@media(max-width:480px){.wi-post__body h1,.wi-page__body h1,.wi-messageboard__body h1{font-size:1.32rem}.wi-post__body h2,.wi-page__body h2,.wi-messageboard__body h2{font-size:1.22rem}.wi-post__body h3,.wi-page__body h3,.wi-messageboard__body h3{font-size:1.12rem}}:root{--space-xs: .25rem;--space-sm: .5rem;--space-md: 1rem;--space-lg: 1.5rem;--space-xl: 2rem;--space-2xl: 3rem;--space-3xl: 4rem;--space-4xl: 6rem;--container-sm: 640px;--container-md: 768px;--container-lg: 1024px;--container-xl: 1200px;--content-max: 800px;--section-spacing: clamp(3rem, 2rem + 3vw, 6rem)}:root{--ease-out-expo: cubic-bezier(.16, 1, .3, 1);--ease-out-quart: cubic-bezier(.25, 1, .5, 1);--ease-in-out-cubic: cubic-bezier(.65, 0, .35, 1);--duration-fast: .15s;--duration-normal: .3s;--duration-slow: .5s;--duration-breath: 3s}@keyframes breathe{0%,to{opacity:.4;transform:scale(1)}50%{opacity:.7;transform:scale(1.08)}}@keyframes fadeInUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}@keyframes float{0%,to{transform:translateY(0)}50%{transform:translateY(-6px)}}@keyframes shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}@keyframes scrollHint{0%,to{opacity:.4;transform:translateY(0)}50%{opacity:1;transform:translateY(8px)}}.halo-comment-widget{background:var(--glass-bg);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);border:1px solid var(--glass-border);border-radius:16px;padding:var(--space-md);margin-top:var(--space-xl);width:100%;max-width:600px;margin-inline:auto}.halo-comment-widget .comment-item{background:var(--bg-raised);border:1px solid var(--rule);border-radius:12px;padding:var(--space-sm);margin-bottom:var(--space-xs);transition:box-shadow var(--duration-normal) var(--ease-out-expo),transform var(--duration-normal) var(--ease-out-expo)}.halo-comment-widget .comment-item:hover{box-shadow:var(--shadow-sm);transform:translateY(-1px)}.halo-comment-widget .comment-reply-item{background:var(--bg);border:1px solid var(--rule);border-radius:12px;padding:var(--space-xs) var(--space-sm);margin-top:var(--space-xs);transition:box-shadow var(--duration-normal) var(--ease-out-expo),transform var(--duration-normal) var(--ease-out-expo)}.halo-comment-widget .comment-reply-item:hover{box-shadow:var(--shadow-sm);transform:translateY(-1px)}.halo-comment-widget .comment-header{display:flex;align-items:center;gap:var(--space-xs);margin-bottom:var(--space-xs)}.halo-comment-widget .comment-avatar{width:24px;height:24px;border-radius:9999px;box-shadow:var(--shadow-sm)}.halo-comment-widget .comment-author{font-weight:600;color:var(--ink);font-size:var(--text-xs)}.halo-comment-widget .comment-time{font-size:var(--text-xs);color:var(--ink-3);letter-spacing:var(--tracking-wide)}.halo-comment-widget .comment-content{font-size:var(--text-sm);line-height:var(--leading-relaxed);color:var(--ink);margin-bottom:var(--space-xs)}.halo-comment-widget .comment-form{background:var(--bg-raised);border:1px solid var(--rule);border-radius:12px;padding:var(--space-sm);margin-bottom:var(--space-md)}.halo-comment-widget .comment-input,.halo-comment-widget .comment-textarea{width:100%;padding:var(--space-sm) var(--space-md);background:var(--bg);border:1px solid var(--rule);border-radius:8px;color:var(--ink);font-family:var(--font-body);font-size:var(--text-sm);transition:border-color var(--duration-fast) var(--ease-out-quart),box-shadow var(--duration-fast) var(--ease-out-quart)}.halo-comment-widget .comment-input:focus,.halo-comment-widget .comment-textarea:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 15%,transparent)}.halo-comment-widget .comment-input::placeholder,.halo-comment-widget .comment-textarea::placeholder{color:var(--ink-3)}.halo-comment-widget .comment-textarea{min-height:80px;resize:vertical}.halo-comment-widget .comment-button{display:inline-flex;align-items:center;justify-content:center;padding:var(--space-sm) var(--space-lg);background:var(--accent);color:var(--bg);border:none;border-radius:8px;font-family:var(--font-body);font-size:var(--text-sm);font-weight:600;cursor:pointer;transition:background var(--duration-fast) var(--ease-out-quart),transform var(--duration-fast) var(--ease-out-quart),box-shadow var(--duration-fast) var(--ease-out-quart)}.halo-comment-widget .comment-button:hover{background:var(--accent-hover);transform:translateY(-1px);box-shadow:var(--shadow-md)}.halo-comment-widget .comment-button:active{transform:translateY(0)}.halo-comment-widget .comment-pagination{display:flex;justify-content:center;align-items:center;gap:var(--space-md);margin-top:var(--space-lg)}.halo-comment-widget .comment-pagination-button{padding:var(--space-xs) var(--space-md);background:var(--bg-raised);border:1px solid var(--rule);border-radius:8px;color:var(--ink-2);font-size:var(--text-sm);cursor:pointer;transition:border-color var(--duration-fast) var(--ease-out-quart),color var(--duration-fast) var(--ease-out-quart)}.halo-comment-widget .comment-pagination-button:hover{border-color:var(--accent);color:var(--accent)}.halo-comment-widget .comment-reply-button{font-size:var(--text-xs);color:var(--ink-3);cursor:pointer;transition:color var(--duration-fast) var(--ease-out-quart)}.halo-comment-widget .comment-reply-button:hover{color:var(--accent)}.halo-comment-widget .comment-smiley-button{background:none;border:none;cursor:pointer;font-size:var(--text-lg);transition:transform var(--duration-fast) var(--ease-out-quart)}.halo-comment-widget .comment-smiley-button:hover{transform:scale(1.2)}html.dark .halo-comment-widget .comment-input:focus,html.dark .halo-comment-widget .comment-textarea:focus{box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 15%,transparent)}html.dark .halo-comment-widget .comment-button:hover{box-shadow:var(--shadow-md)}[data-comment-style=minimal] .halo-comment-widget{background:transparent;backdrop-filter:none;-webkit-backdrop-filter:none;border:none;border-top:1px solid var(--rule);border-radius:0;padding:var(--space-lg) 0}[data-comment-style=minimal] .halo-comment-widget .comment-item{background:transparent;border:none;border-bottom:1px solid var(--rule);border-radius:0;padding:var(--space-md) 0}[data-comment-style=minimal] .halo-comment-widget .comment-item:hover{box-shadow:none;transform:none}[data-comment-style=minimal] .halo-comment-widget .comment-reply-item{background:transparent;border:none;border-radius:0;padding:var(--space-xs) 0}[data-comment-style=minimal] .halo-comment-widget .comment-reply-item:hover{box-shadow:none;transform:none}[data-comment-style=minimal] .halo-comment-widget .comment-form{background:transparent;border:1px solid var(--rule);border-radius:12px;padding:var(--space-md)}[data-show-avatar=false] .halo-comment-widget .comment-avatar{display:none}.halo-search-widget .search-modal{background:var(--glass-bg);backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px);border:1px solid var(--glass-border);border-radius:24px;box-shadow:var(--shadow-lg);overflow:hidden}.halo-search-widget .search-input{width:100%;padding:var(--space-lg) var(--space-xl);background:transparent;border:none;border-bottom:1px solid var(--rule);color:var(--ink);font-family:var(--font-body);font-size:var(--text-lg);outline:none;transition:border-color var(--duration-fast) var(--ease-out-quart)}.halo-search-widget .search-input::placeholder{color:var(--ink-3)}.halo-search-widget .search-input:focus{border-bottom-color:var(--accent)}.halo-search-widget .search-result-item{padding:var(--space-md) var(--space-xl);border-bottom:1px solid var(--rule);cursor:pointer;transition:background var(--duration-fast) var(--ease-out-quart),padding-left var(--duration-fast) var(--ease-out-quart)}.halo-search-widget .search-result-item:hover{background:var(--accent-bg);padding-left:calc(var(--space-xl) + 4px)}.halo-search-widget .search-result-item:last-child{border-bottom:none}.halo-search-widget .search-result-title{font-size:var(--text-md);font-weight:600;color:var(--ink);margin-bottom:var(--space-xs)}.halo-search-widget .search-result-content{font-size:var(--text-sm);color:var(--ink-2);line-height:var(--leading-relaxed);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.halo-search-widget .search-result-label{font-size:var(--text-xs);color:var(--ink-3);letter-spacing:var(--tracking-wide)}.halo-search-widget .search-empty{padding:var(--space-3xl) var(--space-xl);text-align:center;color:var(--ink-3);font-size:var(--text-sm)}.halo-search-widget .search-hint{font-size:var(--text-xs);color:var(--ink-3);padding:var(--space-sm) var(--space-xl);border-top:1px solid var(--rule);text-align:center}.halo-search-widget .search-highlight{color:var(--accent);font-weight:600}.halo-search-widget .search-backdrop{background:#2c242066;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px)}html.dark .halo-search-widget .search-backdrop{background:#00000080}html.dark .halo-search-widget .search-result-item:hover{background:var(--accent-bg)}.lg-backdrop{background-color:#120e0cf5}.lg-toolbar{background:#ffffff14;backdrop-filter:blur(24px) saturate(1.2);-webkit-backdrop-filter:blur(24px) saturate(1.2);border-bottom:none;padding:4px 12px;height:44px}.lg-toolbar .lg-icon{color:#ffffffb3;width:36px;height:36px;font-size:17px;border-radius:8px;transition:all .2s ease;padding:0!important;line-height:36px!important}.lg-toolbar .lg-icon:before{vertical-align:middle!important;line-height:36px!important}.lg-toolbar .lg-icon:hover{color:#fff;background:#ffffff1f}.lg-inner{top:44px!important;bottom:0!important;transition:bottom .35s cubic-bezier(.16,1,.3,1),transform .35s cubic-bezier(.16,1,.3,1);will-change:bottom,transform}.lg-actions .lg-next,.lg-actions .lg-prev{background:#ffffff14;backdrop-filter:blur(16px) saturate(1.2);-webkit-backdrop-filter:blur(16px) saturate(1.2);color:#ffffffb3;border-radius:14px;width:48px;height:48px;font-size:24px;transition:all .25s cubic-bezier(.16,1,.3,1);border:1px solid rgba(255,255,255,.06)}.lg-actions .lg-next:hover,.lg-actions .lg-prev:hover{color:#fff;background:#ffffff26;border-color:#ffffff1f;transform:scale(1.05)}.lg-sub-html{position:absolute;left:0;right:0;bottom:0;background:linear-gradient(to top,rgba(18,14,12,.8) 0%,transparent 100%);color:#ffffffd9;font-family:var(--font-body);font-size:13px;letter-spacing:.02em;padding:48px 16px 12px;transition:bottom .35s cubic-bezier(.16,1,.3,1)}.wi-lg-caption{font-size:13px;color:#ffffffd9;margin-bottom:6px}.wi-lg-exif{display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px}.wi-lg-exif__camera,.wi-lg-exif__lens{font-size:11px;color:#ffffff8c;letter-spacing:.03em}.wi-lg-exif__params{display:flex;flex-wrap:wrap;gap:4px}.wi-lg-exif__aperture,.wi-lg-exif__shutter,.wi-lg-exif__iso,.wi-lg-exif__focal{display:inline-flex;align-items:center;font-size:10px;font-weight:500;color:#ffffffb3;background:#ffffff14;border-radius:4px;padding:2px 6px;letter-spacing:.04em;font-variant-numeric:tabular-nums;line-height:1.4}.lg-thumb-outer{background:#120e0cd9;backdrop-filter:blur(24px) saturate(1.2);-webkit-backdrop-filter:blur(24px) saturate(1.2);border-top:1px solid rgba(255,255,255,.06);padding:8px 0}.lg-thumb-item{border-color:transparent;border-radius:8px;overflow:hidden;border-width:2px;transition:all .25s cubic-bezier(.16,1,.3,1);opacity:.5;cursor:pointer}.lg-thumb-item.active{border-color:var(--accent)!important;opacity:1;transform:scale(1.05)}.lg-thumb-item:hover{border-color:#ffffff4d!important;opacity:.85}.lg-counter{color:#ffffff80;font-size:12px;font-family:var(--font-body);letter-spacing:.08em;font-variant-numeric:tabular-nums}.lg-progress-bar{height:2px;top:0}.lg-progress-bar .lg-progress{background:linear-gradient(90deg,var(--accent),var(--accent-hover));height:2px;border-radius:1px}.lg-outer .lg-thumb-outer{transform:translateY(100%);transition:transform .35s cubic-bezier(.16,1,.3,1);will-change:transform}.lg-outer.wi-thumb-shown .lg-thumb-outer{transform:translateY(0)}.lg-outer.wi-thumb-shown .lg-inner{bottom:100px!important;transition:bottom .35s cubic-bezier(.16,1,.3,1)}.lg-outer.wi-thumb-shown .lg-sub-html{bottom:100px;transition:bottom .35s cubic-bezier(.16,1,.3,1)}.lg-outer .lg-item{transition:opacity .3s ease,transform .3s ease}.lg-outer .lg-image{transition:opacity .25s ease}.lg-outer .lg-item.lg-complete .lg-image{opacity:1}.lg-outer .lg-item .lg-image{opacity:0}html.dark .lg-backdrop{background-color:#0a0806f7}html.dark .lg-toolbar{background:#ffffff0f}html.dark .lg-toolbar .lg-icon{color:#fff9}html.dark .lg-toolbar .lg-icon:hover{color:#fff;background:#ffffff1a}html.dark .lg-actions .lg-next,html.dark .lg-actions .lg-prev{background:#ffffff0f;color:#fff9;border-color:#ffffff0a}html.dark .lg-actions .lg-next:hover,html.dark .lg-actions .lg-prev:hover{color:#fff;background:#ffffff1f;border-color:#ffffff14}html.dark .lg-sub-html{background:linear-gradient(to top,rgba(10,8,6,.85) 0%,transparent 100%);color:#ffffffbf}html.dark .lg-thumb-outer{background:#0a0806e0;border-top-color:#ffffff0a}html.dark .lg-thumb-item{opacity:.4}html.dark .lg-thumb-item.active{border-color:var(--accent)!important;opacity:1}html.dark .lg-thumb-item:hover{border-color:#fff3!important;opacity:.75}html.dark .lg-counter{color:#fff6}html.dark .wi-lg-caption{color:#ffffffbf}html.dark .wi-lg-exif__camera,html.dark .wi-lg-exif__lens{color:#ffffff73}html.dark .wi-lg-exif__aperture,html.dark .wi-lg-exif__shutter,html.dark .wi-lg-exif__iso,html.dark .wi-lg-exif__focal{color:#fff9;background:#ffffff0f}@media(max-width:768px){.lg-toolbar{padding:2px 8px;height:40px}.lg-toolbar .lg-icon{width:32px;height:32px;font-size:15px;line-height:32px!important}.lg-toolbar .lg-icon:before{line-height:32px!important}.lg-inner{top:40px!important;bottom:0!important;transition:bottom .35s cubic-bezier(.16,1,.3,1)}.lg-actions .lg-next,.lg-actions .lg-prev{width:40px;height:40px;font-size:20px;border-radius:12px}.lg-sub-html{font-size:12px;padding:36px 12px 8px}.wi-lg-caption{font-size:12px;margin-bottom:4px}.wi-lg-exif{gap:4px 8px}.wi-lg-exif__camera,.wi-lg-exif__lens{font-size:10px}.wi-lg-exif__aperture,.wi-lg-exif__shutter,.wi-lg-exif__iso,.wi-lg-exif__focal{font-size:9px;padding:1px 5px}.lg-outer.wi-thumb-shown .lg-inner{bottom:80px!important}.lg-outer.wi-thumb-shown .lg-sub-html{bottom:80px}.lg-sub-html{padding:32px 12px 8px}.lg-outer .lg-thumb-outer{padding:6px 0}.lg-thumb-item{border-radius:6px}}@media(max-width:639px){.lg-toolbar .lg-icon{width:28px;height:28px;font-size:14px;line-height:28px!important}.lg-toolbar .lg-icon:before{line-height:28px!important}.lg-actions .lg-next,.lg-actions .lg-prev{width:44px;height:44px;font-size:20px;border-radius:12px}.lg-sub-html{font-size:11px;padding:28px 10px 6px}.wi-lg-exif{display:none}.lg-outer.wi-thumb-shown .lg-inner{bottom:64px!important}.lg-outer.wi-thumb-shown .lg-sub-html{bottom:64px}}:root{--xhhao-com-text-1: var(--ink);--xhhao-com-text-2: var(--ink-2);--xhhao-com-bg: var(--bg);--xhhao-com-bg-card: var(--bg-raised);--xhhao-com-bg-2: var(--bg-raised);--xhhao-com-border: var(--rule);--xhhao-com-primary: var(--accent);--xhhao-com-shadow: rgb(15 23 42 / .08)}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0;min-width:0}html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;text-size-adjust:100%;hanging-punctuation:first last}@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}body{margin:0;padding:0;font-family:var(--font-body);font-size:var(--text-base);line-height:var(--leading-normal);color:var(--ink);background-color:var(--bg);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;word-wrap:break-word;overflow-wrap:break-word;overflow-x:hidden;tab-size:4}::selection{background-color:var(--accent);color:var(--bg)}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--caramel);border-radius:9999px}::-webkit-scrollbar-thumb:hover{background:var(--accent)}a{color:var(--accent);text-decoration:none;transition:color var(--duration-fast) var(--ease-out-quart)}a:hover{color:var(--accent-hover)}a:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:8px}img,video,svg{max-width:100%;height:auto}.wi-main img,.wi-main video{display:block}img{border-radius:12px}p{margin-block-end:var(--space-md)}blockquote{margin-block:var(--space-lg);padding:var(--space-md) var(--space-lg);border-left:3px solid var(--accent);color:var(--ink-2);font-size:var(--text-md);line-height:var(--leading-relaxed);background:var(--bg-raised);border-radius:0 8px 8px 0}pre{padding:var(--space-lg);border-radius:12px;overflow-x:auto;background:var(--ink);color:#f8f8f2;font-family:var(--font-mono);font-size:var(--text-sm);line-height:var(--leading-relaxed);tab-size:2;scrollbar-width:none;-ms-overflow-style:none}pre::-webkit-scrollbar{display:none}code{font-family:var(--font-mono);font-size:.88em;padding:.15em .4em;background:var(--bg-raised);border:1px solid var(--rule);border-radius:8px}pre>code{all:unset;font-size:.9em;color:inherit}hr{margin-block:var(--space-2xl);border:none;border-top:1px solid var(--rule)}table{width:100%;border-collapse:collapse;font-size:var(--text-sm);overflow-x:auto;display:block}table th,table td{padding:var(--space-sm) var(--space-md);border:1px solid var(--rule);text-align:left}table th{background:var(--bg-raised);font-weight:600;color:var(--ink)}table td{color:var(--ink-2)}.wi-container{width:100%;max-width:1200px;margin-inline:auto;padding-inline:clamp(1rem,3vw,2rem)}.wi-section{padding-block:var(--section-spacing)}.wi-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.wi-main{padding-top:100px;padding-bottom:0;position:relative;z-index:1;background-color:var(--bg);width:100%;overflow-x:hidden;overflow-x:clip}.wi-main--wide.wi-main--home{padding-top:0;padding-bottom:0;padding-inline:0;background-color:transparent;max-width:100%;margin:0;overflow-x:hidden;overflow-x:clip;z-index:auto}.wi-content-wrap{max-width:800px;margin:0 auto;padding-inline:clamp(1rem,3vw,2rem);overflow-x:hidden;overflow-x:clip}.wi-content-wrap--wide{max-width:1200px}.wi-main--wide{max-width:1400px;width:100%;margin:0 auto}@media(max-width:768px){body{font-size:var(--text-base)}p{margin-block-end:1.2em}.wi-content-wrap{padding-inline:1.25rem}blockquote{padding:var(--space-sm) var(--space-md);font-size:var(--text-base)}pre{padding:var(--space-md);font-size:var(--text-sm)}}@media(max-width:480px){body{font-size:var(--text-base)}.wi-content-wrap{padding-inline:1rem}blockquote{padding:var(--space-sm) var(--space-sm);font-size:var(--text-base)}table{font-size:var(--text-sm)}th,td{padding:var(--space-sm) var(--space-sm)}}.theme-toggle[data-astro-cid-dz5h74bc]{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:34px;height:34px;padding:0;border:none;border-radius:8px;background:transparent;color:var(--ink-2);cursor:pointer;transition:background .15s ease,color .15s ease}.theme-toggle[data-astro-cid-dz5h74bc]:hover{background:var(--bg-raised);color:var(--ink)}.wi-navbar-wrapper[data-astro-cid-5blmo7yk]{position:fixed;top:0;left:0;right:0;z-index:100;display:flex;justify-content:center;padding:.75rem 1rem;pointer-events:none;transition:transform .35s cubic-bezier(.16,1,.3,1),padding var(--duration-normal) var(--ease-out-expo)}.wi-navbar--hidden[data-astro-cid-5blmo7yk]{transform:translateY(-100%)}.wi-navbar__capsule[data-astro-cid-5blmo7yk]{display:flex;align-items:center;gap:.5rem;width:100%;height:56px;padding:0 1.5rem;margin:0 auto;pointer-events:auto;transition:background var(--duration-normal) var(--ease-out-expo),box-shadow var(--duration-normal) var(--ease-out-expo),transform var(--duration-normal) var(--ease-out-expo)}.wi-navbar--glass[data-astro-cid-5blmo7yk] .wi-navbar__capsule[data-astro-cid-5blmo7yk]{border-radius:9999px;background:var(--glass-bg);backdrop-filter:blur(20px) saturate(180%);-webkit-backdrop-filter:blur(20px) saturate(180%);border:1px solid var(--glass-border);box-shadow:var(--shadow-md);max-width:900px}.wi-navbar--glass[data-astro-cid-5blmo7yk].wi-navbar--scrolled .wi-navbar__capsule[data-astro-cid-5blmo7yk]{background:var(--bg-overlay);box-shadow:var(--shadow-lg);transform:scale(.98)}.wi-navbar--minimal[data-astro-cid-5blmo7yk]{padding:0}.wi-navbar--minimal[data-astro-cid-5blmo7yk] .wi-navbar__capsule[data-astro-cid-5blmo7yk]{border-radius:0;background:transparent;backdrop-filter:none;-webkit-backdrop-filter:none;border:none;border-bottom:1px solid transparent;box-shadow:none;max-width:100%;padding:0 2rem;transition:background .3s ease,border-color .3s ease}.wi-navbar--minimal[data-astro-cid-5blmo7yk].wi-navbar--scrolled .wi-navbar__capsule[data-astro-cid-5blmo7yk]{background:var(--bg);border-bottom-color:var(--rule)}.wi-navbar--float[data-astro-cid-5blmo7yk] .wi-navbar__capsule[data-astro-cid-5blmo7yk]{border-radius:16px;background:var(--glass-bg);backdrop-filter:blur(24px) saturate(180%);-webkit-backdrop-filter:blur(24px) saturate(180%);border:1px solid var(--glass-border);box-shadow:var(--shadow-lg);max-width:800px;transition:transform .3s cubic-bezier(.16,1,.3,1),background .3s ease,box-shadow .3s ease}.wi-navbar--float[data-astro-cid-5blmo7yk].wi-navbar--scrolled .wi-navbar__capsule[data-astro-cid-5blmo7yk]{transform:scale(.96);box-shadow:var(--shadow-md)}.wi-navbar__brand[data-astro-cid-5blmo7yk]{display:flex;align-items:center;gap:.5rem;text-decoration:none;flex-shrink:0}.wi-navbar__logo[data-astro-cid-5blmo7yk]{height:32px;width:auto;border-radius:8px;object-fit:contain}.wi-navbar__logo--square[data-astro-cid-5blmo7yk]{border-radius:0}.wi-navbar__logo--rounded[data-astro-cid-5blmo7yk]{border-radius:8px}.wi-navbar__logo--circle[data-astro-cid-5blmo7yk]{border-radius:50%}.wi-navbar__title[data-astro-cid-5blmo7yk]{font-family:var(--font-sans);font-weight:700;font-size:var(--text-md);color:var(--ink);letter-spacing:var(--tracking-tight);white-space:nowrap;transition:color var(--duration-fast) var(--ease-out-quart)}.wi-navbar__brand[data-astro-cid-5blmo7yk]:hover .wi-navbar__title[data-astro-cid-5blmo7yk]{color:var(--accent)}.wi-navbar__nav[data-astro-cid-5blmo7yk]{display:flex;align-items:center;gap:.25rem;flex:1;justify-content:center;min-width:0}.wi-navbar__item[data-astro-cid-5blmo7yk]{position:relative;display:inline-flex}.wi-navbar__submenu[data-astro-cid-5blmo7yk]{position:absolute;top:100%;left:50%;transform:translate(-50%) translateY(6px);display:flex;flex-direction:column;min-width:168px;padding:6px;margin:0;list-style:none;border-radius:var(--radius-md, 12px);background:var(--bg-raised);border:1px solid var(--rule);box-shadow:var(--shadow-lg);opacity:0;visibility:hidden;transition:opacity .18s ease,transform .18s var(--ease-out-quart),visibility .18s;z-index:101}.wi-navbar__item--has-children[data-astro-cid-5blmo7yk]:after{content:"";position:absolute;left:0;right:0;top:100%;height:10px}.wi-navbar__item--has-children[data-astro-cid-5blmo7yk]:hover .wi-navbar__submenu[data-astro-cid-5blmo7yk],.wi-navbar__item--has-children[data-astro-cid-5blmo7yk]:focus-within .wi-navbar__submenu[data-astro-cid-5blmo7yk]{opacity:1;visibility:visible;transform:translate(-50%) translateY(0)}.wi-navbar__submenu-link[data-astro-cid-5blmo7yk]{display:block;padding:.5rem .75rem;border-radius:8px;font-size:var(--text-sm);color:var(--ink-2);text-decoration:none;white-space:nowrap;transition:color .15s ease,background .15s ease}.wi-navbar__submenu-link[data-astro-cid-5blmo7yk]:hover{color:var(--accent);background:color-mix(in srgb,var(--accent) 8%,transparent)}.wi-navbar__item--has-children[data-astro-cid-5blmo7yk]>.wi-navbar__link[data-astro-cid-5blmo7yk]:after{content:"";display:inline-block;width:4px;height:4px;margin-left:.3rem;margin-top:-2px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(45deg);opacity:.6;transition:transform .18s var(--ease-out-quart)}.wi-navbar__item--has-children[data-astro-cid-5blmo7yk]:hover>.wi-navbar__link[data-astro-cid-5blmo7yk]:after{transform:rotate(225deg);margin-top:2px}.wi-navbar__link[data-astro-cid-5blmo7yk]{display:inline-flex;align-items:center;padding:.3rem .7rem;border-radius:9999px;font-size:var(--text-sm);color:var(--ink-2);text-decoration:none;white-space:nowrap;transition:color var(--duration-fast) var(--ease-out-quart),background var(--duration-fast) var(--ease-out-quart)}.wi-navbar__link[data-astro-cid-5blmo7yk]:hover{color:var(--accent);background:var(--bg-raised)}.wi-navbar__link--active[data-astro-cid-5blmo7yk]{color:var(--ink);background:var(--bg-raised);font-weight:600}.wi-navbar__actions[data-astro-cid-5blmo7yk]{display:flex;align-items:center;gap:.25rem;flex-shrink:0;margin-left:auto}.wi-navbar__action-btn[data-astro-cid-5blmo7yk]{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;padding:0;border:none;border-radius:9999px;background:transparent;color:var(--ink-2);cursor:pointer;transition:background var(--duration-fast) var(--ease-out-quart),color var(--duration-fast) var(--ease-out-quart)}.wi-navbar__action-btn[data-astro-cid-5blmo7yk]:hover{background:var(--bg-raised);color:var(--ink)}.wi-navbar__action-btn[data-astro-cid-5blmo7yk]:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.wi-navbar__menu-btn[data-astro-cid-5blmo7yk]{display:none}@media(max-width:768px){.wi-navbar-wrapper[data-astro-cid-5blmo7yk]{padding:.5rem .75rem}.wi-navbar__capsule[data-astro-cid-5blmo7yk]{padding:0 1rem}.wi-navbar__nav[data-astro-cid-5blmo7yk]{display:none}.wi-navbar__action-btn[data-astro-cid-5blmo7yk]{width:40px;height:40px}.wi-navbar__menu-btn[data-astro-cid-5blmo7yk]{display:inline-flex}}footer[data-astro-cid-sz7xmlte]{position:relative;border-top:1px solid var(--rule);background-color:var(--bg)}footer[data-astro-cid-sz7xmlte]:before{content:"";position:absolute;inset:0;pointer-events:none;background-color:color-mix(in srgb,var(--bg) 97%,var(--accent) 3%);-webkit-mask-image:linear-gradient(to bottom,transparent,#000);mask-image:linear-gradient(to bottom,transparent,#000)}.footer-inner[data-astro-cid-sz7xmlte]{position:relative;max-width:1200px;width:100%;margin:0 auto;padding:1.25rem;display:flex;flex-direction:column;align-items:center;gap:.75rem}.footer-bottom[data-astro-cid-sz7xmlte]{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:1rem;font-size:.85rem;color:var(--ink-3);width:100%}.footer-bottom--center[data-astro-cid-sz7xmlte]{justify-content:center}.footer-bottom--center[data-astro-cid-sz7xmlte] .footer-bottom__left[data-astro-cid-sz7xmlte]{flex:none}.footer-bottom__left[data-astro-cid-sz7xmlte]{display:flex;align-items:center;gap:.75rem;flex-wrap:wrap}.footer-copyright[data-astro-cid-sz7xmlte]{color:var(--ink-3)}.footer-icp[data-astro-cid-sz7xmlte] a[data-astro-cid-sz7xmlte]{color:var(--ink-3);text-decoration:none;transition:color .15s ease}.footer-icp[data-astro-cid-sz7xmlte] a[data-astro-cid-sz7xmlte]:hover{color:var(--ink-2)}.footer-mps[data-astro-cid-sz7xmlte] a[data-astro-cid-sz7xmlte]{display:inline-flex;align-items:center;gap:.3rem;color:var(--ink-3);text-decoration:none;transition:color .15s ease}.footer-mps[data-astro-cid-sz7xmlte] a[data-astro-cid-sz7xmlte]:hover{color:var(--ink-2)}.footer-mps__icon[data-astro-cid-sz7xmlte]{flex:none;vertical-align:middle}.footer-stats[data-astro-cid-sz7xmlte]{display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:.5rem 1.25rem;width:100%;font-size:.8rem;color:var(--ink-3)}.footer-stat[data-astro-cid-sz7xmlte]{display:inline-flex;align-items:baseline;gap:.3rem}.footer-stat__value[data-astro-cid-sz7xmlte]{font-weight:600;color:var(--ink-2);font-variant-numeric:tabular-nums}.footer-stat__label[data-astro-cid-sz7xmlte]{opacity:.8}.footer-socials[data-astro-cid-sz7xmlte]{display:inline-flex;align-items:center;gap:.75rem}.footer-socials[data-astro-cid-sz7xmlte] a[data-astro-cid-sz7xmlte]{display:inline-flex;align-items:center;justify-content:center;color:var(--ink-3);text-decoration:none;font-size:1.05rem;transition:color .15s ease}.footer-socials[data-astro-cid-sz7xmlte] a[data-astro-cid-sz7xmlte]:hover{color:var(--ink-2)}.footer-bottom__right[data-astro-cid-sz7xmlte]{display:flex;align-items:center;gap:.5rem}.footer-bottom__right[data-astro-cid-sz7xmlte] a[data-astro-cid-sz7xmlte]{color:var(--ink-3);text-decoration:none;transition:color .15s ease}.footer-bottom__right[data-astro-cid-sz7xmlte] a[data-astro-cid-sz7xmlte]:hover{color:var(--ink-2)}.footer-separator[data-astro-cid-sz7xmlte]{color:var(--ink-3);opacity:.5}.footer-custom[data-astro-cid-sz7xmlte]{width:100%;text-align:center;font-size:.85rem;color:var(--ink-3);line-height:1.8}.footer-custom[data-astro-cid-sz7xmlte] a,.footer-custom[data-astro-cid-sz7xmlte] p,.footer-custom[data-astro-cid-sz7xmlte] span{display:inline;margin-inline:.25em}.footer-custom[data-astro-cid-sz7xmlte] a{color:var(--ink-3);text-decoration:none;transition:color .15s ease}.footer-custom[data-astro-cid-sz7xmlte] a:hover{color:var(--ink-2)}.footer-custom[data-astro-cid-sz7xmlte] img{display:inline-block;vertical-align:middle;border-radius:4px}.footer-custom[data-astro-cid-sz7xmlte] div{text-align:center}.footer-injected[data-astro-cid-sz7xmlte]{width:100%;text-align:center;font-size:.85rem;color:var(--ink-3);line-height:1.8}.footer-injected[data-astro-cid-sz7xmlte] a,.footer-injected[data-astro-cid-sz7xmlte] p,.footer-injected[data-astro-cid-sz7xmlte] span{display:inline;margin-inline:.25em}.footer-injected[data-astro-cid-sz7xmlte] a{color:var(--ink-3);text-decoration:none;transition:color .15s ease}.footer-injected[data-astro-cid-sz7xmlte] a:hover{color:var(--ink-2)}.footer-injected[data-astro-cid-sz7xmlte] img{display:inline-block;vertical-align:middle;border-radius:4px}.footer-injected[data-astro-cid-sz7xmlte] div{text-align:center}@media(max-width:768px){.footer-bottom[data-astro-cid-sz7xmlte]{flex-direction:column;align-items:center;text-align:center}.footer-bottom__left[data-astro-cid-sz7xmlte],.footer-bottom__right[data-astro-cid-sz7xmlte]{justify-content:center}.footer-custom[data-astro-cid-sz7xmlte],.footer-injected[data-astro-cid-sz7xmlte]{font-size:.75rem}}.wi-mobile-menu[data-astro-cid-6aabv5oc]{position:fixed;inset:0;z-index:200;pointer-events:none;visibility:hidden}.wi-mobile-menu--open[data-astro-cid-6aabv5oc]{pointer-events:auto;visibility:visible}.wi-mobile-menu__backdrop[data-astro-cid-6aabv5oc]{position:absolute;inset:0;background:#0006;opacity:0;transition:opacity var(--duration-normal) var(--ease-out-expo)}.wi-mobile-menu--open[data-astro-cid-6aabv5oc] .wi-mobile-menu__backdrop[data-astro-cid-6aabv5oc]{opacity:1}.wi-mobile-menu__panel[data-astro-cid-6aabv5oc]{position:absolute;top:0;right:0;bottom:0;width:min(85vw,360px);display:flex;flex-direction:column;background:var(--glass-bg);backdrop-filter:blur(24px) saturate(180%);-webkit-backdrop-filter:blur(24px) saturate(180%);border-left:1px solid var(--glass-border);box-shadow:var(--shadow-lg);transform:translate(100%);transition:transform var(--duration-normal) var(--ease-out-expo)}.wi-mobile-menu--open[data-astro-cid-6aabv5oc] .wi-mobile-menu__panel[data-astro-cid-6aabv5oc]{transform:translate(0)}.wi-mobile-menu__header[data-astro-cid-6aabv5oc]{display:flex;align-items:center;justify-content:flex-end;padding:1rem 1.25rem;border-bottom:1px solid var(--glass-border)}.wi-mobile-menu__close[data-astro-cid-6aabv5oc]{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;padding:0;border:none;border-radius:9999px;background:transparent;color:var(--ink-2);cursor:pointer;transition:background var(--duration-fast) var(--ease-out-quart),color var(--duration-fast) var(--ease-out-quart)}.wi-mobile-menu__close[data-astro-cid-6aabv5oc]:hover{background:var(--bg-raised);color:var(--ink)}.wi-mobile-menu__close[data-astro-cid-6aabv5oc]:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.wi-mobile-menu__nav[data-astro-cid-6aabv5oc]{flex:1;overflow-y:auto;padding:1rem 1.25rem;display:flex;flex-direction:column;gap:.25rem}.wi-mobile-menu__link[data-astro-cid-6aabv5oc]{display:flex;align-items:center;padding:.75rem 1rem;border-radius:12px;font-size:var(--text-lg);font-weight:500;color:var(--ink-2);text-decoration:none;transition:color var(--duration-fast) var(--ease-out-quart),background var(--duration-fast) var(--ease-out-quart)}.wi-mobile-menu__link--sub[data-astro-cid-6aabv5oc]{padding-left:2rem;font-size:var(--text-base);font-weight:400;color:var(--ink-3)}.wi-mobile-menu__link[data-astro-cid-6aabv5oc]:hover{color:var(--accent);background:var(--bg-raised)}.wi-mobile-menu__link--active[data-astro-cid-6aabv5oc]{color:var(--accent);background:var(--bg-raised);font-weight:600}.wi-mobile-menu__footer[data-astro-cid-6aabv5oc]{display:flex;flex-direction:column;gap:.5rem;padding:1rem 1.25rem;border-top:1px solid var(--glass-border)}.wi-mobile-menu__action-btn[data-astro-cid-6aabv5oc]{display:flex;align-items:center;gap:.75rem;width:100%;padding:.75rem 1rem;border:none;border-radius:12px;background:transparent;color:var(--ink-2);font-size:var(--text-md);font-family:var(--font-sans);cursor:pointer;transition:color var(--duration-fast) var(--ease-out-quart),background var(--duration-fast) var(--ease-out-quart)}.wi-mobile-menu__action-btn[data-astro-cid-6aabv5oc]:hover{color:var(--ink);background:var(--bg-raised)}.wi-mobile-menu__action-btn[data-astro-cid-6aabv5oc]:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.wi-mobile-menu__icon-sun[data-astro-cid-6aabv5oc],.dark .wi-mobile-menu__icon-moon[data-astro-cid-6aabv5oc]{display:none}.dark .wi-mobile-menu__icon-sun[data-astro-cid-6aabv5oc]{display:block}.wi-click-fx-layer{position:fixed;inset:0;z-index:12050;pointer-events:none;overflow:hidden}.wi-click-fx{position:fixed;pointer-events:none;will-change:transform,opacity;user-select:none}.wi-click-fx--text{font-size:18px;font-weight:700;transform:translate(-50%,-50%);animation:wi-fx-text 1.2s ease-out forwards;text-shadow:0 1px 2px rgba(0,0,0,.18)}.wi-click-fx--heart{font-size:20px;opacity:1;transition:transform 1s cubic-bezier(.16,1,.3,1),opacity 1s ease-out}.wi-click-fx--spark{width:6px;height:6px;border-radius:50%;opacity:1;transition:transform .8s cubic-bezier(.16,1,.3,1),opacity .8s ease-out}.wi-click-fx--ripple{width:30px;height:30px;border:2px solid;border-radius:50%;transform:translate(-50%,-50%) scale(.5);opacity:.9;transition:transform .7s ease-out,opacity .7s ease-out}.wi-click-fx--particle{width:8px;height:8px;border-radius:50%;opacity:1;transition:transform .7s cubic-bezier(.16,1,.3,1),opacity .7s ease-out}.wi-click-fx--star{font-size:16px;opacity:1;transition:transform .8s cubic-bezier(.16,1,.3,1),opacity .8s ease-out}.wi-click-fx--trail-star{font-size:12px;transform:translate(-50%,-50%);opacity:.9;transition:opacity .6s ease-out,transform .6s ease-out}.wi-click-fx--trail-particle{width:6px;height:6px;border-radius:50%;transform:translate(-50%,-50%);opacity:.9;transition:opacity .5s ease-out,transform .5s ease-out}@keyframes wi-fx-text{0%{opacity:0;transform:translate(-50%,-50%) scale(.5)}20%{opacity:1;transform:translate(-50%,-80%) scale(1.1)}to{opacity:0;transform:translate(-50%,-120%) scale(.9)}}html{min-height:100vh}html.wi-theme-transition,html.wi-theme-transition *,html.wi-theme-transition *:before,html.wi-theme-transition *:after{transition:background-color .3s ease,color .3s ease,border-color .3s ease,box-shadow .3s ease,fill .3s ease,stroke .3s ease!important}.wi-body{min-height:100vh;display:flex;flex-direction:column}.wi-main{flex:1}.wi-reveal{opacity:0;transform:translateY(20px);transition:opacity var(--duration-normal, .3s) var(--ease-out-expo, cubic-bezier(.16, 1, .3, 1)),transform var(--duration-normal, .3s) var(--ease-out-expo, cubic-bezier(.16, 1, .3, 1))}.wi-revealed{opacity:1;transform:translateY(0)}html.wi-no-animations .wi-reveal{opacity:1;transform:none;transition:none}
diff --git a/compat/assets/Layout.DXZc2eEc.css b/compat/assets/Layout.DXZc2eEc.css
new file mode 100644
index 0000000..6696e9b
--- /dev/null
+++ b/compat/assets/Layout.DXZc2eEc.css
@@ -0,0 +1 @@
+@charset "UTF-8";:root{--bg: #faf7f2;--bg-raised: #f3ede5;--bg-overlay: color-mix(in srgb, var(--bg) 85%, transparent);--ink: #2c2420;--ink-2: #7a6e64;--ink-3: #b5a99e;--rule: #e8e0d6;--accent: #d4764e;--accent-hover: #c4613a;--accent-bg: #fdf0e8;--mist-pink: #f0e4de;--sea-salt: #e8e0d6;--caramel: #8b6f5e;--glass-bg: color-mix(in srgb, var(--bg) 72%, transparent);--glass-border: color-mix(in srgb, var(--rule) 50%, transparent);--shadow-sm: 0 1px 3px color-mix(in srgb, var(--ink) 6%, transparent);--shadow-md: 0 4px 16px color-mix(in srgb, var(--ink) 8%, transparent);--shadow-lg: 0 8px 32px color-mix(in srgb, var(--ink) 12%, transparent);--shadow-glow: 0 0 40px color-mix(in srgb, var(--accent) 15%, transparent)}html.dark{--bg: #1e1c1a;--bg-raised: #292623;--bg-overlay: color-mix(in srgb, var(--bg) 85%, transparent);--ink: #e9e4dd;--ink-2: #aaa096;--ink-3: #7c7268;--rule: #3b362f;--accent: #e89a64;--accent-hover: #f2ad79;--accent-bg: #2c231b;--mist-pink: #2e2823;--sea-salt: #302b26;--caramel: #a38b7b;--glass-bg: color-mix(in srgb, var(--bg) 72%, transparent);--glass-border: color-mix(in srgb, var(--rule) 50%, transparent);--shadow-sm: 0 1px 3px rgba(0, 0, 0, .24);--shadow-md: 0 4px 16px rgba(0, 0, 0, .3);--shadow-lg: 0 8px 32px rgba(0, 0, 0, .4);--shadow-glow: 0 0 40px rgba(232, 154, 100, .12)}html[data-palette=matcha]{--bg: #f6f8f1;--bg-raised: #ecf1e3;--ink: #26302a;--ink-2: #6d7a6e;--ink-3: #a8b3a4;--rule: #dde5d4;--accent: #6f9d52;--accent-hover: #5d8943;--accent-bg: #ecf3e2;--mist-pink: #e7eddc;--sea-salt: #dfe8d3;--caramel: #7d8a68}html[data-palette=matcha].dark{--bg: #1b1f1a;--bg-raised: #252b22;--ink: #e6e9e0;--ink-2: #a3ab9c;--ink-3: #767e70;--rule: #363d33;--accent: #9cc47f;--accent-hover: #aed493;--accent-bg: #242c1f;--mist-pink: #262d22;--sea-salt: #282f24;--caramel: #98a387}html[data-palette=indigo]{--bg: #f5f7fa;--bg-raised: #eaeff5;--ink: #232a33;--ink-2: #66707d;--ink-3: #a3adb8;--rule: #dce2ea;--accent: #4a6fa5;--accent-hover: #3d5d8c;--accent-bg: #e9eff8;--mist-pink: #e2e8f0;--sea-salt: #dbe4ee;--caramel: #707c8e}html[data-palette=indigo].dark{--bg: #191d23;--bg-raised: #222831;--ink: #e4e7ec;--ink-2: #9aa4b1;--ink-3: #6d7683;--rule: #323a45;--accent: #7fa3d1;--accent-hover: #93b4dc;--accent-bg: #1f2632;--mist-pink: #232830;--sea-salt: #252b34;--caramel: #8b95a6}html[data-palette=sakura]{--bg: #faf5f6;--bg-raised: #f3eaec;--ink: #322a2c;--ink-2: #7d6e72;--ink-3: #b4a6aa;--rule: #ecdfe2;--accent: #d97387;--accent-hover: #c85d72;--accent-bg: #fbeef1;--mist-pink: #f2e2e6;--sea-salt: #eddfe3;--caramel: #96757e}html[data-palette=sakura].dark{--bg: #201b1c;--bg-raised: #2a2425;--ink: #ece5e6;--ink-2: #b0a4a7;--ink-3: #7f7276;--rule: #3c3436;--accent: #e89aab;--accent-hover: #f0aec0;--accent-bg: #2d2225;--mist-pink: #2f2729;--sea-salt: #31282a;--caramel: #a88d94}html[data-palette=violet]{--bg: #f7f5fa;--bg-raised: #eeeaf5;--ink: #2b2733;--ink-2: #6f6a7c;--ink-3: #aaa5b6;--rule: #e2ddeb;--accent: #8a6fc0;--accent-hover: #7759ae;--accent-bg: #f0eaf9;--mist-pink: #e8e2f0;--sea-salt: #e3dcee;--caramel: #7f7590}html[data-palette=violet].dark{--bg: #1c1a21;--bg-raised: #26222f;--ink: #e8e5ee;--ink-2: #a49eaf;--ink-3: #746e80;--rule: #373241;--accent: #b49ae0;--accent-hover: #c3ace8;--accent-bg: #262033;--mist-pink: #292434;--sea-salt: #2b2536;--caramel: #948caa}html[data-palette=sea]{--bg: #f3f8f7;--bg-raised: #e8f0ee;--ink: #21302d;--ink-2: #647872;--ink-3: #9fb1ac;--rule: #d9e6e3;--accent: #3d9c8f;--accent-hover: #2f8578;--accent-bg: #e5f3f0;--mist-pink: #dee9e6;--sea-salt: #d6e5e1;--caramel: #6c8680}html[data-palette=sea].dark{--bg: #181f1e;--bg-raised: #212a28;--ink: #e3eae8;--ink-2: #9aaba6;--ink-3: #6d7d79;--rule: #2f3b39;--accent: #6cc3b4;--accent-hover: #82d0c2;--accent-bg: #1d2a27;--mist-pink: #222c2a;--sea-salt: #242e2c;--caramel: #869894}html[data-palette=amber]{--bg: #faf7ef;--bg-raised: #f3eddc;--ink: #322b1e;--ink-2: #7d7360;--ink-3: #b5ab94;--rule: #eae1cb;--accent: #b97f1c;--accent-hover: #9f6a0e;--accent-bg: #f9efd8;--mist-pink: #f0e8d2;--sea-salt: #ebe2ca;--caramel: #96835c}html[data-palette=amber].dark{--bg: #201d16;--bg-raised: #2a261d;--ink: #ebe6d9;--ink-2: #b0a893;--ink-3: #7f7866;--rule: #3c3729;--accent: #e0a83e;--accent-hover: #ebba5c;--accent-bg: #2c251a;--mist-pink: #2f2a1e;--sea-salt: #312c20;--caramel: #a89a76}html[data-palette=plum]{--bg: #f9f4f5;--bg-raised: #f1e8ea;--ink: #2f2427;--ink-2: #796a6f;--ink-3: #b1a2a7;--rule: #e9dde0;--accent: #a4506b;--accent-hover: #8d3f59;--accent-bg: #f7e9ee;--mist-pink: #ecdee2;--sea-salt: #e5d8db;--caramel: #8d6f77}html[data-palette=plum].dark{--bg: #1f1a1b;--bg-raised: #292223;--ink: #eae2e4;--ink-2: #ada0a4;--ink-3: #7c6e73;--rule: #3a3133;--accent: #d98aa3;--accent-hover: #e39fb5;--accent-bg: #2b2023;--mist-pink: #2d2527;--sea-salt: #2f2729;--caramel: #a08890}html[data-palette=graphite]{--bg: #f7f7f6;--bg-raised: #eeedeb;--ink: #262626;--ink-2: #6e6e6c;--ink-3: #ababa8;--rule: #e0e0de;--accent: #3f3f3e;--accent-hover: #262626;--accent-bg: #ececea;--mist-pink: #e9e9e7;--sea-salt: #e5e5e3;--caramel: #7b7b78}html[data-palette=graphite].dark{--bg: #1b1b1a;--bg-raised: #252524;--ink: #e8e8e6;--ink-2: #a5a5a2;--ink-3: #757572;--rule: #353534;--accent: #c9c9c5;--accent-hover: #d8d8d4;--accent-bg: #262625;--mist-pink: #2a2a29;--sea-salt: #2c2c2b;--caramel: #8f8f8c}html[data-palette=cocoa]{--bg: #f8f4f0;--bg-raised: #f0e8e1;--ink: #2e2722;--ink-2: #786c62;--ink-3: #b3a89d;--rule: #e7ddd3;--accent: #9a6b4f;--accent-hover: #835539;--accent-bg: #f5e9e0;--mist-pink: #ecdfd4;--sea-salt: #e6d9cd;--caramel: #8a6f5b}html[data-palette=cocoa].dark{--bg: #1e1a17;--bg-raised: #282320;--ink: #eae4dd;--ink-2: #aca199;--ink-3: #7b7169;--rule: #3a332e;--accent: #cd9878;--accent-hover: #daa98c;--accent-bg: #2a211c;--mist-pink: #2d2721;--sea-salt: #2f2923;--caramel: #a08d7c}html[data-palette=azure]{--bg: #f4f8fb;--bg-raised: #e9f1f7;--ink: #223038;--ink-2: #62737e;--ink-3: #a0b0ba;--rule: #dbe7ee;--accent: #3b82c4;--accent-hover: #2e6ba5;--accent-bg: #e7f1f9;--mist-pink: #e0ebf2;--sea-salt: #d8e6ef;--caramel: #6d8090}html[data-palette=azure].dark{--bg: #172026;--bg-raised: #202a31;--ink: #e3eaef;--ink-2: #99a8b3;--ink-3: #6b7a85;--rule: #2e3a42;--accent: #74b3e0;--accent-hover: #88c1e8;--accent-bg: #1d2830;--mist-pink: #222c34;--sea-salt: #243038;--caramel: #8496a3}:root{--font-sans: "LXGW WenKai", "Noto Serif SC", "Source Han Serif SC", Georgia, serif;--font-body: "LXGW WenKai", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;--font-mono: "JetBrains Mono", "Fira Code", monospace;--text-xs: clamp(.75rem, .7rem + .2vw, .8rem);--text-sm: clamp(.875rem, .82rem + .2vw, .95rem);--text-base: clamp(1rem, .94rem + .25vw, 1.05rem);--text-md: clamp(1.1rem, 1.02rem + .3vw, 1.2rem);--text-lg: clamp(1.2rem, 1.1rem + .45vw, 1.3rem);--text-xl: clamp(1.35rem, 1.2rem + .7vw, 1.6rem);--text-2xl: clamp(1.65rem, 1.4rem + 1.05vw, 2rem);--text-3xl: clamp(1.95rem, 1.6rem + 1.65vw, 2.4rem);--text-4xl: clamp(2.3rem, 1.8rem + 2.25vw, 3.2rem);--text-5xl: clamp(2.8rem, 2rem + 3.5vw, 4rem);--leading-none: 1;--leading-tight: 1.2;--leading-snug: 1.35;--leading-normal: 1.6;--leading-relaxed: 1.75;--leading-loose: 2;--tracking-tight: -.02em;--tracking-normal: 0;--tracking-wide: .04em;--tracking-wider: .08em;--tracking-widest: .12em}h1,h2,h3,h4,h5,h6{font-family:var(--font-sans);font-weight:700;line-height:var(--leading-tight);letter-spacing:var(--tracking-tight);color:var(--ink);margin-bottom:var(--space-sm)}h1{font-size:var(--text-3xl);margin-bottom:var(--space-lg)}h2{font-size:var(--text-2xl);padding-left:var(--space-md);border-left:3px solid var(--accent);margin-bottom:var(--space-sm)}h3{font-size:var(--text-xl);position:relative;padding-left:var(--space-lg)}h3:before{content:"";display:block;position:absolute;left:0;top:50%;transform:translateY(-50%);width:6px;height:6px;border-radius:50%;background:var(--accent);opacity:.6}h4{font-size:var(--text-md);color:var(--ink-2)}h5{font-size:var(--text-base);color:var(--ink-2)}h6{font-size:var(--text-sm);color:var(--ink-3)}.wi-post__body :is(h1,h2,h3,h4,h5,h6),.wi-page__body :is(h1,h2,h3,h4,h5,h6),.wi-messageboard__body :is(h1,h2,h3,h4,h5,h6){font-family:var(--font-sans);font-weight:700;line-height:1.35;letter-spacing:-.01em;color:var(--ink);scroll-margin-top:88px;text-wrap:balance;padding-left:0;border-left:0}.wi-post__body :is(h1,h2,h3,h4,h5,h6):before,.wi-post__body :is(h1,h2,h3,h4,h5,h6):after,.wi-page__body :is(h1,h2,h3,h4,h5,h6):before,.wi-page__body :is(h1,h2,h3,h4,h5,h6):after,.wi-messageboard__body :is(h1,h2,h3,h4,h5,h6):before,.wi-messageboard__body :is(h1,h2,h3,h4,h5,h6):after{content:none}.wi-post__body h1,.wi-page__body h1,.wi-messageboard__body h1{font-size:clamp(1.6rem,1.4rem + 1vw,2rem);margin-top:2em;margin-bottom:.7em}.wi-post__body h2,.wi-page__body h2,.wi-messageboard__body h2{font-size:clamp(1.42rem,1.3rem + .6vw,1.68rem);margin-top:1.9em;margin-bottom:.65em}.wi-post__body h3,.wi-page__body h3,.wi-messageboard__body h3{font-size:clamp(1.24rem,1.16rem + .4vw,1.4rem);margin-top:1.7em;margin-bottom:.6em}.wi-post__body h4,.wi-page__body h4,.wi-messageboard__body h4{font-size:clamp(1.1rem,1.05rem + .25vw,1.2rem);margin-top:1.5em;margin-bottom:.5em}.wi-post__body h5,.wi-page__body h5,.wi-messageboard__body h5{font-size:1.04rem;margin-top:1.4em;margin-bottom:.45em}.wi-post__body h6,.wi-page__body h6,.wi-messageboard__body h6{font-size:.98rem;font-weight:600;color:var(--ink-3);margin-top:1.4em;margin-bottom:.45em}.wi-post__body :is(h1,h2,h3,h4,h5,h6)+:is(h1,h2,h3,h4,h5,h6),.wi-page__body :is(h1,h2,h3,h4,h5,h6)+:is(h1,h2,h3,h4,h5,h6),.wi-messageboard__body :is(h1,h2,h3,h4,h5,h6)+:is(h1,h2,h3,h4,h5,h6){margin-top:.6em}.wi-post__body>:is(h1,h2,h3,h4,h5,h6):first-child,.wi-page__body>:is(h1,h2,h3,h4,h5,h6):first-child,.wi-messageboard__body>:is(h1,h2,h3,h4,h5,h6):first-child{margin-top:0}.wi-post__body p,.wi-page__body p,.wi-messageboard__body p{margin-block-end:1.2em}.wi-post__body *,.wi-page__body *,.wi-messageboard__body *{max-width:100%}.wi-post__body :is(pre,code,table),.wi-page__body :is(pre,code,table),.wi-messageboard__body :is(pre,code,table){overflow-x:auto}.wi-post__body pre,.wi-page__body pre,.wi-messageboard__body pre{margin-block:1.5em;padding:1.25em;border-radius:12px;border:1px solid var(--rule);background:var(--bg-raised);font-size:.875em;line-height:1.6}.wi-post__body pre code,.wi-page__body pre code,.wi-messageboard__body pre code{background:none;padding:0;border:none;border-radius:0;font-size:inherit}.wi-post__body code,.wi-page__body code,.wi-messageboard__body code{background:var(--bg-raised);padding:.15em .4em;border-radius:8px;font-size:.875em;border:1px solid var(--rule)}.wi-post__body blockquote,.wi-page__body blockquote,.wi-messageboard__body blockquote{margin-block:1.25em;padding-block:.7em;padding-inline:1.25em}.wi-post__body blockquote>:is(p,ul,ol,pre,figure,table,h1,h2,h3,h4,h5,h6),.wi-page__body blockquote>:is(p,ul,ol,pre,figure,table,h1,h2,h3,h4,h5,h6),.wi-messageboard__body blockquote>:is(p,ul,ol,pre,figure,table,h1,h2,h3,h4,h5,h6){margin-block:0}.wi-post__body blockquote>*+*,.wi-page__body blockquote>*+*,.wi-messageboard__body blockquote>*+*{margin-block-start:.55em}.wi-post__body blockquote>p:empty,.wi-page__body blockquote>p:empty,.wi-messageboard__body blockquote>p:empty{display:none}.wi-post__body blockquote>p:has(>br:only-child),.wi-page__body blockquote>p:has(>br:only-child),.wi-messageboard__body blockquote>p:has(>br:only-child){display:none}.wi-post__body :is(ul,ol),.wi-page__body :is(ul,ol),.wi-messageboard__body :is(ul,ol){padding-inline-start:1.5em;margin-block-end:1.2em}.wi-post__body li,.wi-page__body li,.wi-messageboard__body li{margin-block-end:.6em}.wi-post__body a,.wi-page__body a,.wi-messageboard__body a{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:.2em}.wi-post__body :is(.ai-summary,.abstract),.wi-post__body [class*=ai-summary],.wi-post__body [class*=ai-abstract],.wi-post__body [class*=likcc-article-summary],.wi-page__body :is(.ai-summary,.abstract),.wi-page__body [class*=ai-summary],.wi-page__body [class*=ai-abstract],.wi-page__body [class*=likcc-article-summary],.wi-messageboard__body :is(.ai-summary,.abstract),.wi-messageboard__body [class*=ai-summary],.wi-messageboard__body [class*=ai-abstract],.wi-messageboard__body [class*=likcc-article-summary]{margin-bottom:15px}.wi-post__body img,.wi-post__body video,.wi-page__body img,.wi-page__body video,.wi-messageboard__body img,.wi-messageboard__body video{display:block;max-width:100%;height:auto;margin-inline:auto}.wi-post__body img,.wi-post__body video,.wi-page__body img,.wi-page__body video,.wi-messageboard__body img,.wi-messageboard__body video{border-radius:12px;margin-block:1.5em}.wi-post__body img[role=presentation],.wi-post__body img[aria-hidden=true],.wi-post__body :is(.emoji,.icon,.avatar,.badge),.wi-page__body img[role=presentation],.wi-page__body img[aria-hidden=true],.wi-page__body :is(.emoji,.icon,.avatar,.badge),.wi-messageboard__body img[role=presentation],.wi-messageboard__body img[aria-hidden=true],.wi-messageboard__body :is(.emoji,.icon,.avatar,.badge){display:inline;margin-inline:0;border-radius:0}.wi-post__body [align=center],.wi-post__body [style*="text-align:center"],.wi-post__body [style*="text-align: center"],.wi-page__body [align=center],.wi-page__body [style*="text-align:center"],.wi-page__body [style*="text-align: center"],.wi-messageboard__body [align=center],.wi-messageboard__body [style*="text-align:center"],.wi-messageboard__body [style*="text-align: center"]{text-align:center}.wi-post__body iframe,.wi-page__body iframe,.wi-messageboard__body iframe{display:block;max-width:100%;margin-inline:auto;border:none}.wi-post__body figure,.wi-page__body figure,.wi-messageboard__body figure{display:block;max-width:100%;margin-inline:auto;margin-block:1.5em;text-align:center}.wi-post__body figure :is(img,video),.wi-page__body figure :is(img,video),.wi-messageboard__body figure :is(img,video){margin-block:0}.wi-post__body figcaption,.wi-page__body figcaption,.wi-messageboard__body figcaption{color:var(--ink-3);font-size:.875rem;line-height:1.6;text-align:center;margin-top:.6em}.wi-post__body .wi-lightgallery-item,.wi-page__body .wi-lightgallery-item,.wi-messageboard__body .wi-lightgallery-item{display:block;width:fit-content;max-width:100%;margin-inline:auto;border-radius:12px;line-height:0}.wi-post__body .wi-lightgallery-item>img,.wi-page__body .wi-lightgallery-item>img,.wi-messageboard__body .wi-lightgallery-item>img{margin-block:0}.wi-post__body .wi-embed,.wi-page__body .wi-embed,.wi-messageboard__body .wi-embed{position:relative;width:100%;max-width:100%;margin-inline:auto;margin-block:1.5em;overflow:hidden;border-radius:12px;background:var(--bg-raised)}.wi-post__body .wi-embed>:is(iframe,video,embed,object),.wi-page__body .wi-embed>:is(iframe,video,embed,object),.wi-messageboard__body .wi-embed>:is(iframe,video,embed,object){position:absolute;inset:0;width:100%;height:100%;margin:0;border-radius:0;border:0}.wi-post__body .wi-media-loading,.wi-page__body .wi-media-loading,.wi-messageboard__body .wi-media-loading{filter:blur(20px);opacity:.6}.wi-post__body .wi-media-loaded,.wi-page__body .wi-media-loaded,.wi-messageboard__body .wi-media-loaded{filter:blur(0);opacity:1}@media(max-width:768px){.wi-post__body h1,.wi-page__body h1,.wi-messageboard__body h1{font-size:1.4rem}.wi-post__body h2,.wi-page__body h2,.wi-messageboard__body h2{font-size:1.28rem}.wi-post__body h3,.wi-page__body h3,.wi-messageboard__body h3{font-size:1.16rem}.wi-post__body h4,.wi-page__body h4,.wi-messageboard__body h4{font-size:1.05rem}.wi-post__body h5,.wi-page__body h5,.wi-messageboard__body h5{font-size:1rem}.wi-post__body h6,.wi-page__body h6,.wi-messageboard__body h6{font-size:.95rem}.wi-post__body p,.wi-page__body p,.wi-messageboard__body p{margin-block-end:1.35em}.wi-post__body pre,.wi-page__body pre,.wi-messageboard__body pre{font-size:.9em;padding:1em}.wi-post__body code,.wi-page__body code,.wi-messageboard__body code{font-size:.9em}.wi-post__body img,.wi-post__body video,.wi-page__body img,.wi-page__body video,.wi-messageboard__body img,.wi-messageboard__body video{margin-block:1.2em}.wi-post__body img,.wi-post__body video,.wi-post__body .wi-lightgallery-item,.wi-post__body figure,.wi-page__body img,.wi-page__body video,.wi-page__body .wi-lightgallery-item,.wi-page__body figure,.wi-messageboard__body img,.wi-messageboard__body video,.wi-messageboard__body .wi-lightgallery-item,.wi-messageboard__body figure{max-width:100%}}@media(max-width:480px){.wi-post__body h1,.wi-page__body h1,.wi-messageboard__body h1{font-size:1.32rem}.wi-post__body h2,.wi-page__body h2,.wi-messageboard__body h2{font-size:1.22rem}.wi-post__body h3,.wi-page__body h3,.wi-messageboard__body h3{font-size:1.12rem}}:root{--space-xs: .25rem;--space-sm: .5rem;--space-md: 1rem;--space-lg: 1.5rem;--space-xl: 2rem;--space-2xl: 3rem;--space-3xl: 4rem;--space-4xl: 6rem;--container-sm: 640px;--container-md: 768px;--container-lg: 1024px;--container-xl: 1200px;--content-max: 800px;--section-spacing: clamp(3rem, 2rem + 3vw, 6rem)}:root{--ease-out-expo: cubic-bezier(.16, 1, .3, 1);--ease-out-quart: cubic-bezier(.25, 1, .5, 1);--ease-in-out-cubic: cubic-bezier(.65, 0, .35, 1);--duration-fast: .15s;--duration-normal: .3s;--duration-slow: .5s;--duration-breath: 3s}@keyframes breathe{0%,to{opacity:.4;transform:scale(1)}50%{opacity:.7;transform:scale(1.08)}}@keyframes fadeInUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}@keyframes float{0%,to{transform:translateY(0)}50%{transform:translateY(-6px)}}@keyframes shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}@keyframes scrollHint{0%,to{opacity:.4;transform:translateY(0)}50%{opacity:1;transform:translateY(8px)}}.halo-comment-widget{background:var(--glass-bg);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);border:1px solid var(--glass-border);border-radius:16px;padding:var(--space-md);margin-top:var(--space-xl);width:100%;max-width:600px;margin-inline:auto}.halo-comment-widget .comment-item{background:var(--bg-raised);border:1px solid var(--rule);border-radius:12px;padding:var(--space-sm);margin-bottom:var(--space-xs);transition:box-shadow var(--duration-normal) var(--ease-out-expo),transform var(--duration-normal) var(--ease-out-expo)}.halo-comment-widget .comment-item:hover{box-shadow:var(--shadow-sm);transform:translateY(-1px)}.halo-comment-widget .comment-reply-item{background:var(--bg);border:1px solid var(--rule);border-radius:12px;padding:var(--space-xs) var(--space-sm);margin-top:var(--space-xs);transition:box-shadow var(--duration-normal) var(--ease-out-expo),transform var(--duration-normal) var(--ease-out-expo)}.halo-comment-widget .comment-reply-item:hover{box-shadow:var(--shadow-sm);transform:translateY(-1px)}.halo-comment-widget .comment-header{display:flex;align-items:center;gap:var(--space-xs);margin-bottom:var(--space-xs)}.halo-comment-widget .comment-avatar{width:24px;height:24px;border-radius:9999px;box-shadow:var(--shadow-sm)}.halo-comment-widget .comment-author{font-weight:600;color:var(--ink);font-size:var(--text-xs)}.halo-comment-widget .comment-time{font-size:var(--text-xs);color:var(--ink-3);letter-spacing:var(--tracking-wide)}.halo-comment-widget .comment-content{font-size:var(--text-sm);line-height:var(--leading-relaxed);color:var(--ink);margin-bottom:var(--space-xs)}.halo-comment-widget .comment-form{background:var(--bg-raised);border:1px solid var(--rule);border-radius:12px;padding:var(--space-sm);margin-bottom:var(--space-md)}.halo-comment-widget .comment-input,.halo-comment-widget .comment-textarea{width:100%;padding:var(--space-sm) var(--space-md);background:var(--bg);border:1px solid var(--rule);border-radius:8px;color:var(--ink);font-family:var(--font-body);font-size:var(--text-sm);transition:border-color var(--duration-fast) var(--ease-out-quart),box-shadow var(--duration-fast) var(--ease-out-quart)}.halo-comment-widget .comment-input:focus,.halo-comment-widget .comment-textarea:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 15%,transparent)}.halo-comment-widget .comment-input::placeholder,.halo-comment-widget .comment-textarea::placeholder{color:var(--ink-3)}.halo-comment-widget .comment-textarea{min-height:80px;resize:vertical}.halo-comment-widget .comment-button{display:inline-flex;align-items:center;justify-content:center;padding:var(--space-sm) var(--space-lg);background:var(--accent);color:var(--bg);border:none;border-radius:8px;font-family:var(--font-body);font-size:var(--text-sm);font-weight:600;cursor:pointer;transition:background var(--duration-fast) var(--ease-out-quart),transform var(--duration-fast) var(--ease-out-quart),box-shadow var(--duration-fast) var(--ease-out-quart)}.halo-comment-widget .comment-button:hover{background:var(--accent-hover);transform:translateY(-1px);box-shadow:var(--shadow-md)}.halo-comment-widget .comment-button:active{transform:translateY(0)}.halo-comment-widget .comment-pagination{display:flex;justify-content:center;align-items:center;gap:var(--space-md);margin-top:var(--space-lg)}.halo-comment-widget .comment-pagination-button{padding:var(--space-xs) var(--space-md);background:var(--bg-raised);border:1px solid var(--rule);border-radius:8px;color:var(--ink-2);font-size:var(--text-sm);cursor:pointer;transition:border-color var(--duration-fast) var(--ease-out-quart),color var(--duration-fast) var(--ease-out-quart)}.halo-comment-widget .comment-pagination-button:hover{border-color:var(--accent);color:var(--accent)}.halo-comment-widget .comment-reply-button{font-size:var(--text-xs);color:var(--ink-3);cursor:pointer;transition:color var(--duration-fast) var(--ease-out-quart)}.halo-comment-widget .comment-reply-button:hover{color:var(--accent)}.halo-comment-widget .comment-smiley-button{background:none;border:none;cursor:pointer;font-size:var(--text-lg);transition:transform var(--duration-fast) var(--ease-out-quart)}.halo-comment-widget .comment-smiley-button:hover{transform:scale(1.2)}html.dark .halo-comment-widget .comment-input:focus,html.dark .halo-comment-widget .comment-textarea:focus{box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 15%,transparent)}html.dark .halo-comment-widget .comment-button:hover{box-shadow:var(--shadow-md)}[data-comment-style=minimal] .halo-comment-widget{background:transparent;backdrop-filter:none;-webkit-backdrop-filter:none;border:none;border-top:1px solid var(--rule);border-radius:0;padding:var(--space-lg) 0}[data-comment-style=minimal] .halo-comment-widget .comment-item{background:transparent;border:none;border-bottom:1px solid var(--rule);border-radius:0;padding:var(--space-md) 0}[data-comment-style=minimal] .halo-comment-widget .comment-item:hover{box-shadow:none;transform:none}[data-comment-style=minimal] .halo-comment-widget .comment-reply-item{background:transparent;border:none;border-radius:0;padding:var(--space-xs) 0}[data-comment-style=minimal] .halo-comment-widget .comment-reply-item:hover{box-shadow:none;transform:none}[data-comment-style=minimal] .halo-comment-widget .comment-form{background:transparent;border:1px solid var(--rule);border-radius:12px;padding:var(--space-md)}[data-show-avatar=false] .halo-comment-widget .comment-avatar{display:none}.halo-search-widget .search-modal{background:var(--glass-bg);backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px);border:1px solid var(--glass-border);border-radius:24px;box-shadow:var(--shadow-lg);overflow:hidden}.halo-search-widget .search-input{width:100%;padding:var(--space-lg) var(--space-xl);background:transparent;border:none;border-bottom:1px solid var(--rule);color:var(--ink);font-family:var(--font-body);font-size:var(--text-lg);outline:none;transition:border-color var(--duration-fast) var(--ease-out-quart)}.halo-search-widget .search-input::placeholder{color:var(--ink-3)}.halo-search-widget .search-input:focus{border-bottom-color:var(--accent)}.halo-search-widget .search-result-item{padding:var(--space-md) var(--space-xl);border-bottom:1px solid var(--rule);cursor:pointer;transition:background var(--duration-fast) var(--ease-out-quart),padding-left var(--duration-fast) var(--ease-out-quart)}.halo-search-widget .search-result-item:hover{background:var(--accent-bg);padding-left:calc(var(--space-xl) + 4px)}.halo-search-widget .search-result-item:last-child{border-bottom:none}.halo-search-widget .search-result-title{font-size:var(--text-md);font-weight:600;color:var(--ink);margin-bottom:var(--space-xs)}.halo-search-widget .search-result-content{font-size:var(--text-sm);color:var(--ink-2);line-height:var(--leading-relaxed);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.halo-search-widget .search-result-label{font-size:var(--text-xs);color:var(--ink-3);letter-spacing:var(--tracking-wide)}.halo-search-widget .search-empty{padding:var(--space-3xl) var(--space-xl);text-align:center;color:var(--ink-3);font-size:var(--text-sm)}.halo-search-widget .search-hint{font-size:var(--text-xs);color:var(--ink-3);padding:var(--space-sm) var(--space-xl);border-top:1px solid var(--rule);text-align:center}.halo-search-widget .search-highlight{color:var(--accent);font-weight:600}.halo-search-widget .search-backdrop{background:#2c242066;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px)}html.dark .halo-search-widget .search-backdrop{background:#00000080}html.dark .halo-search-widget .search-result-item:hover{background:var(--accent-bg)}.lg-backdrop{background-color:#120e0cf5}.lg-toolbar{background:#ffffff14;backdrop-filter:blur(24px) saturate(1.2);-webkit-backdrop-filter:blur(24px) saturate(1.2);border-bottom:none;padding:4px 12px;height:44px}.lg-toolbar .lg-icon{color:#ffffffb3;width:36px;height:36px;font-size:17px;border-radius:8px;transition:all .2s ease;padding:0!important;line-height:36px!important}.lg-toolbar .lg-icon:before{vertical-align:middle!important;line-height:36px!important}.lg-toolbar .lg-icon:hover{color:#fff;background:#ffffff1f}.lg-inner{top:44px!important;bottom:0!important;transition:bottom .35s cubic-bezier(.16,1,.3,1),transform .35s cubic-bezier(.16,1,.3,1);will-change:bottom,transform}.lg-actions .lg-next,.lg-actions .lg-prev{background:#ffffff14;backdrop-filter:blur(16px) saturate(1.2);-webkit-backdrop-filter:blur(16px) saturate(1.2);color:#ffffffb3;border-radius:14px;width:48px;height:48px;font-size:24px;transition:all .25s cubic-bezier(.16,1,.3,1);border:1px solid rgba(255,255,255,.06)}.lg-actions .lg-next:hover,.lg-actions .lg-prev:hover{color:#fff;background:#ffffff26;border-color:#ffffff1f;transform:scale(1.05)}.lg-sub-html{position:absolute;left:0;right:0;bottom:0;background:linear-gradient(to top,rgba(18,14,12,.8) 0%,transparent 100%);color:#ffffffd9;font-family:var(--font-body);font-size:13px;letter-spacing:.02em;padding:48px 16px 12px;transition:bottom .35s cubic-bezier(.16,1,.3,1)}.wi-lg-caption{font-size:13px;color:#ffffffd9;margin-bottom:6px}.wi-lg-exif{display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px}.wi-lg-exif__camera,.wi-lg-exif__lens{font-size:11px;color:#ffffff8c;letter-spacing:.03em}.wi-lg-exif__params{display:flex;flex-wrap:wrap;gap:4px}.wi-lg-exif__aperture,.wi-lg-exif__shutter,.wi-lg-exif__iso,.wi-lg-exif__focal{display:inline-flex;align-items:center;font-size:10px;font-weight:500;color:#ffffffb3;background:#ffffff14;border-radius:4px;padding:2px 6px;letter-spacing:.04em;font-variant-numeric:tabular-nums;line-height:1.4}.lg-thumb-outer{background:#120e0cd9;backdrop-filter:blur(24px) saturate(1.2);-webkit-backdrop-filter:blur(24px) saturate(1.2);border-top:1px solid rgba(255,255,255,.06);padding:8px 0}.lg-thumb-item{border-color:transparent;border-radius:8px;overflow:hidden;border-width:2px;transition:all .25s cubic-bezier(.16,1,.3,1);opacity:.5;cursor:pointer}.lg-thumb-item.active{border-color:var(--accent)!important;opacity:1;transform:scale(1.05)}.lg-thumb-item:hover{border-color:#ffffff4d!important;opacity:.85}.lg-counter{color:#ffffff80;font-size:12px;font-family:var(--font-body);letter-spacing:.08em;font-variant-numeric:tabular-nums}.lg-progress-bar{height:2px;top:0}.lg-progress-bar .lg-progress{background:linear-gradient(90deg,var(--accent),var(--accent-hover));height:2px;border-radius:1px}.lg-outer .lg-thumb-outer{transform:translateY(100%);transition:transform .35s cubic-bezier(.16,1,.3,1);will-change:transform}.lg-outer.wi-thumb-shown .lg-thumb-outer{transform:translateY(0)}.lg-outer.wi-thumb-shown .lg-inner{bottom:100px!important;transition:bottom .35s cubic-bezier(.16,1,.3,1)}.lg-outer.wi-thumb-shown .lg-sub-html{bottom:100px;transition:bottom .35s cubic-bezier(.16,1,.3,1)}.lg-outer .lg-item{transition:opacity .3s ease,transform .3s ease}.lg-outer .lg-image{transition:opacity .25s ease}.lg-outer .lg-item.lg-complete .lg-image{opacity:1}.lg-outer .lg-item .lg-image{opacity:0}html.dark .lg-backdrop{background-color:#0a0806f7}html.dark .lg-toolbar{background:#ffffff0f}html.dark .lg-toolbar .lg-icon{color:#fff9}html.dark .lg-toolbar .lg-icon:hover{color:#fff;background:#ffffff1a}html.dark .lg-actions .lg-next,html.dark .lg-actions .lg-prev{background:#ffffff0f;color:#fff9;border-color:#ffffff0a}html.dark .lg-actions .lg-next:hover,html.dark .lg-actions .lg-prev:hover{color:#fff;background:#ffffff1f;border-color:#ffffff14}html.dark .lg-sub-html{background:linear-gradient(to top,rgba(10,8,6,.85) 0%,transparent 100%);color:#ffffffbf}html.dark .lg-thumb-outer{background:#0a0806e0;border-top-color:#ffffff0a}html.dark .lg-thumb-item{opacity:.4}html.dark .lg-thumb-item.active{border-color:var(--accent)!important;opacity:1}html.dark .lg-thumb-item:hover{border-color:#fff3!important;opacity:.75}html.dark .lg-counter{color:#fff6}html.dark .wi-lg-caption{color:#ffffffbf}html.dark .wi-lg-exif__camera,html.dark .wi-lg-exif__lens{color:#ffffff73}html.dark .wi-lg-exif__aperture,html.dark .wi-lg-exif__shutter,html.dark .wi-lg-exif__iso,html.dark .wi-lg-exif__focal{color:#fff9;background:#ffffff0f}@media(max-width:768px){.lg-toolbar{padding:2px 8px;height:40px}.lg-toolbar .lg-icon{width:32px;height:32px;font-size:15px;line-height:32px!important}.lg-toolbar .lg-icon:before{line-height:32px!important}.lg-inner{top:40px!important;bottom:0!important;transition:bottom .35s cubic-bezier(.16,1,.3,1)}.lg-actions .lg-next,.lg-actions .lg-prev{width:40px;height:40px;font-size:20px;border-radius:12px}.lg-sub-html{font-size:12px;padding:36px 12px 8px}.wi-lg-caption{font-size:12px;margin-bottom:4px}.wi-lg-exif{gap:4px 8px}.wi-lg-exif__camera,.wi-lg-exif__lens{font-size:10px}.wi-lg-exif__aperture,.wi-lg-exif__shutter,.wi-lg-exif__iso,.wi-lg-exif__focal{font-size:9px;padding:1px 5px}.lg-outer.wi-thumb-shown .lg-inner{bottom:80px!important}.lg-outer.wi-thumb-shown .lg-sub-html{bottom:80px}.lg-sub-html{padding:32px 12px 8px}.lg-outer .lg-thumb-outer{padding:6px 0}.lg-thumb-item{border-radius:6px}}@media(max-width:639px){.lg-toolbar .lg-icon{width:28px;height:28px;font-size:14px;line-height:28px!important}.lg-toolbar .lg-icon:before{line-height:28px!important}.lg-actions .lg-next,.lg-actions .lg-prev{width:44px;height:44px;font-size:20px;border-radius:12px}.lg-sub-html{font-size:11px;padding:28px 10px 6px}.wi-lg-exif{display:none}.lg-outer.wi-thumb-shown .lg-inner{bottom:64px!important}.lg-outer.wi-thumb-shown .lg-sub-html{bottom:64px}}:root{--xhhao-com-text-1: var(--ink);--xhhao-com-text-2: var(--ink-2);--xhhao-com-bg: var(--bg);--xhhao-com-bg-card: var(--bg-raised);--xhhao-com-bg-2: var(--bg-raised);--xhhao-com-border: var(--rule);--xhhao-com-primary: var(--accent);--xhhao-com-shadow: rgb(15 23 42 / .08)}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0;min-width:0}html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;text-size-adjust:100%;hanging-punctuation:first last}@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}body{margin:0;padding:0;font-family:var(--font-body);font-size:var(--text-base);line-height:var(--leading-normal);color:var(--ink);background-color:var(--bg);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;word-wrap:break-word;overflow-wrap:break-word;overflow-x:hidden;tab-size:4}::selection{background-color:var(--accent);color:var(--bg)}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--caramel);border-radius:9999px}::-webkit-scrollbar-thumb:hover{background:var(--accent)}a{color:var(--accent);text-decoration:none;transition:color var(--duration-fast) var(--ease-out-quart)}a:hover{color:var(--accent-hover)}a:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:8px}img,video,svg{max-width:100%;height:auto}.wi-main img,.wi-main video{display:block}img{border-radius:12px}p{margin-block-end:var(--space-md)}blockquote{margin-block:var(--space-lg);padding:var(--space-md) var(--space-lg);border-left:3px solid var(--accent);color:var(--ink-2);font-size:var(--text-md);line-height:var(--leading-relaxed);background:var(--bg-raised);border-radius:0 8px 8px 0}pre{padding:var(--space-lg);border-radius:12px;overflow-x:auto;background:var(--ink);color:#f8f8f2;font-family:var(--font-mono);font-size:var(--text-sm);line-height:var(--leading-relaxed);tab-size:2;scrollbar-width:none;-ms-overflow-style:none}pre::-webkit-scrollbar{display:none}code{font-family:var(--font-mono);font-size:.88em;padding:.15em .4em;background:var(--bg-raised);border:1px solid var(--rule);border-radius:8px}pre>code{all:unset;font-size:.9em;color:inherit}hr{margin-block:var(--space-2xl);border:none;border-top:1px solid var(--rule)}table{width:100%;border-collapse:collapse;font-size:var(--text-sm);overflow-x:auto;display:block}table th,table td{padding:var(--space-sm) var(--space-md);border:1px solid var(--rule);text-align:left}table th{background:var(--bg-raised);font-weight:600;color:var(--ink)}table td{color:var(--ink-2)}.wi-container{width:100%;max-width:1200px;margin-inline:auto;padding-inline:clamp(1rem,3vw,2rem)}.wi-section{padding-block:var(--section-spacing)}.wi-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.wi-main{padding-top:100px;padding-bottom:0;position:relative;z-index:1;background-color:var(--bg);width:100%;overflow-x:hidden;overflow-x:clip}.wi-main--wide.wi-main--home{padding-top:0;padding-bottom:0;padding-inline:0;background-color:transparent;max-width:100%;margin:0;overflow-x:hidden;overflow-x:clip;z-index:auto}.wi-content-wrap{max-width:800px;margin:0 auto;padding-inline:clamp(1rem,3vw,2rem);overflow-x:hidden;overflow-x:clip}.wi-content-wrap--wide{max-width:1200px}.wi-main--wide{max-width:1400px;width:100%;margin:0 auto}@media(max-width:768px){body{font-size:var(--text-base)}p{margin-block-end:1.2em}.wi-content-wrap{padding-inline:1.25rem}blockquote{padding:var(--space-sm) var(--space-md);font-size:var(--text-base)}pre{padding:var(--space-md);font-size:var(--text-sm)}}@media(max-width:480px){body{font-size:var(--text-base)}.wi-content-wrap{padding-inline:1rem}blockquote{padding:var(--space-sm) var(--space-sm);font-size:var(--text-base)}table{font-size:var(--text-sm)}th,td{padding:var(--space-sm) var(--space-sm)}}.theme-toggle[data-astro-cid-dz5h74bc]{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:34px;height:34px;padding:0;border:none;border-radius:8px;background:transparent;color:var(--ink-2);cursor:pointer;transition:background .15s ease,color .15s ease}.theme-toggle[data-astro-cid-dz5h74bc]:hover{background:var(--bg-raised);color:var(--ink)}.wi-navbar-wrapper[data-astro-cid-5blmo7yk]{position:fixed;top:0;left:0;right:0;z-index:100;display:flex;justify-content:center;padding:.75rem 1rem;pointer-events:none;transition:transform .35s cubic-bezier(.16,1,.3,1),padding var(--duration-normal) var(--ease-out-expo)}.wi-navbar--hidden[data-astro-cid-5blmo7yk]{transform:translateY(-100%)}.wi-navbar__capsule[data-astro-cid-5blmo7yk]{display:flex;align-items:center;gap:.5rem;width:100%;height:56px;padding:0 1.5rem;margin:0 auto;pointer-events:auto;transition:background var(--duration-normal) var(--ease-out-expo),box-shadow var(--duration-normal) var(--ease-out-expo),transform var(--duration-normal) var(--ease-out-expo)}.wi-navbar--glass[data-astro-cid-5blmo7yk] .wi-navbar__capsule[data-astro-cid-5blmo7yk]{border-radius:9999px;background:var(--glass-bg);backdrop-filter:blur(20px) saturate(180%);-webkit-backdrop-filter:blur(20px) saturate(180%);border:1px solid var(--glass-border);box-shadow:var(--shadow-md);max-width:900px}.wi-navbar--glass[data-astro-cid-5blmo7yk].wi-navbar--scrolled .wi-navbar__capsule[data-astro-cid-5blmo7yk]{background:var(--bg-overlay);box-shadow:var(--shadow-lg);transform:scale(.98)}.wi-navbar--minimal[data-astro-cid-5blmo7yk]{padding:0}.wi-navbar--minimal[data-astro-cid-5blmo7yk] .wi-navbar__capsule[data-astro-cid-5blmo7yk]{border-radius:0;background:transparent;backdrop-filter:none;-webkit-backdrop-filter:none;border:none;border-bottom:1px solid transparent;box-shadow:none;max-width:100%;padding:0 2rem;transition:background .3s ease,border-color .3s ease}.wi-navbar--minimal[data-astro-cid-5blmo7yk].wi-navbar--scrolled .wi-navbar__capsule[data-astro-cid-5blmo7yk]{background:var(--bg);border-bottom-color:var(--rule)}.wi-navbar--float[data-astro-cid-5blmo7yk] .wi-navbar__capsule[data-astro-cid-5blmo7yk]{border-radius:16px;background:var(--glass-bg);backdrop-filter:blur(24px) saturate(180%);-webkit-backdrop-filter:blur(24px) saturate(180%);border:1px solid var(--glass-border);box-shadow:var(--shadow-lg);max-width:800px;transition:transform .3s cubic-bezier(.16,1,.3,1),background .3s ease,box-shadow .3s ease}.wi-navbar--float[data-astro-cid-5blmo7yk].wi-navbar--scrolled .wi-navbar__capsule[data-astro-cid-5blmo7yk]{transform:scale(.96);box-shadow:var(--shadow-md)}.wi-navbar__brand[data-astro-cid-5blmo7yk]{display:flex;align-items:center;gap:.5rem;text-decoration:none;flex-shrink:0}.wi-navbar__logo[data-astro-cid-5blmo7yk]{height:32px;width:auto;border-radius:8px;object-fit:contain}.wi-navbar__logo--square[data-astro-cid-5blmo7yk]{border-radius:0}.wi-navbar__logo--rounded[data-astro-cid-5blmo7yk]{border-radius:8px}.wi-navbar__logo--circle[data-astro-cid-5blmo7yk]{border-radius:50%}.wi-navbar__title[data-astro-cid-5blmo7yk]{font-family:var(--font-sans);font-weight:700;font-size:var(--text-md);color:var(--ink);letter-spacing:var(--tracking-tight);white-space:nowrap;transition:color var(--duration-fast) var(--ease-out-quart)}.wi-navbar__brand[data-astro-cid-5blmo7yk]:hover .wi-navbar__title[data-astro-cid-5blmo7yk]{color:var(--accent)}.wi-navbar__nav[data-astro-cid-5blmo7yk]{display:flex;align-items:center;gap:.25rem;flex:1;justify-content:center;min-width:0}.wi-navbar__item[data-astro-cid-5blmo7yk]{position:relative;display:inline-flex}.wi-navbar__submenu[data-astro-cid-5blmo7yk]{position:absolute;top:100%;left:50%;transform:translate(-50%) translateY(6px);display:flex;flex-direction:column;min-width:168px;padding:6px;margin:0;list-style:none;border-radius:var(--radius-md, 12px);background:var(--bg-raised);border:1px solid var(--rule);box-shadow:var(--shadow-lg);opacity:0;visibility:hidden;transition:opacity .18s ease,transform .18s var(--ease-out-quart),visibility .18s;z-index:101}.wi-navbar__item--has-children[data-astro-cid-5blmo7yk]:after{content:"";position:absolute;left:0;right:0;top:100%;height:10px}.wi-navbar__item--has-children[data-astro-cid-5blmo7yk]:hover .wi-navbar__submenu[data-astro-cid-5blmo7yk],.wi-navbar__item--has-children[data-astro-cid-5blmo7yk]:focus-within .wi-navbar__submenu[data-astro-cid-5blmo7yk]{opacity:1;visibility:visible;transform:translate(-50%) translateY(0)}.wi-navbar__submenu-link[data-astro-cid-5blmo7yk]{display:block;padding:.5rem .75rem;border-radius:8px;font-size:var(--text-sm);color:var(--ink-2);text-decoration:none;white-space:nowrap;transition:color .15s ease,background .15s ease}.wi-navbar__submenu-link[data-astro-cid-5blmo7yk]:hover{color:var(--accent);background:color-mix(in srgb,var(--accent) 8%,transparent)}.wi-navbar__item--has-children[data-astro-cid-5blmo7yk]>.wi-navbar__link[data-astro-cid-5blmo7yk]:after{content:"";display:inline-block;width:4px;height:4px;margin-left:.3rem;margin-top:-2px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(45deg);opacity:.6;transition:transform .18s var(--ease-out-quart)}.wi-navbar__item--has-children[data-astro-cid-5blmo7yk]:hover>.wi-navbar__link[data-astro-cid-5blmo7yk]:after{transform:rotate(225deg);margin-top:2px}.wi-navbar__link[data-astro-cid-5blmo7yk]{display:inline-flex;align-items:center;padding:.3rem .7rem;border-radius:9999px;font-size:var(--text-sm);color:var(--ink-2);text-decoration:none;white-space:nowrap;transition:color var(--duration-fast) var(--ease-out-quart),background var(--duration-fast) var(--ease-out-quart)}.wi-navbar__link[data-astro-cid-5blmo7yk]:hover{color:var(--accent);background:var(--bg-raised)}.wi-navbar__link--active[data-astro-cid-5blmo7yk]{color:var(--ink);background:var(--bg-raised);font-weight:600}.wi-navbar__actions[data-astro-cid-5blmo7yk]{display:flex;align-items:center;gap:.25rem;flex-shrink:0;margin-left:auto}.wi-navbar__action-btn[data-astro-cid-5blmo7yk]{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;padding:0;border:none;border-radius:9999px;background:transparent;color:var(--ink-2);cursor:pointer;transition:background var(--duration-fast) var(--ease-out-quart),color var(--duration-fast) var(--ease-out-quart)}.wi-navbar__action-btn[data-astro-cid-5blmo7yk]:hover{background:var(--bg-raised);color:var(--ink)}.wi-navbar__action-btn[data-astro-cid-5blmo7yk]:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.wi-navbar__menu-btn[data-astro-cid-5blmo7yk]{display:none}@media(max-width:768px){.wi-navbar-wrapper[data-astro-cid-5blmo7yk]{padding:.5rem .75rem}.wi-navbar__capsule[data-astro-cid-5blmo7yk]{padding:0 1rem}.wi-navbar__nav[data-astro-cid-5blmo7yk]{display:none}.wi-navbar__action-btn[data-astro-cid-5blmo7yk]{width:40px;height:40px}.wi-navbar__menu-btn[data-astro-cid-5blmo7yk]{display:inline-flex}}footer[data-astro-cid-sz7xmlte]{position:relative;border-top:1px solid var(--rule);background-color:var(--bg)}footer[data-astro-cid-sz7xmlte]:before{content:"";position:absolute;inset:0;pointer-events:none;background-color:color-mix(in srgb,var(--bg) 97%,var(--accent) 3%);-webkit-mask-image:linear-gradient(to bottom,transparent,#000);mask-image:linear-gradient(to bottom,transparent,#000)}.footer-inner[data-astro-cid-sz7xmlte]{position:relative;max-width:1200px;width:100%;margin:0 auto;padding:1.25rem;display:flex;flex-direction:column;align-items:center;gap:.75rem}.footer-bottom[data-astro-cid-sz7xmlte]{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:1rem;font-size:.85rem;color:var(--ink-3);width:100%}.footer-bottom--center[data-astro-cid-sz7xmlte]{justify-content:center}.footer-bottom--center[data-astro-cid-sz7xmlte] .footer-bottom__left[data-astro-cid-sz7xmlte]{flex:none}.footer-bottom__left[data-astro-cid-sz7xmlte]{display:flex;align-items:center;gap:.75rem;flex-wrap:wrap}.footer-copyright[data-astro-cid-sz7xmlte]{color:var(--ink-3)}.footer-icp[data-astro-cid-sz7xmlte] a[data-astro-cid-sz7xmlte]{color:var(--ink-3);text-decoration:none;transition:color .15s ease}.footer-icp[data-astro-cid-sz7xmlte] a[data-astro-cid-sz7xmlte]:hover{color:var(--ink-2)}.footer-mps[data-astro-cid-sz7xmlte] a[data-astro-cid-sz7xmlte]{display:inline-flex;align-items:center;gap:.3rem;color:var(--ink-3);text-decoration:none;transition:color .15s ease}.footer-mps[data-astro-cid-sz7xmlte] a[data-astro-cid-sz7xmlte]:hover{color:var(--ink-2)}.footer-mps__icon[data-astro-cid-sz7xmlte]{flex:none;vertical-align:middle}.footer-stats[data-astro-cid-sz7xmlte]{display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:.5rem 1.25rem;width:100%;font-size:.8rem;color:var(--ink-3)}.footer-stat[data-astro-cid-sz7xmlte]{display:inline-flex;align-items:baseline;gap:.3rem}.footer-stat__value[data-astro-cid-sz7xmlte]{font-weight:600;color:var(--ink-2);font-variant-numeric:tabular-nums}.footer-stat__label[data-astro-cid-sz7xmlte]{opacity:.8}.footer-socials[data-astro-cid-sz7xmlte]{display:inline-flex;align-items:center;gap:.75rem}.footer-socials[data-astro-cid-sz7xmlte] a[data-astro-cid-sz7xmlte]{display:inline-flex;align-items:center;justify-content:center;color:var(--ink-3);text-decoration:none;font-size:1.05rem;transition:color .15s ease}.footer-socials[data-astro-cid-sz7xmlte] a[data-astro-cid-sz7xmlte]:hover{color:var(--ink-2)}.footer-bottom__right[data-astro-cid-sz7xmlte]{display:flex;align-items:center;gap:.5rem}.footer-bottom__right[data-astro-cid-sz7xmlte] a[data-astro-cid-sz7xmlte]{color:var(--ink-3);text-decoration:none;transition:color .15s ease}.footer-bottom__right[data-astro-cid-sz7xmlte] a[data-astro-cid-sz7xmlte]:hover{color:var(--ink-2)}.footer-separator[data-astro-cid-sz7xmlte]{color:var(--ink-3);opacity:.5}.footer-custom[data-astro-cid-sz7xmlte]{width:100%;text-align:center;font-size:.85rem;color:var(--ink-3);line-height:1.8}.footer-custom[data-astro-cid-sz7xmlte] a,.footer-custom[data-astro-cid-sz7xmlte] p,.footer-custom[data-astro-cid-sz7xmlte] span{display:inline;margin-inline:.25em}.footer-custom[data-astro-cid-sz7xmlte] a{color:var(--ink-3);text-decoration:none;transition:color .15s ease}.footer-custom[data-astro-cid-sz7xmlte] a:hover{color:var(--ink-2)}.footer-custom[data-astro-cid-sz7xmlte] img{display:inline-block;vertical-align:middle;border-radius:4px}.footer-custom[data-astro-cid-sz7xmlte] div{text-align:center}.footer-injected[data-astro-cid-sz7xmlte]{width:100%;text-align:center;font-size:.85rem;color:var(--ink-3);line-height:1.8}.footer-injected[data-astro-cid-sz7xmlte] a,.footer-injected[data-astro-cid-sz7xmlte] p,.footer-injected[data-astro-cid-sz7xmlte] span{display:inline;margin-inline:.25em}.footer-injected[data-astro-cid-sz7xmlte] a{color:var(--ink-3);text-decoration:none;transition:color .15s ease}.footer-injected[data-astro-cid-sz7xmlte] a:hover{color:var(--ink-2)}.footer-injected[data-astro-cid-sz7xmlte] img{display:inline-block;vertical-align:middle;border-radius:4px}.footer-injected[data-astro-cid-sz7xmlte] div{text-align:center}@media(max-width:768px){.footer-bottom[data-astro-cid-sz7xmlte]{flex-direction:column;align-items:center;text-align:center}.footer-bottom__left[data-astro-cid-sz7xmlte],.footer-bottom__right[data-astro-cid-sz7xmlte]{justify-content:center}.footer-custom[data-astro-cid-sz7xmlte],.footer-injected[data-astro-cid-sz7xmlte]{font-size:.75rem}}.wi-mobile-menu[data-astro-cid-6aabv5oc]{position:fixed;inset:0;z-index:200;pointer-events:none;visibility:hidden}.wi-mobile-menu--open[data-astro-cid-6aabv5oc]{pointer-events:auto;visibility:visible}.wi-mobile-menu__backdrop[data-astro-cid-6aabv5oc]{position:absolute;inset:0;background:#0006;opacity:0;transition:opacity var(--duration-normal) var(--ease-out-expo)}.wi-mobile-menu--open[data-astro-cid-6aabv5oc] .wi-mobile-menu__backdrop[data-astro-cid-6aabv5oc]{opacity:1}.wi-mobile-menu__panel[data-astro-cid-6aabv5oc]{position:absolute;top:0;right:0;bottom:0;width:min(85vw,360px);display:flex;flex-direction:column;background:var(--glass-bg);backdrop-filter:blur(24px) saturate(180%);-webkit-backdrop-filter:blur(24px) saturate(180%);border-left:1px solid var(--glass-border);box-shadow:var(--shadow-lg);transform:translate(100%);transition:transform var(--duration-normal) var(--ease-out-expo)}.wi-mobile-menu--open[data-astro-cid-6aabv5oc] .wi-mobile-menu__panel[data-astro-cid-6aabv5oc]{transform:translate(0)}.wi-mobile-menu__header[data-astro-cid-6aabv5oc]{display:flex;align-items:center;justify-content:flex-end;padding:1rem 1.25rem;border-bottom:1px solid var(--glass-border)}.wi-mobile-menu__close[data-astro-cid-6aabv5oc]{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;padding:0;border:none;border-radius:9999px;background:transparent;color:var(--ink-2);cursor:pointer;transition:background var(--duration-fast) var(--ease-out-quart),color var(--duration-fast) var(--ease-out-quart)}.wi-mobile-menu__close[data-astro-cid-6aabv5oc]:hover{background:var(--bg-raised);color:var(--ink)}.wi-mobile-menu__close[data-astro-cid-6aabv5oc]:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.wi-mobile-menu__nav[data-astro-cid-6aabv5oc]{flex:1;overflow-y:auto;padding:1rem 1.25rem;display:flex;flex-direction:column;gap:.25rem}.wi-mobile-menu__link[data-astro-cid-6aabv5oc]{display:flex;align-items:center;padding:.75rem 1rem;border-radius:12px;font-size:var(--text-lg);font-weight:500;color:var(--ink-2);text-decoration:none;transition:color var(--duration-fast) var(--ease-out-quart),background var(--duration-fast) var(--ease-out-quart)}.wi-mobile-menu__link--sub[data-astro-cid-6aabv5oc]{padding-left:2rem;font-size:var(--text-base);font-weight:400;color:var(--ink-3)}.wi-mobile-menu__link[data-astro-cid-6aabv5oc]:hover{color:var(--accent);background:var(--bg-raised)}.wi-mobile-menu__link--active[data-astro-cid-6aabv5oc]{color:var(--accent);background:var(--bg-raised);font-weight:600}.wi-mobile-menu__footer[data-astro-cid-6aabv5oc]{display:flex;flex-direction:column;gap:.5rem;padding:1rem 1.25rem;border-top:1px solid var(--glass-border)}.wi-mobile-menu__action-btn[data-astro-cid-6aabv5oc]{display:flex;align-items:center;gap:.75rem;width:100%;padding:.75rem 1rem;border:none;border-radius:12px;background:transparent;color:var(--ink-2);font-size:var(--text-md);font-family:var(--font-sans);cursor:pointer;transition:color var(--duration-fast) var(--ease-out-quart),background var(--duration-fast) var(--ease-out-quart)}.wi-mobile-menu__action-btn[data-astro-cid-6aabv5oc]:hover{color:var(--ink);background:var(--bg-raised)}.wi-mobile-menu__action-btn[data-astro-cid-6aabv5oc]:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.wi-mobile-menu__icon-sun[data-astro-cid-6aabv5oc],.dark .wi-mobile-menu__icon-moon[data-astro-cid-6aabv5oc]{display:none}.dark .wi-mobile-menu__icon-sun[data-astro-cid-6aabv5oc]{display:block}.wi-click-fx-layer{position:fixed;inset:0;z-index:12050;pointer-events:none;overflow:hidden}.wi-click-fx{position:fixed;pointer-events:none;will-change:transform,opacity;user-select:none}.wi-click-fx--text{font-size:18px;font-weight:700;transform:translate(-50%,-50%);animation:wi-fx-text 1.2s ease-out forwards;text-shadow:0 1px 2px rgba(0,0,0,.18)}.wi-click-fx--heart{font-size:20px;opacity:1;transition:transform 1s cubic-bezier(.16,1,.3,1),opacity 1s ease-out}.wi-click-fx--spark{width:6px;height:6px;border-radius:50%;opacity:1;transition:transform .8s cubic-bezier(.16,1,.3,1),opacity .8s ease-out}.wi-click-fx--ripple{width:30px;height:30px;border:2px solid;border-radius:50%;transform:translate(-50%,-50%) scale(.5);opacity:.9;transition:transform .7s ease-out,opacity .7s ease-out}.wi-click-fx--particle{width:8px;height:8px;border-radius:50%;opacity:1;transition:transform .7s cubic-bezier(.16,1,.3,1),opacity .7s ease-out}.wi-click-fx--star{font-size:16px;opacity:1;transition:transform .8s cubic-bezier(.16,1,.3,1),opacity .8s ease-out}.wi-click-fx--trail-star{font-size:12px;transform:translate(-50%,-50%);opacity:.9;transition:opacity .6s ease-out,transform .6s ease-out}.wi-click-fx--trail-particle{width:6px;height:6px;border-radius:50%;transform:translate(-50%,-50%);opacity:.9;transition:opacity .5s ease-out,transform .5s ease-out}@keyframes wi-fx-text{0%{opacity:0;transform:translate(-50%,-50%) scale(.5)}20%{opacity:1;transform:translate(-50%,-80%) scale(1.1)}to{opacity:0;transform:translate(-50%,-120%) scale(.9)}}html{min-height:100vh}html.wi-theme-transition,html.wi-theme-transition *,html.wi-theme-transition *:before,html.wi-theme-transition *:after{transition:background-color .3s ease,color .3s ease,border-color .3s ease,box-shadow .3s ease,fill .3s ease,stroke .3s ease!important}.wi-body{min-height:100vh;display:flex;flex-direction:column}.wi-main{flex:1}.wi-reveal{opacity:0;transform:translateY(20px);transition:opacity var(--duration-normal, .3s) var(--ease-out-expo, cubic-bezier(.16, 1, .3, 1)),transform var(--duration-normal, .3s) var(--ease-out-expo, cubic-bezier(.16, 1, .3, 1))}.wi-revealed{opacity:1;transform:translateY(0)}html.wi-no-animations .wi-reveal{opacity:1;transform:none;transition:none}
diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts
index 60ce41d..09ae63f 100644
--- a/docs/.vitepress/config.mts
+++ b/docs/.vitepress/config.mts
@@ -35,7 +35,9 @@ export default defineConfig({
{ text: '瞬间', link: '/config/moments' },
{ text: '图库', link: '/config/photos' },
{ text: '友情链接', link: '/config/links' },
- { text: '朋友圈', link: '/config/friends' },
+ { text: '订阅', link: '/config/subscriptions' },
+ { text: '欢迎弹窗', link: '/config/welcome-popup' },
+ { text: '微信读书', link: '/config/weread' },
{ text: '记得', link: '/config/important-dates' },
{ text: '留言板', link: '/config/messageboard' },
{ text: '评论', link: '/config/comment' },
@@ -53,7 +55,7 @@ export default defineConfig({
{ text: '瞬间', link: '/pages/moments' },
{ text: '图库', link: '/pages/photos' },
{ text: '友情链接', link: '/pages/links' },
- { text: '朋友圈', link: '/pages/friends' },
+ { text: '订阅', link: '/pages/subscriptions' },
{ text: '记得', link: '/pages/important-dates' },
{ text: '自定义页面', link: '/pages/custom-page' },
{ text: '扩展页面', link: '/pages/extended' },
diff --git a/docs/changelog.md b/docs/changelog.md
index 2e4248e..14117b2 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -1,5 +1,40 @@
# 更新日志
+## v1.2.7
+
+### 文档全面校准(与最新版主题对齐)
+
+- 🔌 **移除「朋友圈」插件的全部使用说明**:`plugin-friends` 已不再提供,原先的 feed / RSS 聚合能力
+ 由官方 **「链接管理」(PluginLinks)插件的订阅**承担。主题的对应实现是 `page_subscriptions.html`
+ 自定义模板与 `subscriptions` 设置分组;新增订阅配置 / 订阅页面文档,删除旧的朋友圈配置与页面文档
+- 📌 主题保留 `friends.html` 模板与「朋友圈」设置分组**仅用于兼容旧站点**,`pluginFinder` 检测不到
+ 该插件时会显示空状态;新站点请勿再依赖,文档已明确标注
+- ⬆️ 全文统一 Halo 版本要求为 **2.27.0+**(`docs/guide/getting-started.md` 原写 `2.24.0`,与
+ `theme.yaml` 的 `requires: ">=2.27.0"` 不一致)
+- 🧹 清理与代码不符的描述:已移除的光感跟随 `animation_cursor_glow`、主题并不自带的
+ i18n 国际化、没有对应模板的「足迹页面」;`docs/config/style.md` 补上实际存在的
+ `click_effect_enabled` / `click_effect_type`
+- 📚 补齐此前完全没有文档的三个设置分组:**欢迎弹窗、订阅、微信读书**;自定义页面模板清单
+ 同步为 4 个(默认 / 留言板 / 订阅 / 微信读书)
+- 🔢 配置数量统一为 **17 组 / 126 项**,插件适配表按实际 **10 款**校准,VitePress 侧边栏同步调整
+- 🔗 所有文档内部相对链接复核为 0 处失效
+
+### 可选 API 设置项文案精简
+
+- ✂️ 主题设置中「自定义 IP 定位主 API」「自定义 IP 定位备选 API」「自定义一言 API」
+ 三个配置项的 `help` 移除三段冗长的隐私披露文案,仅保留功能说明(候选接口地址、留空回退规则)
+- 🛡️ 第三方数据流向与隐私披露仍由 README「外部资源与隐私」章节、配置文档与 FAQ 完整承载,
+ 满足 5.1 要求;设置界面文案精简不影响「默认零第三方请求」的结论
+- ↩️ 三个字段恢复按功能开关条件显示(「启用欢迎弹窗」开关 / 「描述文案来源」),与 v1.2.6
+ 的设计一致;同时修正三个配置块的缩进,与 `settings.yaml` 其余字段对齐
+- 🔒 `pnpm audit:external` 的 5.1 检查改为:三个字段必须存在、`help` 不得回潮出现披露文案、
+ README 必须保留隐私披露章节
+
+### 正文引用块留白(与上一轮改动合并)
+
+- 🎨 修复文章 / 单页 / 留言板正文引用块文字下方空白过大:块内元素外边距与 `padding` 叠加导致
+ 双层留白,现统一收敛,并折叠编辑器生成的空段落;引用块上下外边距同步收紧
+
## v1.2.6
> v1.2.5 为审核被拒的未发布版本,从未对外分发;其全部整改内容纳入 v1.2.6 一并发布。
diff --git a/docs/config/article.md b/docs/config/article.md
index 7adbcee..54a5bd3 100644
--- a/docs/config/article.md
+++ b/docs/config/article.md
@@ -22,6 +22,8 @@
| `article_related_title` | 文本 | `相关推荐` | 相关文章标题 |
| `article_show_share` | 开关 | `true` | 显示分享按钮 |
| `article_share_title` | 文本 | `分享` | 分享区域标题 |
+| `article_extra_spacing` | 开关 | `true` | 中英文混排自动加空格;依赖「API 扩展包」,插件未安装时自动跳过 |
+| `article_extra_highlight` | 开关 | `false` | 服务端代码高亮;依赖「API 扩展包」全量版(含 JS 运行时),开启后替代主题自带配色,环境不支持请勿开启 |
## 详细说明
diff --git a/docs/config/basic.md b/docs/config/basic.md
index d1ee152..3995cfb 100644
--- a/docs/config/basic.md
+++ b/docs/config/basic.md
@@ -13,7 +13,6 @@
| `label_search` | 文本 | `搜索` | 搜索按钮的标签文案 |
| `label_theme_switch` | 文本 | `切换主题` | 主题切换按钮的标签文案 |
| `label_archives_title` | 文本 | `归档` | 归档页面的标题文案 |
-| `language` | 下拉 | `auto` | 主题界面语言 |
## 详细说明
@@ -70,22 +69,8 @@ label_archives_title: "Archives"
```
::: tip
-标签文案的修改会即时生效,无需重启 Halo。如果使用多语言场景,可以配合 Halo 的多语言插件实现更完整的国际化。
-:::
-
-### 语言(language)
-
-设置主题界面的显示语言,影响导航栏、文章页、错误页等所有主题内置文案。提供以下选项:
-
-| 值 | 说明 |
-| --- | --- |
-| `auto` | 跟随浏览器语言自动匹配(默认) |
-| `zh_CN` | 简体中文 |
-| `zh_TW` | 繁體中文 |
-| `en` | English |
-
-::: tip
-选择 `auto` 时,主题会根据访客浏览器的语言设置自动匹配最接近的语言。如果浏览器语言不在支持列表中,将回退到简体中文。
+标签文案的修改会即时生效,无需重启 Halo。主题**不内置界面语言切换 / 多语言包**,
+需要多语言站点时请使用 Halo 或相应插件提供的能力;主题内置的少量界面文案可通过上方 3 个标签项自定义。
:::
## 相关页面
diff --git a/docs/config/footer.md b/docs/config/footer.md
index f5d52a1..4b98b44 100644
--- a/docs/config/footer.md
+++ b/docs/config/footer.md
@@ -12,6 +12,12 @@
| `footer_show_powered` | 开关 | `true` | 显示「Powered by Halo」 |
| `footer_show_theme` | 开关 | `true` | 显示主题版本 |
| `footer_custom_html` | 代码 | — | 自定义 HTML(统计代码等) |
+| `footer_show_stats` | 开关 | `true` | 在页脚显示全站统计 |
+| `footer_stats_items` | 多选 | `post,category,comment,visit` | 统计项:`post` 文章 / `category` 分类 / `comment` 评论 / `visit` 访问 / `upvote` 点赞 / `word` 总字数(总字数依赖「API 扩展包」,未安装时自动隐藏) |
+| `footer_show_icp` | 开关 | `false` | 显示 ICP 备案号(开启后 `footer_icp` 才会显示) |
+| `footer_show_mps` | 开关 | `false` | 显示公网安备号与徽标 |
+| `footer_mps` | 文本 | — | 公网安备号(需开启上方开关) |
+| `footer_mps_url` | 文本 | — | 公网安备跳转链接,留空默认 `https://beian.mps.gov.cn/` |
## 详细说明
diff --git a/docs/config/friends.md b/docs/config/friends.md
deleted file mode 100644
index 091bfd4..0000000
--- a/docs/config/friends.md
+++ /dev/null
@@ -1,62 +0,0 @@
-# 朋友圈
-
-朋友圈模块用于聚合展示你订阅的站点最新动态,类似于 RSS 阅读器的社交化呈现。访客可以在你的站点上浏览友站最新文章,发现更多优质内容。
-
-## 配置项一览
-
-| 配置项 | 类型 | 默认值 | 说明 |
-| --- | --- | --- | --- |
-| `friends_page_title` | 文本 | `朋友圈` | 页面标题 |
-
-## 前置依赖
-
-::: danger
-朋友圈功能依赖 Halo 的 **plugin-friends** 插件。如果未安装此插件,朋友圈页面将无法正常工作。
-
-安装方式:Halo 后台 → **插件** → **安装** → 搜索「朋友圈」或从 [GitHub Releases](https://www.halo.run/store/apps/app-yISsV) 下载安装。
-:::
-
-## 详细说明
-
-### 页面标题(friends_page_title)
-
-朋友圈页面的标题,显示在页面顶部。
-
-```yaml
-friends_page_title: "朋友圈" # 默认
-friends_page_title: "友圈" # 简称
-friends_page_title: "Friends" # 英文站点
-```
-
-## RSS 订阅说明
-
-朋友圈的核心机制是通过 RSS 订阅聚合友站内容:
-
-1. 在 Halo 后台的 Friends 插件设置中添加友站的 RSS 订阅地址
-2. 插件会定期抓取这些 RSS 源的最新文章
-3. 朋友圈页面按时间倒序展示所有订阅源的最新文章
-
-### 添加订阅源
-
-1. 登录 Halo 后台管理控制台
-2. 进入 **链接** 管理页面
-3. 点击 **新建** 或 **编辑** 填写:元数据 **RSS 地址** 友站的 RSS 订阅地址
-4. 保存后,插件会在下次抓取周期自动拉取内容,亦可进入 **朋友圈** 自行同步
-
-::: tip
-大多数博客平台都提供 RSS 订阅功能。常见的 RSS 地址格式:
-- WordPress:`/feed/`
-- Halo:`/rss.xml` 或 `/feed/`
-- Hexo:`/atom.xml` 或 `/rss2.xml`
-- Typecho:`/feed/`
-:::
-
-::: warning
-RSS 抓取频率取决于插件配置,通常为每 30 分钟到数小时一次。新添加的订阅源可能需要等待一个抓取周期才能在页面显示内容。
-:::
-
-## 相关页面
-
-- [友情链接](/config/links) — 友情链接页面配置
-- [页脚](/config/footer) — 页脚社交链接配置
-- [朋友圈页面](/pages/friends) — 朋友圈模板与结构说明
diff --git a/docs/config/hero.md b/docs/config/hero.md
index d7f92ef..5d29ac2 100644
--- a/docs/config/hero.md
+++ b/docs/config/hero.md
@@ -10,7 +10,7 @@ Hero 首屏是 WarmIsland 主题的标志性区域,占据首页首屏的全部
| `hero_title` | 文本 | — | 主标题(留空则使用站点标题) |
| `hero_subtitle` | 文本 | — | 副标题(留空则使用站点副标题) |
| `hero_description_mode` | 下拉 | `none` | 描述文案来源:`none` / `hitokoto` / `custom`,默认不显示描述文案 |
-| `hero_hitokoto_api` | URL | `https://v1.hitokoto.cn/` | 选「一言」时自动填入官方接口;留空则使用内置本地句子库(零外部请求) |
+| `hero_hitokoto_api` | URL | `https://v1.hitokoto.cn/` | 默认预填官方接口(描述来源非「无」时显示,仅「一言」模式生效);清空则使用内置本地句子库(零外部请求) |
| `hero_hitokoto_categories` | 多选 | `d, i, k` | 句子类型筛选,仅对自定义 API 生效 |
| `hero_custom_description` | 多行文本 | — | 自定义描述文案 |
| `hero_hitokoto_auto_refresh` | 开关 | `false` | 一言自动刷新 |
@@ -49,23 +49,30 @@ hero_subtitle: "记录温暖与灵感"
| 值 | 说明 |
| --- | --- |
| `none` | **默认**。不显示描述文案,不渲染一言元素,也不发起任何请求 |
-| `hitokoto` | 显示一句话文案;自动填入官方接口 `https://v1.hitokoto.cn/`,清空该字段则使用内置本地句子库 |
+| `hitokoto` | 显示一句话文案;API 字段默认预填官方接口 `https://v1.hitokoto.cn/`,清空该字段则使用内置本地句子库 |
| `custom` | 显示自定义的描述文案(静态文本,不发起任何请求) |
### 一言模式(hitokoto)
-默认 `none` 时一言元素不渲染。切换到 `hitokoto` 后,设置项「自定义一言 API」自动填入
-`https://v1.hitokoto.cn/`,浏览器会向该地址发起 GET 请求获取句子(第三方可见访客 IP / User-Agent)。
+默认 `none` 时一言元素不渲染。「自定义一言 API」设置项在描述来源非「无」时显示,并默认预填
+`https://v1.hitokoto.cn/`;切换到 `hitokoto` 后该值生效,浏览器会向该地址发起 GET 请求
+获取句子(第三方可见访客 IP / User-Agent)。
若把该字段清空,则回退到主题内置的本地句子库 `assets/data/hitokoto.json`
(随主题自托管的静态 JSON,零外部请求),每次刷新随机展示一条,也不会因为第三方接口不可用而出现空白。
可直接编辑该 JSON 替换成自己喜欢的句子。
#### 自定义一言 API(hero_hitokoto_api)
-选择「一言」或「自定义」后才会显示该设置项。选择「一言」时自动填入 `https://v1.hitokoto.cn/`;
-**选择「一言」或「自定义」后若留空,则使用主题内置的本地句子库(零外部请求)**。
-**只有填写后才会向该地址发起请求**,需自行在站点隐私说明中披露,详见 README「外部资源与隐私」。
-也可换成自建实例或其他兼容接口。
+该设置项在「描述文案来源」非「无」时显示,`help` 只说明候选地址与留空回退规则;
+字段默认预填 `https://v1.hitokoto.cn/`,**仅在「一言」模式下生效**。
+**选择「一言」或「自定义」后若把该字段留空,则使用主题内置的本地句子库(零外部请求)**。
+只有填写后才会向该地址发起请求,第三方可见访客 IP / User-Agent;完整的数据流向与隐私披露
+见 README「外部资源与隐私」章节。也可换成自建实例或其他兼容接口。
+
+::: tip
+「描述文案来源」默认「无」时一言元素不渲染,因此即使字段预填了官方地址,
+也不会产生任何外部请求。隐私披露统一在 README 与本文档说明,设置界面不重复展示。
+:::
::: warning
这是站点管理员主动开启的可选能力。把描述文案来源改回「无」、或清空该字段即可随时停止外部请求,无需重装主题。
diff --git a/docs/config/links.md b/docs/config/links.md
index b563290..5b49662 100644
--- a/docs/config/links.md
+++ b/docs/config/links.md
@@ -6,8 +6,12 @@
| 配置项 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
+| `links_apply_form_enabled` | 开关 | `true` | 页底显示友链申请表单;需插件开启「友链申请」,否则自动隐藏 |
| `links_page_title` | 文本 | `友情链接` | 页面标题 |
| `links_style` | 下拉 | `cards` | 展示样式:`grid` / `list` / `cards` |
+| `links_show_comment` | 开关 | `false` | 页面底部显示评论区 |
+| `links_random_order` | 开关 | `false` | 友链卡片随机排列 |
+| `links_random_portal` | 开关 | `true` | 页面右上角显示「随机传送」按钮 |
## 前置依赖
@@ -15,6 +19,9 @@
友情链接功能依赖 Halo 的 **PluginLinks** 插件。如果未安装此插件,友情链接页面将无法正常工作。
安装方式:Halo 后台 → **插件** → **安装** → 搜索「链接管理」→ 安装并启用。
+
+同一个插件还提供 **RSS 订阅能力**(原「朋友圈」插件的 feed 聚合功能已由它取代),
+对应主题的[订阅配置](/config/subscriptions)与[订阅页面](/pages/subscriptions)。
:::
## 详细说明
@@ -65,6 +72,7 @@ PluginLinks 支持链接分组功能。你可以将友链按不同类别分组
## 相关页面
-- [朋友圈](/config/friends) — 朋友圈页面配置
+- [订阅配置](/config/subscriptions) — 同一插件提供的 RSS 订阅动态
+- [订阅页面](/pages/subscriptions) — 博友文章动态页面
- [页脚](/config/footer) — 页脚社交链接配置
- [友情链接页面](/pages/links) — 友链模板与结构说明
diff --git a/docs/config/moments.md b/docs/config/moments.md
index 3ff61b1..bca197f 100644
--- a/docs/config/moments.md
+++ b/docs/config/moments.md
@@ -10,6 +10,7 @@
| `moments_style` | 下拉 | `cards` | 展示样式:`cards` / `masonry` |
| `moments_loading_mode` | 下拉 | `infinite_scroll` | 加载方式:`infinite_scroll` / `pagination` |
| `moments_page_size` | 数字 | `10` | 每页显示数量 |
+| `moments_cover` | 附件 | — | 瞬间页顶部封面图,建议尺寸 1500×500 |
## 前置依赖
diff --git a/docs/config/navbar.md b/docs/config/navbar.md
index 74e41ec..c858a65 100644
--- a/docs/config/navbar.md
+++ b/docs/config/navbar.md
@@ -9,6 +9,9 @@
| `navbar_style` | 下拉 | `glass` | 导航栏样式:`glass` / `minimal` / `float` |
| `navbar_show_search` | 开关 | `true` | 显示搜索按钮 |
| `navbar_show_theme_switch` | 开关 | `true` | 显示主题切换按钮 |
+| `navbar_brand_type` | 下拉 | `title` | 左侧显示:`title` 站点名称 / `logo` Logo |
+| `navbar_logo` | 附件 | — | 导航栏 Logo;仅在「Logo」模式下显示,留空回退到基础设置的自定义 Logo |
+| `navbar_logo_radius` | 下拉 | `rounded` | Logo 圆角:`square` / `rounded` / `circle`(Logo 模式下生效) |
## 详细说明
diff --git a/docs/config/style.md b/docs/config/style.md
index c1e52ea..ccbbfb3 100644
--- a/docs/config/style.md
+++ b/docs/config/style.md
@@ -14,7 +14,8 @@
| `animation_enabled` | 开关 | `true` | 全局动画总开关 |
| `animation_breath` | 开关 | `true` | 呼吸动画效果 |
| `animation_scroll_reveal` | 开关 | `true` | 滚动渐入动画 |
-| `animation_cursor_glow` | 开关 | `false` | 光感跟随效果 |
+| `click_effect_enabled` | 开关 | `false` | 鼠标点击效果总开关 |
+| `click_effect_type` | 下拉 | `values` | 点击效果类型(8 种效果 + 关闭,仅在总开关开启时显示) |
| `custom_css` | 代码 | — | 自定义 CSS 代码 |
## 详细说明
@@ -121,13 +122,11 @@ WarmIsland 提供了丰富的动画效果,所有动画都可以独立开关:
滚动渐入动画基于 Intersection Observer API 实现,对性能影响极小。如果页面内容较多,建议保持开启以提升浏览体验。
:::
-#### 光感跟随(animation_cursor_glow)
+#### 鼠标点击效果(click_effect_enabled / click_effect_type)
-启用后,鼠标移动时会在光标附近产生柔和的光晕跟随效果,为页面增添灵动感。
-
-::: warning
-光感跟随效果在移动端不会生效(因为移动端没有鼠标光标)。在低端设备上可能会影响渲染性能,如遇卡顿建议关闭。
-:::
+`click_effect_enabled` 默认关闭;开启后 `click_effect_type` 才会显示,可选 8 种效果:
+社会主义核心价值观、随机彩色爱心、烟花、烟花波纹、粒子、星星、星星拖尾、粒子拖尾,
+另可选「关闭」。特效在访客点击时由浏览器本地绘制,不加载远程脚本、不发送任何数据。
### 自定义 CSS(custom_css)
diff --git a/docs/config/subscriptions.md b/docs/config/subscriptions.md
new file mode 100644
index 0000000..fc2c3f7
--- /dev/null
+++ b/docs/config/subscriptions.md
@@ -0,0 +1,59 @@
+# 订阅
+
+订阅模块用于展示博友们的最新文章动态(feed / RSS 聚合)。这项能力由 **Halo 官方「链接管理」(PluginLinks)插件的订阅**提供,主题只负责把插件抓取到的订阅动态渲染成页面。
+
+> `plugin-friends`(朋友圈)插件已不再提供,原来的 feed 聚合功能由链接管理插件的订阅取代。
+> 主题中的 `friends.html` 模板与「朋友圈」设置分组仅用于兼容旧站点,新站点请使用订阅页面模板,
+> 详见[历史兼容说明](#历史兼容说明)。
+
+## 配置项一览
+
+| 配置项 | 类型 | 默认值 | 说明 |
+| --- | --- | --- | --- |
+| `subscriptions_page_title` | 文本 | `订阅` | 页面标题 |
+| `subscriptions_subtitle` | 文本 | `博友们的最新文章` | 页面副标题 |
+| `subscriptions_page_size` | 数字 | `20` | 每页展示的动态条数,范围 1–100 |
+| `subscriptions_loading_mode` | 下拉 | `pagination` | `pagination` 分页 / `infinite_scroll` 下滑加载 |
+| `subscriptions_layout` | 下拉 | `list` | `list` 列表卡片 / `grid` 网格卡片 |
+
+## 前置依赖
+
+::: danger
+订阅页面依赖 Halo 官方 **「链接管理」(PluginLinks)** 插件的 RSS 订阅能力,
+可在[应用市场](https://www.halo.run/store/apps/app-hfbQg)安装。未安装或未启用订阅时,
+页面会显示空状态提示,不会报错。
+:::
+
+订阅源由链接管理插件维护(为博友链接配置 RSS 订阅地址、按插件自身的周期抓取),
+主题通过 Halo 的 `linkFeedFinder` 读取已抓取的动态列表,不自行抓取、不缓存、不向第三方发起请求。
+订阅源的添加入口与抓取频率以所安装插件版本的说明为准。
+
+## 详细说明
+
+### 加载方式(subscriptions_loading_mode)
+
+- `pagination`:页面底部显示「较新 / 较旧」翻页链接,按时间游标分页。
+- `infinite_scroll`:滚动到列表底部时自动加载下一页,并显示加载状态与「没有更多了」提示。
+
+### 布局样式(subscriptions_layout)
+
+- `list`:单列宽卡片,默认布局,适合长摘要阅读。
+- `grid`:一行三列(窄屏自动降为两列 / 一列),卡片内容垂直排列。
+
+两种方式下每条动态都展示作者头像 / 名称、发布日期、文章标题与摘要,标题与作者链接均带
+`rel="noopener noreferrer"`;作者名为空时会显示占位字符,不会因字符串截取报错。
+
+## 历史兼容说明
+
+主题仍保留 `templates/friends.html` 与设置中的「朋友圈」分组(`friends_page_title`),
+它们只读取旧 `plugin-friends` 插件的数据。该插件已不再提供,因此:
+
+- 新站点**不要**再创建 `/friends` 页面或依赖这个分组;
+- 旧站点若已停用该插件,`friends.html` 会显示空状态而不会报错;
+- 需要 feed 聚合时,请改用 `page_subscriptions.html` 订阅模板。
+
+## 相关页面
+
+- [订阅页面](/pages/subscriptions) — 页面结构、模板选择与迁移说明
+- [友情链接配置](/config/links) — 同一插件的友链展示配置
+- [自定义页面](/pages/custom-page) — 全部自定义页面模板
diff --git a/docs/config/welcome-popup.md b/docs/config/welcome-popup.md
new file mode 100644
index 0000000..89dbdc2
--- /dev/null
+++ b/docs/config/welcome-popup.md
@@ -0,0 +1,44 @@
+# 欢迎弹窗
+
+欢迎弹窗在首页以浮层形式向访客打招呼。**默认关闭**,开启后也只显示主题内置的本地静态欢迎语,
+不会自动向任何第三方发起请求。
+
+## 配置项一览
+
+| 配置项 | 类型 | 默认值 | 说明 |
+| --- | --- | --- | --- |
+| `welcome_popup_enabled` | 开关 | `false` | 启用欢迎弹窗 |
+| `welcome_popup_position` | 下拉 | `top-center` | 弹窗位置,共 5 种 |
+| `welcome_popup_duration` | 数字 | `5` | 自动消失时间(秒),范围 3–60 |
+| `welcome_popup_show_once` | 开关 | `true` | 同一浏览器会话内仅显示一次 |
+| `welcome_popup_api` | URL | 留空 | 自定义 IP 定位主 API(可选) |
+| `welcome_popup_fallback_api` | URL | 留空 | 自定义 IP 定位备选 API(可选) |
+
+## 弹窗位置
+
+| 值 | 位置 |
+| --- | --- |
+| `top-center` | 顶端居中(默认) |
+| `top-left` / `top-right` | 左上 / 右上 |
+| `bottom-left` / `bottom-right` | 左下 / 右下 |
+
+`welcome_popup_show_once` 使用浏览器 `sessionStorage` 记录同会话已显示状态;
+关闭该开关后每次访问首页都会弹出。清除浏览器站点数据即可重置。
+
+## 可选的 IP 定位能力(默认关闭)
+
+两个 API 字段仅在「启用欢迎弹窗」开关打开时显示,`help` 只说明候选地址与留空规则;
+第三方数据流向与隐私披露由本文档下方条目及 README「外部资源与隐私」章节承载。
+字段**默认留空**,此时弹窗只显示本地欢迎语,不发起任何外部请求。
+只有管理员显式填写后,浏览器才会向该地址请求并把**访客 IP**暴露给第三方服务以换取粗略地理位置:
+
+- 候选主 / 备选接口:`https://myip.ipip.net/json`、`https://r.inews.qq.com/api/ip2city?otype=json`
+- 数据流向与隐私披露要求见 README「外部资源与隐私」章节
+- 清空字段或关闭弹窗即可立即停止,无需重装主题
+
+> 主题不预置、不代理这些接口,也不保存访客位置数据;填写前请自行评估服务商的隐私政策。
+
+## 相关页面
+
+- [基础设置](/config/basic) — 站点名称、Logo 等
+- [首页](/pages/home) — 首页模块说明
diff --git a/docs/config/weread.md b/docs/config/weread.md
new file mode 100644
index 0000000..02c3e88
--- /dev/null
+++ b/docs/config/weread.md
@@ -0,0 +1,30 @@
+# 微信读书
+
+微信读书模块用于展示书架与阅读记录,主题提供 `weread.html` 自定义页面模板,
+数据由[微信读书插件](https://github.com/yeora26/halo-weread-plugin)提供,访客无需登录即可查看。
+
+::: info
+该页面依赖 Halo **2.27+** 的能力;主题声明的兼容范围为 `>=2.27.0`。
+:::
+
+## 配置项一览
+
+| 配置项 | 类型 | 默认值 | 说明 |
+| --- | --- | --- | --- |
+| `weread_page_title` | 文本 | — | 页面标题(顶部标题与浏览器标签页标题);插件自带的标题区会自动隐藏以避免重复 |
+| `weread_page_subtitle` | 文本 | — | 页面副标题 |
+
+留空时由模板回退到默认文案,不会导致页面报错。
+
+## 使用方式
+
+1. 安装并启用微信读书插件
+2. Halo 后台 → **页面** → **新建** → 自定义模板选择「**微信读书**」(`WeRead`)
+3. 发布页面并加入导航菜单
+
+页面地址由创建页面时设定的 slug 决定,主题不提供固定路由。
+
+## 相关页面
+
+- [自定义页面](/pages/custom-page) — 全部自定义页面模板
+- [扩展页面](/pages/extended) — 插件前台页面一览
diff --git a/docs/customize/development.md b/docs/customize/development.md
index e31812d..b76ccb9 100644
--- a/docs/customize/development.md
+++ b/docs/customize/development.md
@@ -125,7 +125,7 @@ WarmIsland/
│ │ # LightGallery / ClickEffect / ScrollReveal / ThemeSwitcher 等
│ ├── layouts/ # Layout.astro(含页面布局契约渲染模式)
│ ├── pages/ # index / post / page / archives / categories / category /
-│ │ # tags / tag / links / friends / moments / moment / photos /
+│ │ # tags / tag / links / friends(历史兼容)/ moments / moment / photos /
│ │ # douban / equipments / important-dates / steam / weread /
│ │ # page_messageboard / page_subscriptions / layout
│ └── styles/ # main.scss + 12 个 _*.scss 片段
@@ -154,7 +154,7 @@ WarmIsland/
| 技术 | 版本 | 用途 |
|------|------|------|
-| [Halo](https://www.halo.run/) | 2.27+ | 博客运行时,提供 Finder API 与主题渲染 |
+| [Halo](https://www.halo.run/) | 2.27.0+ | 博客运行时,提供 Finder API 与主题渲染 |
| [Astro](https://astro.build) | 6.x | 组件开发,构建输出静态 `.html` 模板 |
| [Thymeleaf](https://www.thymeleaf.org/) | - | Halo 服务端模板引擎(源码里直接写 `th:*`) |
diff --git a/docs/customize/style.md b/docs/customize/style.md
index 6541c90..fadf588 100644
--- a/docs/customize/style.md
+++ b/docs/customize/style.md
@@ -202,6 +202,7 @@ else if (!stored && prefersDark) { isDark = true; }
| `animation_enabled` | 启用动效 | `true` |
| `animation_breath` | 呼吸动画 | `true` |
| `animation_scroll_reveal` | 滚动渐入 | `true` |
-| `animation_cursor_glow` | 光感跟随 | `false` |
+| `click_effect_enabled` | 鼠标点击效果 | `false` |
+| `click_effect_type` | 点击效果类型(8 种 + 关闭) | `values` |
关闭动效时,`html` 元素添加 `wi-no-animations` 类名。
diff --git a/docs/faq.md b/docs/faq.md
index 49c04b1..f7dec69 100644
--- a/docs/faq.md
+++ b/docs/faq.md
@@ -116,10 +116,23 @@ v1.2.1 起安装包会保留各版本的哈希资源(v1.1.7 之后全部覆盖
| 瞬间 | [PluginMoments](https://www.halo.run/store/apps/app-SnwWD) |
| 图库 | [PluginPhotos](https://www.halo.run/store/apps/app-BmQJW) |
| 友链 | [PluginLinks](https://www.halo.run/store/apps/app-hfbQg) |
-| 朋友圈 | [PluginFriends](https://www.halo.run/store/apps/app-yISsV) |
+| 订阅动态 | 同为 [PluginLinks](https://www.halo.run/store/apps/app-hfbQg) 的 RSS 订阅能力,需选择「订阅」自定义模板 |
安装并启用插件后,页面会自动显示内容。未安装插件时页面会显示友好的提示信息。
+**「朋友圈」插件已不再提供**:feed / RSS 聚合已由官方「链接管理」插件的订阅取代,
+主题保留 `friends.html` 模板与「朋友圈」设置分组仅用于兼容旧站点。新站点请新建页面并选择
+「订阅」自定义模板,详见 README「自定义页面模板」与[订阅页面](https://nxxy335.top/WarmIsland/pages/subscriptions.html)。
+
+### 原来的「朋友圈」页面不能用了,怎么迁移?
+
+1. 安装 / 启用官方「链接管理」(PluginLinks)插件,把 RSS 订阅源迁到该插件的订阅中
+2. Halo 后台 → 页面 → 新建 → 自定义模板选择「订阅」(`page_subscriptions.html`)
+3. 在主题设置 → 订阅中调整每页条数、分页 / 下滑加载与列表 / 网格布局
+4. 确认动态正常展示后,删除旧的 `/friends` 页面与菜单项
+
+旧的 `friends.html` 检测不到 `plugin-friends` 时只会显示空状态,不会影响站点其他页面。
+
### 主题会向第三方服务发请求吗?
**默认不会。** 所有脚本、样式、字体、图标、主题 Logo 与一言句子库都随主题自托管,
@@ -128,14 +141,14 @@ v1.2.1 起安装包会保留各版本的哈希资源(v1.1.7 之后全部覆盖
1. 访客**主动点击**分享按钮 / 备案链接 / 应用市场链接时才跳转到对应站点;
2. 站点管理员在主题设置里**显式填写**了「自定义一言 API」或「自定义 IP 定位 API」——
- 后者会把访客 IP 发送给该第三方服务换取地理位置,**需自行在站点隐私说明中披露**,
- 详见 README「外部资源与隐私」。
+ 后者会把访客 IP 发送给该第三方服务换取地理位置;数据流向与披露要求见
+ README「外部资源与隐私」。
可选接口地址(仅作候选,主题不会自动请求):
| 能力 | 可选地址 |
| --- | --- |
-| 一言 | `https://v1.hitokoto.cn/`(选择「一言」时自动填入) |
+| 一言 | `https://v1.hitokoto.cn/`(默认预填,仅「一言」模式生效) |
| IP 定位主 / 备选 API | `https://myip.ipip.net/json`、`https://r.inews.qq.com/api/ip2city?otype=json` |
完整逐项说明见 README 的「外部资源与隐私」章节。发版前可运行 `pnpm audit:external` 复核。
@@ -144,10 +157,11 @@ v1.2.1 起安装包会保留各版本的哈希资源(v1.1.7 之后全部覆盖
1. Hero「描述文案来源」**默认为「无」**,此时不显示描述文案、不渲染一言元素,零外部请求;
想显示句子请改为「一言」
-2. 选择「一言」后会自动填入 `https://v1.hitokoto.cn/`,此时才会产生外部请求;
+2. 「自定义一言 API」字段在「描述文案来源」非「无」时显示,且默认预填 `https://v1.hitokoto.cn/`,
+ 选择「一言」后该值才生效并产生外部请求;
**把该字段清空即回退到主题内置的 `assets/data/hitokoto.json` 本地句子库(零外部请求)**,
- 直接编辑该 JSON 即可替换文案。只有填写后才会向该地址发起请求,需自行在站点隐私说明中披露,
- 详见 README「外部资源与隐私」
+ 直接编辑该 JSON 即可替换文案。只有填写后才会向该地址发起请求,数据流向与披露要求见
+ README「外部资源与隐私」
3. 「自定义」模式显示「自定义描述文案」中的静态文本,不发起任何请求;
「句子类型」筛选仅对填写了 API 的一言模式生效
diff --git a/docs/guide/getting-started.md b/docs/guide/getting-started.md
index cc58c45..0427413 100644
--- a/docs/guide/getting-started.md
+++ b/docs/guide/getting-started.md
@@ -8,13 +8,15 @@ WarmIsland(暖屿)是一款为 [Halo](https://halo.run) 打造的博客主
- 🌙 **深色模式** — 跟随系统/浅色/深色三种方案,平滑切换
- 📱 **响应式布局** — 桌面到手机完美适配
- 📝 **沉浸阅读** — 侧边目录、进度条、代码高亮、图片灯箱
-- 🔌 **插件生态** — 瞬间、图库、友链、朋友圈、豆瓣、装备、Steam
-- ⚙️ **灵活配置** — 全维度自定义面板,无需改代码
+- 🔌 **插件生态** — 瞬间、图库、友链、订阅动态、豆瓣、装备、Steam
+- 🔒 **默认零第三方请求** — 静态资源全部自托管,可选 API 默认留空
+- ⚙️ **灵活配置** — 17 个分组 / 126 个配置项,无需改代码
## 前置要求
-- Halo >= 2.24.0
+- **Halo >= 2.27.0**(主题 `theme.yaml` 声明 `requires: ">=2.27.0"`;页面布局契约与微信读书页面依赖 2.27 的能力)
- 已安装并运行 Halo 实例
+- 如需插件页面(瞬间、图库、友链、订阅等),另需安装对应插件
## 安装方式
@@ -33,6 +35,11 @@ WarmIsland(暖屿)是一款为 [Halo](https://halo.run) 打造的博客主
4. 上传下载的 `.zip` 文件
5. 点击 **启用** 激活主题
+::: warning
+从源码自行打包时,必须先执行 `pnpm release`(build → snapshot → package)。
+只上传源码或漏跑构建的 ZIP 会因缺少 `templates/` 导致首页 404,详见 [FAQ](/faq)。
+:::
+
## 初始配置
安装并启用主题后,建议按以下顺序进行初始配置:
@@ -49,8 +56,8 @@ WarmIsland(暖屿)是一款为 [Halo](https://halo.run) 打造的博客主
进入 **样式设置**:
-- 选择 **配色方案**(跟随系统/浅色/深色)
-- 设置 **强调色**(默认 `#d4764e` 暖橘色)
+- 选择 **配色方案**(跟随系统/浅色/深色)与 **主题配色**(11 套预设)
+- 设置 **强调色**(留空则跟随所选配色,暖屿·赤陶为 `#d4764e`)
- 选择 **圆角风格** 和 **容器宽度**
### 第三步:导航菜单
@@ -64,7 +71,7 @@ WarmIsland(暖屿)是一款为 [Halo](https://halo.run) 打造的博客主
进入 **Hero 首屏** 设置:
- 设置主标题和副标题
-- 选择描述文案来源(默认「无」/ 一言 / 自定义);默认不显示描述、不发起请求;选「一言」自动填入 `https://v1.hitokoto.cn/`,清空该字段则使用内置本地句子库(零外部请求)
+- 选择描述文案来源(默认「无」/ 一言 / 自定义);默认不显示描述、不发起请求;「自定义一言 API」字段在来源非「无」时显示并默认预填 `https://v1.hitokoto.cn/`(仅「一言」模式生效),清空该字段则使用内置本地句子库(零外部请求)
- 可选上传背景图片
### 第五步:页脚信息
@@ -75,7 +82,14 @@ WarmIsland(暖屿)是一款为 [Halo](https://halo.run) 打造的博客主
- 添加社交链接(GitHub、微博等)
- 可选添加自定义 HTML(统计代码等)
+### 可选:订阅动态页面
+
+如需展示博友文章动态,安装官方「链接管理」(PluginLinks)插件并维护 RSS 订阅源,
+再新建一个页面选择「订阅」自定义模板即可。原先的「朋友圈」插件已不再提供,
+详见[订阅页面](/pages/subscriptions)。
+
## 下一步
- [基础设置](/config/basic) — 完整的主题配置说明
- [样式设置](/config/style) — 调整配色、圆角、动画
+- [订阅配置](/config/subscriptions) — feed 聚合动态设置
diff --git a/docs/guide/introduction.md b/docs/guide/introduction.md
index b123f7d..a17f311 100644
--- a/docs/guide/introduction.md
+++ b/docs/guide/introduction.md
@@ -2,10 +2,15 @@
**WarmIsland(暖屿)** 是一款为 [Halo](https://halo.run) 打造的博客主题。暖如灯火,静如留白——它以柔和的色调和舒缓的节奏回归内容本身,为记录与阅读留出一方安静从容的角落。
-> 本主题由 AI 开发完成。
+> 本项目使用 AI 辅助开发,产出已由开发者完成代码审查、构建产物核验与 Halo 开发生态适配。
它的名字来源于一个画面——深夜里温暖的小岛。我们希望每一个来到你站点的访客,都能感受到那份安静而舒适的氛围。
+## 环境要求
+
+- Halo **2.27.0 及以上**(`theme.yaml` 的 `requires` 为 `>=2.27.0`):页面布局契约、微信读书页面均依赖 2.27 的能力
+- v1.2.0 起内置主题配色系统(纯 CSS 变量实现);更低版本的 Halo 请使用主题 v1.1.x
+
## 设计理念
暖屿的设计围绕三个核心词展开:**温暖、沉浸、精致**。
@@ -28,19 +33,20 @@
- **暖色调设计语言** — 橘色强调色 + 呼吸光球 + 渐变背景
- **三种导航栏样式** — Glass(毛玻璃)/ Minimal(极简)/ Float(浮动胶囊)
+- **内置配色系统** — 11 套预设调色板,每套含浅色 / 深色完整色板
- **深色模式** — 跟随系统、浅色、深色三种方案,一键切换平滑过渡
-- **动效系统** — 滚动渐入、光感跟随、呼吸动画,均可独立开关
+- **动效系统** — 滚动渐入、呼吸动画、点击特效,均可独立开关
### 📝 阅读体验
- **文章目录** — 桌面端侧边悬浮 + 移动端底部抽屉,支持展开模式选项
- **阅读进度条** — 实时显示阅读进度
- **代码高亮** — 由代码高亮插件 / API 扩展包输出,主题提供 Warm / Cold 本地配色,不加载远程脚本
-- **图片灯箱** — 点击放大,支持左右切换
+- **图片灯箱** — 点击放大,支持左右切换与 EXIF 信息
- **图片懒加载** — blur-up 渐显效果,优化加载体验
- **点赞功能** — 一键点赞,状态持久化
- **相关文章推荐** — 文章底部推荐相关内容
-- **分享功能** — 微博 / X / Facebook / Telegram / 复制链接
+- **分享功能** — QQ / 微博 / X / Facebook / Telegram / 复制文章链接
### 📱 响应式
@@ -49,11 +55,10 @@
- 文章卡片自动切换为上下布局
- 目录自动切换为悬浮按钮 + 抽屉
-### 🔍 SEO 与国际化
+### 🔍 SEO 与结构化数据
- **Open Graph 元标签** — 优化社交媒体分享预览
-- **JSON-LD 结构化数据** — 提升搜索引擎理解与展示
-- **i18n 国际化** — 简体中文、繁体中文、英语,支持跟随浏览器自动匹配
+- **JSON-LD 结构化数据** — 文章标题 / 作者 / 日期 / 封面,由转义后的 `` 生成,不拼接不可信字符串
### 🔌 插件生态
@@ -64,28 +69,38 @@
| 瞬间 | PluginMoments | Timeline / Cards / Masonry 三种布局 |
| 图库 | PluginPhotos | Masonry / Grid / Carousel + 分组浏览 |
| 友情链接 | PluginLinks | Cards / Grid / List 三种布局 |
-| 朋友圈 | plugin-friends | 友站动态时间线 |
+| 订阅 | PluginLinks(RSS 订阅) | 博友文章动态,分页 / 下滑加载、列表 / 网格布局 |
| 豆瓣 | 豆瓣插件 | 观影/读书/音乐记录 |
| 装备 | 装备插件 | 按分组展示装备清单 |
| Steam | Steam 插件 | 游戏资料与徽章 |
+| 记得 | plugin-important-dates | 重要日期 / 牵挂的人 / 爱车双视图 |
+
+> 「朋友圈」(`plugin-friends`)插件已不再提供,其 feed 聚合能力由官方「链接管理」插件的订阅取代,
+> 详见[订阅页面](/pages/subscriptions)。
### ⚙️ 灵活配置
-17 个配置分组、120 余个配置项,覆盖站点的方方面面:
+17 个配置分组、126 个配置项,覆盖站点的方方面面:
-- 基础信息、样式、导航栏、Hero 首屏
-- 首页、文章、瞬间、图库、友情链接
-- 朋友圈、留言板、评论、页脚
+- 基础信息、样式、导航栏、Hero 首屏、欢迎弹窗
+- 首页、文章、瞬间、图库、友情链接、订阅
+- 微信读书、记得、留言板、评论、页脚
所有配置都在 Halo 后台的图形化面板中完成,无需修改代码。
+### 🔒 默认零第三方请求
+
+全部脚本、样式、字体、图标、句子库与主题 Logo 随主题自托管;Hero 描述文案默认「无」、
+欢迎弹窗默认关闭、两个可选 API 字段默认留空,页面不会自动向第三方发起请求。
+详见 README「外部资源与隐私」。
+
## 技术栈
- **Astro 6** — 构建输出 Thymeleaf 模板
- **Thymeleaf** — Halo 使用的服务端模板引擎
- **原生 JavaScript + SCSS** — 交互与样式(无 Vue / 无远程运行时)
- **LightGallery 2.9.0(GPLv3)** — 图片灯箱,随构建自托管打包
-- **LXGW WenKai(OFL 1.1)** — 本地字体分片,无远程字体请求
+- **LXGW WenKai(OFL 1.1)** — 本地字体分片,许可证全文随包分发
- **代码高亮** — 交由 Halo 应用市场插件提供,主题只自托管配色 CSS
## 适用场景
@@ -95,7 +110,7 @@ WarmIsland 适合以下类型的站点:
- 📖 **个人博客** — 记录生活、分享思考
- 📸 **摄影站** — 图库页面展示作品
- 🎮 **游戏博客** — Steam 页面展示游戏资料
-- 📚 **读书笔记** — 豆瓣页面展示阅读记录
+- 📚 **读书笔记** — 豆瓣 / 微信读书页面展示阅读记录
- 💭 **碎碎念** — 瞬间页面记录日常灵感
## 下一步
diff --git a/docs/index.md b/docs/index.md
index ffbd9f4..b850f34 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -26,7 +26,7 @@ features:
- title: 📝 沉浸阅读
details: 文章目录侧边悬浮、阅读进度条、代码高亮、图片灯箱,打造专注的阅读体验
- title: 🔌 插件生态
- details: 深度集成瞬间、图库、友情链接、朋友圈、豆瓣、装备、Steam 等插件页面
+ details: 深度集成瞬间、图库、友情链接、订阅动态、豆瓣、装备、Steam 等插件页面
- title: ⚙️ 灵活配置
details: 丰富的主题设置面板,涵盖样式、导航、首页、文章、评论等全维度自定义
---
diff --git a/docs/pages/custom-page.md b/docs/pages/custom-page.md
index 36241cb..69cfe93 100644
--- a/docs/pages/custom-page.md
+++ b/docs/pages/custom-page.md
@@ -1,32 +1,49 @@
# 自定义页面
-自定义页面是 Halo 的独立页面功能,用于创建关于、友链等独立内容页面。
+自定义页面是 Halo 的独立页面功能,用于创建关于、留言板、订阅动态、微信读书等独立内容页面。
## 使用方式
1. 进入 Halo 后台 → **页面** → **新建**
2. 填写页面标题和内容
-3. 可选择自定义模板
-4. 发布页面
+3. 可选:在「自定义模板」中选择主题提供的模板
+4. 发布页面,并把页面加入导航菜单
+
+页面地址由创建时设定的 slug 决定,主题不为自定义模板提供固定路由。
## 页面模板
-主题提供以下自定义页面模板:
+`theme.yaml` 中注册了 3 个自定义模板,加上默认的 `page.html` 共 4 种:
-| 模板 | 文件 | 说明 |
-|------|------|------|
-| 默认 | page.html | 标准内容页面 |
-| 留言板 | page_messageboard.html | 带评论的留言板页面 |
+| 模板 | 模板文件 | 说明 |
+|------|---------|------|
+| 默认 | `page.html` | 标准内容页面 |
+| 留言板(MessageBoard) | `page_messageboard.html` | 带评论的留言墙,标题与副标题可配置 |
+| 订阅(Subscriptions) | `page_subscriptions.html` | 博友文章订阅动态,依赖官方「链接管理」插件的 RSS 订阅 |
+| 微信读书(WeRead) | `weread.html` | 微信读书书架,依赖微信读书插件,访客免登录查看 |
### 留言板模板
-选择留言板模板后,页面会自动集成评论组件,访客可以直接留言。标题和副标题使用主题设置中的配置。
+选择留言板模板后,页面会集成评论组件,访客可以直接留言。标题和副标题在
+**主题设置 → 留言板** 中配置,详见[留言板配置](/config/messageboard)。
-使用步骤:
+### 订阅模板
-1. 新建页面,选择自定义模板为「留言板」
-2. 在主题设置 → 留言板中配置标题和副标题
-3. 发布页面,添加到导航菜单
+feed / RSS 聚合不再依赖已停止提供的「朋友圈」插件,而由官方
+「链接管理」(PluginLinks)插件的订阅能力提供。使用步骤:
+
+1. 安装并启用[链接管理插件](https://www.halo.run/store/apps/app-hfbQg),维护博友链接的 RSS 订阅源
+2. 新建页面,自定义模板选择「订阅」
+3. 在**主题设置 → 订阅**中调整每页条数、加载方式与布局,详见[订阅配置](/config/subscriptions)
+
+未安装插件或暂无订阅动态时页面会显示友好提示,不会报错。
+完整说明见[订阅页面](/pages/subscriptions)。
+
+### 微信读书模板
+
+选择「微信读书」模板后展示书架与阅读记录,标题 / 副标题在
+**主题设置 → 微信读书** 中配置,详见[微信读书配置](/config/weread)。
+该页面依赖 Halo 2.27+ 的能力。
## 页面功能
diff --git a/docs/pages/extended.md b/docs/pages/extended.md
index a70b9d0..b68993b 100644
--- a/docs/pages/extended.md
+++ b/docs/pages/extended.md
@@ -6,31 +6,37 @@ WarmIsland 主题深度集成了多款 Halo 插件,提供了丰富的扩展页
| 页面 | 所需插件 | 路由 |
|------|----------|------|
-| 瞬间 | [PluginMoments](https://www.halo.run/store/apps/app-SnwWD) | /moments |
-| 图库 | [PluginPhotos](https://www.halo.run/store/apps/app-BmQJW) | /photos |
-| 友情链接 | [PluginLinks](https://www.halo.run/store/apps/app-hfbQg) | /links |
-| 朋友圈 | [plugin-friends](https://www.halo.run/store/apps/app-yISsV) | /friends |
-| 豆瓣 | [plugin-douban](https://www.halo.run/store/apps/app-srBOL) | /douban |
-| 装备 | [equipment](https://www.halo.run/store/apps/app-ytygyqml) | /equipments |
-| 足迹 | [footprint](https://www.halo.run/store/apps/app-XCtAQ) | /footprints |
-| Steam | [steam](https://www.halo.run/store/apps/app-0ojqyzfh) | /steam |
-| 记得 | [plugin-important-dates](https://github.com/yyliucha/plugin-important-dates) | /important-dates |
+| 瞬间 | [PluginMoments](https://www.halo.run/store/apps/app-SnwWD) | `/moments` |
+| 图库 | [PluginPhotos](https://www.halo.run/store/apps/app-BmQJW) | `/photos` |
+| 友情链接 | [PluginLinks](https://www.halo.run/store/apps/app-hfbQg) | `/links` |
+| 订阅动态 | [PluginLinks](https://www.halo.run/store/apps/app-hfbQg)(RSS 订阅) | 自定义页面,无固定路由 |
+| 豆瓣 | [plugin-douban](https://www.halo.run/store/apps/app-srBOL) | `/douban` |
+| 装备 | [equipment](https://www.halo.run/store/apps/app-ytygyqml) | `/equipments` |
+| Steam | [steam](https://www.halo.run/store/apps/app-0ojqyzfh) | `/steam` |
+| 记得 | [plugin-important-dates](https://github.com/yyliucha/plugin-important-dates) | `/important-dates` |
+
+> 「朋友圈」(`plugin-friends`)插件已不再提供,其 feed / RSS 聚合能力由官方「链接管理」插件的订阅取代。
+> 主题保留的 `friends.html` 仅供旧站点兼容,新站点请使用订阅模板,详见[订阅页面](/pages/subscriptions)。
+
+## 订阅页面
+
+订阅页面依赖官方「链接管理」插件的 RSS 订阅,展示博友们的最新文章,
+支持分页 / 下滑加载与列表 / 网格布局。它属于自定义页面模板,地址由你创建页面时的 slug 决定。
+使用前请在 Halo 后台 → 页面 → 新建 → 自定义模板中选择「订阅」。
+
+详见[订阅页面](/pages/subscriptions)与[订阅配置](/config/subscriptions)。
## 豆瓣页面
-[豆瓣插件](https://www.halo.run/store/apps/app-srBOL)
-展示豆瓣观影/读书/音乐记录,支持按类型和状态筛选。
+
+[豆瓣插件](https://www.halo.run/store/apps/app-srBOL)展示豆瓣观影/读书/音乐记录,支持按类型和状态筛选。
## 装备页面
-[装备管理插件](https://www.halo.run/store/apps/app-ytygyqml)
-展示个人装备清单,按分组分类展示。
-## 足迹页面
-[足迹插件](https://www.halo.run/store/apps/app-XCtAQ)
-展示个人足迹地图。
+[装备管理插件](https://www.halo.run/store/apps/app-ytygyqml)展示个人装备清单,按分组分类展示。
## Steam 页面
-[Steam](https://www.halo.run/store/apps/app-0ojqyzfh)
-展示 Steam 游戏资料,包括:
+
+[Steam](https://www.halo.run/store/apps/app-0ojqyzfh)展示 Steam 游戏资料,包括:
- 玩家头像和昵称
- 游戏统计
@@ -39,8 +45,7 @@ WarmIsland 主题深度集成了多款 Halo 插件,提供了丰富的扩展页
## 记得页面
-[记得插件](https://github.com/yyliucha/plugin-important-dates)
-记录重要的日子、牵挂的人与座驾,「生活 / 爱车」双视图展示:
+[记得插件](https://github.com/yyliucha/plugin-important-dates)记录重要的日子、牵挂的人与座驾,「生活 / 爱车」双视图展示:
- 重要日期(含农历)与倒计时便签
- 牵挂的人:大头贴、昵称、关系与生日倒计时
diff --git a/docs/pages/friends.md b/docs/pages/friends.md
deleted file mode 100644
index 4e08964..0000000
--- a/docs/pages/friends.md
+++ /dev/null
@@ -1,25 +0,0 @@
-# 朋友圈
-
-朋友圈页面展示订阅的友站最新文章动态,需要安装 [朋友圈插件](https://www.halo.run/store/apps/app-yISsV)。
-
-## 功能说明
-
-页面以时间线形式展示友站更新,每条动态包含:
-
-- 友站名称和头像
-- 文章标题和链接
-- 发布时间
-
-## 使用方式
-
-1. 在 Halo 后台安装并启用朋友圈插件
-2. 在插件设置中添加友站 RSS 订阅源
-3. 主题自动读取并展示友站动态
-
-::: tip
-朋友圈插件负责数据抓取,主题负责前端展示。如需调整抓取频率或内容,请在插件设置中操作。
-:::
-
-## 相关配置
-
-- [朋友圈配置](/config/friends) — 页面标题
diff --git a/docs/pages/home.md b/docs/pages/home.md
index b7549f0..f7b84da 100644
--- a/docs/pages/home.md
+++ b/docs/pages/home.md
@@ -16,7 +16,7 @@ Hero 区域占据整个视口高度,包含:
- **主标题**:默认使用站点标题,可在主题设置中自定义
- **副标题**:默认使用站点副标题
-- **描述文案**:默认「无」(不显示、零请求);可选「一言」(自动填入 `https://v1.hitokoto.cn/`,清空则用内置本地句子库)或「自定义」静态文案
+- **描述文案**:默认「无」(不显示、零请求);可选「一言」(API 字段默认预填 `https://v1.hitokoto.cn/`,清空则用内置本地句子库)或「自定义」静态文案
- **视觉效果**:渐变背景 + 呼吸光球 + 滚动模糊
页面滚动时,Hero 区域会产生模糊效果,内容向上淡出,底部有向下箭头提示滚动。
diff --git a/docs/pages/links.md b/docs/pages/links.md
index c6ed033..816c0be 100644
--- a/docs/pages/links.md
+++ b/docs/pages/links.md
@@ -29,3 +29,5 @@
## 相关配置
- [友情链接配置](/config/links) — 展示样式
+- [订阅配置](/config/subscriptions) — 同一插件提供的 RSS 订阅动态
+- [订阅页面](/pages/subscriptions) — 博友文章动态页面
diff --git a/docs/pages/subscriptions.md b/docs/pages/subscriptions.md
new file mode 100644
index 0000000..2271a86
--- /dev/null
+++ b/docs/pages/subscriptions.md
@@ -0,0 +1,53 @@
+# 订阅页面
+
+订阅页面按时间倒序展示博友们的最新文章,即原先「朋友圈 / feed 聚合」所提供的能力。
+现在它由 **Halo 官方「链接管理」(PluginLinks)插件的 RSS 订阅**驱动,主题提供
+`page_subscriptions.html` 自定义模板负责前端展示。
+
+## 使用方式
+
+1. 安装并启用 [链接管理插件](https://www.halo.run/store/apps/app-hfbQg),在插件中维护博友链接的 RSS 订阅源
+2. 进入 Halo 后台 → **页面** → **新建**
+3. 选择自定义模板「**订阅**」(`Subscriptions`,对应 `page_subscriptions.html`)
+4. 发布页面,并按需加入导航菜单
+
+> 页面地址由你创建页面时设定的 slug 决定,主题**不提供固定的 `/subscriptions` 路由**;
+> 只有插件提供的扩展页面(如 `/links`、`/moments`)才是固定路由。
+
+## 页面内容
+
+每条订阅动态是一张卡片,包含:
+
+- 作者头像(缺失时显示首字占位)、作者名称与主页链接
+- 发布日期
+- 文章标题(点击跳转原文)、摘要
+- 空数据时的友好提示,以及未安装链接管理插件时的安装引导
+
+标题与作者链接均使用 `target="_blank"` + `rel="noopener noreferrer"`,
+主题本身不会向第三方发起请求。
+
+## 展示与加载
+
+在[订阅配置](/config/subscriptions)中可调:
+
+| 能力 | 可选值 |
+| --- | --- |
+| 布局 | 单列列表卡片 / 网格卡片(窄屏自动收敛列数) |
+| 加载方式 | 底部分页(较新 / 较旧)/ 下滑自动加载 |
+| 每页条数 | 1–100,默认 20 |
+| 标题与副标题 | 自定义文本 |
+
+## 从「朋友圈」迁移
+
+`plugin-friends`(朋友圈)插件已不再提供,原来的 `/friends` 页面与「朋友圈」设置分组
+仅作为旧站点兼容保留,模板检测到插件不可用时会显示空状态。迁移步骤:
+
+1. 安装 / 启用「链接管理」插件,把原本在朋友圈插件里维护的 RSS 订阅源迁到链接管理插件的订阅中
+2. 新建一个页面并选择「订阅」自定义模板
+3. 确认动态正常展示后,删除旧的 `/friends` 页面与菜单项
+
+## 相关配置
+
+- [订阅配置](/config/subscriptions) — 全部 5 个设置项
+- [友情链接页面](/pages/links) — 同一插件的友链展示
+- [扩展页面](/pages/extended) — 插件前台页面一览
diff --git a/package.json b/package.json
index 5ab9fc8..6257d9a 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,5 @@
{
- "version": "1.2.6",
+ "version": "1.2.7",
"type": "module",
"engines": {
"node": ">=22.12.0"
diff --git a/scripts/audit-external.mjs b/scripts/audit-external.mjs
index 6f4f1ad..6222114 100644
--- a/scripts/audit-external.mjs
+++ b/scripts/audit-external.mjs
@@ -5,7 +5,8 @@
* - 1.4 远程执行与动态加载:禁止远程加载核心代码 / 动态拉取并执行组件
* - 4.4.4 性能与外部资源:不得预连接外部 CDN、加载远程脚本样式、打包无关大资源
* - 4.4.2 内容渲染安全:不得把站点内容用 th:utext 拼进