[{"data":1,"prerenderedAt":137},["ShallowReactive",2],{"archive-groups":3},[4],{"year":5,"posts":6},2025,[7,20,31,40,49,58,68,75,82,89,97,105,112,121,129],{"path":8,"title":9,"description":10,"date":11,"updated":12,"tags":13,"category":15,"cover":17,"draft":18,"pinned":19,"featured":18},"\u002Fposts\u002Ftypography-over-color","排版比配色更决定气质","把同样一套颜色交给两个人排，出来的东西可以完全不同。这篇讲我怎么用字重、行距和留白，在不换颜色的前提下改变一个页面的脾气。","2025-10-28",null,[14,15,16],"排版","设计","CSS","\u002Fimages\u002Fcovers\u002Ftypography.png",false,true,{"path":21,"title":22,"description":23,"date":24,"updated":12,"tags":25,"category":29,"cover":30,"draft":18,"pinned":19,"featured":18},"\u002Fposts\u002Fxml-escaping-stress-test","特殊字符与代码块压测：& \u003C > \" ' 全都要","一篇专门用来喂 RSS\u002FAtom 校验器的文章。正文里塞满了 & \u003C > 引号、CDATA 边界、嵌套代码块和原始 HTML 片段。","2025-10-20",[26,27,28],"RSS","XML","测试","工程","\u002Fimages\u002Fcovers\u002Fcharset.png",{"path":32,"title":33,"description":34,"date":35,"updated":12,"tags":36,"category":39,"cover":12,"draft":18,"pinned":18,"featured":18},"\u002Fposts\u002Fmath-test","在博客里写公式","用 KaTeX 在 Markdown 里写行内与块级数学公式：语法、排版约定、以及写错时的表现。","2025-11-07",[37,38,14],"数学","KaTeX","写作",{"path":41,"title":42,"description":43,"date":44,"updated":12,"tags":45,"category":29,"cover":12,"draft":18,"pinned":18,"featured":18},"\u002Fposts\u002Fdeleted-90-percent","我删掉了站点的 90% 功能","一个博客需要什么？列表、文章、归档、搜索、订阅。其他东西我全删了，然后发现加载时间从 2.3 秒掉到了 380 毫秒。","2025-10-12",[46,47,48],"性能","架构","反思",{"path":50,"title":51,"description":52,"date":53,"updated":12,"tags":54,"category":29,"cover":12,"draft":18,"pinned":18,"featured":18},"\u002Fposts\u002Fcjk-tokenizer","中文分词为什么把搜索做坏了","MiniSearch 默认按空格切词，对中文来说等于完全失效。这篇讲 CJK 该怎么切，以及 bigram 加单字兜底为什么比单纯整词匹配更靠谱。","2025-09-30",[55,56,57],"搜索","MiniSearch","中文",{"path":59,"title":60,"description":61,"date":62,"updated":12,"tags":63,"category":66,"cover":67,"draft":18,"pinned":18,"featured":19},"\u002Fposts\u002Fview-transitions","View Transitions 不是动画库","用它做页面切换、做主题扩散、做列表到详情的共享元素过渡。它真正的价值不是\"让页面动起来\"，而是让你不必手动管理进入和离开两套状态。","2025-09-18",[64,65,16],"动画","浏览器","前端","\u002Fimages\u002Fcovers\u002Fview-transition.png",{"path":69,"title":70,"description":71,"date":72,"updated":12,"tags":73,"category":29,"cover":12,"draft":18,"pinned":18,"featured":18},"\u002Fposts\u002Fstatic-search","静态博客的搜索为什么不用后端","300KB 的索引、一次懒加载、纯前端查询。对一个几百篇文章的博客来说，这个方案比任何搜索引擎都合适。","2025-09-05",[55,47,74],"SSG",{"path":76,"title":77,"description":78,"date":79,"updated":12,"tags":80,"category":15,"cover":12,"draft":18,"pinned":18,"featured":18},"\u002Fposts\u002Fstop-using-cards","别再用卡片装一切","卡片是个好东西，但它有明确的使用条件。当每一块内容都变成同样圆角同样阴影的卡片时，页面就失去了层级，读者也失去了方向。","2025-08-22",[15,81,48],"布局",{"path":83,"title":84,"description":85,"date":86,"updated":12,"tags":87,"category":66,"cover":12,"draft":18,"pinned":18,"featured":18},"\u002Fposts\u002Fself-hosted-fonts","自托管字体的一年","从 Google Fonts 换成自托管，从自托管换成子集化分片。聊聊为什么一个中文字体能从 25MB 变成实际加载 180KB。","2025-08-08",[88,46,57],"字体",{"path":90,"title":91,"description":92,"date":93,"updated":12,"tags":94,"category":15,"cover":12,"draft":18,"pinned":18,"featured":18},"\u002Fposts\u002Fdark-mode-design","暗色模式不是把颜色反过来","反转配色是最省事的做法，也是最糟的做法。暗色模式需要重新设计对比度、阴影、饱和度和层级关系。","2025-07-25",[95,15,96],"暗色模式","可访问性",{"path":98,"title":99,"description":100,"date":101,"updated":12,"tags":102,"category":29,"cover":12,"draft":18,"pinned":18,"featured":18},"\u002Fposts\u002Fzero-hardcode","一个配置文件能解决多少问题","零硬编码听起来是教条，实践起来是架构约束。这篇讲我怎么用四个配置文件把全站的可变内容抽干净，以及它带来的真实收益。","2025-07-10",[47,103,104],"配置","可维护性",{"path":106,"title":107,"description":108,"date":109,"updated":12,"tags":110,"category":111,"cover":12,"draft":18,"pinned":18,"featured":18},"\u002Fposts\u002Fslow-writing","慢下来之后我才开始写得下去","追求\"高效写作\"的那几年，我一篇文章都没写完。放弃效率之后，反而写了几十篇。","2025-06-18",[39,48],"随笔",{"path":113,"title":114,"description":115,"date":116,"updated":12,"tags":117,"category":15,"cover":12,"draft":18,"pinned":18,"featured":18},"\u002Fposts\u002Fmobile-first-375","写给 375px 的界面","移动端不是缩小版桌面。底部 Tab 栏、可达的拇指区、iOS 安全区——这些细节决定了移动端体验的下限。","2025-06-02",[118,119,120],"响应式","移动端","交互",{"path":122,"title":123,"description":124,"date":125,"updated":12,"tags":126,"category":66,"cover":12,"draft":18,"pinned":18,"featured":18},"\u002Fposts\u002Fno-loading-feel","无加载不是速度，是连续感","一个 300ms 的白屏比一个 800ms 的骨架屏更让人焦虑。这篇讲怎么用 SSG、预取和 view transition 把页面跳转做成「一瞬间的事」。","2025-05-15",[46,127,128],"体验","Nuxt",{"path":130,"title":131,"description":132,"date":133,"updated":12,"tags":134,"category":66,"cover":12,"draft":18,"pinned":18,"featured":18},"\u002Fposts\u002Fcss-variables-as-api","我把 CSS 变量当成了 API","设计 token 写进配置文件，构建期编译成 CSS 变量，组件只读变量。这套做法让「改一处，全站生效」从口号变成了构建期保证。","2025-04-20",[16,135,136],"设计系统","构建",1794113901485]