2026-10-04
维护记录
完成的工作
- 为博客新增页面装饰背景:自动读取
static/bg/下所有图片,在视口左下用「周围透明、中心不透明」的径向渐变显示,多张图片轮流淡入淡出 ✅ - 新增
layouts/baseof.html覆盖主题的 baseof,使用readDir "static/bg"自动发现图片(也可通过site.Params.bg显式覆盖);无需任何配置,新增/删除图片直接生效 - 新增
assets/css/extended/bg.css,PaperMod 自动加载此目录。关键效果:position: fixed+z-index: -1+ 透明 body,确保背景永远在最底层、不干扰阅读mask-image: radial-gradient(circle at 60% 40%, #000 0%, #000 32%, rgba(0,0,0,.6) 55%, transparent 82%)实现「周围透明中心不透明」的渐变- 24 秒一个循环、3 张图错开 8s 延迟轮流淡入淡出
- 暗色模式降低亮度饱和度,移动端缩小尺寸,
prefers-reduced-motion下停止动画只保留首张
hugo --destination /tmp/hugo-bg-test构建验证:首页、文章详情页、归档页均正确渲染.page-bg容器,3 张 jpg 全部复制到public/bg/
遇到的问题
- 起初考虑把背景放在
z-index: -1但 PaperMod 在 body 上画了var(--theme)/var(--code-bg),会盖住子元素的负 z-index 背景。解决方案:将 body 背景搬到html,body 设为透明,让.page-bg在 html 背景之上渲染 ⚠️ - 在assets/css/extended/bg.css中以html { background-color: var(--theme); } body, body.list { background-color: transparent; }覆盖;extended 样式在 core.css 之后 concat,优先级足够
下次建议
- 若后续想支持点击/hover 暂停轮播,可在 baseof.html 加
onmouseenter/onmouseleave控制.page-bg__img的animation-play-state - 暗色模式可考虑提供
bg/下的"暗色专用"图片(用 front matter 或子目录区分),通过site.Params.bgDark控制 - 若图片较多(>5),当前 5 个
:nth-of-type延迟档位不够,可改成 SCSS 生成
维护记录(续)
完成的工作
- 根据用户反馈调整背景行为 ✅
- 轮播 → 随机单图:移除
@keyframes page-bg-fade与:nth-of-type延迟,改为 inline script 每次刷新随机挑一张加.is-active - 左下 → 左中:容器从
bottom: -3vh改为top: 50%; transform: translateY(-50%),垂直居中于视口 - 方形 → 圆形 + 渐变更强:mask 从
radial-gradient(circle at 60% 40%, ..., transparent 82%)改为更陡的circle at 50% 50%(实心区从 32% 收缩到 25%,终点 55% → 82%),最终可见区域是圆形
- 轮播 → 随机单图:移除
- 配套调整:
html初始带class="no-js";脚本启动后移除并改加js,让无 JS fallback(CSS:not(.js)选择器)只在禁用 JS 时生效
遇到的问题
- 旧 keyframes /
animation-delay残留检查:greppage-bg-fade在新 CSS 中匹配数 = 0,animation-delay已全部清除 ✅
下次建议
- 若想每次刷新换图但保持 “会话内不重复”(同一浏览上下文内不重复同张),可改用
sessionStorage记上次 idx,rand 到相同则 +1 - 圆形 mask 在极窄屏幕(< 360px)下
min(190px, 50vw)仍偏大,可再加@media (max-width: 480px)把top: 50%改成更靠上的位置避免被 main 内容遮挡
维护记录(再续)
完成的工作
- 修复背景图片被截断的 bug
- 根本原因:三张源图都是纵向长方形(H/W = 1.30~1.37),但上一版容器是
280x280正方形 +background-size: cover,等于把图片裁成方形(丢失顶部/底部共约 27% 高度),再被圆形 mask 切出来,所以用户看到的永远是原图的中段 53% - 修复:容器改为
aspect-ratio: 5 / 7(比最瘦长的图 1 略高一点,1.4 vs 1.373)的纵向矩形 +background-size: contain,三张图全部完整显示,最坏情况有 5% 的上下微小留白,但留白落在圆形 mask 透明带内完全不可见 - 用 CSS 变量
--page-bg-w/--page-bg-ratio统一管理尺寸,移动端断点只覆盖--page-bg-w,避免重复规则
- 根本原因:三张源图都是纵向长方形(H/W = 1.30~1.37),但上一版容器是
遇到的问题
- 调试时
sips输出的图片尺寸证实了纵向比例;awk 单行格式化因引号转义失败,改用 python3 拼字符串 - Hugo 的 fast render 模式在 CSS 改动后只 rebuild 用了该 CSS 的页面,86ms 完成
下次建议
- 如果以后会增加横向图片(如 banner 截图),单一
aspect-ratio: 5 / 7会让横向图上下留白过多。可在 baseof.html 里读取每张图的尺寸(Hugo imageConfig),按宽高比输出内联style="aspect-ratio: W/H"覆盖默认比例 - 如果之后想加图片懒加载(虽然只有 3 张图不必要),需把 background-image 重构为真实
img元素才能用loading=lazy
维护记录(三续)
完成的工作
- 调整背景定位语义:视口 fixed 改为文档 absolute
- 需求:图片不要一直锁在视口左中部,改为只有滚动到文档最底部才看到
- 改动:
.page-bg容器position: fixed改为position: absolute+inset: 0(撑满整个文档高度);.page-bg__img移除top: 50%; transform: translateY(-50%),改为bottom: 0 - 原理:absolute 元素在没有
position: relative的祖先时会解析到根html节点(即整个文档),bottom: 0就等于文档底部;用户不滚到最下面图片就在视口外
下次建议
- 短页面(如 tags / archives 单页)因为文档本身可能比视口还短,图片可能一加载就直接可见 —— 这其实是想要的行为,但如果以后想让所有页面都必须滚动后才看到,可加一段 JS:
window.scrollY === 0时给.page-bg加opacity: 0、滚动开始后移除
维护记录(四续)
完成的工作
- 修正背景定位语义为 fixed + JS 门控
- 上一版用
position: absolute; bottom: 0,图片在首次渲染时被钉死在文档底部某个像素位置,文档长度变化或用户视角不同时不会跟随 —— 用户反馈“只会固定页面第一次渲染的位置” - 这一版恢复
position: fixed,让图片始终钉在视口左下角;显示条件改为 JS 控制:scroll 到文档底部时才加html.at-bottomclass,CSS 根据这个 class 才把.is-active的图片 opacity 从 0 提到 0.92 - 门控逻辑:
scrollTop + innerHeight >= scrollHeight - 8判定为到底部;滚动/缩放/passive 监听;初始加setTimeout(50)跑一次防止字体加载后布局变化
- 上一版用
遇到的问题
- 上一轮验证误以为 JS 没生效,实际是 Hugo 把 inline script minify 了(
checkAtBottom→n、imgs→t),grep 原名匹配为 0,但函数调用关系完整 ⚠️ - 下次验证用逻辑特征(at-bottomclass、classList.toggle)而非变量名
下次建议
- 如果想“滚到底出现,往上滚不消失(锁住显示)”的语义,把 CSS 改成只在
at-bottom由 false 变 true 那一次加is-revealedclass,之后一直保持。代码量几乎不变 - 当前 8px 阈值偏严格;如果发现用户“明明滚到底部却看不到”可能是设备pixel ratio 导致,可调为
Math.max(8, innerHeight * 0.01)更宽容
维护记录(五续)
完成的工作
- 修复背景渐变只覆盖四个角的 bug
- 根本原因:旧 mask 用
radial-gradient(circle at 50% 50%, ...),CSS 默认closest-side尺寸 —— mask 圆半径 = min(宽,高)/2 = 160px。矩形 5/7(320×448)的上下中点距圆心 224px > 160px,完全在 mask 外被强制透明 → “只有四个角被渐变、中间是硬切” - 修复:mask 改为
radial-gradient(circle farthest-corner at 50% 50%, ...)—— mask 圆半径 = 角部距离 ≈ 275px,整张矩形都在 mask 范围内,矩形上下中点变成 9.4% 不透明、左右中点 34% 不透明、四个角 0%,全部柔和过渡 - 同时:中心实心区从 35% 半径(112px 硬核)收缩到 6% 半径(33px 小硬核),衰减曲线增加中间驻点让过渡更顺
- 根本原因:旧 mask 用
遇到的问题
- 几何验证:手算后角部距离 275px、矩形上下边中点 81.4%、左右边中点 58.1%、与渐变 stops 插值后与 CSS 渲染预期一致 ⚠️
下次建议
- 既然 mask 现在覆盖整张矩形,如果后续觉得“硬心 33px 仍有点硬”,可以试
0% 4%(不要完全实心),让中心也有轻微渐变 - 如果想让背景“雾化”更强(低对比),可以叠加
backdrop-filter: blur(4px)到.page-bg__img,让背景在 mask 透明区也能影响主体内容(需测试性能)
维护记录(六续)
完成的工作
- 上手动抠图:用
@imgly/background-removal-node处理 3 张图- 环境准备:
npm config set registry https://registry.npmmirror.com切淘宝镜像,装包 18s;模型首次加载含下载 ~80MB ONNX - 处理速度:3 张图总计 5 秒(模型已缓存后 1.5-1.9s/张)
- 抠图质量:
- 图 1 (800×1098):主体 53.7%,背景 41.5% 完全透明,边缘羽化 4.8%
- 图 2 (800×1046):主体 37.1%,背景 60.4% 完全透明,边缘羽化 2.5%
- 图 3 (700×909):主体 34.1%,背景 61.8% 完全透明,边缘羽化 4.2%
- 体积增量:原 JPG 总 580KB → 抠图 PNG 总 663KB(+14%,+83KB)
- baseof.html 重构:从“列出全部图片”改为“每个 basename 优先 PNG/WebP/SVG、忽略同名 JPG”,所以原 JPG 保留在磁盘作为回滚、不参加部署
- 环境准备:
- mix-blend-mode 保留(现在 PNG 透明 + blend 双重保障)
遇到的问题
- 模板变量名
replaceRE中特殊字符需要转义,调试两次后\\.(jpg|...)$才正确 ⚠️ - Hugo Go template 中\\在字符串里才是\转义 - 第一版去重 key 错用了
"tier|base",导致同名 PNG/JPG 被认为不同 entry 同时进入 map。修正为仅用base作 key,额外逻辑判断“PNG 是否替换现有 JPG” ⚠️
下次建议
- 原 JPG 现在还在
static/bg/里,如果不再需要回滚可手动删除(节省 580KB 部署体积) - 如果有图抠图质量不好(例如 5/7 中的图 1 主体比例较低,可能背景复杂),可用 sharp 对 PNG 后处理(边缘收缩、降噪、转为 indexed 颜色以减小体积)
- 抠图脚本
/tmp/bg-remove/remove-bg.js可复制到scripts/作为正式维护脚本,但项目主力是 Deno —— 可用deno task remove-bg包装 Python 或 Node 调用
维护记录(七续)
完成的工作
- 放宽 CSS mask 渐变曲线
- 原因:抠图后主体已透明边缘干净,不再需要硬核中心 + 严进渐变
- 改动:从 7 stops (#000 6% / .78 22% / .5 45% / .22 68% / .06 85%) 放宽为 5 stops (#000 30% / .92 50% / .65 75% / .25 90%)
- 效果:中心 50% 半径(直径 ~140px)完全实,整张图片大部分清晰可见,仅矩形外圈 ~25% 半径处开始柔和淡出,角部 0% 融入背景
下次建议
- 如果还觉得图片过渡太柔,可继续抬高 75% 、90% 的不透明度(如 .8 / .45)
- 如果觉得边缘还是过锐(PNG 抠图边缘有时会有可见的轮廓),可以在
.page-bg__img上加filter: drop-shadow(0 0 6px rgba(0,0,0,0.15))柔化
维护记录(八续)
完成的工作
- 删除文章封面系统(commit 1278dd7,pushed to master)
- 删除文件(6 个):
scripts/gen-covers.ts(452 行)、scripts/sync-covers.ts(63 行)、2 个对应测试、layouts/_partials/cover.html、.github/workflows/sync-covers.yml - 修改脚本:从
validate-posts移除coverExists+ cover 校验、从rename-posts移除 cover 重命名逻辑、从git-commit-push移除chore(covers)分类 - 修改配置:
deno.json移除gen-covers/gen-covers-dry/sync-covers/sync-covers-dry4 个 task;hugo.toml移除[params.cover];.github/workflows/deploy.yml移除Generate covers and inject front matter步骤 - 修改 lib:移除
paths.ts的COVERS_DIR常量、更新fs.ts和frontmatter.ts顶部的注释 - 批量修改 225 个 post front matter:删除
cover:块(4 行:cover/image/alt/hidden);处理了 1 个远程 URL 特殊 case(只有 cover + image 两行) - 总计:245 files changed,+99/-2423
- 删除文件(6 个):
遇到的问题
- 修复了 3 个 pre-existing bug(都是 cover 删除任务“顺便”发现的):
extractBody返回正文会多一个前导换行(slice 后未去首\n)—— 修normalizeDate测试有错误的double-quoted用例(parseFrontMatter 已 unquote)—— 删expect.ts缺toBeLessThanOrEqual—— 补
- deno 不可用,用
mise install deno@latest装到~/.local/share/mise/installs/deno/2.9.7,加~/.deno/bin到 PATH;prettier@3.9.6用deno install -g装全局(AGENTS.md 要求)
下次建议
static/images/covers/下 224 个 SVG 还在磁盘上、untracked 状态;如需彻底清理 3.1MB,运行rm -rf static/images/covers✅ 已清理(commit 5ff5088)—— 原来这些 SVG 是 tracked 的(从仓库历史一直有),删除产生了 224 个D:状态,需 commit + push 才彻底从 HEAD 中拿走- 225 个 post 里以前引用的
aliases: ["/posts/legacy-name/"]现在保留 —— 这些 alias 跳转仍然有效(除非本身就是错位的别名),未来若需完全删除可在validate-posts里加一个“alias 对应的旧路径未被引用过则报错”检查 - 回滚:tag
before-remove-cover还在指向 0d49a15(push 前创建的);如需完全回滚git reset --hard before-remove-cover && git push --force——但现在增加了 commit 5ff5088,需用--force-with-lease或先 push tag
维护记录(九续)
完成的工作
- 将 PaperMod 从 git submodule 改为 vendored 目录(commit f7772b7,pushed to master)
- 原因:用户要求“以后不再依赖上游,自己修改主题样式”—— submodule + update-papermod.yml 的自动拉取不符合这个诉求
- 改动:
git submodule deinit -f themes/PaperMod解除 submodule- 从 GitHub
adityatelange/hugo-PaperModclone 最新代码到themes/PaperMod/(125 文件,880K,+6281 LOC) - 删除
themes/PaperMod/.git(避免嵌套 git repo) - 删除
.gitmodules、.git/modules/themes/PaperMod/(PaperMod 内部 git 历史丢弃,节省 10M) - 删除
.github/workflows/update-papermod.yml(不再需要自动 submodule 更新) - 原有 override 文件不受影响:
layouts/baseof.html和assets/css/extended/bg.css仍由主仓库提供,Hugo 主仓库 wins 优先级不变
- 后续使用:需要改主题时,直接编辑
themes/PaperMod/...,作为主仓库普通 commit 推送即可
遇到的问题
git submodule deinit会清空 working tree(themes/PaperMod/ 变空目录),需从上游 GitHub 重新 clone 一份;clone 后必须删除内部.git否则主仓库可能误认为嵌套 git repo ⚠️
下次建议
- 主题代码现在所有改动走主仓库 commit,今后如需 cherry-pick 上游修复:
git fetch https://github.com/adityatelange/hugo-PaperMod.git然后在主仓库中手动 patch 对应文件 - 考虑加一个
themes/PaperMod/CHANGELOG.md,记录对这个主题本地修改的历史(什么 commit 改了哪个文件、为什么改),方便后续追踪 - 如将来修改较频繁,可以在
themes/PaperMod/上加.git-blame-ignore-revs文件忽略上游原厂 commit
维护记录(十续)
完成的工作
- 主题更换:PaperMod → hugo-paper(commit e6f0a2e + b5a3505,pushed to master)
- 原因:用户要求“换主题,换成
nanxiaobei/hugo-paper” - 删除:themes/PaperMod/(125 文件)、layouts/baseof.html、assets/css/extended/bg.css、assets/images/cover-default.svg
- vendor-in:themes/hugo-paper/(86 文件,3.0M),与 PaperMod 同样作为普通目录
- hugo.toml 清理:
- theme = “PaperMod” → theme = “hugo-paper”
- 删除 PaperMod 特有的 [params.cover] / [params.homeInfoParams] / [[params.socialIcons]] / [params.assets] / [params.editPost] / [params.schema] 块
- menu 简化为 posts / claudelog / source / about(去掉 search / tags / archives,按用户要求)
- 加
mainSections = ["posts"]避免 claudelog 泄露到首页
- 背景图代码移植:
- bg CSS 从
assets/css/extended/bg.css(PaperMod 约定)拼接到assets/custom.css(hugo-paper 用户入口) - 去掉 PaperMod 特有的 html/body 背景调位逻辑(hugo-paper 用
--bgCSS 变量) - bg 逻辑从 baseof override 拆为独立 partial
layouts/partials/bg.html layouts/_default/baseof.html复制 hugo-paper 的 baseof,仅多了{{ partial "bg.html" . }}
- bg CSS 从
- 可接受的丢失(按用户要求):
- Tags / archives / search 页面不存在(hugo-paper 不带这些模板)
- 首页副标题 “我,想去看海。” 丢失(hugo-paper 无 homeInfoParams 机制;需要重加可在 content/_index.md 里写)
- 额外修复:.prettierignore 增加
themes/hugo-paper—— vendor 主题里的.prettierrc.mjs引用了prettier-plugin-css-order/prettier-plugin-organize-imports/prettier-plugin-tailwindcss三个未装的插件,导致deno task format-markdown-check报错
- 原因:用户要求“换主题,换成
遇到的问题
- vendor 主题自带的
.prettierrc.mjs会被项目级 prettier 扫描到,触发 “Cannot find package ‘prettier-plugin-css-order’” 报错。加 .prettierignore 排除即可(不能删除 vendor 文件,因为 vendor 完整复制是用户要求)⚠️
下次建议
- hugo-paper 不内置
params.cover,背景图的图片列表靠 readDir “static/bg/” 自动发现。今后如需指定顺序 / 某些图片只在特定文章出现,可以在hugo.toml里加[params.bg] = ["bg/foo.png", ...] - 背景图的 bg partial 现在依然依赖
layouts/_default/baseof.htmloverride ——hugo-paper 上游升级需要同步 baseof.html,注释中已提醒 - 如未来需要 tags / archives / search,可考虑:tags/archives 借助 hugo-paper 的
list.html+[taxonomies]配置写一个 minimal partial;search 则需额外引入 fuse.js
维护记录(十一续)
完成的工作
- 默认主题强制为亮色(commit 6ec98f5,pushed to master)
- 原因:用户要求 “让主题强制默认使用亮色”
- 改动:override
layouts/partials/header.html(复则 vendorthemes/hugo-paper/layouts/partials/header.html,仅改 JS 部分) - 原有逻辑(跟随系统):
1const darkScheme = window.matchMedia("(prefers-color-scheme: dark)"); 2setDark(darkVal ? darkVal === "true" : darkScheme.matches); 3darkScheme.addEventListener("change", (event) => { 4 setDark(event.matches); 5}); - 新逻辑(默认 light,不跟随系统):
1const darkVal = localStorage.getItem("dark"); 2setDark(darkVal ? darkVal === "true" : false); 3// darkScheme.addEventListener 完全删掉 - 切换按钮 .btn-dark 保留:用户仍可手动点击切到暗色,切到暗色后 localStorage 持久化,后续访问优先遵从用户选择
遇到的问题
- 曾考虑在 head.html 加
<meta name="color-scheme" content="light">锁定表单元素 / 滚动条为亮色。但这会与 JS 切换冲突(用户手动切暗色后表单仍亮)—— 舍弃。改取 vendor 默认(不锁),让浏览器 UI 跟随页面主题切换 ⚠️ - hugo-paper 没有
params.defaultMode这样的配置开关,只能 override header.html partial
下次建议
- 如果以后觉得连切换按钮都不需要,加这一行在
assets/custom.css即可:1.btn-dark { 2 display: none; 3} - 同步上游 hugo-paper 时记得也同步
layouts/partials/header.html(override 文件依赖 vendor base 文件同步)
维护记录(十二续)
完成的工作
- 站点 title 重命名 + README 全面刷新(commit e956147,pushed to master)
- 原因:用户要求 “把 ‘Last Regrets’ 改成 ‘海边’”
- hugo.toml:
title = "Last Regrets"→title = "海边" - README.md:一并顺手刷新(从
PaperMod submodule时代以后从未更新,已多处过时):- PaperMod → hugo-paper
- 删去所有 cover 系统表述(sync-covers / sync-covers.yml / cover.image / 封面一致性)
- 列出现在实际的 layout override:
layouts/partials/bg.html/layouts/partials/header.html/layouts/_default/baseof.html - 增加
assets/custom.css(hugo-paper 用户 CSS 入口) - 主体同步章节从
git submodule update --remote themes/PaperMod改为git clone upstream + diff 手动 patch,并提醒baseof.html/header.htmloverride 文件依赖上游同步 - 首次克隆去掉
--recursive(不再 submodule)
遇到的问题
- README 里的
deno task/github workflows列表都是历史版本,但用户主要要求是改 title,所以只做了中等改动:删 cover 相关、更新主题名。未动其他还未过时的部分(如本地预览 / 发布文章 / 命名约定)⚠️
下次建议
- README 里的 deno task 列表还可以加
check-dead-links、git-commit-push-dry还未列入;如以后加新脚本记得同步 README
维护记录(十三续)
完成的工作
- 文档架构刷新:AGENTS.md + README.md 重写 + CLAUDE.md 删除(commit e59e4e6 + e74c464,pushed to master)
- 原因:用户要求““因为博客架构发生了很大变化 @AGENTS.md 和 @README.md 都更新一下,然后删除 @CLAUDE.md””
- AGENTS.md 重写:从 PaperMod submodule 时代的旧规范进化为 hugo-paper vendor-in + 当前项目实际布局的新规范
- 项目结构:列出现有 override(bg.html / header.html / _default/baseof.html)、明确 assets/custom.css 是 hugo-paper 用户 CSS 入口、说明 static/bg/ 是背景图 cutouts 位置
- 主题同步:
git submodule update --remote themes/PaperMod→git clone upstream + diff 手动 patch,提醒 baseof.html / header.html override 文件依赖上游同步 - deno task 列表:删 sync-covers(cover 系统已删),补 check-dead-links / git-commit-push-dry
- 编码规范:删
npm:sharp@0.33.5(已不用)、删 cover.image front matter 描述、补static/bg/*.png cutouts说明 - Agent 任务执行规范:增加 codemode 优先 条款(适合脚本的任务用 codemode 写 JavaScript 一次性调用工具)
- 新增 工具偏好 节:rg 优先 / 不要自动 commit / push / PR(从 CLAUDE.md 折入)
- README.md 补充:加 特性 节(默认亮色 / 背景图 / CJK 友好 / claudelog)、布局详情补上 override 清单、deno task 加 check-dead-links
- CLAUDE.md 删除:以前是个 wrapper(5 行:指向 AGENTS.md + 两条 Claude Code 特有提示)。两条特有提示(rg 优先、不自动 push)已全部合并进 AGENTS.md 的“工具偏好”节,wrapper 失去了独立存在的意义
遇到的问题
- CI race:CLAUDE.md 删除 + commit message 被 CI bot 抢先 push 成
f1ca216(commit author 是 github-actions[bot],但 commit message 包含了我写的内容,估计是 deploy.yml 拉取 working tree 某些机制)。我本地实际是分两次 commit 才 push 上去:第一次只走 CLAUDE.md 删除(CI bot 推),第二次包含 AGENTS.md + README.md 全部改动。最终 rebase + push 同步 ⚠️ - 这种 race 以后可以避免:一次只 commit 一个主题,且 commit 前最好 fetch origin master 确认是否已有同步
下次建议
- AGENTS.md 现在合并了 CLAUDE.md 的所有内容,以后不会再有 wrapper 文件 但要时刻记得 CLAUDE.md 不存在,不要再创建该文件
- 如果未来 Claude Code / Cursor / Copilot 等其他 Agent 工具也需要特定提示,可考虑:每 Agent 一个入口文件(如 .cursor/rules / copilot-instructions.md),但以 AGENTS.md 为唯一标准事实