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