<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Xieluyang</title><description>Demo Site</description><link>https://007912.xyz/</link><language>en</language><item><title>准星代码</title><link>https://007912.xyz/posts/zx/</link><guid isPermaLink="true">https://007912.xyz/posts/zx/</guid><pubDate>Mon, 05 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;m0NESY&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;CSGO-pzzrk-mecT3-M8NvF-JK3hV-osVrC
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;NiKo&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;CSGO-e8nE5-LRxJf-YcNu2-e72fz-BqFVF
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>给 DeepSeek Harness Web 界面加一只 Live2D 桌宠</title><link>https://007912.xyz/posts/chajain/</link><guid isPermaLink="true">https://007912.xyz/posts/chajain/</guid><description>给 DeepSeek Harness Web 界面加一只 Live2D 桌宠：打开 DSH 就能看到可爱的二次元角色站在聊天界面角落。 内置 4 个角色可自由切换，点她会弹出聊天气泡说符合人设的台词（台词可自己改）， 也支持随时导入自己的模型。零运行时依赖，纯插件挂载 —— 安装即启用，卸载不留痕。</description><pubDate>Tue, 29 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;div class=&quot;badge-row&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.shields.io/badge/license-MIT-263146&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/DeepSeek%20Harness-plugin-4b6fff&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/Live2D-Cubism%202%20%7C%203%20%7C%204%20%7C%205-7da1de&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/%E5%86%85%E7%BD%AE%E8%A7%92%E8%89%B2-4-ff9ec4&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/%E8%BF%90%E8%A1%8C%E6%97%B6%E4%BE%9D%E8%B5%96-0-brightgreen&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/Node-%E2%89%A520-339933?logo=nodedotjs&amp;amp;logoColor=white&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/%E5%B9%B3%E5%8F%B0-Windows%20%7C%20macOS%20%7C%20Linux-6b7f99&quot; alt=&quot;Static Badge&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;h1&gt;dsh-live2d-widget&lt;/h1&gt;
&lt;p&gt;项目地址：&lt;a href=&quot;https://github.com/xieluyang912/dsh-live2d-widget&quot;&gt;dsh-live2d-widget&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;给 DeepSeek Harness Web 界面加一只 Live2D 桌宠：打开 DSH 就能看到可爱的二次元角色站在聊天界面角落。
内置 4 个角色可自由切换，点她会弹出聊天气泡说符合人设的台词（台词可自己改），
也支持随时导入自己的模型。零运行时依赖，纯插件挂载 —— 安装即启用，卸载不留痕。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;功能亮点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;可爱的内置角色&lt;/strong&gt; — 纱雾、雷姆、伊斯特、缇娅，覆盖 Cubism 2 与 Cubism 4 两代运行时。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;点击说话&lt;/strong&gt; — 点模型弹出一句符合角色人设的台词，气泡带角色名；&lt;strong&gt;每个角色的台词都能自己改&lt;/strong&gt;（一行一句，存到本地）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;拖动摆位&lt;/strong&gt; — 按住模型直接拖到屏幕任意位置，松手即记住，重启后还在。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自由切换&lt;/strong&gt; — 面板点一下即换模型；每个模型各自记住自己的适配、位置与台词。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;导入自己的模型&lt;/strong&gt; — 支持 &lt;code&gt;.zip&lt;/code&gt;、整个模型文件夹、或直接填本机目录路径；&lt;strong&gt;按内容识别入口文件&lt;/strong&gt;，所以 &lt;code&gt;model.json&lt;/code&gt;、&lt;code&gt;rem.json&lt;/code&gt;、自定义文件名都能认出来。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可控的大小&lt;/strong&gt; — 「大小」调的是画布，模型等比放大而&lt;strong&gt;永远不会被裁掉&lt;/strong&gt;；「适配」单独控制模型在画布里的占比。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;精确输入&lt;/strong&gt; — 每个数值都同时有滑块和输入框：可以拖，也可以直接敲数字，还能按住数字左右拖动微调。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不打扰办事&lt;/strong&gt; — 默认只占左下角，可隐藏（&lt;code&gt;Ctrl+Shift+L&lt;/code&gt;），可穿透点击聊天界面。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;零运行时依赖&lt;/strong&gt; — Live2D 运行时随包发布（单个 JS 文件），不联网、不拉 CDN；解压也用自带的零依赖实现。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不污染 DSH&lt;/strong&gt; — 整只挂件活在 Shadow DOM 里，样式与 DSH 和其他插件互不影响。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;快速开始&lt;/h2&gt;
&lt;p&gt;前置条件：已安装 &lt;a href=&quot;https://github.com/deepseek-ai/deepseek-harness&quot;&gt;DeepSeek Harness&lt;/a&gt;（&lt;code&gt;dsh&lt;/code&gt; 命令可用）
与 &lt;strong&gt;Node.js &lt;code&gt;^22.19 || &amp;gt;=24&lt;/code&gt;&lt;/strong&gt;（与 DSH 自身要求一致）。&lt;/p&gt;
&lt;p&gt;三种安装方式，任选一种：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# ① 从 GitHub 安装（推荐：装完即有 4 个内置角色）
dsh plugin --profile web add github:xieluyang912/dsh-live2d-widget

#    等价的显式 git 写法
dsh plugin --profile web add git+https://github.com/xieluyang912/dsh-live2d-widget.git

# ② 从 npm 安装
dsh plugin --profile web add dsh-live2d-widget

# ③ 本地目录安装（开发用，pnpm 会建 junction，改代码即生效）
dsh plugin --profile web add link:D:/Plugins/dsh-live2d-widget

# 卸载
dsh plugin --profile web remove dsh-live2d-widget
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;dsh plugin&lt;/code&gt; 是 pnpm 的透传（&lt;code&gt;--profile web&lt;/code&gt; 之后的参数原样交给 pnpm），
所以 pnpm 支持的写法（&lt;code&gt;github:&lt;/code&gt;、&lt;code&gt;git+https:&lt;/code&gt;、npm 包名、&lt;code&gt;link:&lt;/code&gt;、tarball）都能用。&lt;/p&gt;
&lt;p&gt;安装命令会自动把插件写进 &lt;code&gt;%USERPROFILE%\.dsh\profiles\web\package.json&lt;/code&gt; 的
&lt;code&gt;dsh.profile.bundles&lt;/code&gt;，&lt;strong&gt;不需要手工改 profile patch&lt;/strong&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;从 git / npm 安装时不需要编译&lt;/strong&gt;：本插件是纯 JavaScript，没有构建步骤，
也没有 &lt;code&gt;install&lt;/code&gt; / &lt;code&gt;prepare&lt;/code&gt; 生命周期脚本，所以不会被 pnpm 的
&lt;code&gt;ERR_PNPM_IGNORED_BUILDS&lt;/code&gt; 拦住，装完即可用。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;改完插件要重载才生效 —— 两半的加载方式不一样。&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;浏览器那半&lt;/strong&gt;（&lt;code&gt;assets/live2d-widget.js&lt;/code&gt;、&lt;code&gt;assets/vendor&lt;/code&gt;）&lt;strong&gt;每次请求都从磁盘重读&lt;/strong&gt;，刷新页面即可。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Host 那半&lt;/strong&gt;（&lt;code&gt;lib/index.js&lt;/code&gt;、内置模型清单与模型文件）&lt;strong&gt;启动时读进进程内存&lt;/strong&gt;，必须重启 &lt;code&gt;dsh web&lt;/code&gt;。
DSH 在 agent 运行期间会拒绝重载插件（插件市场日志写的是 &lt;code&gt;refused while agents are running&lt;/code&gt;），
所以要等当前会话结束或手动重启。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;判断自己在看哪一版：面板里出现了「大小 / 适配 / 点击台词」但模型列表还是旧的，
就是&lt;strong&gt;浏览器半边已更新、host 半边还是旧的&lt;/strong&gt; —— 重启一下就好。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;用法&lt;/h2&gt;
&lt;p&gt;打开 DSH 后左下角出现角色，右上角有个圆形 &lt;strong&gt;L2D&lt;/strong&gt; 按钮，点它展开控制面板。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;区块&lt;/th&gt;
&lt;th&gt;能做什么&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;模型&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;点任意一项立即切换；「导入」标记的是你自己导入的模型，右侧 &lt;code&gt;×&lt;/code&gt; 可删除&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;大小&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;整体大小（0.4× ~ 2.2×）。调的是画布，模型跟着等比放大，&lt;strong&gt;永远不会被裁掉&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;适配&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;模型在画布里的占比（0.1 ~ 3.0）。主要给导入的模型微调用；内置角色已标定好，保持 1 即可&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;左右 / 上下&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;模型在画布内的位置微调（−2 ~ 2）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;透明&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;整体透明度（15 ~ 100）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;左右翻转 / 换边&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;镜像、在左下角和右下角之间切换&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;随机动作 / 随机表情&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;手动逗一下模型（模型没有动作或表情时按钮自动置灰）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;恢复默认&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;把当前模型的大小、适配、位置和外观重置回内置默认值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;隐藏模型&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;收起来，&lt;code&gt;Ctrl+Shift+L&lt;/code&gt; 恢复&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;点击台词&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;折叠区块：气泡开关、停留时长、台词编辑&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;导入自己的模型&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;折叠区块：zip / 文件夹 / 本机路径三种导入方式&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;数值怎么调&lt;/h3&gt;
&lt;p&gt;每个数值都有三种调法，三者永远同步：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;拖滑块&lt;/strong&gt; —— 最直观。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;直接输入&lt;/strong&gt; —— 在右边的输入框里敲数字，回车或点开别处生效。超出范围会自动收到边界，敲了非法字符会退回原值。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;按住数字左右拖&lt;/strong&gt; —— 在输入框上按住横向拖动即可微调（拖满约 320px 走完整个范围），松手时如果没拖动就进入输入模式。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;点击台词&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;展开「点击台词」，勾选 &lt;strong&gt;点击模型时说话&lt;/strong&gt;，点模型就会弹气泡说一句随机台词。&lt;/li&gt;
&lt;li&gt;文本框里 &lt;strong&gt;一行一句&lt;/strong&gt;，点「保存台词」生效；「恢复默认台词」回到该角色的内置人设台词；「试说一句」立即预览。&lt;/li&gt;
&lt;li&gt;「停留」控制气泡显示多久（2 ~ 20 秒）。&lt;/li&gt;
&lt;li&gt;台词 &lt;strong&gt;按模型分别保存&lt;/strong&gt;，可以给每个角色写符合自己口味的话。&lt;/li&gt;
&lt;li&gt;切换模型时也会自动打个招呼。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;内置台词都是按角色写的，例如雷姆会说「雷姆，会一直相信你的。」、
纱雾会说「哥哥，你回来啦……」，伊斯特会说「知识，就是力量哦。」&lt;/p&gt;
&lt;h3&gt;拖动与快捷键&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;按住模型直接拖&lt;/strong&gt;到想放的地方，松手自动记住。拖动不会误触发点击台词。
放到屏幕上方也没问题，面板会自动收缩以免超出屏幕顶部。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;操作&lt;/th&gt;
&lt;th&gt;效果&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;拖动模型&lt;/td&gt;
&lt;td&gt;移动位置（自动记住）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;单击模型&lt;/td&gt;
&lt;td&gt;说一句台词&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Ctrl+Shift+L&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;显示 / 隐藏模型&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;点 &lt;strong&gt;L2D&lt;/strong&gt; 按钮&lt;/td&gt;
&lt;td&gt;展开 / 收起控制面板&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;导入自己的模型&lt;/h2&gt;
&lt;p&gt;「导入自己的模型」区块提供三种方式，都会自动去掉压缩包 / 文件夹的最外层目录：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方式&lt;/th&gt;
&lt;th&gt;适合&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;选择 zip 压缩包&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;最常见；模型包通常就是 zip&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;选择模型文件夹&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;模型已经解压在磁盘上&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;填写本机模型目录&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;大模型：由插件直接从磁盘读取，不经过浏览器上传&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;入口文件是 &lt;strong&gt;按内容识别&lt;/strong&gt; 的：Cubism 3/4/5 认 &lt;code&gt;FileReferences.Moc&lt;/code&gt;，Cubism 2 认顶层的
&lt;code&gt;model&lt;/code&gt; + &lt;code&gt;textures&lt;/code&gt;。所以入口叫 &lt;code&gt;model.json&lt;/code&gt;、&lt;code&gt;rem.json&lt;/code&gt;、&lt;code&gt;chara-def.json&lt;/code&gt; 还是别的名字都能认出来，
不必符合命名规范。同一个目录里有多个入口时（例如同一角色的多套衣服），
内置模型用显式 &lt;code&gt;entry&lt;/code&gt; 指定，导入的模型可以先只放要用的那一套。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;模型版权归原作者所有。请自行确认你有权使用所导入的模型（很多模型禁止商用或二次分发）。
本插件只提供加载能力，不附带任何你导入的模型。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;内置角色&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;角色&lt;/th&gt;
&lt;th&gt;出处&lt;/th&gt;
&lt;th&gt;Cubism&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;纱雾 · 埃罗芒阿老师&lt;/td&gt;
&lt;td&gt;埃罗芒阿老师&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;雷姆 · Re:从零开始&lt;/td&gt;
&lt;td&gt;Re:从零开始的异世界生活&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;伊斯特 · 海王星&lt;/td&gt;
&lt;td&gt;海王星&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;缇娅 · Live2D 官方示例&lt;/td&gt;
&lt;td&gt;Live2D 官方示例模型&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;模型资源取自公开合集 &lt;a href=&quot;https://github.com/Eikanya/Live2d-model&quot;&gt;Eikanya/Live2d-model&lt;/a&gt;，
&lt;strong&gt;著作权归各自权利人&lt;/strong&gt;，不适用本插件的 MIT 许可（详见 &lt;a href=&quot;LICENSE&quot;&gt;LICENSE&lt;/a&gt;）。&lt;/p&gt;
&lt;h2&gt;工作原理&lt;/h2&gt;
&lt;p&gt;插件分 host 与 browser 两半：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DSH web app
  │  tapIndex 注入 &amp;lt;script defer src=&quot;/dsh-live2d/widget.js&quot;&amp;gt;
  ▼
browser 半（Shadow DOM：画布 + 气泡 + 控制面板）
  ├─ GET  /dsh-live2d/runtime.js        Live2D 运行时（随包发布，单文件自足）
  ├─ GET  /dsh-live2d/api/state         模型清单 + 设置 + 被跳过的模型
  ├─ POST /dsh-live2d/api/settings      持久化偏好
  ├─ POST /dsh-live2d/api/import-zip    原始 zip 上传
  ├─ POST /dsh-live2d/api/import-files  文件夹上传（base64）
  ├─ POST /dsh-live2d/api/import-path   直接读本机目录
  ├─ POST /dsh-live2d/api/delete        删除导入的模型
  └─ GET  /dsh-live2d/model/&amp;lt;id&amp;gt;/&amp;lt;相对路径&amp;gt;   模型文件（prefix 路由 + ETag）
  ▲
  │  每一条路由都先过 ctx.connection.requestRejection()
host 半（lib/index.js，跑在 DSH 进程里）
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Host 半&lt;/strong&gt; 用 &lt;code&gt;ctx.webServer.register&lt;/code&gt; 注册路由、用 &lt;code&gt;ctx.webServer.tapIndex&lt;/code&gt; 注入脚本；
模型文件走一条 &lt;code&gt;prefix&lt;/code&gt; 路由，路径经过 &lt;code&gt;..&lt;/code&gt; 过滤 + &lt;code&gt;realpath&lt;/code&gt; 校验，越权访问直接 403。
大贴图用 ETag + &lt;code&gt;Cache-Control: immutable&lt;/code&gt;，浏览器只回源一次。
入口文件为 0 字节（文件损坏）的模型会被显式跳过，并在 &lt;code&gt;/api/state&lt;/code&gt; 的 &lt;code&gt;skipped&lt;/code&gt; 里说明原因，
而不是让运行时抛出难以理解的 &lt;code&gt;Unexpected end of JSON input&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Browser 半&lt;/strong&gt; 整只挂在 Shadow DOM 里；只在主聊天界面初始化（见下）；层级取 &lt;code&gt;z-index: 90&lt;/code&gt;，
在聊天内容之上、DSH 的浮层与弹窗之下。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;四个踩过的坑（都写在代码注释里）&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;运行时只 &lt;code&gt;init()&lt;/code&gt; 一次，切模型靠重复 &lt;code&gt;load()&lt;/code&gt;。&lt;/strong&gt; &lt;code&gt;l2d&lt;/code&gt; 的 &lt;code&gt;destroy()&lt;/code&gt; &lt;strong&gt;不释放 WebGL 上下文&lt;/strong&gt;，
每切一次就 &lt;code&gt;init()&lt;/code&gt; 一次会一路泄漏上下文，直到浏览器把最早的丢掉、模型变白。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;画布的 CSS 尺寸必须由插件自己写。&lt;/strong&gt; 运行时的引导函数会在「计算尺寸 == 属性尺寸」时把
&lt;code&gt;style.width/height&lt;/code&gt; &lt;strong&gt;冻结&lt;/strong&gt;到画布上；一旦冻结，画布就再也不跟随外层容器，
表现为「改大小没反应 / 模型被裁」。所以 &lt;code&gt;applyStyles()&lt;/code&gt; 每次都显式写 &lt;code&gt;canvas.style.width/height&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;尺寸不能靠放大模型。&lt;/strong&gt; 运行时先把模型&lt;strong&gt;适配&lt;/strong&gt;到画布，&lt;code&gt;scale&lt;/code&gt; 是相对这个适配的倍率，
超过标定值的 &lt;code&gt;scale&lt;/code&gt; 只会把角色裁掉，不会让他变大。因此「大小」调&lt;strong&gt;画布&lt;/strong&gt;，「适配」调占比。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;挂载时机必须观察，不能假设。&lt;/strong&gt; DSH 启动会先往 &lt;code&gt;#root&lt;/code&gt; 画一层「Loading plugins…」，
所有插件加载完才挂 composer。所以用 &lt;strong&gt;MutationObserver 持续观察&lt;/strong&gt;（最长 5 分钟）
而不是等几秒就放弃 —— 否则冷启动慢一点就静默没有模型。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;默认值怎么来的&lt;/h3&gt;
&lt;p&gt;Live2D 模型没有统一尺寸：每个作者在自己的画布里按任意比例作画，
所以一个全局默认值不可能让所有模型都好看。&lt;code&gt;tools/calibrate.html&lt;/code&gt; 会依次加载每个模型、
读回画面像素、迭代调整 &lt;code&gt;scale&lt;/code&gt;/&lt;code&gt;position&lt;/code&gt;，直到轮廓居中且填满画布高度 ——
内置 4 个角色的默认值就是这样量出来的（目标 88% 高度，
留出 12% 余量吸收待机动作带来的轮廓抖动）。&lt;/p&gt;
&lt;h2&gt;数据与设置&lt;/h2&gt;
&lt;p&gt;都在 &lt;code&gt;%USERPROFILE%\.dsh&lt;/code&gt; 下，重装插件不丢：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;路径&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.dsh-live2d.json&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;当前模型、大小、外观、每个模型的适配与位置、每个模型的自定义台词、已导入模型清单&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;live2d-models/&amp;lt;id&amp;gt;/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;你导入的模型文件&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;权限与安全边界&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;每条自定义路由都先过 &lt;code&gt;ctx.connection.requestRejection()&lt;/code&gt;：Host/Origin 被伪造（DNS 重绑定）
或&lt;strong&gt;未认证&lt;/strong&gt;的请求一律拒绝，和官方插件同一套信任栅栏。&lt;/li&gt;
&lt;li&gt;模型文件路由做 &lt;code&gt;..&lt;/code&gt; 过滤 + &lt;code&gt;realpath&lt;/code&gt; 校验，符号链接也无法越出模型目录。&lt;/li&gt;
&lt;li&gt;导入同时限制文件数量、单文件体积与解压后总体积，防止 zip 炸弹。&lt;/li&gt;
&lt;li&gt;插件不自带沙箱：文件、Shell、sandbox 与 approval 策略完全沿用当前 DSH profile。&lt;/li&gt;
&lt;li&gt;插件不联网：运行时随包发布，模型从本地磁盘读取。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;已知限制&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;内置 4 个角色都是 &lt;strong&gt;Cubism 2&lt;/strong&gt;；Cubism 3/4/5（&lt;code&gt;*.model3.json&lt;/code&gt;）由运行时支持，可通过导入使用。&lt;/li&gt;
&lt;li&gt;「适配」超过 1 会让模型超出画布而被裁切 —— 那是这个控件的本意（给画得很小的导入模型放大用），
想要整体变大请用「大小」。&lt;/li&gt;
&lt;li&gt;面板要挤在模型上方那块空间里；空间不够时（模型很大或窗口很矮）会自动改成&lt;strong&gt;覆盖在模型上&lt;/strong&gt;显示。&lt;/li&gt;
&lt;li&gt;隐藏模型只是视觉隐藏，运行时的渲染循环仍在跑；想彻底停掉请用「隐藏模型」+ 关掉页面。&lt;/li&gt;
&lt;li&gt;音频静音：模型的待机动作若自带音效，播放音量为 0。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;常见问题&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;模型不见了 / 想找回来&lt;/strong&gt; —— 按 &lt;code&gt;Ctrl+Shift+L&lt;/code&gt;；或删掉 &lt;code&gt;.dsh-live2d.json&lt;/code&gt; 回到默认状态。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;点了模型不说话&lt;/strong&gt; —— 检查「点击台词」里的开关；台词清空后会显示占位台词「……」。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;导入报「没有找到 Live2D 模型文件」&lt;/strong&gt; —— 包里既没有 &lt;code&gt;*.model3.json&lt;/code&gt; / &lt;code&gt;*.model.json&lt;/code&gt;，
也没有任何含 &lt;code&gt;model&lt;/code&gt; + &lt;code&gt;textures&lt;/code&gt;（或 &lt;code&gt;FileReferences.Moc&lt;/code&gt;）的 json。
有些包只放了贴图和 &lt;code&gt;.moc3&lt;/code&gt;，缺模型描述文件，这种包本身不完整、任何加载器都用不了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;导入报「不支持压缩算法」/「该 zip 已加密」&lt;/strong&gt; —— 换一个未加密的普通 zip；
自带解压器支持 store 与 deflate，不支持加密和分卷包。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;模型显示成一片空白 / 提示入口文件为空&lt;/strong&gt; —— 文件在复制过程中被截断成了 0 字节。
重新复制一次模型文件即可；插件会把这类模型列进 &lt;code&gt;skipped&lt;/code&gt; 并说明原因。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;面板里少了几项&lt;/strong&gt; —— 「点击台词」和「导入自己的模型」默认折叠，点标题栏展开。&lt;/p&gt;
&lt;h2&gt;开发&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 独立调试服务：把插件挂在桩 ctx 上，用普通 HTTP 暴露（无 DSH 鉴权，方便调试）
node tools/harness.mjs 8899
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;harness 会把 &lt;code&gt;DSH_HOME&lt;/code&gt; 指到自己的临时目录（&lt;code&gt;$env:TEMP\dsh-live2d-harness-home&lt;/code&gt;），
&lt;strong&gt;不会读写你在用的 DSH 的设置&lt;/strong&gt;；需要时可用 &lt;code&gt;DSH_HARNESS_HOME&lt;/code&gt; 覆盖。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;URL&lt;/th&gt;
&lt;th&gt;用途&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;http://127.0.0.1:8899/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;模拟聊天页，看挂件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;?panel=1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;自动展开控制面板&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;?speak=1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;持续显示气泡（方便截图）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;?ce=1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;用 &lt;code&gt;contenteditable&lt;/code&gt; 当输入框（DSH 真实形态）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;?boot=1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;先显示 9 秒启动遮罩，再出现输入框（验证挂载门限）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;?diag=1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;量化自检：画布尺寸、模型实际绘制尺寸、拖动、气泡、数值控件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/tools/calibrate.html&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;为新模型标定默认 &lt;code&gt;scale&lt;/code&gt; / &lt;code&gt;position&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;改 &lt;code&gt;assets/live2d-widget.js&lt;/code&gt; 后直接刷新页面即可；改 &lt;code&gt;lib/index.js&lt;/code&gt; 需要重载插件。&lt;/p&gt;
&lt;h2&gt;目录结构&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;dsh-live2d-widget/
├── cordis.patch.yml          # bundle 挂载声明
├── package.json              # dsh.bundle.patch 指向 cordis.patch.yml
├── lib/
│   ├── index.js              # Host 半：路由、模型注册表、导入、设置持久化
│   └── zip.mjs               # 零依赖 zip 解压（store + deflate + Zip64 + GBK 文件名）
├── assets/
│   ├── live2d-widget.js      # Browser 半：渲染 + 气泡 + 控制面板 + 导入 UI
│   ├── vendor/l2d.min.js     # Live2D 运行时（Cubism 2 &amp;amp; 6 内置，单文件自足）
│   └── models/&amp;lt;id&amp;gt;/          # 内置模型
├── docs/                     # 截图与 README 素材
└── tools/                    # 开发用，不随包发布
    ├── harness.mjs
    └── calibrate.html
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;致谢&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Live2D 运行时&lt;/strong&gt;：&lt;a href=&quot;https://github.com/hacxy/l2d&quot;&gt;&lt;code&gt;l2d&lt;/code&gt;&lt;/a&gt;（MIT），基于 Live2D 官方 Cubism SDK 二次封装，
vendored 在 &lt;code&gt;assets/vendor/l2d.min.js&lt;/code&gt;，同时保留其 LICENSE 与 README 便于追溯。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;形态与注入方式&lt;/strong&gt;参考了 &lt;a href=&quot;https://github.com/hacxy/l2d-widget&quot;&gt;hacxy/l2d-widget&lt;/a&gt; 与
&lt;a href=&quot;https://github.com/MeteorNOX/DeepSeek-Balance-Whale-Widget&quot;&gt;MeteorNOX/DeepSeek-Balance-Whale-Widget&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;模型资源&lt;/strong&gt;取自 &lt;a href=&quot;https://github.com/Eikanya/Live2d-model&quot;&gt;Eikanya/Live2d-model&lt;/a&gt;，
著作权归各自权利人。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cubism SDK 的使用须遵守
&lt;a href=&quot;https://www.live2d.com/eula/live2d-proprietary-software-license-agreement_en.html&quot;&gt;Live2D Proprietary Software License&lt;/a&gt;。
商业用途请自行确认是否需要向 Live2D Inc. 申请许可。&lt;/p&gt;
&lt;h2&gt;License&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;LICENSE&quot;&gt;MIT&lt;/a&gt;（插件代码）。内置模型与 Cubism SDK 的授权见上文「致谢」与 &lt;a href=&quot;LICENSE&quot;&gt;LICENSE&lt;/a&gt;。&lt;/p&gt;
</content:encoded></item><item><title>博客更新日志：给页脚加上 CC 许可声明</title><link>https://007912.xyz/posts/cc-license/</link><guid isPermaLink="true">https://007912.xyz/posts/cc-license/</guid><description>页脚多了一行 CC BY-NC-SA 4.0 声明 —— 协议怎么选、代码写在哪、以及暗色模式下图标看不见的两个坑</description><pubDate>Sun, 27 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;div class=&quot;badge-row&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.shields.io/badge/qq-234259867-blue?logo=qq&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/github-xieluyang912-orange?logo=github&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/pnpm-%3E%3D9-green?logo=pnpm&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/nodedotjs-%3E%3D20-red?logo=nodedotjs&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/%E6%94%AF%E6%8C%81%E5%BA%93-astro-yellow?logo=astro&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/%E8%AE%B8%E5%8F%AF%E8%AF%81-CC%20BY--NC--SA%204.0-lightgrey&quot; alt=&quot;Static Badge&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;页脚现在多了一行版权声明：本站内容采用 &lt;strong&gt;CC BY-NC-SA 4.0&lt;/strong&gt; 协议授权，后面跟着四个官方图标。&lt;/p&gt;
&lt;p&gt;这篇文章记录三件事：为什么选这个协议、代码写在哪个文件、以及实现时踩到的两个坑。&lt;/p&gt;
&lt;h1&gt;声明长什么样&lt;/h1&gt;
&lt;p&gt;页脚最下面那行就是，结构是标准的 CC 署名格式：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;xieluyang&apos; blog&lt;/strong&gt; © 2026 by &lt;strong&gt;xieluayng&lt;/strong&gt; is licensed under &lt;strong&gt;Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International&lt;/strong&gt; [cc] [by] [nc] [sa]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这是 Creative Commons 官方推荐的排版方式，由五段组成：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;部分&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;th&gt;作用&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;作品名&lt;/td&gt;
&lt;td&gt;xieluyang&apos; blog&lt;/td&gt;
&lt;td&gt;哪件作品被授权&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;年份&lt;/td&gt;
&lt;td&gt;2026&lt;/td&gt;
&lt;td&gt;版权起始年份&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;作者&lt;/td&gt;
&lt;td&gt;xieluayng&lt;/td&gt;
&lt;td&gt;版权归谁&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;协议名&lt;/td&gt;
&lt;td&gt;CC BY-NC-SA 4.0&lt;/td&gt;
&lt;td&gt;用哪个协议&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;协议图标&lt;/td&gt;
&lt;td&gt;cc / by / nc / sa&lt;/td&gt;
&lt;td&gt;协议条款的可视化缩写&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1&gt;为什么是 CC BY-NC-SA 4.0&lt;/h1&gt;
&lt;p&gt;Creative Commons 的协议是「模块拼装」出来的，四个模块两两组合，得到六种常用协议。本站选的这三个模块是：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;缩写&lt;/th&gt;
&lt;th&gt;全称&lt;/th&gt;
&lt;th&gt;含义&lt;/th&gt;
&lt;th&gt;本站&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;BY&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Attribution&lt;/td&gt;
&lt;td&gt;转载必须署名原作者&lt;/td&gt;
&lt;td&gt;✅ 保留&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NC&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;NonCommercial&lt;/td&gt;
&lt;td&gt;不得用于商业用途&lt;/td&gt;
&lt;td&gt;✅ 保留&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SA&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ShareAlike&lt;/td&gt;
&lt;td&gt;衍生作品必须用同样的协议&lt;/td&gt;
&lt;td&gt;✅ 保留&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ND&lt;/td&gt;
&lt;td&gt;NoDerivatives&lt;/td&gt;
&lt;td&gt;不允许修改后发布&lt;/td&gt;
&lt;td&gt;❌ 未选&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;四个模块里只有一个没选：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;没选 ND&lt;/strong&gt;：ND 禁止修改。但博客文章被摘录、被翻译、被节选，绝大多数情况下是合理的引用行为，一刀切禁掉反而拦住了正常的传播。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:::note[SA 到底约束了什么]
SA（ShareAlike，相同方式共享）的要求是：&lt;strong&gt;你可以改我的文章再发，但发出来的那一版也必须用 CC BY-NC-SA 4.0 授权&lt;/strong&gt; —— 不能换成一个更宽松的协议，更不能闭源。&lt;/p&gt;
&lt;p&gt;它只沿着「衍生作品」这条线往下传：只做引用、不产生新作品的读者，感受不到任何额外负担。
:::&lt;/p&gt;
&lt;p&gt;:::note[这一行最初不是这个协议]
页脚第一版写的是 &lt;strong&gt;CC BY-NC 4.0&lt;/strong&gt;（少了 SA），后来才补成现在的 BY-NC-SA 4.0。多出来的 SA 只在「有人把文章改一改再发布」这个场景下起作用 —— 换来的是衍生内容不会跑出这套协议之外。&lt;/p&gt;
&lt;p&gt;改的时候协议名、链接、图标&lt;strong&gt;三处都要动&lt;/strong&gt;，具体见下面「换协议时最容易漏的一处」。
:::&lt;/p&gt;
&lt;p&gt;所以这个组合的含义可以一句话概括：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;欢迎转载和引用，署名就行，别拿去做生意，改了再发也请继续用同样的协议。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;它管不着什么&lt;/h2&gt;
&lt;p&gt;有两点必须说清楚，否则这行声明容易给人错误的预期：&lt;/p&gt;
&lt;p&gt;:::warning[CC 协议不覆盖代码]
文章里的代码片段，严格来说不属于「文学艺术作品」，CC 协议对它并不是最合适的授权工具。正经做法是代码用 MIT 或 Apache 之类的&lt;strong&gt;软件协议&lt;/strong&gt;单独声明 —— 本站代码本来就是从 &lt;a href=&quot;https://github.com/saicaca/fuwari&quot;&gt;Fuwari&lt;/a&gt;（MIT）改来的，沿用原协议即可。&lt;/p&gt;
&lt;p&gt;页脚这行声明，主要覆盖的是&lt;strong&gt;文章正文&lt;/strong&gt;。
:::&lt;/p&gt;
&lt;p&gt;:::note[NC 只约束别人，不约束自己]
「非商业性使用」限制的是&lt;strong&gt;被授权方&lt;/strong&gt;。也就是说：别人不能拿本站内容去卖钱，但我自己保留一切权利 —— 想出书、想接广告、想授权给商业机构，都不受这行声明影响。&lt;/p&gt;
&lt;p&gt;版权始终在自己手里，CC 协议是「预先给出的许可」，不是「放弃版权」。
:::&lt;/p&gt;
&lt;h1&gt;代码写在哪&lt;/h1&gt;
&lt;p&gt;全部改动集中在一个文件：&lt;a href=&quot;https://github.com/xieluyang912/fuwari/blob/main/src/components/Footer.astro&quot;&gt;&lt;code&gt;src/components/Footer.astro&lt;/code&gt;&lt;/a&gt; 的第 21–31 行，也就是原来 &quot;Powered by Astro &amp;amp; Fuwari&quot; 那行的&lt;strong&gt;下面&lt;/strong&gt;、同一个圆角容器&lt;strong&gt;内部&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;新增的是一个和上面那行同样式的 &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;transition text-50 text-sm text-center mt-2&quot;&amp;gt;
    &amp;lt;a class=&quot;transition link text-[var(--primary)] font-medium&quot; target=&quot;_blank&quot;
       href=&quot;https://007912.xyz/&quot;&amp;gt;xieluyang&apos; blog&amp;lt;/a&amp;gt;
    &amp;amp;copy; {currentYear} by
    &amp;lt;a class=&quot;transition link text-[var(--primary)] font-medium&quot; target=&quot;_blank&quot;
       href=&quot;https://github.com/xieluyang912&quot;&amp;gt;xieluayng&amp;lt;/a&amp;gt;
    is licensed under
    &amp;lt;a class=&quot;transition link text-[var(--primary)] font-medium&quot; target=&quot;_blank&quot;
       href=&quot;https://creativecommons.org/licenses/by-nc-sa/4.0/&quot;&amp;gt;Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International&amp;lt;/a&amp;gt;
    &amp;lt;img class=&quot;dark:invert&quot; src=&quot;https://mirrors.creativecommons.org/presskit/icons/cc.svg&quot; alt=&quot;&quot; style=&quot;...&quot;&amp;gt;
    &amp;lt;img class=&quot;dark:invert&quot; src=&quot;https://mirrors.creativecommons.org/presskit/icons/by.svg&quot; alt=&quot;&quot; style=&quot;...&quot;&amp;gt;
    &amp;lt;img class=&quot;dark:invert&quot; src=&quot;https://mirrors.creativecommons.org/presskit/icons/nc.svg&quot; alt=&quot;&quot; style=&quot;...&quot;&amp;gt;
    &amp;lt;img class=&quot;dark:invert&quot; src=&quot;https://mirrors.creativecommons.org/presskit/icons/sa.svg&quot; alt=&quot;&quot; style=&quot;...&quot;&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;几个设计上的选择：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;类名照抄上面那一行&lt;/strong&gt;（&lt;code&gt;text-50 text-sm text-center&lt;/code&gt;），视觉上两行才是同一套语言，字号颜色自动跟着主题变量走。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;mt-2&lt;/code&gt;&lt;/strong&gt; 拉开和 &quot;Powered by&quot; 的间距，否则两行贴在一起像一句话。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;年份用 &lt;code&gt;{currentYear}&lt;/code&gt; 而不是写死 &lt;code&gt;2026&lt;/code&gt;&lt;/strong&gt;：文件顶部本来就有一行 &lt;code&gt;const currentYear = new Date().getFullYear()&lt;/code&gt;，上面版权行也用它。跟着用，以后不用每年手动改。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:::note[关于 id=&quot;license-year&quot;]
初版我给年份 span 加了个 &lt;code&gt;id=&quot;license-year&quot;&lt;/code&gt;，想的是以后用 JS 更新。但翻了一遍源码，全站&lt;strong&gt;没有任何脚本&lt;/strong&gt;引用它 —— 上面那行的 &lt;code&gt;id=&quot;copyright-year&quot;&lt;/code&gt; 同样是个没人用的空壳，年份其实是构建时就算好的。&lt;/p&gt;
&lt;p&gt;既然是静态构建，直接写 &lt;code&gt;{currentYear}&lt;/code&gt; 就够了，多出来的 id 只是噪音，已删。
:::&lt;/p&gt;
&lt;h1&gt;两个必须处理的细节&lt;/h1&gt;
&lt;p&gt;直接照抄官方给的 HTML 片段，会坏在两点上：&lt;/p&gt;
&lt;h2&gt;1. 暗色模式下图标会消失&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;mirrors.creativecommons.org&lt;/code&gt; 上的这几个图标是&lt;strong&gt;纯黑色&lt;/strong&gt;的 SVG。&lt;/p&gt;
&lt;p&gt;本站有暗色主题，页脚在暗色下背景接近黑 —— 黑图标放在黑底上，等于没有。这不是「有点淡」，是彻底看不见。&lt;/p&gt;
&lt;p&gt;解决办法是 Tailwind 的 &lt;code&gt;invert&lt;/code&gt; 工具类，配合本站的暗色变体：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;img class=&quot;dark:invert&quot; src=&quot;...cc.svg&quot; ...&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;dark:invert&lt;/code&gt; 只在 &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; 挂上 &lt;code&gt;dark&lt;/code&gt; 类时生效，把黑色反成白色。浅色模式下原样不动。&lt;/p&gt;
&lt;h2&gt;2. 图标会比文字低一截&lt;/h2&gt;
&lt;p&gt;官方片段只给了 &lt;code&gt;max-width&lt;/code&gt; 和 &lt;code&gt;max-height&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;style=&quot;max-width: 1em;max-height:1em;margin-left: .2em;&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; 默认是 &lt;code&gt;display: inline&lt;/code&gt;，参与文字基线对齐 —— 图标的&lt;strong&gt;底边&lt;/strong&gt;会对齐到文字基线，视觉上就是整体往下沉了一截，和旁边的字不在一条线上。&lt;/p&gt;
&lt;p&gt;补两个属性即可：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;display:inline-block; vertical-align:middle;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::warning[这两个坑不止 CC 图标会遇到]
&lt;strong&gt;远程 SVG 图标 + 有暗色主题 + 行内跟随文字&lt;/strong&gt; —— 这个组合都会翻车。以后往正文或页脚塞任何外部图标，先检查这两点。
:::&lt;/p&gt;
&lt;h1&gt;图标从哪来&lt;/h1&gt;
&lt;p&gt;四个图标走的是 Creative Commons 官方的 presskit 镜像，这是 CC 官方提供的标准素材地址：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://mirrors.creativecommons.org/presskit/icons/cc.svg   # CC 标志
https://mirrors.creativecommons.org/presskit/icons/by.svg   # 署名
https://mirrors.creativecommons.org/presskit/icons/nc.svg   # 非商业
https://mirrors.creativecommons.org/presskit/icons/sa.svg   # 相同方式共享
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;用哪个协议就挂哪几个图标。本站的 BY-NC-SA 是 &lt;strong&gt;cc + by + nc + sa 四个&lt;/strong&gt;；换成 BY-SA 就少一个 &lt;code&gt;nc&lt;/code&gt;，换成 CC0 只挂 &lt;code&gt;cc.svg&lt;/code&gt; 和 &lt;code&gt;zero.svg&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;另外推荐在页面里也放上协议全文的链接（就是那行 &quot;Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International&quot; 上的超链接），指向 &lt;code&gt;https://creativecommons.org/licenses/by-nc-sa/4.0/&lt;/code&gt;。CC 官方建议&lt;strong&gt;图标 + 协议名 + 链接&lt;/strong&gt;三者齐全，只放图标容易被误解成别的协议。&lt;/p&gt;
&lt;p&gt;:::note[图标是远程加载的]
和&lt;a href=&quot;/posts/badge&quot;&gt;徽章那篇&lt;/a&gt;里说的一样：这些 SVG 是&lt;strong&gt;访客浏览器直接向 mirrors.creativecommons.org 请求&lt;/strong&gt;的，构建时不会下载。&lt;/p&gt;
&lt;p&gt;好处是离线也能构建成功；代价是网络不通时那三个位置会空着 —— 因为 &lt;code&gt;alt=&quot;&quot;&lt;/code&gt;，连替代文字都没有。这是刻意的：图标只是协议名的视觉补充，旁边的文字已经把授权说清楚了，图标缺失不影响法律效力。
:::&lt;/p&gt;
&lt;h1&gt;以后要改什么&lt;/h1&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;想改&lt;/th&gt;
&lt;th&gt;改哪里&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;换协议&lt;/td&gt;
&lt;td&gt;改协议名文字、链接地址、图标文件名（三处都要动）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;改署名&lt;/td&gt;
&lt;td&gt;改 &quot;xieluayng&quot; 那几个字和它指向的链接&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;改年份&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;不用改&lt;/strong&gt;，&lt;code&gt;{currentYear}&lt;/code&gt; 每年自动更新&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;改博客名&lt;/td&gt;
&lt;td&gt;改 &quot;xieluyang&apos; blog&quot; 和它指向的链接&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;整行删掉&lt;/td&gt;
&lt;td&gt;删 &lt;code&gt;Footer.astro&lt;/code&gt; 第 21–31 行那个 &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;，其余不动&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;:::warning[换协议时最容易漏的一处]
四个图标是&lt;strong&gt;手写的四个 &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt;&lt;/strong&gt;，不是循环生成的。从 BY-NC-SA 换成 BY-SA 时，很容易只改协议名和链接、忘了删掉那行 &lt;code&gt;nc.svg&lt;/code&gt; —— 结果文字写的是 BY-SA，图标里却还挂着 NC，两者矛盾。&lt;/p&gt;
&lt;p&gt;协议名、链接、图标，&lt;strong&gt;三处必须一致&lt;/strong&gt;。
:::&lt;/p&gt;
&lt;h1&gt;这行声明没能覆盖的&lt;/h1&gt;
&lt;p&gt;写在这里免得以后自己忘了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;代码片段&lt;/strong&gt;：如前所述，CC 对代码不是合适的工具，本站代码实际跟着上游 Fuwari 走 MIT。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;封面图和正文配图&lt;/strong&gt;：本站图片多来自 Pexels 等免费图库。&lt;strong&gt;图库图片的版权不在我手里&lt;/strong&gt;，我无权把它们纳入 CC BY-NC-SA 授权。如果将来有人完整转载文章，图片的授权问题需要单独说明。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;访客评论&lt;/strong&gt;：评论存在 GitHub Discussions，版权归评论者本人。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以更准确的说法是：&lt;strong&gt;这行声明覆盖的是「除特别注明外」的原创文章正文&lt;/strong&gt;。&lt;/p&gt;
&lt;h1&gt;加许可声明的检查清单&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;[ ] 协议选好了：BY 必选，NC / SA / ND 按需组合&lt;/li&gt;
&lt;li&gt;[ ] 协议名、链接地址、图标文件&lt;strong&gt;三者一致&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;[ ] 图标加了 &lt;code&gt;dark:invert&lt;/code&gt;（有暗色主题的话）&lt;/li&gt;
&lt;li&gt;[ ] 图标加了 &lt;code&gt;display:inline-block; vertical-align:middle;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;[ ] 年份用 &lt;code&gt;{currentYear}&lt;/code&gt;，别写死&lt;/li&gt;
&lt;li&gt;[ ] 署名和链接指向的是自己&lt;/li&gt;
&lt;li&gt;[ ] 想清楚这行声明的&lt;strong&gt;边界&lt;/strong&gt;：代码？配图？评论？&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>博客更新日志：文章顶部的徽章标签怎么用</title><link>https://007912.xyz/posts/badge/</link><guid isPermaLink="true">https://007912.xyz/posts/badge/</guid><description>badge-row + shields.io 静态徽章：地址怎么拼、中文怎么转义、颜色怎么选</description><pubDate>Sun, 27 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;div class=&quot;badge-row&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.shields.io/badge/%E7%B1%BB%E5%9E%8B-%E7%AC%94%E8%AE%B0-blue&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/%E4%B8%BB%E9%A2%98-shields.io-green?logo=shieldsdotio&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/%E5%BD%92%E5%B1%9E-%E7%BD%91%E7%AB%99%E7%BB%B4%E6%8A%A4-orange&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/markdown-%E9%9D%99%E6%80%81%E6%B8%B2%E6%9F%93-blue?logo=markdown&quot; alt=&quot;Static Badge&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;上面这一排就是这篇笔记要讲的东西。它出现在本站大多数文章的正文最前面，作用是在读者还没开始读之前，先把「讲的是什么、属于哪个方向、用什么做的」交代完。&lt;/p&gt;
&lt;p&gt;以后给新文章加一排，照抄下面的模板改文字就行。本文记录它的三个组成部分、地址怎么拼、本站的配色约定，以及几个踩过的坑。&lt;/p&gt;
&lt;h1&gt;其实是三样东西拼起来的&lt;/h1&gt;
&lt;p&gt;一排徽章由三个部件组成，缺一个都不成立：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;部件&lt;/th&gt;
&lt;th&gt;位置&lt;/th&gt;
&lt;th&gt;作用&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;徽章图片&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://img.shields.io/badge/...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;真正的「标签」，由 shields.io 按 URL 现场生成 SVG&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;容器&lt;/td&gt;
&lt;td&gt;Markdown 里的 &lt;code&gt;&amp;lt;div class=&quot;badge-row&quot;&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;把这一排圈起来，交给下面的 CSS 排版&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;样式&lt;/td&gt;
&lt;td&gt;&lt;code&gt;src/layouts/Layout.astro&lt;/code&gt; 的 &lt;code&gt;&amp;lt;style is:global&amp;gt;&lt;/code&gt;（约 197–211 行）&lt;/td&gt;
&lt;td&gt;排成一行、放不下自动折行、清零图片外边距&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;:::note[为什么样式写在 Layout.astro 里]
Markdown 正文是构建时才拼进页面的，Astro 的组件级 scoped 样式管不到它，所以 &lt;code&gt;.badge-row&lt;/code&gt; 的规则必须放在 &lt;code&gt;&amp;lt;style is:global&amp;gt;&lt;/code&gt; 里。反过来说：&lt;strong&gt;改那一小段会影响全站所有文章的徽章&lt;/strong&gt;，动手前先想清楚。
:::&lt;/p&gt;
&lt;h1&gt;最小可用示例&lt;/h1&gt;
&lt;p&gt;把下面这段贴进文章正文就能用：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;badge-row&quot;&amp;gt;

![Static Badge](https://img.shields.io/badge/qq-234259867-blue?logo=qq)
![Static Badge](https://img.shields.io/badge/github-xieluyang912-orange?logo=github)
![Static Badge](https://img.shields.io/badge/pnpm-%3E%3D9-green?logo=pnpm)

&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;渲染出来是这样：&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;badge-row&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.shields.io/badge/qq-234259867-blue?logo=qq&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/github-xieluyang912-orange?logo=github&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/pnpm-%3E%3D9-green?logo=pnpm&quot; alt=&quot;Static Badge&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;h1&gt;shields.io 的地址怎么拼&lt;/h1&gt;
&lt;p&gt;固定格式是三段，用 &lt;code&gt;-&lt;/code&gt; 连接：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://img.shields.io/badge/&amp;lt;标签&amp;gt;-&amp;lt;内容&amp;gt;-&amp;lt;颜色&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;标签&lt;/strong&gt;（左半，可选）：这一枚在说什么，例如 &lt;code&gt;pnpm&lt;/code&gt;、&lt;code&gt;项目&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;内容&lt;/strong&gt;（右半）：具体值，例如 &lt;code&gt;&amp;gt;=9&lt;/code&gt;、&lt;code&gt;大创&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;颜色&lt;/strong&gt;：命名色或十六进制，控制右半的背景色&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;只有「内容 + 颜色」也合法，会渲染成单段徽章，例如 &lt;code&gt;https://img.shields.io/badge/just%20the%20message-8A2BE2&lt;/code&gt;。&lt;/p&gt;
&lt;h2&gt;转义规则（最容易出错的地方）&lt;/h2&gt;
&lt;p&gt;因为 &lt;code&gt;-&lt;/code&gt; 被用来分隔字段，所以文字里的特殊字符必须先转义：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;想显示&lt;/th&gt;
&lt;th&gt;要写成&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;空格&lt;/td&gt;
&lt;td&gt;&lt;code&gt;_&lt;/code&gt; 或 &lt;code&gt;%20&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;两种都认，&lt;code&gt;%20&lt;/code&gt; 更不容易和下面的规则打架&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;下划线 &lt;code&gt;_&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;__&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;单个 &lt;code&gt;_&lt;/code&gt; 会被当成空格&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;连字符 &lt;code&gt;-&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;单个 &lt;code&gt;-&lt;/code&gt; 是字段分隔符&lt;/strong&gt;，直接写会被拆开&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;中文&lt;/td&gt;
&lt;td&gt;百分号编码&lt;/td&gt;
&lt;td&gt;例如 &lt;code&gt;支持库&lt;/code&gt; → &lt;code&gt;%E6%94%AF%E6%8C%81%E5%BA%93&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;#&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;%23&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;十六进制颜色必须这么写，否则会被当成页内锚点&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;%&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;%25&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;例如 &lt;code&gt;95%&lt;/code&gt; → &lt;code&gt;95%25&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;%2F&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;路径里直接写 &lt;code&gt;/&lt;/code&gt; 会被当成新的路径段&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;连字符这条最坑，看对比（上面是直接写，下面是转义后）：&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;badge-row&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.shields.io/badge/claude-code-orange?logo=claude&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/claude--code-orange?logo=claude&quot; alt=&quot;Static Badge&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;claude-code-orange&lt;/code&gt; 会被拆成「标签 claude + 内容 code + 颜色 orange」三段，想显示 &lt;code&gt;claude-code&lt;/code&gt; 必须写成 &lt;code&gt;claude--code&lt;/code&gt;。&lt;/p&gt;
&lt;h2&gt;可选参数&lt;/h2&gt;
&lt;p&gt;在地址后面用 &lt;code&gt;?&lt;/code&gt; 接查询参数，多个用 &lt;code&gt;&amp;amp;&lt;/code&gt; 连接：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;参数&lt;/th&gt;
&lt;th&gt;作用&lt;/th&gt;
&lt;th&gt;例子&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;style&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;徽章形状&lt;/td&gt;
&lt;td&gt;&lt;code&gt;?style=flat-square&lt;/code&gt;（还有 &lt;code&gt;plastic&lt;/code&gt;、&lt;code&gt;for-the-badge&lt;/code&gt;、&lt;code&gt;social&lt;/code&gt;，默认 &lt;code&gt;flat&lt;/code&gt;）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;logo&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;左侧图标，填 simple-icons 的 slug&lt;/td&gt;
&lt;td&gt;&lt;code&gt;?logo=astro&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;logoColor&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;图标颜色&lt;/td&gt;
&lt;td&gt;&lt;code&gt;?logoColor=white&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;labelColor&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;左半部分的背景色&lt;/td&gt;
&lt;td&gt;&lt;code&gt;?labelColor=grey&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;label&lt;/code&gt; / &lt;code&gt;color&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;覆盖路径里写的标签 / 颜色&lt;/td&gt;
&lt;td&gt;&lt;code&gt;?label=healthiness&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;link&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;给左右两半分别挂链接，&lt;strong&gt;只在 &lt;code&gt;&amp;lt;object&amp;gt;&lt;/code&gt; 标签里生效&lt;/strong&gt;，&lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; 无效&lt;/td&gt;
&lt;td&gt;——&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;想让徽章可以点击跳转，别指望 &lt;code&gt;link&lt;/code&gt;，用 Markdown 链接把图片包起来即可：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[![Static Badge](https://img.shields.io/badge/qq-234259867-blue?logo=qq)](https://qm.qq.com/q/xxxxxx)
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;本站的配色约定&lt;/h1&gt;
&lt;p&gt;颜色不是随便挑的，同一含义尽量用同一个颜色，翻文章时才有一致的观感：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;颜色&lt;/th&gt;
&lt;th&gt;本站用途&lt;/th&gt;
&lt;th&gt;现有例子&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;blue&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;身份、账号、归属&lt;/td&gt;
&lt;td&gt;&lt;code&gt;qq&lt;/code&gt;、&lt;code&gt;github&lt;/code&gt;、&lt;code&gt;steam&lt;/code&gt;、&lt;code&gt;zotero&lt;/code&gt;、&lt;code&gt;归属-网站维护&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;green&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;工具链、技术、版本&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pnpm&lt;/code&gt;、&lt;code&gt;nodedotjs&lt;/code&gt;、&lt;code&gt;支持库-astro&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;orange&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;项目、主题、场景&lt;/td&gt;
&lt;td&gt;&lt;code&gt;项目-大创&lt;/code&gt;、&lt;code&gt;场次-2026.09.26 苏州&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;red&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;关键值或强调&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nodedotjs &amp;gt;=20&lt;/code&gt;、&lt;code&gt;歌手-黄霄雲&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;yellow&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;不刺眼的点缀&lt;/td&gt;
&lt;td&gt;&lt;code&gt;counterstrike&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lightgrey&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;草稿、占位、说明&lt;/td&gt;
&lt;td&gt;&lt;code&gt;状态-草稿&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;可用的颜色有两类：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;shields 自带的命名色&lt;/strong&gt;：&lt;code&gt;brightgreen&lt;/code&gt;、&lt;code&gt;green&lt;/code&gt;、&lt;code&gt;yellow&lt;/code&gt;、&lt;code&gt;yellowgreen&lt;/code&gt;、&lt;code&gt;orange&lt;/code&gt;、&lt;code&gt;red&lt;/code&gt;、&lt;code&gt;blue&lt;/code&gt;、&lt;code&gt;grey&lt;/code&gt;、&lt;code&gt;lightgrey&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;任意 CSS 颜色&lt;/strong&gt;：&lt;code&gt;purple&lt;/code&gt;、&lt;code&gt;pink&lt;/code&gt; 这类颜色名，或十六进制（注意 &lt;code&gt;#&lt;/code&gt; 要写成 &lt;code&gt;%23&lt;/code&gt;，例如 &lt;code&gt;%23ff69b4&lt;/code&gt;）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:::warning[颜色名拼错不会报错]
写错颜色名时 shields 不会提示，而是&lt;strong&gt;静默回退成默认的亮绿 &lt;code&gt;brightgreen&lt;/code&gt;&lt;/strong&gt;。本站早期几排徽章里的「支持库-astro」写的是 &lt;code&gt;yello&lt;/code&gt;（少了一个 w），渲染出来一直是绿色而不是黄色 —— 这次一并改成了 &lt;code&gt;yellow&lt;/code&gt;。同理，&lt;code&gt;logo&lt;/code&gt; 的 slug 写错也不报错，只是图标不显示。
:::&lt;/p&gt;
&lt;h1&gt;图标从哪来&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;logo&lt;/code&gt; 参数的值是 &lt;a href=&quot;https://simpleicons.org&quot;&gt;simple-icons&lt;/a&gt; 的 slug：打开官网点图标标题就能复制，或者直接查仓库里的 &lt;code&gt;slugs.md&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;不确定某个 slug 存不存在，可以先探活：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://cdn.simpleicons.org/&amp;lt;slug&amp;gt;     # 200 = 有，404 = 没有
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;本站用到的几个：&lt;code&gt;qq&lt;/code&gt;、&lt;code&gt;wechat&lt;/code&gt;、&lt;code&gt;github&lt;/code&gt;、&lt;code&gt;steam&lt;/code&gt;、&lt;code&gt;zotero&lt;/code&gt;、&lt;code&gt;applemusic&lt;/code&gt;、&lt;code&gt;counterstrike&lt;/code&gt;、&lt;code&gt;ea&lt;/code&gt;、&lt;code&gt;500px&lt;/code&gt;、&lt;code&gt;ubisoft&lt;/code&gt;、&lt;code&gt;pnpm&lt;/code&gt;、&lt;code&gt;nodedotjs&lt;/code&gt;、&lt;code&gt;astro&lt;/code&gt;、&lt;code&gt;markdown&lt;/code&gt;、&lt;code&gt;pubmed&lt;/code&gt;、&lt;code&gt;claude&lt;/code&gt;、&lt;code&gt;deepseek&lt;/code&gt;、&lt;code&gt;shieldsdotio&lt;/code&gt;。&lt;/p&gt;
&lt;h1&gt;排版上的两个注意点&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;同一段落里换行，中间不要空行。&lt;/strong&gt; Markdown 里连续几行属于同一个 &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt;，&lt;code&gt;.badge-row &amp;gt; p&lt;/code&gt; 才能把它们排成一行；中间插了空行就会被拆成多个 &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt;，一个 &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; 占一行。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; 标签那两行留空行没问题&lt;/strong&gt;，本站惯例是 &lt;code&gt;&amp;lt;div class=&quot;badge-row&quot;&amp;gt;&lt;/code&gt; 后空一行、徽章写在一起、再空一行写 &lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;至于为什么必须套 &lt;code&gt;badge-row&lt;/code&gt;：prose 默认给图片上下各 2em 外边距，一排徽章直接写会被撑出很大的空隙；&lt;code&gt;badge-row&lt;/code&gt; 把 margin 清零，改用 &lt;code&gt;gap&lt;/code&gt; 统一控制行内与行间距，窗口变窄时自动折行。&lt;/p&gt;
&lt;h1&gt;中文一键转义&lt;/h1&gt;
&lt;p&gt;手抄百分号编码太容易错，直接用现成的函数：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# PowerShell：得到 %E6%94%AF%E6%8C%81%E5%BA%93
[uri]::EscapeDataString(&apos;支持库&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Node / 浏览器控制台：同样得到 %E6%94%AF%E6%8C%81%E5%BA%93
encodeURIComponent(&apos;支持库&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;两个函数都不会转义 &lt;code&gt;-&lt;/code&gt;，所以内容里真的要写连字符时，仍然要自己补成 &lt;code&gt;--&lt;/code&gt;。&lt;/p&gt;
&lt;h1&gt;加一排徽章的检查清单&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;[ ] 先想清楚这一排要表达什么：身份？主题？版本？状态？&lt;/li&gt;
&lt;li&gt;[ ] 一行一枚徽章，中间不空行&lt;/li&gt;
&lt;li&gt;[ ] 中文和特殊字符都转义过了&lt;/li&gt;
&lt;li&gt;[ ] 颜色名是合法值（别写 &lt;code&gt;yello&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;logo&lt;/code&gt; 的 slug 用 &lt;code&gt;cdn.simpleicons.org&lt;/code&gt; 探过&lt;/li&gt;
&lt;li&gt;[ ] 整排包在 &lt;code&gt;&amp;lt;div class=&quot;badge-row&quot;&amp;gt;&lt;/code&gt; 里&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;本站现有徽章一览&lt;/h1&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;文件&lt;/th&gt;
&lt;th&gt;徽章主题&lt;/th&gt;
&lt;th&gt;数量&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;src/content/posts/hello-world.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;联系方式 + 技术栈&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;src/content/posts/beiwanglu.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;联系方式 + 技术栈 + 常用软件&lt;/td&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;src/content/posts/giscus.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;联系方式 + 技术栈&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;src/content/posts/xmjs.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;联系方式 + 技术栈 + 常用软件&lt;/td&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;src/content/spec/about.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;联系方式 + 技术栈 + 摄影 / 游戏&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;src/content/posts/1.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;大创项目：学科、人群、技术路线&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;src/content/posts/2.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;大创项目：申报书用途、方法、文献库&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;src/content/posts/huangxiaoyun-live.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;演出信息：歌手、巡演、场次、曲目&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;src/content/posts/tuki.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;图库索引：数量、用途、状态&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;后四篇原来没有徽章，是 2026-09-27 按本文的约定补上的：学习类文章用「项目 / 学科 / 人群 / 技术」这类中性字段，生活类文章用「歌手 / 巡演 / 场次 / 曲目」，草稿统一挂一枚 &lt;code&gt;状态-草稿&lt;/code&gt; 作提示。&lt;/p&gt;
&lt;h1&gt;几个坑速查&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;单个 &lt;code&gt;-&lt;/code&gt; 是字段分隔符，文字里的连字符要写 &lt;code&gt;--&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;颜色名拼错会静默变成亮绿，不报错&lt;/li&gt;
&lt;li&gt;&lt;code&gt;logo&lt;/code&gt; slug 拼错不报错，只是没有图标&lt;/li&gt;
&lt;li&gt;徽章是&lt;strong&gt;访客浏览器直接向 &lt;code&gt;img.shields.io&lt;/code&gt; 请求&lt;/strong&gt;的远程图片，构建时不会下载 —— 所以离线也能构建成功，但网络不通时页面上只剩 alt 文字&lt;/li&gt;
&lt;li&gt;图片 alt 统一写 &lt;code&gt;Static Badge&lt;/code&gt;，和 shields 官方示例保持一致，方便一眼搜出全站所有徽章&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>博客更新日志：照着 mizuki.mysqil.com 把整站版式重排了一遍</title><link>https://007912.xyz/posts/mizuki-relayout/</link><guid isPermaLink="true">https://007912.xyz/posts/mizuki-relayout/</guid><description>从参考站抠出栅格、波浪、卡片结构，逐项对齐；以及过程中踩到的几个静默失败</description><pubDate>Sun, 27 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;div class=&quot;badge-row&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.shields.io/badge/%E7%B1%BB%E5%9E%8B-%E7%AC%94%E8%AE%B0-blue&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/%E5%BD%92%E5%B1%9E-%E7%BD%91%E7%AB%99%E7%BB%B4%E6%8A%A4-orange&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/%E5%8F%82%E8%80%83%E7%AB%99-mizuki.mysqil.com-green&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/%E6%A1%86%E6%9E%B6-astro-purple?logo=astro&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/%E6%A0%B7%E5%BC%8F-tailwind%20v3-38bdf8?logo=tailwindcss&quot; alt=&quot;Static Badge&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;之前给博客加了看板娘、右侧栏统计、日历、音乐播放器这些功能，功能是齐了，但&lt;strong&gt;版式还是 Fuwari 原来的样子&lt;/strong&gt;——页面 75rem 宽、两栏、导航栏是一张不透明的卡片、文章卡片的信息挤在底部一行小字里。&lt;/p&gt;
&lt;p&gt;这次的目标很直接：照着 &lt;a href=&quot;https://mizuki.mysqil.com/&quot;&gt;https://mizuki.mysqil.com/&lt;/a&gt; 把整站的排版重做一遍。参考站是 &lt;a href=&quot;https://github.com/LyraVoid/Mizuki&quot;&gt;Mizuki&lt;/a&gt; 主题的官方演示站，和本站同源（都从 Fuwari 长出来），所以「抄」起来阻力最小。&lt;/p&gt;
&lt;p&gt;本文记录改了哪些东西、怎么确定改对了，以及几个&lt;strong&gt;不报错但静默失效&lt;/strong&gt;的坑——那几个才是真正花时间的部分。&lt;/p&gt;
&lt;h1&gt;一、先学会「量」，再动手改&lt;/h1&gt;
&lt;p&gt;照着别人的站改版式，最大的风险是「我觉得像了」。肉眼看两张截图很容易自我欺骗，所以这次全程靠数字说话，分三步。&lt;/p&gt;
&lt;h2&gt;1. 把参考站截下来&lt;/h2&gt;
&lt;p&gt;用无头 Edge 直接截图，桌面端、长图、深浅色各来一张：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;amp; &quot;C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe&quot; `
  --headless --disable-gpu --hide-scrollbars `
  --window-size=1600,1000 --virtual-time-budget=20000 `
  --screenshot=ref.png &quot;https://mizuki.mysqil.com/&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;--virtual-time-budget&lt;/code&gt; 是给页面留出执行 JS 的时间，不然截到的是骨架。&lt;/p&gt;
&lt;h2&gt;2. 从构建产物里抠数值&lt;/h2&gt;
&lt;p&gt;截图只能看出「大概多宽」，具体多少 rem 得看 CSS。参考站的样式表地址就写在 HTML 里：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 从首页 HTML 里列出所有 stylesheet
[regex]::Matches($html, &apos;&amp;lt;link rel=&quot;stylesheet&quot; href=&quot;([^&quot;]+)&quot;&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;拉下 &lt;code&gt;variables.css&lt;/code&gt; 一看，颜色变量和本站&lt;strong&gt;几乎一模一样&lt;/strong&gt;——因为两边的 &lt;code&gt;variables.styl&lt;/code&gt; 同源。真正的差异全在布局变量上：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;变量&lt;/th&gt;
&lt;th&gt;参考站&lt;/th&gt;
&lt;th&gt;本站（改之前）&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--page-width&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;90rem&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;75rem&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;单侧栏宽度&lt;/td&gt;
&lt;td&gt;&lt;code&gt;17.5rem&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;17.5rem&lt;/code&gt;（但只有一栏）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;栅格列数&lt;/td&gt;
&lt;td&gt;1 / 2 / 3 栏&lt;/td&gt;
&lt;td&gt;1 / 2 栏&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;这一步很关键：&lt;strong&gt;如果颜色本来就一致，那&quot;不像&quot;就一定出在结构和尺寸上&lt;/strong&gt;，不用去瞎调配色。&lt;/p&gt;
&lt;h2&gt;3. 写个探针页量真实宽度&lt;/h2&gt;
&lt;p&gt;CSS 里写了 &lt;code&gt;17.5rem&lt;/code&gt; 不等于页面上真的是 280px——中间可能被 grid 轨道、&lt;code&gt;max-w&lt;/code&gt;、flex 收缩改掉。所以做了一个临时页面，把各容器的 &lt;code&gt;getBoundingClientRect()&lt;/code&gt; 读出来直接画在页面上，再截图：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const w = (sel) =&amp;gt; {
  const el = document.querySelector(sel);
  const r = el.getBoundingClientRect();
  return `${Math.round(r.width)} @x${Math.round(r.left)}`;
};
probe.textContent = [
  `grid=${w(&quot;#main-grid&quot;)}`,
  `sidebar=${w(&quot;#sidebar&quot;)}`,
  `main=${w(&quot;main&quot;)}`,
  `rightSidebar=${w(&quot;#right-sidebar&quot;)}`,
].join(&quot;\n&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[这一步救了我一次]
第一次量出来的结果是 &lt;code&gt;sidebar=171 / main=845 / rightSidebar=360&lt;/code&gt;，而预期是 &lt;code&gt;280 / 816 / 280&lt;/code&gt;。三栏宽度&lt;strong&gt;全错&lt;/strong&gt;，但页面看上去&quot;还行&quot;，肉眼根本发现不了。原因见下面第三节的第一个坑。
:::&lt;/p&gt;
&lt;h1&gt;二、改了哪些地方&lt;/h1&gt;
&lt;h2&gt;页面栅格：75rem → 90rem，三栏在 1280px 出现&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;- grid-cols-[17.5rem_auto]                    /* 一直都是两栏 */
+ grid-cols-1
+ md:grid-cols-[17.5rem_minmax(0,1fr)]
+ xl:grid-cols-[17.5rem_minmax(0,1fr)_17.5rem]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;列数变化和参考站一致：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;视口宽度&lt;/th&gt;
&lt;th&gt;布局&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&amp;lt; 768px&lt;/td&gt;
&lt;td&gt;单栏：正文 → 左栏 → 右栏 → 页脚&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;≥ 768px&lt;/td&gt;
&lt;td&gt;两栏：左栏 | 正文&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;≥ 1280px&lt;/td&gt;
&lt;td&gt;三栏：左栏 | 正文 | 右栏&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;两个细节：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;正文列写成 &lt;code&gt;minmax(0, 1fr)&lt;/code&gt; 而不是 &lt;code&gt;auto&lt;/code&gt;。&lt;/strong&gt; &lt;code&gt;auto&lt;/code&gt; 轨道的下限是&quot;内容的 min-content 宽度&quot;，小屏上它经常比屏幕还宽，会把整个网格顶出去、右侧内容被裁掉。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;跨列的元素要加 &lt;code&gt;min-w-0&lt;/code&gt;。&lt;/strong&gt; 右侧栏在窄屏是 &lt;code&gt;col-span-2&lt;/code&gt; 横跨整行，不加 &lt;code&gt;min-w-0&lt;/code&gt; 的话它会按内容最小宽度去撑轨道。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;横幅底部那条波浪&lt;/h2&gt;
&lt;p&gt;这是参考站最有辨识度的东西，实现方式比想象的朴素——&lt;strong&gt;不是 mask 也不是 clip-path，就是一条 SVG 路径叠了 4 次&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;svg viewBox=&quot;0 20 150 32&quot; preserveAspectRatio=&quot;none&quot;&amp;gt;
  &amp;lt;defs&amp;gt;
    &amp;lt;path id=&quot;gentle-wave&quot;
          d=&quot;M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v48h-352z&quot; /&amp;gt;
  &amp;lt;/defs&amp;gt;
  &amp;lt;use href=&quot;#gentle-wave&quot; y=&quot;0&quot; class=&quot;opacity-25&quot; style=&quot;animation-delay:-2s; animation-duration:7s&quot; /&amp;gt;
  &amp;lt;use href=&quot;#gentle-wave&quot; y=&quot;3&quot; class=&quot;opacity-50&quot; style=&quot;animation-delay:-3s; animation-duration:10s&quot; /&amp;gt;
  &amp;lt;use href=&quot;#gentle-wave&quot; y=&quot;5&quot; class=&quot;opacity-75&quot; style=&quot;animation-delay:-4s; animation-duration:13s&quot; /&amp;gt;
  &amp;lt;use href=&quot;#gentle-wave&quot; y=&quot;7&quot; class=&quot;opacity-100&quot; style=&quot;animation-delay:-5s; animation-duration:20s&quot; /&amp;gt;
&amp;lt;/svg&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;.wave-layer {
  fill: var(--page-bg);            /* 关键：波浪的颜色就是页面底色 */
  animation: wave-move 25s cubic-bezier(.5,.5,.45,.5) infinite;
}
@keyframes wave-move {
  from { transform: translate(-90px, 0); }
  to   { transform: translate(85px, 0); }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;三个要点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;fill&lt;/code&gt; 用 &lt;code&gt;var(--page-bg)&lt;/code&gt;&lt;/strong&gt;，看起来就像页面背景从下面漫上来把横幅&quot;切&quot;掉了。换主题色、切深浅模式时波浪会自动跟着变色，一行 JS 都不用写。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;preserveAspectRatio=&quot;none&quot;&lt;/code&gt; 必须有&lt;/strong&gt;，否则波浪不会随宽度拉伸，窄屏上会缩成一团。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;4 层的差异只有 y 偏移（0/3/5/7）、不透明度（25/50/75/100）和时长（7/10/13/20 秒）&lt;/strong&gt;。时长互质、延迟取负值，波纹就不会同步，形成&quot;水在错位流动&quot;的视差感。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;首页横幅文字：不给整幅图加遮罩&lt;/h2&gt;
&lt;p&gt;参考站的横幅正中有站点大标题，但它&lt;strong&gt;没有铺一层黑色遮罩&lt;/strong&gt;（那样会把图压暗）。可读性全靠文字自己的阴影：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.banner-title    { text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.7); }
.banner-subtitle { text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.6); }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;副标题在配置里，不想要就把两个字段都留空：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;banner: {
  homeText: {
    title: &quot;Xieluyang 的小屋&quot;,
    subtitle: &quot;记录一些值得记下来的东西&quot;,
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;导航栏：顶部透明，滚动后毛玻璃&lt;/h2&gt;
&lt;p&gt;改之前它是一张不透明卡片，&lt;code&gt;!rounded-t-none&lt;/code&gt; 贴着屏幕顶端。改成和参考站一致的两态：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/* 默认：不透明卡片 */
#navbar &amp;gt; .navbar-bar {
  background-color: var(--card-bg);
  border-radius: var(--radius-large);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

/* ① 顶部：完全透明，让横幅透出来 */
#navbar[data-has-banner=&quot;true&quot;]:not(.scrolled) &amp;gt; .navbar-bar {
  background-color: transparent;
  box-shadow: none;
  border-color: transparent;
}

/* ② 滚动后：毛玻璃 */
#navbar[data-has-banner=&quot;true&quot;].scrolled &amp;gt; .navbar-bar {
  background-color: rgba(255, 255, 255, 0.55);
  backdrop-filter: blur(20px);
  border: 1px solid rgba(255, 255, 255, 0.55);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;.scrolled&lt;/code&gt; 由一段十几行的脚本控制：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const SCROLL_THRESHOLD = 50;
const syncScrolled = () =&amp;gt; {
  const top = window.scrollY || document.documentElement.scrollTop || 0;
  navbarEl.classList.toggle(&quot;scrolled&quot;, top &amp;gt; SCROLL_THRESHOLD);
};
window.addEventListener(&quot;scroll&quot;, syncScrolled, { passive: true });
syncScrolled();   // 首屏可能是带着滚动位置刷新的，先同步一次
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;阈值取 50px：一点就变卡片会显得神经质，太大又迟钝。&lt;/p&gt;
&lt;h2&gt;首页顶部的分类筛选条&lt;/h2&gt;
&lt;p&gt;参考站首页第一屏是一条独立的卡片：&lt;code&gt;🏠 | 归档 8 | 各分类&lt;/code&gt;。做成 &lt;code&gt;CategoryBar.astro&lt;/code&gt;，几个细节：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;pill 有三种状态，用属性而不是 class 控制：默认 / &lt;code&gt;:hover&lt;/code&gt; / &lt;code&gt;[data-active]&lt;/code&gt;（当前分类填充主题色）&lt;/li&gt;
&lt;li&gt;分类多的时候可以横向滚动，&lt;strong&gt;滚轮直接转成横向滚动&lt;/strong&gt;，不用按 shift&lt;/li&gt;
&lt;li&gt;两侧有 2.5rem 的渐隐遮罩，滚到头/尾会消失，提示&quot;还有更多&quot;&lt;/li&gt;
&lt;li&gt;脚本按 URL 里的 &lt;code&gt;?category=&lt;/code&gt; 高亮，并挂到 Swup 的 &lt;code&gt;page:view&lt;/code&gt; 上——本站是无刷新跳转，换页后必须重新按当前地址算一次&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;文章卡片：把&quot;底部两行小字&quot;换成图标小块&lt;/h2&gt;
&lt;p&gt;参考站的卡片信息层级很清楚：标题 → 元信息（日期 / 分类 / 字数，每项都是&quot;图标小块 + 文字&quot;）→ 摘要 → 标签 chip 行。&lt;/p&gt;
&lt;p&gt;改之前，字数和阅读时长是卡片底部一行灰色小字：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;text-sm text-black/30&quot;&amp;gt;1736 words | 9 minutes&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;现在并进 &lt;code&gt;PostMeta&lt;/code&gt;，和日期、分类排成一行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;flex items-center&quot;&amp;gt;
  &amp;lt;div class=&quot;meta-icon&quot;&amp;gt;
    &amp;lt;Icon name=&quot;material-symbols:article-outline-rounded&quot; class=&quot;text-xl&quot; /&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;span class=&quot;text-50 text-sm font-medium&quot;&amp;gt;1736 words&amp;lt;/span&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;标签单独排一行 chip（这一行 Fuwari 原本没有）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;flex flex-wrap gap-2 mt-2&quot;&amp;gt;
  &amp;lt;a href=&quot;...&quot; class=&quot;btn-regular h-6 text-xs px-2 rounded-lg active:scale-95 group/tag&quot;&amp;gt;
    &amp;lt;span class=&quot;transition-transform group-hover/tag:translate-x-0.5&quot;&amp;gt;# Markdown&amp;lt;/span&amp;gt;
  &amp;lt;/a&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;左侧栏：加公告卡，目录搬进来&lt;/h2&gt;
&lt;p&gt;参考站左栏的顺序是：个人资料 → 公告 → 标签 → 目录。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;公告卡&lt;/strong&gt;是新加的，可以关掉，关掉后记在 &lt;code&gt;localStorage&lt;/code&gt; 里：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export const announcementConfig: AnnouncementConfig = {
  enable: true,
  title: &quot;公告&quot;,
  content: &quot;欢迎来到我的小站～ 这里主要记录一些学习笔记和折腾过程。&quot;,
  link: { text: &quot;了解更多&quot;, url: &quot;/about/&quot;, external: false },
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;目录&lt;/strong&gt;从&quot;右侧浮动栏&quot;改成&quot;左栏卡片&quot;，这是迫不得已：整页 90rem + 左右各 17.5rem 侧栏之后，两边已经塞不下第四条浮动栏了（算一下：&lt;code&gt;90 + 2×18 = 126rem ≈ 2016px&lt;/code&gt; 才够）。参考站本来就是侧栏目录，正好一致。&lt;/p&gt;
&lt;p&gt;技术上有个坑：目录的 &lt;code&gt;#toc&lt;/code&gt; 是 Swup 的替换容器之一，而侧栏&lt;strong&gt;不在&lt;/strong&gt;替换容器里。最后是这样解决的——卡片外框常驻，&lt;code&gt;#toc&lt;/code&gt; 放在里面，靠 CSS 的 &lt;code&gt;:has()&lt;/code&gt; 决定显不显示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/* 默认不显示，只有 #toc 里真的渲染出了 &amp;lt;table-of-contents&amp;gt;（也就是文章页）才显示 */
.toc-widget-card { display: none; }
.toc-widget-card:has(table-of-contents) { display: block; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;用 &lt;code&gt;:has()&lt;/code&gt; 而不是在服务端判断，是因为侧栏不参与 Swup 替换——服务端算出来的显隐状态在跳页后不会更新。&lt;/p&gt;
&lt;h2&gt;卡片补一条极淡的描边&lt;/h2&gt;
&lt;p&gt;深色模式下卡片底色只比页面底色亮一档，光靠底色分层不够明显：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.enable-card-border .card-base {
  border: 1px solid var(--line-divider);      /* rgba(255,255,255,.08) */
  box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;三、五个坑（都不报错，只是静默失效）&lt;/h1&gt;
&lt;p&gt;这一节是本文的重点。下面每一条都是&quot;构建成功、页面能看、但效果是错的&quot;。&lt;/p&gt;
&lt;h2&gt;1. Tailwind 扫不到拼出来的类名 ⚠️ 最隐蔽&lt;/h2&gt;
&lt;p&gt;我图省事，把侧栏宽度抽成常量再插值：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const sidebarCol = `${SIDEBAR_WIDTH}rem`;
const mainGridClass = [
  `md:grid-cols-[${sidebarCol}_minmax(0,1fr)]`,
  `xl:grid-cols-[${sidebarCol}_minmax(0,1fr)_${sidebarCol}]`,
].join(&quot; &quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Tailwind 是靠&quot;扫描源码文本&quot;来生成 CSS 的。&lt;/strong&gt; 源码里根本不存在 &lt;code&gt;xl:grid-cols-[17.5rem_minmax(0,1fr)_17.5rem]&lt;/code&gt; 这个字符串，只有一堆 &lt;code&gt;${}&lt;/code&gt;，所以这条规则压根不会生成。&lt;/p&gt;
&lt;p&gt;后果不是报错，而是 &lt;code&gt;grid-template-columns&lt;/code&gt; 完全没生效，三个块退化成&quot;按内容自适应&quot;，实测宽度变成 &lt;code&gt;171 / 845 / 360&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;修正很简单——写死字面量：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const mainGridClass = [
  &quot;grid-cols-1&quot;,
  &quot;md:grid-cols-[17.5rem_minmax(0,1fr)]&quot;,
  sidebarConfig.enable ? &quot;xl:grid-cols-[17.5rem_minmax(0,1fr)_17.5rem]&quot; : &quot;&quot;,
].join(&quot; &quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::warning[这类坑的共同点]
&lt;strong&gt;没有报错、没有警告、构建成功、页面&quot;看起来还行&quot;。&lt;/strong&gt; 只有用探针量出 &lt;code&gt;171/845/360&lt;/code&gt; 才暴露。所以别省那一次测量。
:::&lt;/p&gt;
&lt;h2&gt;2. Astro 不转义组件 prop 里的换行&lt;/h2&gt;
&lt;p&gt;给组件传多行字符串会直接编译失败：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- ❌ 报 Unterminated string literal --&amp;gt;
&amp;lt;RightSideBar
    class=&quot;col-span-2 col-start-1 row-start-3 mb-4
           lg:row-start-2 lg:col-span-2&quot;
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;原因是 Astro 把&quot;组件 prop 的字符串&quot;原样塞进 JS 字符串字面量，且&lt;strong&gt;不转义里面的换行符&lt;/strong&gt;。普通 HTML 元素上的多行 &lt;code&gt;class&lt;/code&gt; 没这个问题（那是当 HTML 直接输出的）。&lt;/p&gt;
&lt;p&gt;修法：算好再传，或者写成一行。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- ✅ --&amp;gt;
&amp;lt;RightSideBar class={rightSideBarClass} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;3. Tailwind v3 和 v4 的断点不是一回事&lt;/h2&gt;
&lt;p&gt;参考站用 Tailwind v4，而且它的配置&lt;strong&gt;改写了断点&lt;/strong&gt;：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;前缀&lt;/th&gt;
&lt;th&gt;Tailwind v3 默认&lt;/th&gt;
&lt;th&gt;参考站（v4 + 自定义）&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;768px&lt;/td&gt;
&lt;td&gt;768px&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lg&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1024px&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1280px&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;xl&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1280px&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1920px&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;所以&lt;strong&gt;不能照抄 &lt;code&gt;lg:&lt;/code&gt; 和 &lt;code&gt;xl:&lt;/code&gt;&lt;/strong&gt;。移植时的映射关系是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;参考站的 &lt;code&gt;md:&lt;/code&gt; → 本站 &lt;code&gt;md:&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;参考站的 &lt;code&gt;lg:&lt;/code&gt; → 本站 &lt;code&gt;xl:&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;参考站的 &lt;code&gt;xl:&lt;/code&gt; → 本站 &lt;code&gt;2xl:&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一开始我差点去改 &lt;code&gt;tailwind.config.cjs&lt;/code&gt; 的 &lt;code&gt;screens&lt;/code&gt; 好让前缀一致，但那样会顺手改掉全站所有既有 &lt;code&gt;lg:&lt;/code&gt; 的含义，风险太大，最后还是老老实实逐条换算。&lt;/p&gt;
&lt;h2&gt;4. 无头浏览器不推进 CSS transition（把我骗了一次）&lt;/h2&gt;
&lt;p&gt;验证毛玻璃效果时，我用探针读出这样的结果：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;② 滚动 120px 后
  class            = &quot;z-50 onload-animation group scrolled&quot;   ← 类加上了
  background-color = rgba(0, 0, 0, 0)                          ← 却是透明的？
  backdrop-filter  = blur(0px)                                 ← 0 像素？
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;看起来像&quot;类加上了但样式没生效&quot;。实际原因是：&lt;strong&gt;无头浏览器里 CSS transition 不会推进&lt;/strong&gt;，&lt;code&gt;getComputedStyle&lt;/code&gt; 返回的是过渡的&lt;strong&gt;起始值&lt;/strong&gt;。&lt;code&gt;blur(0px)&lt;/code&gt; 正是从 &lt;code&gt;none&lt;/code&gt; 过渡到 &lt;code&gt;blur(20px)&lt;/code&gt; 的第 0 帧。&lt;/p&gt;
&lt;p&gt;验证方法是把过渡关掉再读：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bar.style.transition = &quot;none&quot;;
nav.classList.add(&quot;scrolled&quot;);
void bar.offsetHeight;        // 强制重排，让新样式立即生效
getComputedStyle(bar);        // 这时候读到的才是最终值
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;② 手动加 .scrolled（已禁用过渡）
  background-color = rgba(255, 255, 255, 0.55)      ✓
  backdrop-filter  = blur(20px)                     ✓
  border-color     = rgba(255, 255, 255, 0.55)      ✓
  box-shadow       = rgba(0,0,0,0.1) 0px 4px 16px   ✓
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;样式本来就是对的，是测量方法有问题。&lt;/p&gt;
&lt;h2&gt;5. 一个把 CSS 偷偷吞进依赖图的 glob&lt;/h2&gt;
&lt;p&gt;这个坑之前就埋着，这次重新构建时踩到了：&lt;code&gt;ImageWrapper.astro&lt;/code&gt; 里为了动态加载图片写了&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const files = import.meta.glob(&quot;../../**&quot;, { import: &quot;default&quot; });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;../../**&lt;/code&gt; 等于 &lt;code&gt;src/**&lt;/code&gt;，&lt;strong&gt;把 &lt;code&gt;src&lt;/code&gt; 下所有文件都塞进了 Vite 的依赖图&lt;/strong&gt;，包括 &lt;code&gt;src/styles/*.css&lt;/code&gt;。副作用是全局样式&quot;顺便&quot;生效了——但加载顺序不可控，Tailwind 处理 &lt;code&gt;@apply&lt;/code&gt; 时偶尔会报 &lt;code&gt;The &apos;link&apos; class does not exist&lt;/code&gt;，构建随机失败（大约 5 次里挂 1 次）。&lt;/p&gt;
&lt;p&gt;修法两步：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;把这个 glob 限定成图片后缀，它本来也只该管图片&lt;/li&gt;
&lt;li&gt;全局样式改成在 &lt;code&gt;Layout.astro&lt;/code&gt; 里显式 &lt;code&gt;import&lt;/code&gt;，顺序写死（变量 → 公共类 → 各样式文件）&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;import &quot;../styles/variables.styl&quot;;
import &quot;../styles/main.css&quot;;
import &quot;../styles/markdown.css&quot;;
// ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;顺带还把跨文件的 &lt;code&gt;@apply&lt;/code&gt; 展开了（&lt;code&gt;markdown.css&lt;/code&gt; 里 &lt;code&gt;@apply link&lt;/code&gt; 依赖 &lt;code&gt;main.css&lt;/code&gt; 先处理完），彻底消除顺序依赖。&lt;/p&gt;
&lt;h1&gt;四、怎么确认改对了&lt;/h1&gt;
&lt;p&gt;光看&quot;我觉得像了&quot;不算数。这次的验收手段有三个：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;探针量数值&lt;/strong&gt; —— 关键容器宽高写进页面再截图，和参考站对比。最终 &lt;code&gt;sidebar=280 / main=816 / rightSidebar=280&lt;/code&gt;，整页 1440px，和参考站完全一致。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;无头截图对比&lt;/strong&gt; —— 1600×1000 视口下逐区块比对，深浅色各来一遍（&lt;code&gt;--blink-settings=preferredColorScheme=1&lt;/code&gt; 可以强制浅色）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;astro check&lt;/code&gt; + &lt;code&gt;biome check&lt;/code&gt;&lt;/strong&gt; —— 保证没引入新的类型错误和格式问题。（&lt;code&gt;astro check&lt;/code&gt; 还剩 2 个错误，都是改动之前就存在的：&lt;code&gt;Navbar.astro&lt;/code&gt; 里 Svelte 组件的 &lt;code&gt;client:only&lt;/code&gt; 类型、&lt;code&gt;archive.astro&lt;/code&gt; 里的 &lt;code&gt;PostForList&lt;/code&gt; 类型。）&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;五、结果&lt;/h1&gt;
&lt;p&gt;对着参考站逐项核对，现在一致的部分：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;整页 90rem、单侧栏 17.5rem、断点 768 / 1280&lt;/li&gt;
&lt;li&gt;横幅底部的四层视差波浪 + 首页居中大标题（靠文字阴影保证可读性）&lt;/li&gt;
&lt;li&gt;导航栏顶部透明、滚动 50px 后变毛玻璃（白 55% + 20px 模糊）&lt;/li&gt;
&lt;li&gt;首页分类筛选条（可横向滚动 + 当前分类高亮）&lt;/li&gt;
&lt;li&gt;文章卡片：标题竖线、图标小块式元信息、摘要、&lt;code&gt;# 标签&lt;/code&gt; chip 行、右侧封面&lt;/li&gt;
&lt;li&gt;左侧栏顺序：个人资料 → 公告 → 标签 → 目录&lt;/li&gt;
&lt;li&gt;卡片统一的极淡描边与投影&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;功能上一点没丢：目录、站点统计、日历、音乐播放器、看板娘、Others 菜单都还在，只是换了位置和长相。&lt;/p&gt;
&lt;h1&gt;六、给以后的自己&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;改版式之前先量，改完再量一次。&lt;/strong&gt; 可视化对比会骗人，数字不会。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tailwind 的类名必须是字面量。&lt;/strong&gt; 任何 &lt;code&gt;${}&lt;/code&gt; 插值都当成&quot;这条规则不存在&quot;来预期。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Astro 组件 prop 不要写多行字符串。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;v3 和 v4 的断点前缀含义不同，跨版本抄代码一定先对表。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;无头浏览器里读 transition 属性会读到起始值&lt;/strong&gt;，验证样式要么禁用过渡，要么读规则的最终值。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;import.meta.glob&lt;/code&gt; 的通配符要收窄。&lt;/strong&gt; &lt;code&gt;../../**&lt;/code&gt; 这种写法会把整个 &lt;code&gt;src&lt;/code&gt; 拖进依赖图，副作用难以预料。&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;参考&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;参考站：&lt;a href=&quot;https://mizuki.mysqil.com/&quot;&gt;https://mizuki.mysqil.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Mizuki 主题源码：&lt;a href=&quot;https://github.com/LyraVoid/Mizuki&quot;&gt;https://github.com/LyraVoid/Mizuki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Fuwari 主题：&lt;a href=&quot;https://github.com/saicaca/fuwari&quot;&gt;https://github.com/saicaca/fuwari&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Tailwind 断点文档：&lt;a href=&quot;https://tailwindcss.com/docs/responsive-design&quot;&gt;https://tailwindcss.com/docs/responsive-design&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>博客更新日志：从 Spaceship 买域名，到 007912.xyz 能打开</title><link>https://007912.xyz/posts/spaceship-domain/</link><guid isPermaLink="true">https://007912.xyz/posts/spaceship-domain/</guid><description>在 Spaceship 下单、加解析记录、绑进 GitHub Pages，以及改 base 路径时踩到的两个坑</description><pubDate>Sun, 27 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;div class=&quot;badge-row&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.shields.io/badge/%E7%B1%BB%E5%9E%8B-%E7%AC%94%E8%AE%B0-blue&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/%E5%BD%92%E5%B1%9E-%E7%BD%91%E7%AB%99%E7%BB%B4%E6%8A%A4-orange&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/%E6%B3%A8%E5%86%8C%E5%95%86-Spaceship-1d4ed8&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/%E8%A7%A3%E6%9E%90-DNS-0ea5e9&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/%E6%89%98%E7%AE%A1-GitHub%20Pages-24292f?logo=github&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/%E5%8D%8F%E8%AE%AE-HTTPS-22c55e?logo=letsencrypt&quot; alt=&quot;Static Badge&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;这个站现在可以通过 &lt;a href=&quot;https://007912.xyz&quot;&gt;https://007912.xyz&lt;/a&gt; 访问了。这一篇把从买域名到真正能打开的全过程记下来 —— 前面是步骤，最后是踩到的两个坑，其中一个把评论区清空了。&lt;/p&gt;
&lt;h1&gt;为什么要买域名&lt;/h1&gt;
&lt;p&gt;在此之前站点一直挂在默认地址上，形如 &lt;code&gt;xieluyang912.github.io/fuwari/&lt;/code&gt;。能用，但有几个别扭的地方：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;分享出去的链接又长又像一串编号，看着不像个正经站点&lt;/li&gt;
&lt;li&gt;以后要是换个托管（比如从 GitHub Pages 挪到别的静态托管），地址就全变了&lt;/li&gt;
&lt;li&gt;域名是自己的东西，托管商可以换，域名不用换&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以决定自己买一个。&lt;/p&gt;
&lt;h1&gt;一、在 Spaceship 下单&lt;/h1&gt;
&lt;p&gt;Spaceship 是 Namecheap 团队做的注册商，界面比传统注册商干净一些。它有个好处是域名自带免费的 Basic DNS 和 Whois 隐私保护 —— 这两样在别家经常要单独加钱或者单独开开关。&lt;/p&gt;
&lt;p&gt;流程本身没什么特别的：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;打开 &lt;a href=&quot;https://www.spaceship.com&quot;&gt;https://www.spaceship.com&lt;/a&gt;，在搜索框里输入想要的域名&lt;/li&gt;
&lt;li&gt;列表里显示能不能注册、首年多少钱&lt;/li&gt;
&lt;li&gt;加入购物车，选注册年限（最少 1 年）&lt;/li&gt;
&lt;li&gt;结账：填邮箱、注册账号、付款&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;:::note[下单前先看一眼续费价]
&lt;code&gt;.xyz&lt;/code&gt; 这类后缀首年经常便宜得离谱，续费价却是另一个数量级。结账页一般会写明续费多少钱，介意的话就把年限一次买长一点，或者记下来明年提前比价。
:::&lt;/p&gt;
&lt;p&gt;买完之后进入域名的 Manage 页面，有两个开关值得确认一下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Auto-renew（自动续费）&lt;/strong&gt;：建议打开。域名过期被释放之后，赎回价通常是注册价的几十倍，还可能已经被别人抢注了。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Whois privacy（隐私保护）&lt;/strong&gt;：Spaceship 对多数后缀是默认送的，确认它是开着的 —— 不然你的姓名、邮箱、电话会直接暴露在 whois 查询里。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;二、加解析记录，把域名指向 GitHub Pages&lt;/h1&gt;
&lt;p&gt;GitHub Pages 对外服务的 IP 是固定的。根域名要用 &lt;strong&gt;A 记录&lt;/strong&gt;（IPv4）和 &lt;strong&gt;AAAA 记录&lt;/strong&gt;（IPv6）指过去，&lt;code&gt;www&lt;/code&gt; 用一条 CNAME 指到默认域名。&lt;/p&gt;
&lt;p&gt;在 Spaceship 的域名管理页找到 DNS（有的地方叫 Advanced DNS），照下面的表加：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;主机&lt;/th&gt;
&lt;th&gt;值&lt;/th&gt;
&lt;th&gt;TTL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;@&lt;/td&gt;
&lt;td&gt;185.199.108.153&lt;/td&gt;
&lt;td&gt;自动&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;@&lt;/td&gt;
&lt;td&gt;185.199.109.153&lt;/td&gt;
&lt;td&gt;自动&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;@&lt;/td&gt;
&lt;td&gt;185.199.110.153&lt;/td&gt;
&lt;td&gt;自动&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;@&lt;/td&gt;
&lt;td&gt;185.199.111.153&lt;/td&gt;
&lt;td&gt;自动&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AAAA&lt;/td&gt;
&lt;td&gt;@&lt;/td&gt;
&lt;td&gt;2606:50c0:8000::153&lt;/td&gt;
&lt;td&gt;自动&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AAAA&lt;/td&gt;
&lt;td&gt;@&lt;/td&gt;
&lt;td&gt;2606:50c0:8001::153&lt;/td&gt;
&lt;td&gt;自动&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AAAA&lt;/td&gt;
&lt;td&gt;@&lt;/td&gt;
&lt;td&gt;2606:50c0:8002::153&lt;/td&gt;
&lt;td&gt;自动&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AAAA&lt;/td&gt;
&lt;td&gt;@&lt;/td&gt;
&lt;td&gt;2606:50c0:8003::153&lt;/td&gt;
&lt;td&gt;自动&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CNAME&lt;/td&gt;
&lt;td&gt;www&lt;/td&gt;
&lt;td&gt;xieluyang912.github.io&lt;/td&gt;
&lt;td&gt;自动&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;几个容易写错的地方：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;主机名只填「这一段」&lt;/strong&gt;。根域名那一栏填 &lt;code&gt;@&lt;/code&gt; 或者留空，&lt;code&gt;www&lt;/code&gt; 就只写 &lt;code&gt;www&lt;/code&gt;，不要把整个域名再写一遍 —— 写成 &lt;code&gt;www.007912.xyz.007912.xyz&lt;/code&gt; 是很常见的低级错误。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CNAME 的值不带仓库名、不带斜杠、末尾不加点&lt;/strong&gt;。是 &lt;code&gt;xieluyang912.github.io&lt;/code&gt;，不是 &lt;code&gt;xieluyang912.github.io/fuwari&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;根域名不能用 CNAME&lt;/strong&gt;。DNS 规范不允许根域出现 CNAME，所以根域老老实实用 A / AAAA。&lt;/li&gt;
&lt;li&gt;AAAA 那四条是 IPv6，不是必须的，加上没坏处。&lt;/li&gt;
&lt;li&gt;如果域名刚买，面板里可能已经有一套默认的 parking 记录，注意别和自己的记录打架。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;改完要等它生效，通常几分钟，慢的话几小时，取决于 TTL 和各地 DNS 缓存的脾气。&lt;/p&gt;
&lt;h1&gt;三、在 GitHub Pages 里绑定域名&lt;/h1&gt;
&lt;p&gt;进仓库的 Settings → Pages：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Build and deployment → Source&lt;/strong&gt; 选 &lt;code&gt;GitHub Actions&lt;/code&gt;。本站的 &lt;code&gt;.github/workflows/deploy.yml&lt;/code&gt; 就是按这个前提写的，选错了部署步骤会直接报错。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Custom domain&lt;/strong&gt; 填 &lt;code&gt;007912.xyz&lt;/code&gt; —— 只填域名，不要带 &lt;code&gt;https://&lt;/code&gt;，也不要带路径 —— 然后 Save。&lt;/li&gt;
&lt;li&gt;等 GitHub 做 DNS check。它会去查你刚加的那几条 A 记录；没生效就会提示 DNS check unsuccessful，不用慌，过一会儿再点一次就行。&lt;/li&gt;
&lt;li&gt;check 通过之后，&lt;strong&gt;Enforce HTTPS&lt;/strong&gt; 的勾才能真正点上。证书由 GitHub 自动签发，一般几分钟到十几分钟，偶尔要等到 24 小时 —— 在这之前 https 打不开是正常的。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;:::note[为什么要在 public/ 里放一份 CNAME]
用「分支 + 目录」的方式发布时，GitHub 会往仓库里写一个 &lt;code&gt;CNAME&lt;/code&gt; 文件来记住自定义域名。但本站是用 Actions 发布构建产物的，没有那个分支，GitHub 没地方写 —— 所以要自己在 &lt;code&gt;public/CNAME&lt;/code&gt; 里放一份，构建时会被原样复制到 &lt;code&gt;dist&lt;/code&gt; 根目录。&lt;/p&gt;
&lt;p&gt;这份文件一旦丢了，自定义域名的设置会被重置，站点就退回默认地址了。
:::&lt;/p&gt;
&lt;h1&gt;四、改站点自己的配置&lt;/h1&gt;
&lt;p&gt;域名换掉之后，站点里有两处必须跟着改，否则站点能打开、但生成出来的链接还是旧的：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// astro.config.mjs
site: &quot;https://007912.xyz&quot;,  // sitemap、RSS、OG 标签用的绝对地址
base: &quot;/&quot;,                   // 绑定自定义域名后站点位于根路径
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# public/CNAME
007912.xyz
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;site&lt;/code&gt; 影响的是构建时生成的绝对链接：&lt;code&gt;sitemap.xml&lt;/code&gt;、RSS 里的文章地址、分享到社交平台时的 OG 卡片。忘了改的话，页面本身没事，但搜索引擎和 RSS 阅读器拿到的还是老地址。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;base&lt;/code&gt; 则是路径前缀。绑了自定义域名，站点就在根路径上，所以是 &lt;code&gt;/&lt;/code&gt;。（哪天想改回用默认地址访问，这里要改回 &lt;code&gt;/fuwari/&lt;/code&gt;，同时删掉 &lt;code&gt;public/CNAME&lt;/code&gt;。）&lt;/p&gt;
&lt;h1&gt;踩到的两个坑&lt;/h1&gt;
&lt;h2&gt;1. base 一改，评论区全空了&lt;/h2&gt;
&lt;p&gt;这是这次最难受的一个。&lt;/p&gt;
&lt;p&gt;换域名之后，所有旧文章底部的评论都不见了 —— 去 GitHub Discussions 里看，评论还在，页面上就是不显示。&lt;/p&gt;
&lt;p&gt;原因是评论用的 giscus 按 &lt;code&gt;pathname&lt;/code&gt; 匹配 discussion：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;换域名前：&lt;code&gt;https://xieluyang912.github.io/fuwari/posts/hello-world/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;换域名后：&lt;code&gt;https://007912.xyz/posts/hello-world/&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;base&lt;/code&gt; 从 &lt;code&gt;/fuwari/&lt;/code&gt; 变成 &lt;code&gt;/&lt;/code&gt;，页面路径整体短了一截，giscus 拿着新路径去 Discussions 里找，自然对不上任何一条。&lt;/p&gt;
&lt;p&gt;已经产生的评论不会自动迁移。根治的办法是&lt;strong&gt;换一种匹配方式&lt;/strong&gt;：把 giscus 的 &lt;code&gt;mapping&lt;/code&gt; 从 &lt;code&gt;pathname&lt;/code&gt; 改成 &lt;code&gt;og:title&lt;/code&gt;，改成按文章标题匹配。这样评论就和域名、路径彻底解耦，以后再换域名也不会丢。代价是文章标题不能随便改。&lt;/p&gt;
&lt;h2&gt;2. Enforce HTTPS 一直点不动&lt;/h2&gt;
&lt;p&gt;绑完域名去勾 HTTPS，发现那个框是灰的、点不了。&lt;/p&gt;
&lt;p&gt;这不是出错了，是顺序问题：GitHub 得先确认域名确实解析到了它、再签发证书，然后「强制 HTTPS」才可用。等的期间可以先自己验证一下解析通没通：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nslookup 007912.xyz
# 或者直接看响应头
curl -I http://007912.xyz
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果 &lt;code&gt;nslookup&lt;/code&gt; 查不到或者还返回旧 IP，先清一下本机 DNS 缓存（Windows 上是 &lt;code&gt;ipconfig /flushdns&lt;/code&gt;），再等一会儿。&lt;/p&gt;
&lt;h1&gt;最后&lt;/h1&gt;
&lt;p&gt;顺带记一句：域名解析到 GitHub Pages 这种境外托管，是&lt;strong&gt;不需要 ICP 备案&lt;/strong&gt;的 —— 备案针对的是放在国内服务器上的站点。代价是国内访问的速度和稳定性看运气，这个只能自己权衡。&lt;/p&gt;
&lt;p&gt;现在站点在 &lt;a href=&quot;https://007912.xyz&quot;&gt;https://007912.xyz&lt;/a&gt;；绑定自定义域名后，原来的默认地址也会跳转到新域名。如果你发现有哪里还是老链接、或者某篇文章的评论对不上，欢迎在下面说一声。&lt;/p&gt;
</content:encoded></item><item><title>博客更新日志：接入 giscus 评论区</title><link>https://007912.xyz/posts/giscus/</link><guid isPermaLink="true">https://007912.xyz/posts/giscus/</guid><description>文章底部现在有评论区了 —— 用 giscus 把评论存进 GitHub Discussions，顺便记录两个踩过的坑</description><pubDate>Sat, 26 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;div class=&quot;badge-row&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.shields.io/badge/qq-234259867-blue?logo=qq&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/wechat-xly15283272038-green?logo=wechat&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/gihub-xieluyang912-orange?logo=github&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/steam-xxllyy-red?logo=steam&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/pnpm-%3E%3D9-green?logo=pnpm&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/nodedotjs-%3E%3D20-red?logo=nodedotjs&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/deepseek-harness-blue?logo=deepseek&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/claude-code-orange?logo=claude&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/%E6%94%AF%E6%8C%81%E5%BA%93-astro-yellow?logo=astro&quot; alt=&quot;Static Badge&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;从今天起，每篇文章的底部都有了评论区。这一篇记录一下它是怎么接进来的、为什么这么选，以及中途踩到的两个坑。&lt;/p&gt;
&lt;h1&gt;评论存在哪里&lt;/h1&gt;
&lt;p&gt;评论区用的是 &lt;a href=&quot;https://giscus.app&quot;&gt;giscus&lt;/a&gt;，一个把 GitHub Discussions 变成评论框的开源组件。&lt;/p&gt;
&lt;p&gt;它和常见的评论系统不太一样的地方在于&lt;strong&gt;没有独立的服务器和数据库&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你在评论区发的每一条，实际上都是仓库 &lt;code&gt;xieluyang912/fuwari&lt;/code&gt; 里 Discussions 的一条回复&lt;/li&gt;
&lt;li&gt;页面上只嵌入一个 iframe，评论数据全部存在 GitHub 上&lt;/li&gt;
&lt;li&gt;因此不会出现「评论服务商跑路了，评论全没了」这种事 —— 数据跟着仓库走&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;代价是&lt;strong&gt;评论需要用 GitHub 账号登录&lt;/strong&gt;。如果你没有 GitHub 账号，或者所在网络访问 GitHub 不稳定，那就没法评论了。这个取舍我选择了前者：数据掌握在自己手里，比多几个匿名评论更重要。&lt;/p&gt;
&lt;h1&gt;怎么评论&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;滚动到文章底部（评论区在版权声明下面）&lt;/li&gt;
&lt;li&gt;点「使用 GitHub 登录」授权一次&lt;/li&gt;
&lt;li&gt;写下想说的话，提交&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;评论同时会出现在仓库的 Discussions 里，地址是 &lt;a href=&quot;https://github.com/xieluyang912/fuwari/discussions&quot;&gt;https://github.com/xieluyang912/fuwari/discussions&lt;/a&gt;，在那边也一样能回复。&lt;/p&gt;
&lt;h1&gt;为什么选 giscus&lt;/h1&gt;
&lt;p&gt;本站是纯静态站点 —— Astro 构建出一堆 HTML，托管在 GitHub Pages 上，构建完成之后没有任何服务端代码。这意味着：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;带服务端的评论系统（云函数 + 数据库那一类）要多维护一套东西，还可能产生费用&lt;/li&gt;
&lt;li&gt;自建服务还要操心备案、续费、被刷&lt;/li&gt;
&lt;li&gt;而 giscus 只需要前端嵌一个 iframe，成本是零&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:::note[分类上的一个小设计]
Discussions 里我建了一个 &lt;strong&gt;Announcements&lt;/strong&gt; 类型的分类来存评论。这个类型只有管理员和 giscus 机器人能发起 discussion，访客只能回复、不能自己开新帖 —— 相当于从源头挡掉一部分垃圾内容。
:::&lt;/p&gt;
&lt;h1&gt;两个踩到的坑&lt;/h1&gt;
&lt;h2&gt;1. 无刷新跳转会让脚本「失忆」&lt;/h2&gt;
&lt;p&gt;本站在用 Swup 做页面切换，点站内链接不会整页刷新，只替换 &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt; 和目录这两个容器。&lt;/p&gt;
&lt;p&gt;最开始我把 giscus 的加载脚本写在评论区组件里 —— 也就是 &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt; 内部。结果有两个问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;每次页面跳转，脚本都会被&lt;strong&gt;重新执行&lt;/strong&gt;一次，可能重复插入评论区&lt;/li&gt;
&lt;li&gt;更麻烦的是：访客如果从首页进来，压根没渲染过文章页的组件，脚本也就没机会注册；之后从首页跳到文章页，评论区不会加载&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以最后把加载逻辑挪到了 &lt;code&gt;src/layouts/Layout.astro&lt;/code&gt;：它在每个页面上都存在、又不在 Swup 替换的范围内，整站只注册一次，再由 Swup 的 &lt;code&gt;page:view&lt;/code&gt; 事件按需注入 iframe。&lt;/p&gt;
&lt;h2&gt;2. 明暗配色不能听系统偏好&lt;/h2&gt;
&lt;p&gt;giscus 官方推荐的配置是 &lt;code&gt;data-theme=&quot;preferred_color_scheme&quot;&lt;/code&gt;，意思是跟随&lt;strong&gt;操作系统&lt;/strong&gt;的深浅色设置。&lt;/p&gt;
&lt;p&gt;但本站的明暗模式是独立的：访客可以在显示设置里手动选浅色、深色或「跟随系统」，这个选择存在浏览器本地，和系统的实际设置未必一致。如果评论区单独跟着系统走，就会出现页面深色、评论区浅色的割裂感。&lt;/p&gt;
&lt;p&gt;解决办法是监听 &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; 上 &lt;code&gt;dark&lt;/code&gt; 类的变化 —— 访客在站内一切换主题，就用 &lt;code&gt;postMessage&lt;/code&gt; 通知 iframe 换配色。用通知而不是整块重新加载，评论区不会闪一下。&lt;/p&gt;
&lt;h1&gt;最后&lt;/h1&gt;
&lt;p&gt;欢迎在下面试试。如果不想登录 GitHub、或者想直接聊，导航栏和侧边栏都能找到我。&lt;/p&gt;
</content:encoded></item><item><title>黄霄雲2026.9.26「宇宙无敌号」苏州站歌单</title><link>https://007912.xyz/posts/huangxiaoyun-live/</link><guid isPermaLink="true">https://007912.xyz/posts/huangxiaoyun-live/</guid><description>黄霄雲「宇宙无敌号」巡演现场曲目全记录</description><pubDate>Sat, 26 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;div class=&quot;badge-row&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.shields.io/badge/%E6%AD%8C%E6%89%8B-%E9%BB%84%E9%9C%84%E9%9B%B2-red&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/%E5%B7%A1%E6%BC%94-%E5%AE%87%E5%AE%99%E6%97%A0%E6%95%8C%E5%8F%B7-blue&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/%E5%9C%BA%E6%AC%A1-2026.09.26%20%E8%8B%8F%E5%B7%9E-orange&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/%E6%9B%B2%E7%9B%AE-33%20%E9%A6%96-green&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/applemusic-%E7%8E%B0%E5%9C%BA%E6%AD%8C%E5%8D%95-red?logo=applemusic&quot; alt=&quot;Static Badge&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;现场曲目记录，按演出顺序整理，共 33 首。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;开场 / Part 1&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;《重返地球》&lt;/li&gt;
&lt;li&gt;《Oracle》&lt;/li&gt;
&lt;li&gt;《淬炼》&lt;/li&gt;
&lt;li&gt;《蝴蝶夫人》&lt;/li&gt;
&lt;li&gt;《11》&lt;/li&gt;
&lt;li&gt;《打开》&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Part 2&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;《此生不换》&lt;/li&gt;
&lt;li&gt;《劫》&lt;/li&gt;
&lt;li&gt;《要不然我们就这样一万年》&lt;/li&gt;
&lt;li&gt;《淬羽风华》&lt;/li&gt;
&lt;li&gt;《怜心》&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Part 3&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;《年少心动雨季》&lt;/li&gt;
&lt;li&gt;《背对背拥抱》 cover 林俊杰&lt;/li&gt;
&lt;li&gt;《没语季节》&lt;/li&gt;
&lt;li&gt;《留不住的夏天》&lt;/li&gt;
&lt;li&gt;《人鱼之歌》&lt;/li&gt;
&lt;li&gt;《甲乙丙丁》 feat. 李佳薇&lt;/li&gt;
&lt;li&gt;《失忆》 嘉宾独唱&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;:::note[乐队秀]
马克老师弹奏了《弯弯的月亮》，纪念刘欢老师。
:::&lt;/p&gt;
&lt;h2&gt;Part 4&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;《平行线》&lt;/li&gt;
&lt;li&gt;《小云》&lt;/li&gt;
&lt;li&gt;《月牙湾》&lt;/li&gt;
&lt;li&gt;《Sad Sometimes》&lt;/li&gt;
&lt;li&gt;《带我去很远地方》&lt;/li&gt;
&lt;li&gt;《烟火里的尘埃》&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;烟火打鼓秀&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;大屏合唱互动环节&lt;/h2&gt;
&lt;p&gt;《没语季节》+《带我去很远地方》+《你真的够了》+《回音如果》+《人鱼之歌》+《小云》&lt;/p&gt;
&lt;h2&gt;Part 5&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;《但愿人长久》 cover 邓丽君&lt;/li&gt;
&lt;li&gt;《梦返》&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;点歌互动&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;《连名带姓》 cover 张惠妹&lt;/li&gt;
&lt;li&gt;《可惜没如果》 cover 林俊杰&lt;/li&gt;
&lt;li&gt;《羽众不同》&lt;/li&gt;
&lt;li&gt;《盲选》&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;抽奖环节&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;Part 6 / 安可&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;《你的答案》&lt;/li&gt;
&lt;li&gt;《回音如果》&lt;/li&gt;
&lt;li&gt;《星辰大海》&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>项目介绍</title><link>https://007912.xyz/posts/xmjs/</link><guid isPermaLink="true">https://007912.xyz/posts/xmjs/</guid><description>这个项目的一个介绍</description><pubDate>Sat, 26 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;项目介绍：Xieluyang 的个人博客&lt;/h1&gt;
&lt;p&gt;&amp;lt;div class=&quot;badge-row&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.shields.io/badge/qq-234259867-blue?logo=qq&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/wechat-xly15283272038-green?logo=wechat&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/gihub-xieluyang912-orange?logo=github&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/steam-xxllyy-red?logo=steam&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/pnpm-%3E%3D9-green?logo=pnpm&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/nodedotjs-%3E%3D20-red?logo=nodedotjs&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/deepseek-harness-blue?logo=deepseek&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/claude-code-orange?logo=claude&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/%E6%94%AF%E6%8C%81%E5%BA%93-astro-yellow?logo=astro&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/applemusic-xxllyy-red?logo=applemusic&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/zotero-xxllyy-blue?logo=zotero&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/counterstrike-Aaamazing-yellow?logo=counterstrike&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/ea-xxllyy-orange?logo=ea&quot; alt=&quot;Static Badge&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;一个基于 &lt;a href=&quot;https://github.com/saicaca/fuwari&quot;&gt;Fuwari&lt;/a&gt; 主题二次开发的纯静态个人博客，
用 &lt;a href=&quot;https://astro.build&quot;&gt;Astro&lt;/a&gt; 构建，源码中所有关键位置都补充了中文注释。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;一、这是什么&lt;/h2&gt;
&lt;p&gt;这是 &lt;strong&gt;Xieluyang&lt;/strong&gt;的个人博客站点。站点本身不含后端服务，
所有页面在构建时一次性生成 HTML，属于标准的&lt;strong&gt;静态站点&lt;/strong&gt;（SSG），因此可以零成本托管在
GitHub Pages、Cloudflare、Vercel 等任意静态托管平台上。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;项目&lt;/th&gt;
&lt;th&gt;值&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;站点标题&lt;/td&gt;
&lt;td&gt;Xieluyang&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;站点语言&lt;/td&gt;
&lt;td&gt;简体中文（&lt;code&gt;zh_CN&lt;/code&gt;）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;主题色相&lt;/td&gt;
&lt;td&gt;250（青色偏蓝），对访客开放调色&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;线上地址&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://xieluyang912.github.io/fuwari/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;文章数量&lt;/td&gt;
&lt;td&gt;4 篇（&lt;code&gt;src/content/posts/&lt;/code&gt;）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;二、技术栈&lt;/h2&gt;
&lt;h3&gt;核心框架&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Astro 5.13.10&lt;/strong&gt; —— 构建框架，负责把 Markdown、组件编译成静态 HTML&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Svelte 5&lt;/strong&gt; —— 用于少数需要客户端交互的组件（搜索框、明暗切换、目录等）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tailwind CSS 3.4&lt;/strong&gt; —— 原子化样式方案，开启嵌套语法&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stylus&lt;/strong&gt; —— 少量全局样式与 CSS 变量定义&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;功能型依赖&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;依赖&lt;/th&gt;
&lt;th&gt;作用&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@swup/astro&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;站内跳转无刷新，带过渡动画&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;astro-expressive-code&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;代码块高亮增强（行号、折叠、语言角标、复制按钮）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pagefind&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;构建期生成全文搜索索引&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;astro-icon&lt;/code&gt; + Font Awesome 6&lt;/td&gt;
&lt;td&gt;图标系统，通过 Iconify 名称引用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;katex&lt;/code&gt; / &lt;code&gt;remark-math&lt;/code&gt; / &lt;code&gt;rehype-katex&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;数学公式渲染&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;photoswipe&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;文章内图片点击放大&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@astrojs/rss&lt;/code&gt; / &lt;code&gt;@astrojs/sitemap&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;RSS 订阅源与 sitemap.xml&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;reading-time&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;估算文章阅读时长&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;工程化&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;pnpm 9.14.4&lt;/strong&gt;（&lt;code&gt;preinstall&lt;/code&gt; 钩子强制只允许 pnpm）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Biome 2.2.5&lt;/strong&gt; —— 代码格式化与 lint，CI 中执行 &lt;code&gt;biome ci&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TypeScript 5.9&lt;/strong&gt; —— 配置对象有完整类型定义，编辑器可提示&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub Actions&lt;/strong&gt; —— 三条工作流：代码质量检查、构建检查、自动部署&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;三、目录结构&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;fuwari/
├── astro.config.mjs        # 构建配置：集成、Markdown 管线、部署地址
├── wrangler.jsonc          # Cloudflare Workers 静态托管配置
├── biome.json              # 代码风格规则
├── pagefind.yml            # 搜索索引生成配置
├── scripts/new-post.js     # 新建文章的脚手架脚本
├── docs/                   # 官方多语言 README（11 种语言）
├── public/favicon/         # 不经构建直接复制的静态资源
├── .github/workflows/      # CI：biome.yml / build.yml / deploy.yml
└── src/
    ├── config.ts           # ★ 站点总配置文件，日常只改这一个
    ├── types/config.ts     # 上述配置的类型定义
    ├── content/
    │   ├── config.ts       # 文章 frontmatter 的字段校验规则
    │   ├── posts/          # 所有 Markdown 文章 + img/ 配图
    │   └── spec/about.md   # 「关于」页正文
    ├── layouts/            # Layout.astro（页面骨架）、MainGridLayout.astro（栅格布局）
    ├── pages/              # 路由：首页分页、归档、文章详情、about、rss.xml、robots.txt
    ├── components/
    │   ├── *.astro         # 导航栏、页脚、文章卡片、正文渲染等
    │   ├── control/        # 分页、返回顶部、按钮等小控件
    │   ├── widget/         # 侧边栏：个人资料、分类、标签、目录、显示设置
    │   └── misc/           # 图片包装、版权声明、Markdown 容器
    ├── plugins/            # 自定义 remark / rehype / Expressive Code 插件
    ├── i18n/               # 11 种语言的界面文案
    ├── styles/             # 全局样式、Markdown 样式、代码块与滚动条样式
    ├── utils/              # 内容、日期、URL、设置相关的工具函数
    └── assets/images/      # 横幅图、头像等需要被构建处理的图片
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;四、功能特性&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;明暗主题 + 自定义主题色&lt;/strong&gt; —— 访客可实时调节色相，配色通过 CSS 变量全局联动&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;文章目录（TOC）&lt;/strong&gt; —— 基于 &lt;code&gt;remark-sectionize&lt;/code&gt; 按标题层级切分，右侧浮动导航，随滚动高亮&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;站内全文搜索&lt;/strong&gt; —— 构建后由 Pagefind 扫描 &lt;code&gt;dist/&lt;/code&gt; 生成索引，纯前端检索，无需服务端&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;代码块增强&lt;/strong&gt; —— 行号、&lt;code&gt;--collapse&lt;/code&gt; 折叠、语言角标、自定义复制按钮、diff 与高亮标记&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Markdown 扩展语法&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;提示框：&lt;code&gt;::note&lt;/code&gt;、&lt;code&gt;::tip&lt;/code&gt;、&lt;code&gt;::important&lt;/code&gt;、&lt;code&gt;::caution&lt;/code&gt;、&lt;code&gt;::warning&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;也兼容 GitHub 的 &lt;code&gt;&amp;gt; [!NOTE]&lt;/code&gt; 写法&lt;/li&gt;
&lt;li&gt;GitHub 仓库卡片：&lt;code&gt;::github{repo=&quot;owner/repo&quot;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;数学公式：行内 &lt;code&gt;$...$&lt;/code&gt; 与独立 &lt;code&gt;$$...$$&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;图片放大&lt;/strong&gt; —— 集成 PhotoSwipe，点开文章配图可全屏查看&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;阅读体验细节&lt;/strong&gt; —— 自动估算阅读时长、标题锚点链接、自定义滚动条、返回顶部按钮&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;响应式布局&lt;/strong&gt; —— 侧边栏在移动端折叠为抽屉式面板&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RSS 与 SEO&lt;/strong&gt; —— 输出 &lt;code&gt;rss.xml&lt;/code&gt;、&lt;code&gt;sitemap-index.xml&lt;/code&gt;、&lt;code&gt;robots.txt&lt;/code&gt;，页面带 OG 标签&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;五、配置方式&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;日常维护只需要改 &lt;code&gt;src/config.ts&lt;/code&gt; 一个文件&lt;/strong&gt;，它导出五个配置对象：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;导出常量&lt;/th&gt;
&lt;th&gt;控制内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;siteConfig&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;标题、副标题、语言、主题色相、首页横幅、favicon&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;navBarConfig&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;顶部导航链接（内置首页 / 归档 / 关于，可加外链）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;profileConfig&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;侧边栏头像、昵称、签名、社交链接&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;licenseConfig&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;文章底部版权声明（当前为 CC BY-NC-SA 4.0）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;expressiveCodeConfig&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;代码高亮主题&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;所有配置在&lt;strong&gt;构建时&lt;/strong&gt;被读取并写进静态页面，因此修改后需重新构建才会生效。
各项字段的类型定义见 &lt;code&gt;src/types/config.ts&lt;/code&gt;，编辑器会给出提示与报错。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;部署相关&lt;/strong&gt;的配置在 &lt;code&gt;astro.config.mjs&lt;/code&gt;：&lt;code&gt;site&lt;/code&gt; 与 &lt;code&gt;base&lt;/code&gt; 必须与最终访问地址一致，
否则 sitemap、RSS 里的绝对链接和静态资源路径都会出错。当前配置对应
GitHub Pages 的项目仓库地址 &lt;code&gt;https://xieluyang912.github.io/fuwari/&lt;/code&gt;。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;六、本地开发与构建&lt;/h2&gt;
&lt;p&gt;环境要求：&lt;strong&gt;Node.js ≥ 20&lt;/strong&gt;、&lt;strong&gt;pnpm ≥ 9&lt;/strong&gt;（首次使用需 &lt;code&gt;npm install -g pnpm&lt;/code&gt;）。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pnpm install          # 安装依赖
pnpm dev              # 启动开发服务器，默认 http://localhost:4321
pnpm build            # 构建生产版本到 dist/，并自动生成搜索索引
pnpm preview          # 本地预览构建产物
pnpm check            # 检查类型与代码错误
pnpm new-post &amp;lt;文件名&amp;gt; # 新建一篇文章
pnpm format           # 用 Biome 格式化 src/
pnpm lint             # 用 Biome 检查并自动修复 src/
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;七、内容写作&lt;/h2&gt;
&lt;p&gt;新建文章推荐用 &lt;code&gt;pnpm new-post &amp;lt;文件名&amp;gt;&lt;/code&gt;，生成的文件位于 &lt;code&gt;src/content/posts/&lt;/code&gt;，
顶部 frontmatter 格式如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
title: 文章标题
published: 2026-09-25
description: 文章摘要，用于列表页展示和 SEO 描述
image: &apos;img/cover.png&apos;    # 封面图，相对当前文章目录
tags: [标签一, 标签二]
category: 分类名
draft: false              # 为 true 时不会被构建进站点
lang: &apos;&apos;                  # 仅当文章语言与站点语言不同时才填
---
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配图统一放在 &lt;code&gt;src/content/posts/img/&lt;/code&gt; 下，用相对路径引用。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;八、部署&lt;/h2&gt;
&lt;p&gt;站内已配置两条部署路径，二选一即可：&lt;/p&gt;
&lt;h3&gt;1. GitHub Pages（当前主用）&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;.github/workflows/deploy.yml&lt;/code&gt; 会在推送到 &lt;code&gt;main&lt;/code&gt; 分支时自动执行：
安装依赖 → &lt;code&gt;pnpm build&lt;/code&gt; → 上传 &lt;code&gt;dist/&lt;/code&gt; → 发布到 Pages。&lt;/p&gt;
&lt;p&gt;前置条件：仓库 &lt;strong&gt;Settings → Pages → Source&lt;/strong&gt; 需设为 &lt;strong&gt;&quot;GitHub Actions&quot;&lt;/strong&gt;。
CI 中使用 &lt;code&gt;--frozen-lockfile&lt;/code&gt;，保证依赖版本与本地一致。&lt;/p&gt;
&lt;h3&gt;2. Cloudflare Workers（静态资源模式）&lt;/h3&gt;
&lt;p&gt;站点是纯静态的，不需要 adapter 也不需要 Worker 脚本，Cloudflare 直接把 &lt;code&gt;dist/&lt;/code&gt; 当静态资源托管：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pnpm build &amp;amp;&amp;amp; npx wrangler deploy
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配置见 &lt;code&gt;wrangler.jsonc&lt;/code&gt;，Worker 名为 &lt;code&gt;xieluyang-blog&lt;/code&gt;。
两个平台互不影响，可以同时存在。&lt;/p&gt;
&lt;h3&gt;辅助工作流&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;build.yml&lt;/code&gt; —— 在 Node 22 / 23 两个版本上跑 &lt;code&gt;astro check&lt;/code&gt; 与 &lt;code&gt;astro build&lt;/code&gt;，确保兼容性&lt;/li&gt;
&lt;li&gt;&lt;code&gt;biome.yml&lt;/code&gt; —— 代码风格检查&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;九、相对原主题的改动&lt;/h2&gt;
&lt;p&gt;相比上游 &lt;a href=&quot;https://github.com/saicaca/fuwari&quot;&gt;saicaca/fuwari&lt;/a&gt;，本仓库主要做了以下本地化调整：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;全量中文注释&lt;/strong&gt; —— &lt;code&gt;src/config.ts&lt;/code&gt;、&lt;code&gt;astro.config.mjs&lt;/code&gt;、&lt;code&gt;wrangler.jsonc&lt;/code&gt;、
&lt;code&gt;.github/workflows/deploy.yml&lt;/code&gt; 等关键文件都写明了每个配置项的作用与注意事项，
降低了后续维护（尤其是隔一段时间回来改）的成本。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;站点信息替换&lt;/strong&gt; —— 标题、语言、主题色、导航链接、个人资料卡片、横幅图均改为本站内容。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;部署地址适配&lt;/strong&gt; —— &lt;code&gt;site&lt;/code&gt; / &lt;code&gt;base&lt;/code&gt; 调整为 GitHub Pages 项目仓库形式，
并新增 GitHub Pages 自动部署工作流。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;内容填充&lt;/strong&gt; —— 新增自我介绍、大创项目资料、网站维护备忘录等文章与配套配图。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;十、参考&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Fuwari 主题：&lt;a href=&quot;https://github.com/saicaca/fuwari&quot;&gt;https://github.com/saicaca/fuwari&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Astro 文档：&lt;a href=&quot;https://docs.astro.build&quot;&gt;https://docs.astro.build&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Expressive Code 文档：&lt;a href=&quot;https://expressive-code.com&quot;&gt;https://expressive-code.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Pagefind 文档：&lt;a href=&quot;https://pagefind.app&quot;&gt;https://pagefind.app&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;本项目源码：&lt;a href=&quot;https://github.com/xieluyang912/fuwari&quot;&gt;https://github.com/xieluyang912/fuwari&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;许可&lt;/h2&gt;
&lt;p&gt;主题部分遵循 &lt;a href=&quot;LICENSE&quot;&gt;MIT License&lt;/a&gt;。文章内容采用
&lt;a href=&quot;https://creativecommons.org/licenses/by-nc-sa/4.0/&quot;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议。&lt;/p&gt;
</content:encoded></item><item><title>你好，这是我的个人blog</title><link>https://007912.xyz/posts/hello-world/</link><guid isPermaLink="true">https://007912.xyz/posts/hello-world/</guid><description>自我介绍，以及这个网站是怎么搭起来的</description><pubDate>Fri, 25 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;div class=&quot;badge-row&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.shields.io/badge/qq-234259867-blue?logo=qq&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/wechat-xly15283272038-green?logo=wechat&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/gihub-xieluyang912-orange?logo=github&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/steam-xxllyy-red?logo=steam&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/pnpm-%3E%3D9-green?logo=pnpm&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/nodedotjs-%3E%3D20-red?logo=nodedotjs&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/deepseek-harness-blue?logo=deepseek&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/claude-code-orange?logo=claude&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/%E6%94%AF%E6%8C%81%E5%BA%93-astro-yellow?logo=astro&quot; alt=&quot;Static Badge&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;欢迎来到我的博客。这是第一篇文章，简单介绍一下我自己，也介绍一下这个网站。&lt;/p&gt;
&lt;h2&gt;关于我&lt;/h2&gt;
&lt;p&gt;我是 &lt;strong&gt;Xieluyang&lt;/strong&gt;，目前在&lt;strong&gt;四川大学&lt;/strong&gt;就读&lt;strong&gt;临床医学&lt;/strong&gt;。&lt;/p&gt;
&lt;h2&gt;关于这个网站&lt;/h2&gt;
&lt;p&gt;这个站点是用 &lt;a href=&quot;https://github.com/saicaca/fuwari&quot;&gt;Fuwari&lt;/a&gt; 搭建的，它是一个基于 &lt;a href=&quot;https://astro.build&quot;&gt;Astro&lt;/a&gt; 的静态博客模板，作者是 &lt;a href=&quot;https://github.com/saicaca&quot;&gt;saicaca&lt;/a&gt;。我选它的原因主要是：纯静态、加载快、开箱即用的功能比较全，而且样式清爽。&lt;/p&gt;
&lt;p&gt;它自带的功能包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;明暗主题切换&lt;/strong&gt;，还支持自定义主题色&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;文章目录（TOC）&lt;/strong&gt;，长文阅读时自动生成右侧导航&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;代码高亮&lt;/strong&gt;，基于 &lt;a href=&quot;https://expressive-code.com/&quot;&gt;Expressive Code&lt;/a&gt;，支持行号、diff 标记和代码块标题&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;站内搜索&lt;/strong&gt;，构建时用 &lt;a href=&quot;https://pagefind.app/&quot;&gt;Pagefind&lt;/a&gt; 生成索引&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RSS 订阅&lt;/strong&gt;，地址是 &lt;a href=&quot;/fuwari/rss.xml&quot;&gt;/fuwari/rss.xml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Markdown 扩展语法&lt;/strong&gt;，比如提示框、GitHub 仓库卡片&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;多语言支持&lt;/strong&gt;，站点语言在 &lt;code&gt;src/config.ts&lt;/code&gt; 里配置&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;部署方面，因为是纯静态站点，可以直接托管在 Vercel、Netlify、Cloudflare Pages 或者 GitHub Pages 上。&lt;/p&gt;
&lt;h2&gt;这里会写什么&lt;/h2&gt;
&lt;p&gt;想写什么就写什么(狗头)&lt;/p&gt;
&lt;h2&gt;联系我&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;GitHub：&lt;a href=&quot;https://github.com/xieluyang912&quot;&gt;@xieluyang912&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;QQ：234259867&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;欢迎交流，也欢迎指出文章里的错误。&lt;/p&gt;
</content:encoded></item><item><title>一个备忘录</title><link>https://007912.xyz/posts/beiwanglu/</link><guid isPermaLink="true">https://007912.xyz/posts/beiwanglu/</guid><description>一个帮助我维护网站的备忘录</description><pubDate>Fri, 25 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;div class=&quot;badge-row&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.shields.io/badge/qq-234259867-blue?logo=qq&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/wechat-xly15283272038-green?logo=wechat&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/gihub-xieluyang912-orange?logo=github&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/steam-xxllyy-red?logo=steam&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/pnpm-%3E%3D9-green?logo=pnpm&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/nodedotjs-%3E%3D20-red?logo=nodedotjs&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/deepseek-harness-blue?logo=deepseek&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/claude-code-orange?logo=claude&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/%E6%94%AF%E6%8C%81%E5%BA%93-astro-yellow?logo=astro&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/applemusic-xxllyy-red?logo=applemusic&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/zotero-xxllyy-blue?logo=zotero&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/counterstrike-Aaamazing-yellow?logo=counterstrike&quot; alt=&quot;Static Badge&quot; /&gt;
&lt;img src=&quot;https://img.shields.io/badge/ea-xxllyy-orange?logo=ea&quot; alt=&quot;Static Badge&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;h1&gt;创建新文章&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;pnpm new-post &amp;lt;filename&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;推送项目到GitHub&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;git status                      # 查看改了哪些文件
git add .                       # 添加所有修改
git commit -m &quot;说明&quot;            # 提交到本地仓库
git pull --rebase origin main   # 先拉取最远端代码
git push origin main            # 推送到GitHub
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;deepseak harness&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;npx @deepseek-ai/dsh web
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;文章图片相关&lt;/h1&gt;
&lt;h2&gt;封面图&lt;/h2&gt;
&lt;p&gt;封面图写在文章开头的 frontmatter 里（图片文件放在 &lt;code&gt;src/content/posts/img/&lt;/code&gt; 下）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;image: ./img/cover.jpg
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;正文插图&lt;/h2&gt;
&lt;p&gt;图片文件放在 &lt;code&gt;src/content/posts/img/&lt;/code&gt; 下，用相对路径引用：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;![图注文字](./img/photo.jpg)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;实际效果（下面这张就是上面那行语法插进来的）：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./img/girl_art_anime_1313052_1280x720.jpg&quot; alt=&quot;樱花下的少女&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;视频相关&lt;/h1&gt;
&lt;h2&gt;方式一：嵌入 B 站视频&lt;/h2&gt;
&lt;p&gt;把 &lt;code&gt;bvid&lt;/code&gt; 换成视频的 BV 号。外面套一层 16:9 的容器，播放器就会跟着屏幕宽度自适应：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div style=&quot;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&quot;&amp;gt;
&amp;lt;iframe src=&quot;https://player.bilibili.com/player.html?bvid=BV1GJ411x7h7&amp;amp;page=1&amp;amp;high_quality=1&amp;amp;danmaku=0&amp;amp;autoplay=0&quot; loading=&quot;lazy&quot; style=&quot;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0;&quot; scrolling=&quot;no&quot; border=&quot;0&quot; frameborder=&quot;no&quot; framespacing=&quot;0&quot; allowfullscreen=&quot;true&quot;&amp;gt;&amp;lt;/iframe&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;实际效果（BV1GJ411x7h7，滚到这里才会加载，不会自动播）：&lt;/p&gt;
&lt;p&gt;&amp;lt;div style=&quot;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&quot;&amp;gt;
&amp;lt;iframe src=&quot;https://player.bilibili.com/player.html?bvid=BV1GJ411x7h7&amp;amp;page=1&amp;amp;high_quality=1&amp;amp;danmaku=0&amp;amp;autoplay=0&quot; loading=&quot;lazy&quot; style=&quot;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0;&quot; scrolling=&quot;no&quot; border=&quot;0&quot; frameborder=&quot;no&quot; framespacing=&quot;0&quot; allowfullscreen=&quot;true&quot;&amp;gt;&amp;lt;/iframe&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;不想要自适应、固定高度就够了的话，用简写版：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;iframe width=&quot;100%&quot; height=&quot;468&quot; src=&quot;//player.bilibili.com/player.html?bvid=你的BV号&amp;amp;autoplay=0&quot; loading=&quot;lazy&quot; scrolling=&quot;no&quot; border=&quot;0&quot; frameborder=&quot;no&quot; framespacing=&quot;0&quot; allowfullscreen=&quot;true&quot;&amp;gt;&amp;lt;/iframe&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;怎么保证不自动播放&lt;/h2&gt;
&lt;p&gt;三个手段叠加，基本杜绝：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;iframe src=&quot;https://player.bilibili.com/player.html?bvid=xxx&amp;amp;autoplay=0&quot; loading=&quot;lazy&quot; ...&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;别写 &lt;code&gt;autoplay=1&lt;/code&gt;&lt;/strong&gt; —— B 站播放器默认就是不自动播放的，会自己播通常是因为复制来的模板里带了 &lt;code&gt;autoplay=1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;&amp;amp;autoplay=0&lt;/code&gt;&lt;/strong&gt; —— 显式关掉。这个参数在部分播放器版本上不太靠谱，所以还要配下面一条&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;loading=&quot;lazy&quot;&lt;/code&gt;&lt;/strong&gt; —— 浏览器原生懒加载：iframe 没滚进视口附近就压根不加载，没加载自然不可能出声。这条是浏览器层面的，比 B 站自己的参数可靠，附带还加快了首屏速度&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;另外浏览器本身有自动播放策略：&lt;strong&gt;带声音的自动播放会被拦截&lt;/strong&gt;，只有静音才允许。所以哪怕参数失效，正常情况下也吵不到人。&lt;/p&gt;
&lt;p&gt;真遇到顽固的自动播放，终极方案是「封面图 + 点击再加载」：先放一张封面，用户点一下才把 iframe 插进 DOM。需要的话我可以写成一个组件，在 Markdown 里一行就能用。&lt;/p&gt;
&lt;h2&gt;方式二：播放 mp4（站内文件或外链）&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; 标签是浏览器原生的播放器，&lt;code&gt;controls&lt;/code&gt; 负责显示进度条，&lt;code&gt;width: 100%&lt;/code&gt; 让它跟着正文宽度走：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;video src=&quot;/fuwari/files/demo.mp4&quot; controls preload=&quot;none&quot; style=&quot;width: 100%; border-radius: var(--radius-large);&quot;&amp;gt;&amp;lt;/video&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;实际效果（这里用的是外链示例文件，换成你自己放在 &lt;code&gt;public/files/&lt;/code&gt; 下的 mp4 就是同样的效果）：&lt;/p&gt;
&lt;p&gt;&amp;lt;video src=&quot;https://media.w3.org/2010/05/sintel/trailer.mp4&quot; controls preload=&quot;none&quot; style=&quot;width: 100%; border-radius: var(--radius-large);&quot;&amp;gt;&amp;lt;/video&amp;gt;&lt;/p&gt;
&lt;h1&gt;文件相关&lt;/h1&gt;
&lt;h2&gt;文件放哪里&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;src/content/posts/img/&lt;/code&gt; 只会处理图片，其他类型（zip / pdf / docx / xlsx / mp4）放到 &lt;code&gt;public/files/&lt;/code&gt; 下，
构建时会原样复制出去，不做压缩和改名。&lt;/p&gt;
&lt;p&gt;注意链接必须带上站点的 base —— 本站是 GitHub Pages 的项目仓库，base 为 &lt;code&gt;/fuwari&lt;/code&gt;，
写成 &lt;code&gt;/files/xxx.zip&lt;/code&gt; 会 404：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[点此下载测试文件](/fuwari/files/test.zip)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;想让浏览器直接弹下载、而不是在线打开，用 HTML 标签加 &lt;code&gt;download&lt;/code&gt; 属性
（Astro 的 Markdown 允许内嵌 HTML）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;a href=&quot;/fuwari/files/test.zip&quot; download&amp;gt;📥 下载测试文件（523 B）&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;实际效果&lt;/h2&gt;
&lt;p&gt;已建好一个测试文件，点下面这个链接就能下载到：&lt;/p&gt;
&lt;p&gt;&amp;lt;a href=&quot;/fuwari/files/test.zip&quot; download&amp;gt;📥 下载测试文件 test.zip（523 B）&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;包内是一个 &lt;a href=&quot;/fuwari/files/test.txt&quot;&gt;test.txt&lt;/a&gt; 和一份说明，用来确认下载链路是通的。&lt;/p&gt;
&lt;h2&gt;几点注意&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;public/&lt;/code&gt; 里的文件会一起进 git 仓库，单文件别超过 100 MB（GitHub 限制），大文件建议放网盘或对象存储再外链&lt;/li&gt;
&lt;li&gt;文件名用英文、不带空格，免得 URL 编码后出幺蛾子&lt;/li&gt;
&lt;li&gt;在线预览 / 直接下载取决于浏览器对文件类型的处理，压缩包一定是下载，pdf 和 txt 多半是直接打开 —— 要强制下载就加 &lt;code&gt;download&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item></channel></rss>