持续迭代
个人站点与私有知识工作区
一个把公开展示和私有资料放在同一套代码里的个人站点:公开页面只展示明确选中的内容,工作区默认私有。
项目概览
它解决什么问题
这个站点有两个读者:来访的人,和我自己。来访的人需要看到项目、笔记和一份克制的介绍;我自己需要一个存放参考资料、运行环境和内部记录的地方。 把两者放进同一个仓库,好处是维护一套构建和部署流程,代价是必须把什么内容可以公开做成显式规则。 站点用 Astro 静态构建,采用 Cloudflare Pages 部署方案。公开列表来自显式选择的数据文件;当前本地工作区由 Pages Functions 校验登录会话,记录保存到独立的 D1 数据库。新版工作区尚未部署到生产。
参与内容
负责的部分
- 信息架构:拆分公开站与工作区两套外壳,公开列表只读取显式选中的记录,旧路由保留为兼容路由。
- 视觉基线:定义颜色、时长、缓动 token;标题用 Outfit 与自托管子集化的霞鹜文楷配对,正文用 Inter 加系统中文字体栈,不下载中文正文字体。
- 动效预算:只用 CSS 关键帧、过渡和 IntersectionObserver,尊重 prefers-reduced-motion,工作区页面不做任何入场动画。
- 访问边界:/workspace/* 由 Pages Functions 中间件保护,监控面板通过短时效签名链接进入,凭据只存在环境变量中。
- 构建与验证:静态 HTML 结构检查、主题颜色语法检查、UTF-8 检查,以及 Playwright 浅深两套主题截图。
关键取舍
值得展开的部分
公开是一个显式动作
公开站的项目和笔记列表都来自 public-site.ts 中的选择数组。一条记录要出现在首页,必须有人把它写进这个文件。这让"忘了隐藏"这类错误在结构上不会发生,也让空状态成为一种正常状态,而不是需要遮掩的缺陷。
中文标题字体的取舍
楷体标题和 Outfit 的几何拉丁字形放在一起,字重要降到 500 才协调。完整的文楷字体约 25 MB,站点用脚本按常用字频切成 9 个 woff2 分片并声明 unicode-range,首屏通常只加载第一片;字体加载失败时回退到系统中文字体,布局不变。
动效只做有理由的部分
首页 Hero 用纯 CSS 关键帧入场,不依赖脚本;列表卡片用 IntersectionObserver 加一个类名,起始不透明度保持 0.5,脚本失效时内容仍然可见。所有位移都包在 prefers-reduced-motion: no-preference 里,工作区页面完全没有入场动画。
私有和公开共用一套构建
工作区和公开页共用静态构建,私人记录由经过会话校验的 API 返回。构建过程不读取私人记录数据库,页面访问与记录接口共用 Pages Functions 的会话边界。
项目影像
页面截图



