絮絮叨叨

2026 年 10 月 17 日,这个站点第三次换装。

第一次是 2024 年 12 月上线时的 Next 主题,第二次是今年 7 月随框架一起换成的 liushen,今天这次,换成了一套我自己写的主题——我叫它 Claude。

熟悉我的朋友应该记得,七月那次搬家我写过一篇 《「工具推荐」TRAE》,里面吐槽过 liushen 是从 Hexo 移植过来的,适配做得很粗,深色模式配色错乱、封面失效、闪念热力图异常,我挨个翻源码去缝补。这三个月我一直在补:补深色模式、补封面、补热力图,十月初还给它加了邮箱订阅。

补到后来我发现一件很尴尬的事:我修的不是 bug,是审美。

那些问题的根源不是代码写错了,而是这套视觉语言本身——全屏大图 banner、粉蓝渐变侧栏、毛玻璃胶囊顶栏、带投影堆叠的卡片——就不是我想要的样子。它没坏,只是不对。

于是有了今天这次更换。

一、第一版被我自己否掉了

一开始我想得很简单:把 liushen 刷成奶白色,不就“换了套皮”吗。

真做完一看,不行。骨架还是 liushen 的骨架,分区还是那个分区,只是颜色从蓝变成了奶白——那叫改配色,不叫新主题。

所以这次重做,我先给自己立了两条硬规矩:

  1. 结构与 liushen 对齐:功能与配置变量名一一对应,不重复造轮子,之前配好的东西不用重新填一遍;
  2. 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]。这个站点的每一次变化,基本都是被这些反馈推着往前走的。

也欢迎订阅我的博客,新文章会第一时间发到邮箱。