絮絮叨叨
2026 年 10 月 17 日,这个站点第三次换装。
第一次是 2024 年 12 月上线时的 Next 主题,第二次是今年 7 月随框架一起换成的 liushen,今天这次,换成了一套我自己写的主题——我叫它 Claude。
熟悉我的朋友应该记得,七月那次搬家我写过一篇 《「工具推荐」TRAE》,里面吐槽过 liushen 是从 Hexo 移植过来的,适配做得很粗,深色模式配色错乱、封面失效、闪念热力图异常,我挨个翻源码去缝补。这三个月我一直在补:补深色模式、补封面、补热力图,十月初还给它加了邮箱订阅。
补到后来我发现一件很尴尬的事:我修的不是 bug,是审美。
那些问题的根源不是代码写错了,而是这套视觉语言本身——全屏大图 banner、粉蓝渐变侧栏、毛玻璃胶囊顶栏、带投影堆叠的卡片——就不是我想要的样子。它没坏,只是不对。
于是有了今天这次更换。
一、第一版被我自己否掉了
一开始我想得很简单:把 liushen 刷成奶白色,不就“换了套皮”吗。
真做完一看,不行。骨架还是 liushen 的骨架,分区还是那个分区,只是颜色从蓝变成了奶白——那叫改配色,不叫新主题。
所以这次重做,我先给自己立了两条硬规矩:
- 结构与 liushen 对齐:功能与配置变量名一一对应,不重复造轮子,之前配好的东西不用重新填一遍;
- UI 全量重写:禁止保留 liushen 的任何一个视觉元素。
第 2 条执行得比想象的狠。整套旧视觉机制是被删掉的,不是改颜色:整页背景图、页头顶图 banner、SVG 波浪、渐变侧栏、毛玻璃顶栏、卡片投影堆叠,连“圆角"”文字颜色“这类开放给用户的自由值都一并去掉了——因为它们会让页面随时跑偏。
二、这套视觉语言,参照的是 Claude 的品牌语言
先说清楚一件事:我不是把官网截图描了一遍,而是把它的设计系统——颜色令牌、字体规则、间距节奏、组件规范——整层抽出来,再按博客的用途重新落地。
为什么一个博客敢挪用一套 AI 产品的品牌语言
因为这套语言的本质不是“科技感”,是编辑感。
你去翻一圈主流 AI 产品的官网,几乎清一色冷色调:OpenAI 的灰蓝、Google 的饱和蓝、微软的商务青。Claude 是那个反着来的——暖调奶白做画布、珊瑚做强调、标题走衬线体。这三个选择加起来,读起来像一本杂志专栏,不像一个 SaaS 落地页。
而对一个写东西的站点来说,“像杂志”恰恰是最对的状态。所以我搬的不是“AI 公司的样子”,是“编辑部的样子”。
三色三位一体,不允许第四种表面
整套系统只有三种表面色调,加一个强调色:
| 角色 | 令牌 | 色值 | 用在哪 |
|---|---|---|---|
| 画布 | --canvas |
#faf9f5 |
页面地板,暖调奶白,不是纯白 |
| 浅卡 | --surface-card |
#efe9de |
卡片面,比画布深一档 |
| 深墨 | --surface-dark |
#181715 |
代码卡、页脚 |
| 珊瑚 | --primary |
#cc785c |
唯一的强调色 |
规矩是:不引入第四种表面色调。 没有紫色卡、没有绿色区块、没有蓝色信息条。色相一多,品牌感立刻散掉。
这里有个容易被误会的地方——深色块不是“深色模式”。它是版面里的一个拍点,浅色模式下照样存在。真正的深色模式是另外一套令牌映射,两件事互不搭界。
字体的那条硬规矩:显示级字重恒为 400
这条是整套语言里我最喜欢的一条,也是最容易被人改坏的一条。
标题用衬线(Copernicus / Tiempos Headline),正文用无衬线(StyreneB / Inter),代码用等宽(JetBrains Mono)。但真正的规矩在字重上:
显示级字号一律字重 400,绝不加粗。需要强调时,换更大的字号,不换更粗的字重。
再配一个负字距(-0.2px 到 -1.5px,字号越大收得越紧)。这两条加起来才是那种“沉着的、想过的”语气。同样的标题换成 700 字重,立刻变成喊话。
老实说,字体栈里前两个名字在绝大多数人的机器上都不存在——Copernicus 和 StyreneB 是 Anthropic 的自有商用字体,没有公开 webfont,真正生效的是后面的回退。我在这套栈里额外补了中文衬线回退链(思源宋体 / Noto Serif SC / 宋体),因为这是个中文站:Copernicus 没有中日韩字形,中文标题会直接掉进系统默认衬线。中文衬线天生比拉丁衬线“重”一些,所以负字距在中文上我收得更保守,不然会挤成一团。
那个小星标
Anthropic 有个四芒放射的小标记(radial spike mark),像一颗手画的星。它在页头品牌位、页脚、“首页”图标上各出现一次,是内联 SVG。
它是全站唯一一个图形化的品牌资产。除此之外,整站没有一个位图 logo、没有一张摄影图。
立体感靠色块,不靠投影
这是跟旧主题差别最大的一条。旧主题靠投影堆叠出层次,这套语言的哲学反过来:色块优先,投影罕见。
| 层级 | 做法 |
|---|---|
| 平的 | 无投影、无边框(页头、首屏、正文区) |
| 细描边 | 1px --hairline 边框(输入框、次级导航) |
| 浅卡 | 换 --surface-card 背景,不加投影 |
| 深卡 | 换 --surface-dark 背景,不加投影 |
| 浮层 | 弱投影(下拉、抽屉这类真的浮起来的东西) |
整个样式表里 box-shadow 只出现了 11 次,而且几乎全在下拉菜单、抽屉、搜索面板这些真的浮在页面上的元素,以及输入框聚焦时的珊瑚光圈上。卡片一律不加投影。
还有个细节我很喜欢:描边色 --hairline(#e6dfd8)和“禁用态”是同一个色值。意思是边框摸上去像“抬高一级”,而不像“画了条线”——因为它是从画布色里调出来的,不是从墨色里调出来的。
珊瑚是稀缺资源
这套语言对珊瑚的态度可以概括成一句话:点缀上吝啬,通栏上大方。
单个元素上,珊瑚只允许小面积出现:主按钮、徽标、列表的项目符号、热力图最高档、深色面上的链接。除此之外——
- 不允许铺满版面
- 不允许用于大段文字
- 不允许拿来做卡片背景和边框网格
只有通栏 CTA 区块允许整块铺满珊瑚。所以首页那条订阅通栏是全站唯一的珊瑚通栏,别处找不到第二块。
原因很朴素:珊瑚一多就不亮了。 强调色的力量来自对比,满屏都是强调,等于没有强调。这是这套语言最容易被破坏的一条,也是我改旧主题时最想推翻的一条。
节奏优先于装饰
页面由若干个“区段”纵向堆叠,规矩只有一句话:相邻两个区段,不得使用同一种表面。
标准的六拍是这样的:
① 奶白 ── 首屏:衬线大标题 + 说明
② 奶白卡 ── 信息卡组(比画布深一档)
③ 深墨 ── 文章列表第一篇大卡 / 首屏右侧代码卡 ← 拍点
④ 奶白 ── 其余文章栅格
⑤ 珊瑚 ── 订阅通栏 CTA ← 第二个拍点
⑥ 深墨 ── 页脚(浅色 / 深色主题都不反转)
用大白话讲:文章的段落需要有起伏,页面也一样。如果从上到下全是同一个底色,读者就失去了“翻页感”,滚多久都像停在同一屏。
深色块在这套设计里是拍点——它自带产品感,比任何装饰插画都更贴题。正因为它稀缺,它才有效。
区段间距 96px,窄屏收到 64px(手机上 96px 会空得离谱)。
图用线描,不用摄影
封面一律是内置 SVG 线描几何,四种构图轮换:珊瑚细线 + 虚线辅助线 + 青绿圆点,画在奶白底上。不引用任何外部位图。
好处很实际:任何时候都不会出现“图裂了”——没有外链就没有裂的可能;也不会出现“图把标题盖住了”——线描本来就是稀疏的。
最后一张表:我搬了什么,又改了什么
官网是卖产品的落地页,博客是给人读长文的,直接照搬会出事。所以有些地方我改了:
| Claude 官网 | 这个博客 | 为什么改 |
|---|---|---|
| 正文 16px / 行高 1.55 | 正文 17px / 行高 1.75 | 中文长文行距要更松,1.55 在中文上太挤 |
| 内容通栏 1200px | 正文测量宽 720px | 一行 40 来个汉字最好读,通栏读长文会串行 |
| Hero 六六分栏 + 产品卡 | 左文右深色代码卡 | 博客首屏得说清“我在写什么” |
| 定价卡 / 模型对比卡 | 文章列表四种排布 | 官网卖产品,博客卖文章 |
| 珊瑚 CTA 通栏 | 订阅通栏 | 同一套机制,文案换成订阅 |
| 全站区段间距 96px | 桌面 96 / 窄屏 64 | 手机屏 96px 空得离谱 |
改完之后,它还是那套语言,但已经是一个博客的样子了。
三、你能看到的具体变化
| 位置 | 变成什么样 |
|---|---|
| 顶栏 | 通栏三分区(品牌 / 菜单 / 按钮组),菜单落在视口中线上;只放站名,站点描述不再跟首屏重复一遍 |
| 首屏 | 左文右深色代码卡,衬线大标题 + 打字机副标题 |
| 文章列表 | 四种排布可后台切换:整齐栅格 / 瀑布流 / 杂志混排 / 紧凑列表 |
| 首页信息区 | 原来侧栏的 9 个 widget 重新落位成「信息卡组 + 编辑列表 + 年份条」,功能一个不少 |
| 订阅 | 从侧栏小卡改成珊瑚通栏 CTA |
| 友链页 | 新增「朋友动态」:抓朋友们的 RSS,先看骨架屏再逐条渲染 |
| 搜索 | 整屏奶白层,不再是弹窗 |
| 图标 | 全部换成内联 SVG,去掉 FontAwesome 依赖 |
| 移动端 | 文章在上、卡片在下(原来卡片会抢到正文前面) |
四种排布里我最喜欢「杂志混排」:置顶文章和正文超过 1200 字的长文会自动放大成跨列大卡,其余保持标准卡。卡片大小由文章本身的属性决定,不是随机花样——写长的人自然得到更大的位置,这比”按位置轮换“公平得多。
四、技术复盘:给同样在折腾 Gridea Pro 的人
下面这部分偏硬核,是这次重写真正花时间的地方。如果你也在自己改主题,希望有点用。
1. 配置项全部加前缀
109 个配置项全部改成 claude 开头。原因很实在:Gridea Pro 的主题配置是共享命名空间的,不同主题之间会互相污染。 换主题时残留的同名变量会把新主题带偏。
只有 20 个”内部契约键“保留了短名——它们是模板与 main.js 之间耦合的通道,改了会导致整套交互失效。
2. 设计令牌单一事实源 + 别名层
所有颜色、圆角、间距必须走 CSS 变量,写死色值算违规。变量分两层:
:root{
/* 基础层:只在这里出现真实色值 */
--canvas:#faf9f5;
--primary:#cc785c;
--surface-dark:#181715;
/* 别名层:主题切换只改这一层 */
--bg:var(--canvas);
--fg:var(--ink);
}
[data-theme="dark"]{
--bg:var(--surface-dark);
--fg:var(--on-dark);
}
组件样式从头到尾一行都不需要动。旧主题里有 300 行 [data-theme="dark"] 的逐元素硬编码覆盖,这套写法下完全不需要——那 300 行本身就是”令牌没建好“的症状。
3. 对比度是硬指标,不是凭感觉
正文与背景的对比度要求 ≥ 4.5:1(这是 WCAG AA 的及格线,大白话就是”视力不太好的长辈也能看清“)。为了守住这条,改了三处:
| 场景 | 原本 | 改后 |
|---|---|---|
| 珊瑚底配白字 | #cc785c → 3.28:1 :cross_mark: |
压暗成 #a9583e → 5.06:1 :check_mark_button: |
| 深色面上的链接 | 压暗色 → 3.54:1 :cross_mark: | 换回原色 #cc785c → 5.47:1 :check_mark_button: |
| 卡片上的次级文字 | --muted → 4.48:1(边缘) |
新增 --fg-muted-strong → 5.97:1 :check_mark_button: |
有意思的是第二行:同一个珊瑚色,在浅色面上要压暗,在深色面上反而要用原色。 这不是审美摇摆,是数学。
4. 动效纪律:不许用 display 硬切
下拉菜单、抽屉、搜索面板这类开合,一律用 visibility + opacity + transform 过渡,禁用 display。
原因是 display 不参与插值,浏览器不会给一个不渲染的元素做动画——关闭时会”啪“地一下消失,没有过渡。
实测踩到的一个坑值得记下来:下拉菜单点了没反应、鼠标移开才收起。根因是鼠标停在触发器上时 :hover 恒成立,光靠增删 .is-open 压不过它。修法是关闭态单独写 .nav-drop.is-closed,并用 .is-closed:hover 提高特异性。
时长上:下拉 200ms、抽屉 280ms、主题切换 380ms(径向遮罩从点击点扩散)、搜索 260ms,并且全部尊重系统的”减弱动效“设置。
5. 两个真实的翻车
翻车一:模板语法。
为了修「关于页」的死链,我在 base.html 顶部写了个宏去解析页脚导航。本地用独立 nunjucks 跑,6 个用例全过、7 个模板 precompile 全过——结果在 Gridea Pro 里一构建,全站渲染失败。
结论:独立 nunjucks 验证通过 ≠ Gridea Pro 的真实引擎认可。 从此任何模板层面的新写法,都必须先在 GP 里实际构建一次才算数。最后这个需求是用最笨也最稳的方式解决的:把 6 个文件里的 /about/ 纯文本替换成 /post/about/,零模板语法、零风险。
翻车二:客户端回写。
Gridea Pro 客户端开着的时候,会用内存里的旧配置回写站点 config.json,把我刚迁移好的配置冲掉,还混进 7 个 liushen 的死键。
教训:改配置前先确认客户端状态,改完提醒自己重启。
最后
从”改个配色“到”重写一套节奏“,这次折腾的工程量远超我最初的预估。但看到首页从上往下滚时那种奶白 → 深色 → 奶白 → 珊瑚的呼吸感,我觉得值。
如果你在浏览时发现了什么不对劲的地方——错位、看不清、点了没反应——欢迎直接在评论区/「一起来找茬」留言,再或者发邮件到 [email protected]。这个站点的每一次变化,基本都是被这些反馈推着往前走的。
也欢迎订阅我的博客,新文章会第一时间发到邮箱。
评论