/* ============================================================
   有牛 — 内页样式：文章详情、归档、标签、404
   复用 site.css 的变量与材料语言，只补结构性的部分。
   ============================================================ */

/* ---------- 页脚品牌（深底上给 logo 一块乳白底，保证读得清） ---------- */
.site-foot__brand img{
  width:40px; height:40px; border-radius:50%;
  background:var(--milk);
  border:var(--hair) solid var(--milk);
  object-fit:contain;
}

/* ---------- 面包屑 ---------- */
.crumbs{
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  font-size:var(--step-meta); letter-spacing:.06em;
  color:var(--ink-60);
}
.crumbs a{ text-decoration:none; transition:color .2s var(--ease); }
.crumbs a:hover{ color:var(--pasture); }
.crumbs__now{ color:var(--ink); }

/* ===========================================================
   逐行揭示（public/js/prose-reveal.js）
   -----------------------------------------------------------
   初始状态写在 CSS 里、由 JS 揭幕，这样首帧就是藏好的，不会先亮一下再收回去。
   万一 JS 没跑起来，那条 8 秒的 ynFail 会把内容放出来 —— 文章永远读得到。
   =========================================================== */

/* 初始：正文每个块 + 文章大标题，都先藏起来。
   选择器挂在静态 HTML 上（而不是 JS 后来加的类），首帧就是藏好的，
   不会先亮一下再被 JS 收回去。
   注意 :not(.is-in) 不能省：带 id 的选择器特异性高过 .rv-b.is-in，
   少了它，露面的那条规则永远赢不了，文章会一直隐形。 */
.js #prose > *:not(.is-in),
.js .artHead__title:not(.is-in){
  opacity:0;
  animation:ynFail 0s linear 8s forwards;
}
.js .artHead__title:not(.is-in){ transform:translateY(14px); }
/* 脚本顺利接管了，兜底动画撤掉 */
.js.yn-rv-armed #prose > *,
.js.yn-rv-armed .artHead__title{ animation:none; }

@keyframes ynFail{ to{ opacity:1; } }

/* 拆过行的块：由行负责出场，块自己不再位移 */
.rv-split{ transform:none !important; }

.rv-ln{
  display:inline-block;
  /* width:max-content 是必须的，不是保险：
     inline-block 的宽度默认「能用多少缩多少」（shrink-to-fit）。但凡旁边有浮动模块
     （::: tip |右），那一行留给正文的地方就变窄了，行盒被压窄、里面的字被
     overflow:hidden 横着切掉半截 —— 看起来像排版坏了。
     钉成 max-content，行盒就永远等于「这行字本身的宽度」，
     该绕排照样绕排，但一个字都不会被吃掉。 */
  width:max-content;
  overflow:hidden;               /* 这行露出多少，全看这里 */
  vertical-align:top;
  /* inline-block 会让行末空格被吃掉一点点，补回来，免得整行窄半格 */
  white-space:normal;
}
.rv-ln--atom{ overflow:visible; width:auto; max-width:100%; }   /* 图片这类不要被裁 */
/* 字体到位后如果发现行被裁了（量行时用的是替身字体），把遮罩撤掉 */
.yn-rv-nomask .rv-ln{ overflow:visible; }

.rv-in{
  display:inline-block;
  opacity:0;
  transform:translateY(105%);
  transition:opacity .5s var(--ease), transform .58s var(--ease);
}
.rv-in.is-in{ opacity:1; transform:none; }

/* 一块整体的位移（没拆行的块走这条） */
.rv-b{
  transition:opacity .55s var(--ease), transform .62s var(--ease);
}
.rv-b.is-in{ opacity:1; transform:none; }

/* 收摊 / 减少动效：一律直接给全 */
.yn-rv-off #prose > *,
.yn-rv-off .artHead__title,
.yn-rv-off .rv-in{
  opacity:1 !important; transform:none !important; animation:none !important;
}

@media (prefers-reduced-motion: reduce){
  .rv-b,.rv-in{ opacity:1 !important; transform:none !important; animation:none !important; transition:none !important; }
}

@media print{
  .rv-b,.rv-in{ opacity:1 !important; transform:none !important; }
  /* 打印时没有「滚动到」这回事，全文一律显形 */
  .js #prose > *,
  .js .artHead__title{ opacity:1 !important; transform:none !important; }
}

/* ---------- 内页通用页头 ---------- */
.pageHead{ padding-top:clamp(118px,15vh,168px); }
.pageHead__title{ font-size:clamp(2rem,4.6vw,3.4rem); margin-top:18px; }
.pageHead__lead{ margin-top:18px; }
/* 页头后面紧跟的章节不用再撑一次上下留白，否则中间空一大片 */
.pageHead + .sec{ padding-block-start:clamp(38px,6vh,64px); }

/* ============================================================
   文章详情
   ============================================================ */

/*
  文章头 = 「文字区」+「地平线带」。
  地平线带高度固定并用 padding-bottom 预留出来，文字永远不会压到草地上。
  之前的问题是场景用绝对定位贴底、文字跟着内容自然流动，窄屏时两者就会重叠。
*/
.artHead{
  position:relative; isolation:isolate; overflow:hidden;
  padding-top:clamp(104px,13vh,146px);
  padding-bottom:clamp(170px,24vh,250px);
  background:linear-gradient(180deg,
    color-mix(in srgb, var(--mist) 58%, var(--milk)) 0%,
    var(--milk) 82%);
}
.artHead__inner{ position:relative; z-index:5; }

.artHead__scene{
  position:absolute; left:0; right:0; bottom:0; z-index:1;
  height:clamp(170px,24vh,250px);
  overflow:hidden;
}
.artHead__sun{
  position:absolute; right:11%; top:6%;
  width:clamp(44px,4.6vw,72px); aspect-ratio:1; border-radius:50%;
  background:var(--hay);
  box-shadow:0 0 0 10px color-mix(in srgb,var(--hay) 24%, transparent),
             0 0 64px 18px color-mix(in srgb,var(--hay) 34%, transparent);
}
.artHead__scene > *{ will-change:translate; }
/* 远坡铺满整条带子（山脊落在带宽约 40% 处），近处草地压在底部 */
.artHead__hills{ position:absolute; left:0; bottom:0; width:100%; height:100%; }
.artHead__grass{ position:absolute; left:0; bottom:0; width:100%; height:42%; }

.artHead__title{
  font-size:clamp(1.85rem,4.6vw,3.5rem);
  line-height:1.3; max-width:19em;
  margin-top:22px;
}
.artHead__meta{
  display:flex; align-items:center; gap:14px; flex-wrap:wrap;
  margin-top:clamp(20px,3vh,30px);
  font-size:var(--step-meta); letter-spacing:.08em;
  color:var(--ink-60); font-variant-numeric:tabular-nums;
}
.artHead__meta .dot{ width:5px; height:5px; border-radius:50%; background:var(--hay); }
/* 作者署名：多人写的时候得看得出是谁的活 */
.artHead__author{
  display:inline-flex; align-items:center; gap:6px;
  color:var(--ink); font-weight:700; letter-spacing:.04em;
}
.artHead__author::before{
  content:""; width:18px; height:2px; background:var(--hay); border-radius:2px;
}
.artHead__tags{
  display:flex; gap:10px; flex-wrap:wrap;
  list-style:none; margin:18px 0 0; padding:0;
}
.artHead__tags a{
  display:inline-block; text-decoration:none;
  font-size:var(--step-meta); letter-spacing:.06em;
  border:var(--hair) solid var(--ink); border-radius:var(--r-pill);
  padding:3px 14px 4px;
  transition:background .25s var(--ease), transform .25s var(--ease);
}
.artHead__tags a:hover{ background:var(--leaf-14); transform:translateY(-2px); }

/* ---------- 正文区：左目录 + 右正文 ---------- */
.artBody{
  display:grid;
  grid-template-columns:minmax(0,220px) minmax(0,1fr);
  gap:clamp(28px,5vw,64px);
  align-items:start;
  padding-block:clamp(44px,7vh,76px) 0;
}
/* 正文钉在第二列。目录少于 3 项时模板不会输出 aside.toc，
   那时候如果正文还按「自动排」走，就会掉进第一列那条 220px 的空槽、
   变成窄窄的一长条（读起来非常难受）。所以：
     · 显式指定列号 —— 认不出下面那条 :has 的老浏览器也只会多留白，不会变窄
     · 目录不在的时候，正文直接跨满两列 */
.artBody > .prose{ grid-column:2; }
.artBody:not(:has(> .toc)) > .prose{ grid-column:1 / -1; }
.artBody > .prose{ max-width:44rem; }

.toc{
  position:sticky; top:96px;
  border-left:var(--line) solid var(--ink);
  padding-left:20px;
  font-size:.92rem;
}
.toc__h{
  font-family:var(--font-display); font-weight:900;
  font-size:.78rem; letter-spacing:.14em; text-transform:uppercase;
  color:var(--ink-60); margin-bottom:14px;
}
.toc ol{ list-style:none; margin:0; padding:0; }
.toc li{ margin-bottom:9px; line-height:1.6; }
.toc a{
  text-decoration:none; color:var(--ink-60);
  transition:color .2s var(--ease), padding-left .2s var(--ease);
}
.toc a:hover{ color:var(--pasture); padding-left:4px; }
.toc__l3{ padding-left:14px; font-size:.88rem; }

/* ---------- 排版：正文 ---------- */
.prose{
  font-size:1.075rem;
  line-height:2.05;
  color:var(--ink);
}
.prose > * + *{ margin-top:1.5em; }

.prose h2{
  font-family:var(--font-display); font-weight:900;
  font-size:clamp(1.36rem,2.3vw,1.85rem);
  line-height:1.4; letter-spacing:-.005em;
  margin-top:2.4em; padding-top:.2em;
  scroll-margin-top:96px;
}
.prose h2::after{
  content:""; display:block; width:56px; height:4px;
  background:var(--hay); margin-top:14px;
}
.prose h3{
  font-family:var(--font-display); font-weight:900;
  font-size:clamp(1.1rem,1.7vw,1.3rem);
  line-height:1.5; margin-top:2em;
  scroll-margin-top:96px;
}
.prose h4{ font-weight:700; font-size:1.06rem; margin-top:1.7em; }

.prose a{
  color:var(--pasture);
  text-decoration:underline;
  text-decoration-thickness:1.5px;
  text-underline-offset:4px;
  transition:background .2s var(--ease);
}
.prose a:hover{ background:var(--leaf-14); }

/* 加粗：为什么不能只写 font-weight。
 *
 * 正文是 --font-body（霞鹜文楷 / 楷体 / 宋体 / STKaiti 这条楷体系列），
 * 这类手写感字体**只有一个字重**，`font-weight:700` 是落空的 ——
 * 浏览器也不会替它合成加粗。实测同一串「命令模式重点」在 400 / 700 / 900 下
 * 渲染宽度完全一致（103.53px，差 0），页面上加粗和正文一样重，肉眼分不出。
 *
 * 所以改成给字形**描一圈边**：这是同字族的「真加粗」，楷体的手感原样保住。
 * 宽度是 0.45px —— 并排比过 0.30 / 0.45 / 0.60 三档：0.30 仍偏弱，
 * 0.60 开始把「模式」「编辑」这类笔画密的字堵到一起，0.45 是分界点。
 * 描边是居中的，向外各扩 0.225px，所以不改排版宽度（横排不会因此重排）。
 *
 * 用 -webkit- 前缀写法是刻意的：Chrome / Safari / Edge / Firefox 都认这个名字
 * （Firefox 从 49 起把它当别名支持），而标准名 text-stroke 反而没人实现。
 * 万一哪个浏览器不认，也只是退回「跟正文一样重」，跟改之前一样，不会更糟。
 *
 * font-weight 留着：现在不生效，但哪天正文换成有粗体的字体，它就该接手。
 */
.prose strong,.prose b{
  font-weight:700;
  -webkit-text-stroke:.45px currentColor;
}

.prose ul,.prose ol{ padding-left:1.5em; }
.prose li{ margin-top:.55em; }
.prose li::marker{ color:var(--pasture); }
.prose ol li::marker{ font-family:var(--font-display); font-weight:900; font-size:.9em; }

/* 引用块有两副面孔，按「里面装的是什么」分。

   ① 装的是段落 / 列表 / 代码 / 图 —— 真在「引用一段内容」。
      这时候卡片态是对的：给一块底，「这段是别人说的」。
   ② 装的是标题 —— `>### 一、xxx`，作者其实是在**给标题挂一根色条**。
      卡片态套上去就散了：
        · padding-top 20px 和标题自己的 margin-top 2em 会叠起来
          （外边距和 padding 不合并），标题上方塌出一大片空心色块；
        · 底色把标题裹成一张卡，跟同一篇里其他 h2/h3 不是一个体系，
          它没法跟那些标题排在同一条线上。

   判据用「有没有非标题的直接子元素」而不是枚举 p/ul/pre —— 反过来写，
   将来多出什么新块（figure、details、::: 模块）都会自动落回卡片态，
   不会因为漏了一个标签就把内容挤成一堆。 */
.prose blockquote{
  --bq-pad-y:20px;
  --bq-pad-x:26px;
  border-left:5px solid var(--hay);
  background:color-mix(in srgb, var(--hay) 9%, var(--milk));
  padding:var(--bq-pad-y) var(--bq-pad-x);
  font-size:1.04em;
  color:color-mix(in srgb, var(--ink) 86%, var(--pasture));
}
.prose blockquote p + p{ margin-top:1em; }

/* ② 素引用：只剩那根竖条，底色和上下内边距都撤掉。
   左内边距留着 —— 竖条到文字的距离跟卡片态一致，两种引用看起来才是一家人。
   font-size 还原成 1em：1.04em 的微放大是给正文段落用的，标题字号是绝对值，
   吃不到它，留着只会让 h1（em 单位）在两种引用里长得不一样。 */
.prose blockquote:not(:has(> :not(h1, h2, h3, h4, h5, h6))){
  background:none;
  padding:0 0 0 var(--bq-pad-x);
  font-size:inherit;
  color:inherit;
  /* ★ 关键一手：margin-top 归零，让标题自己的 margin-top 透上来
     （块上没有 padding-top / border-top，外边距会合并）。
     所以它的上下间距跟块外同级标题**一模一样** ——
     不是凑一个近似值，是真排在同一条线上。 */
  margin-top:0;
}

/* 卡片态里，第一个元素要是标题就贴顶 —— padding-top 已经给了呼吸。
   不归零的话两层上边距一叠，标题就被顶到半空里去。
   注意要排除素引用（那种情况上一条正指望这 2em 透上来当外边距）。 */
.prose blockquote:has(> :not(h1, h2, h3, h4, h5, h6)) > :is(h1, h2, h3, h4, h5, h6):first-child{
  margin-top:0;
}

/* 引用里标题下面的内容别贴着标题走 */
.prose blockquote > :is(h1, h2, h3, h4, h5, h6) + *{ margin-top:1em; }

.prose code{
  font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size:.88em;
  background:color-mix(in srgb, var(--leaf) 14%, var(--milk));
  border:var(--hair) solid color-mix(in srgb, var(--ink) 22%, var(--milk));
  border-radius:4px;
  padding:.12em .42em;
}
.prose pre{
  background:var(--ink); color:color-mix(in srgb, var(--milk) 90%, var(--leaf));
  border-radius:var(--r-sticker);
  border:var(--line) solid var(--ink);
  padding:22px 24px;
  overflow-x:auto;
  line-height:1.75;
  font-size:.9rem;
  box-shadow:5px 5px 0 color-mix(in srgb, var(--ink) 22%, var(--milk));
}
.prose pre code{
  background:none; border:0; padding:0;
  font-size:inherit; color:inherit;
}

/* 代码块里的四类高亮（span 由 src/highlight.js 生成，只这四种）。
   底色是 --ink 那种深墨，所以每一档都得够亮才读得出来 —— 注释那档尤其，
   压太暗会整块糊成灰的（52% 试过，太闷，最后定在 58%）。
   四档全从站内调色板里取，不另外引新色：
     注释 = 压暗的乳白 · 字符串 = 干草黄 · 关键字 = 草叶绿 · 数字 = 晨雾蓝
   只挂在 .prose 下：这套 span 只可能来自围栏代码块，
   别的地方（比如后台自己的界面）不该受影响。 */
.prose .tok-com{ color:color-mix(in srgb, var(--milk) 58%, var(--ink)); }
.prose .tok-str{ color:var(--hay); }
.prose .tok-kw{ color:var(--leaf); }
.prose .tok-num{ color:var(--mist); }

/* 只有「没写尺寸」的图才撑满整栏。
   一旦写了 width / height（`![图](/a.png =600x)`），就把尺寸交还给作者 ——
   注意这里不能写 `width:auto`：那条 CSS 会盖掉 HTML 尺寸属性这种
   presentation hint，图片会弹回原始像素尺寸。所以给尺寸图只兜一道 max-width，
   其余全留给属性本身。
   用属性选择器而不是加 class，用户手写 <img width="300"> 也能自动跟着走。 */
.prose img{
  border:var(--line) solid var(--ink);
  border-radius:var(--r-sticker);
}
.prose img:not([width]):not([height]){
  width:100%; height:auto;
}
.prose img[width],
.prose img[height]{
  max-width:100%;
}
.prose figure{ margin-inline:0; }
.prose figcaption{
  margin-top:12px; font-size:var(--step-meta);
  color:var(--ink-60); text-align:center;
}

/* ---------- 表格 ----------
   两条取舍：

   ① 造型上它是一张「贴纸」，不是一张铁丝网。外框沿用全站的材料语言
      （2px 墨线 + 圆角 + 硬阴影，跟 ::: 模块同一套），表格在正文里因此是
      一块看得见边界的东西；内部**只留横线，竖线全撤** —— 中文表格列少、
      字长，横线已经足够分行，竖线一多就密得读不动。

   ② 圆角要真生效，border-collapse 得切成 separate：collapse 模式下单元格
      四角是直角，会把表格自己的圆角顶破。表格又没法用 overflow:hidden 收边
      （对 table 无效），所以四个角手工补半径。补的时候按「表头管上两角、
      最后一行管下两角」分开写 —— 写 tr:last-child 会先命中 thead 那一行，
      把表头下沿也裁圆。 */
.prose table{
  width:100%;
  border-collapse:separate; border-spacing:0;
  font-size:.96rem; line-height:1.65;
  background:var(--milk);
  border:var(--line) solid var(--ink);
  border-radius:var(--r-sticker);
  box-shadow:5px 5px 0 color-mix(in srgb, var(--ink) 14%, var(--milk));
}
.prose th,.prose td{
  padding:12px 16px; text-align:left; vertical-align:top;
  border-bottom:var(--hair) solid color-mix(in srgb, var(--ink) 20%, var(--milk));
}
/* 最后一行不画底线：收在外框上，圆角才干净 */
.prose tbody tr:last-child > th,
.prose tbody tr:last-child > td{ border-bottom:0; }

/* 表头：牧草深绿底 + 乳白字。这是站里已有的「深色材料」（页脚、代码块同源），
   比原来的淡绿底立得住，也把「表头 / 数据」的分界一次说清。
   不再刷隔行底色 —— 表头已是实色块，上头再加斑马纹会打架；
   扫行改靠 hover 高亮，不靠条纹。 */
.prose thead th{
  font-family:var(--font-display); font-weight:900;
  font-size:.86rem; letter-spacing:.08em;
  color:var(--milk); background:var(--pasture);
  white-space:nowrap;
  /* 表头和第一行数据之间不画线：深绿块的下沿自己就是分界，
     再压一条浅墨线只会在深色上糊出一层脏边 */
  border-bottom:0;
}
.prose tbody tr{ transition:background .15s var(--ease); }
.prose tbody tr:hover{ background:color-mix(in srgb, var(--hay) 12%, var(--milk)); }

/* 四角对齐外框半径（外框 2px，所以内减 2px） */
.prose thead th:first-child{ border-top-left-radius:calc(var(--r-sticker) - 2px); }
.prose thead th:last-child{ border-top-right-radius:calc(var(--r-sticker) - 2px); }
.prose tbody tr:last-child > :first-child{ border-bottom-left-radius:calc(var(--r-sticker) - 2px); }
.prose tbody tr:last-child > :last-child{ border-bottom-right-radius:calc(var(--r-sticker) - 2px); }
/* 手写的、没带表头的表也得有上圆角 */
.prose table:not(:has(thead)) tbody tr:first-child > :first-child{ border-top-left-radius:calc(var(--r-sticker) - 2px); }
.prose table:not(:has(thead)) tbody tr:first-child > :last-child{ border-top-right-radius:calc(var(--r-sticker) - 2px); }

/* 对齐交给作者：`| ---: |` 这类写法 marked 会吐 align 属性，照做就是 ——
   数字列右对齐配等宽数字，是读表最好用的一手，不用作者记类名。 */
.prose :is(th,td)[align="right"]{ text-align:right; font-variant-numeric:tabular-nums; }
.prose :is(th,td)[align="center"]{ text-align:center; }

.prose hr{
  border:0; border-top:var(--line) solid var(--ink);
  width:72px; margin-inline:auto;
}

/* ---------- 文末 ---------- */
.artFoot{
  margin-top:clamp(40px,6vh,64px);
  padding-top:26px;
  border-top:var(--line) solid var(--ink);
}
.artFoot__sign{ display:flex; align-items:center; gap:14px; }
.artFoot__sign img{
  width:52px; height:52px; border-radius:50%;
  background:color-mix(in srgb, var(--milk) 90%, var(--leaf));
  border:var(--line) solid var(--ink); object-fit:contain;
}
.artFoot__sign b{ display:block; font-family:var(--font-display); font-weight:900; font-size:1.05rem; }
.artFoot__sign span{ display:block; font-size:var(--step-meta); color:var(--ink-60); }
.artFoot__cover{
  margin-top:22px; width:100%; height:auto;
  border:var(--line) solid var(--ink); border-radius:var(--r-sticker);
}

/* ---------- 上一篇 / 下一篇 ---------- */
.artNav{
  display:grid; grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(16px,3vw,36px);
  margin-top:clamp(38px,6vh,60px);
}
.artNav__item{
  display:block; text-decoration:none;
  border-top:var(--line) solid var(--ink);
  padding:18px 2px 20px;
  transition:background .3s var(--ease), padding-left .3s var(--ease), padding-right .3s var(--ease);
}
.artNav__item span{
  display:block; font-size:var(--step-meta); letter-spacing:.1em;
  color:var(--ink-60); margin-bottom:8px;
}
.artNav__item b{
  font-size:var(--step-h3); font-weight:400; line-height:1.5;
  display:block;
}
.artNav__item--next{ text-align:right; }
.artNav__item--prev:hover{ background:var(--leaf-14); padding-left:14px; }
.artNav__item--next:hover{ background:var(--hay-30); padding-right:14px; }

/* ---------- 相关文章 ---------- */
.related{ border-top:var(--line) solid var(--ink); margin-top:clamp(56px,9vh,96px); }

/* ============================================================
   归档 / 标签
   ============================================================ */

.months{
  list-style:none; margin:0; padding:0;
  display:grid; grid-template-columns:repeat(auto-fill,minmax(150px,1fr));
  gap:0 clamp(16px,3vw,40px);
}
.months li{
  display:flex; align-items:baseline; justify-content:space-between; gap:12px;
  border-top:var(--hair) solid var(--ink);
  padding:12px 2px 13px;
  font-size:.94rem;
}
.months b{ font-weight:400; font-variant-numeric:tabular-nums; }
.months span{ font-size:var(--step-meta); color:var(--ink-60); }

.tagCloud{
  list-style:none; margin:0; padding:0;
  display:flex; flex-wrap:wrap; gap:12px;
}
.tagCloud a{
  display:inline-flex; align-items:baseline; gap:8px;
  text-decoration:none;
  border:var(--line) solid var(--ink); border-radius:var(--r-pill);
  padding:8px 18px 9px;
  background:var(--milk);
  transition:transform .22s var(--ease), box-shadow .22s var(--ease), background .22s var(--ease);
}
.tagCloud a:hover{
  transform:translate(-1px,-2px);
  box-shadow:4px 5px 0 var(--ink);
  background:var(--hay-30);
}
.tagCloud i{
  font-style:normal; font-size:var(--step-meta);
  color:var(--ink-60); font-variant-numeric:tabular-nums;
}

.yearNav,.anotherTags{
  display:flex; flex-wrap:wrap; gap:10px;
  margin-top:clamp(34px,5vh,54px);
  padding-top:24px; border-top:var(--line) solid var(--ink);
}
.yearNav__item{
  text-decoration:none;
  border:var(--hair) solid var(--ink); border-radius:var(--r-pill);
  padding:5px 16px 6px;
  font-family:var(--font-display); font-weight:900; font-size:.86rem;
  letter-spacing:.03em;
  transition:background .22s var(--ease);
}
.yearNav__item:hover{ background:var(--leaf-14); }
.yearNav__item.is-now{ background:var(--ink); color:var(--milk); }

/* ============================================================
   全部文章（/all）—— 年 → 月 → 行
   ------------------------------------------------------------
   参照的是一种「超大浅灰年份 + 分组列表」的常见写法，照搬会变成跟本站
   毫无关系的模板感（米色 + 灰字 + 一堆留白）。翻成站内语汇之后是这样：
     · 年份是这一段的路碑 —— 字号给到最大、颜色压到最浅（墨 52%），
       后面接一条淡墨线把「共几篇」推到行尾，年份就不会孤零零地飘着；
     · 月份只是次级分隔 —— 一行小字，靠字距和留白分层，不跟年份抢线；
     · 文章行复用首页那套（绿底扫过、草叶从底下长出来），
       但日期从「2026.09.28」缩成「28」：在年月分组下面，前两段是重复信息。
   ============================================================ */

/* 年份多的时候给一条直接跳过去的窄路；只有一年时模板不会渲染它 */
.yearJump{
  display:flex; flex-wrap:wrap; gap:10px;
  padding-top:clamp(26px,4vh,38px);
}
.yearJump .yearNav__item{ display:inline-flex; align-items:baseline; gap:7px; }
.yearJump .yearNav__item i{
  font-style:normal; font-weight:400; font-size:.76rem;
  color:var(--ink-60); font-variant-numeric:tabular-nums;
}

/* .sec 的上下 padding 在这里不适用（一段接一段，不能每段都留满） */
.sec.allBand{ padding-block:clamp(30px,5vh,54px) 0; scroll-margin-top:96px; }
.sec.allBand:last-of-type{ padding-bottom:clamp(26px,4vh,42px); }

.allBand__head{
  display:flex; align-items:center; gap:clamp(14px,2.4vw,26px);
  margin-bottom:clamp(14px,2.4vh,24px);
}
.allBand__year{
  flex:none;
  font-family:var(--font-display); font-weight:900;
  font-size:clamp(2.4rem,5.4vw,4rem); line-height:1;
  letter-spacing:-.025em; font-variant-numeric:tabular-nums;
  /* 52% 的墨：对牛乳白是 3.7:1 —— 这个字号（最小 38px）按大文本标准
     只要 3:1，留了余量；比纯黑浅一大截，才当得起「路碑」而不是标题。 */
  color:color-mix(in srgb, var(--ink) 52%, var(--milk));
  text-decoration:none;
  transition:color .28s var(--ease);
}
.allBand__year:hover{ color:var(--ink); }
.allBand__rule{
  flex:1 1 auto; min-width:24px; height:var(--hair);
  background:color-mix(in srgb, var(--ink) 24%, transparent);
}
.allBand__count{
  flex:none; font-size:var(--step-meta); color:var(--ink-60);
  letter-spacing:.1em; white-space:nowrap;
}

/* 月与月之间拉开，月与自己的文章之间收紧 —— 靠近谁就是谁的 */
.allMonth + .allMonth{ margin-top:clamp(32px,4.6vh,48px); }
.allMonth__head{
  display:flex; align-items:baseline; gap:8px;
  margin-bottom:2px; padding-left:2px;
  font-family:var(--font-display); font-weight:900;
  font-size:.8rem; letter-spacing:.18em;
  color:var(--ink-60);
}
.allMonth__head i{ font-style:normal; opacity:.45; }
.allMonth__en{ letter-spacing:.24em; }

/* 行：不加分隔线，靠间距和 hover 认行。56 行每行都描一道线会变成表格。 */
.allList{ border-bottom:0; }
.allList .post{
  grid-template-columns:54px minmax(0,1fr) 132px 88px;
  gap:clamp(14px,2vw,24px);
  padding:13px 4px 15px;
  border-top:0;
}
.allList .post__date{
  font-family:var(--font-display); font-weight:900;
  font-size:.92rem; letter-spacing:.02em;
}
/* hover 时草叶是从行底长出来的 42px 高图形，行本身只有 66px 高，
   压到相邻行会很难看 —— 这里把它收小一号，留在自己这一行里 */
.allList .post__grass{ width:32px; bottom:2px; }

.allFoot{
  padding-block:clamp(34px,5vh,54px) clamp(60px,9vh,100px);
  border-top:var(--line) solid var(--ink);
}
.allFoot .lead a{ text-underline-offset:5px; text-decoration-thickness:1.5px; }
.allFoot .lead a:hover{ color:var(--pasture); }

/* ============================================================
   404
   ============================================================ */
.notFound{ padding-block:clamp(120px,18vh,200px) clamp(80px,12vh,140px); }
.notFound__grid{
  display:grid; grid-template-columns:minmax(0,300px) minmax(0,1fr);
  gap:clamp(32px,6vw,80px); align-items:center;
}
.notFound__sticker{
  border:var(--line) solid var(--ink); border-radius:var(--r-sticker);
  background:color-mix(in srgb, var(--milk) 94%, var(--leaf));
  padding:18px 18px 0; box-shadow:6px 6px 0 var(--ink);
}
.notFound__sticker img{ margin-inline:auto; width:100%; height:auto; }
.notFound__code{
  font-size:clamp(3rem,9vw,6rem); line-height:1;
  color:var(--hay);
  -webkit-text-stroke:2px var(--ink);
}
.notFound h1{ font-size:clamp(1.5rem,3.4vw,2.2rem); margin-top:10px; }

/* ============================================================
   响应式
   ============================================================ */
@media (max-width:1080px){
  .artBody{ grid-template-columns:minmax(0,1fr); }
  /* 折成单列了，就得把正文收回第 1 列。
     上面 `.artBody > .prose{ grid-column:2 }` 是给两栏时写的：单列网格里
     指定第 2 列不会报错，而是**悄悄生成一个隐式列** —— 正文照样被推到右边，
     第 1 列（目录）被挤成 0 宽，而目录里的字是溢出来的，
     于是手机上看到的是「目录的一列字压在正文左边」。
     390px 下量到的网格是 `0px 322px`，目录宽 0，就是这么来的。 */
  .artBody > .prose{ grid-column:1 / -1; }
  .toc{
    position:static; order:-1;
    border-left:0; border-top:var(--line) solid var(--ink);
    padding:18px 0 0;
  }
  .toc ol{ display:flex; flex-wrap:wrap; gap:6px 18px; }
  .toc li{ margin-bottom:0; }
  .toc__l3{ padding-left:0; }
}

@media (max-width:960px){
  .notFound__grid{ grid-template-columns:minmax(0,1fr); }
  .notFound__sticker{ max-width:260px; }
}

@media (max-width:760px){
  .prose{ font-size:1.04rem; line-height:1.98; }
  .prose pre{ padding:16px 16px; font-size:.84rem; box-shadow:4px 4px 0 color-mix(in srgb, var(--ink) 22%, var(--milk)); }
  /* 只改两个量，卡片态和素引用一起跟着收窄 —— 分开写就得在每处重复一遍长选择器 */
  .prose blockquote{ --bq-pad-y:16px; --bq-pad-x:18px; }
  .prose table{ font-size:.9rem; box-shadow:4px 4px 0 color-mix(in srgb, var(--ink) 14%, var(--milk)); }
  .prose th,.prose td{ padding:10px 12px; }
  /* 表头窄屏允许折行：nowrap 的短标签遇上更窄的屏会顶破表格 */
  .prose thead th{ white-space:normal; letter-spacing:.04em; }
  .artNav{ grid-template-columns:minmax(0,1fr); }
  .artNav__item--next{ text-align:left; }
  .pageHead{ padding-top:clamp(104px,14vh,140px); }
  .months{ grid-template-columns:repeat(auto-fill,minmax(132px,1fr)); }
}

/* ============================================================
   邻居（友链）
   卡片沿用全站的「贴纸」语言：乳白底 + 2px 墨线 + 硬阴影，
   hover 时抬起来、描边加粗，是这块地里少数该有手感的地方。
   ============================================================ */

.linkFarm{
  list-style:none; margin:0; padding:0;
  display:grid; gap:clamp(14px,1.6vw,20px);
  grid-template-columns:repeat(auto-fill, minmax(272px, 1fr));
}
.linkCard{ display:flex; }

.linkCard__hit{
  display:flex; align-items:flex-start; gap:15px;
  width:100%; padding:17px 18px;
  background:var(--milk);
  border:var(--line) solid var(--ink);
  border-radius:var(--r-sticker);
  box-shadow:4px 4px 0 color-mix(in srgb, var(--ink) 22%, transparent);
  text-decoration:none;
  transition:transform .28s var(--ease), box-shadow .28s var(--ease), background .28s var(--ease);
}
.linkCard__hit:hover{
  transform:translate(-2px,-3px);
  box-shadow:7px 8px 0 var(--ink);
  background:var(--leaf-14);
}

.linkCard__logo{
  flex:none; width:56px; height:56px;
  display:grid; place-items:center; overflow:hidden;
  background:var(--hay-30);
  border:var(--hair) solid var(--ink);
  border-radius:var(--r-sticker);
}
.linkCard__logo img{ width:100%; height:100%; object-fit:cover; }
.linkCard__initial{
  font-family:var(--font-display); font-weight:900;
  font-size:1.5rem; line-height:1; color:var(--pasture);
}

.linkCard__body{ display:flex; flex-direction:column; gap:3px; min-width:0; }
.linkCard__name{
  display:flex; align-items:center; gap:6px;
  font-family:var(--font-display); font-weight:900;
  font-size:1.04rem; line-height:1.35;
}
.linkCard__go{
  font-style:normal; font-weight:400; font-size:.9em; opacity:.42;
  transition:transform .28s var(--ease), opacity .28s var(--ease);
}
.linkCard__hit:hover .linkCard__go{ transform:translate(2px,-2px); opacity:1; }

.linkCard__host{
  font-family:var(--font-display); font-weight:400;
  font-size:.72rem; letter-spacing:.04em; color:var(--ink-60);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.linkCard__desc{ margin-top:5px; font-size:.9rem; line-height:1.75; color:var(--ink-60); }

/* 一块牌子都没有时 */
.linkEmpty{
  padding:clamp(38px,6vh,58px) 24px; text-align:center;
  border:var(--line) dashed color-mix(in srgb, var(--ink) 34%, var(--milk));
  border-radius:var(--r-sticker);
  background:color-mix(in srgb, var(--leaf) 5%, var(--milk));
}
.linkEmpty__title{ font-family:var(--font-display); font-weight:900; font-size:1.1rem; }
.linkEmpty__hint{ margin-top:8px; font-size:.9rem; color:var(--ink-60); }

/* 「也想做邻居」的木牌：顶部钉了一颗钉子 */
.linkAsk{ padding-block-start:0; }
.linkAsk__card{
  position:relative; max-width:640px;
  padding:clamp(26px,4vw,38px) clamp(22px,3.4vw,34px);
  background:var(--milk);
  border:var(--line) solid var(--ink);
  border-radius:var(--r-sticker);
  box-shadow:5px 5px 0 color-mix(in srgb, var(--ink) 20%, transparent);
}
.linkAsk__peg{
  position:absolute; left:50%; top:-13px;
  width:26px; height:13px; margin-left:-13px;
  background:var(--hay);
  border:var(--line) solid var(--ink);
  border-radius:4px 4px 0 0;
}
.linkAsk__title{ font-size:var(--step-h3); }
.linkAsk__text{ margin-top:12px; color:var(--ink-60); line-height:1.95; }
.linkAsk__btn{ margin-top:20px; }

@media (max-width:760px){
  /* 这里必须把手机端的行重排自己再写一遍：`.allList .post` 比 site.css 里的
     `.post` 更具体，会把那边早就为窄屏写好的 grid-areas 一并盖掉 ——
     只改桌面不补这份，手机上就是四列挤成一团。
     排列也跟首页那套不一样：首页的行高、留白都宽，日期独占一行才撑得住；
     这里的列表动辄五六十行，日期、标题、标签挤回一行才不至于翻不到底。 */
  .allList .post{
    grid-template-columns:42px minmax(0,1fr) auto;
    grid-template-areas:"date title tag";
    align-items:baseline;
    gap:0 12px;
    padding:16px 2px 18px;
  }
  .allList .post__date{ grid-area:date; }
  .allList .post__title{ grid-area:title; }
  .allList .post__tag{ grid-area:tag; }
  .allList .post__time{ display:none; }
  .allList .post__grass{ width:26px; bottom:0; }

  .allBand__head{ gap:13px; }
  .allBand__year{ font-size:clamp(2.1rem,11vw,2.9rem); }
  .allBand__count{ font-size:.74rem; letter-spacing:.06em; }
}

@media (max-width:420px){
  .linkFarm{ grid-template-columns:1fr; }
}
