/* ═══════════════════════════════════════════════════════════════
   MOZUNSTUDIO · 设计令牌与基础样式
   ─────────────────────────────────────────────────────────────
   设计原则（从参考图里提炼，但克制使用）：

     1. 靠【排版和留白】撑质感，不靠渐变和光晕
        —— 满屏渐变是廉价感的第一来源

     2. 圆角只在【按钮和输入框】上，卡片用直角 + 细线
        —— 全是圆角卡片会糊成一坨

     3. 强调色只有【紫 → 粉】一条，其余全是灰阶
        —— 蓝绿黄红只保留"警示"用途，不出现在正常界面

     4. 字号做三级跳，不做平铺
        —— 大标题要大到能当主角，正文要小到能退后

     5. 数据和技术信息用等宽字体
        —— 这是"专业工具"的味道，不是"网页"的味道

   ═══════════════════════════════════════════════════════════════ */

:root {
  /* ── 背景：四层，拉开纵深 ── */
  --bg:        #08070e;
  --bg-deep:   #050409;
  --surface:   #100f19;
  --surface-2: #171520;

  /* ── 描边：两级，细而明确 ── */
  --rule:      #1d1a28;
  --rule-2:    #2b2739;

  /* ── 文字：四级，层级分明 ──
     注意 --ink-4 是"最小的那级"，用在全大写等宽小标签上。
     太暗会看不见（我第一版就调太暗了），所以它不能低于这个亮度。 */
  --ink:       #ecebf4;
  --ink-2:     #a09db6;
  --ink-3:     #716e88;
  --ink-4:     #58556c;

  /* ── 唯一强调色：紫 → 粉 ── */
  /* 强调色：淡蓝。
     紫色只留给首页第四屏那一处"音乐的大海"（--brand-grad）。
     功能性的东西 —— 按钮、当前项、高亮文字、链接悬停 —— 全部走淡蓝。
     为什么：紫色是"情绪"，蓝色是"可操作"。一个页面里两者不该抢同一件事。 */
  --a1:        #7ec8f0;
  --a2:        #a8d6f5;
  --brand-grad: linear-gradient(100deg, #a855f7 0%, #e879f9 100%);

  /* ── 语义色：只在出问题时出现 ── */
  --warn:      #e8a33d;
  --danger:    #e8545c;
  --sky:       #9dc9f0;   /* 淡蓝 —— 只在首页那句英文标用 */

  /* ── 尺寸 ── */
  --r:    8px;    /* 按钮/输入框 */
  --r-s:  6px;
    /* 布局宽度跟着视口走，别写死。
     1120px 在 1440 屏上是 78%，在 2739 屏上只剩 41% ——
     大屏上整站像一张邮票贴在屏幕正中。
     clamp 让它在大屏上真的铺开，小屏仍然守 1120 以内。 */
  /* 2026-10-25：从 clamp(1120, 78vw, 1480) 改成下面这条。
     旧的写法在 2512 屏上算到 1480（59%），还被三档 @media 覆盖成 1680。
     两套机制在同一条属性上抢权 —— 那是"大屏露馅"的一半原因。
     现在只留这一条，三档断点已删（见文件末尾的说明）。 */
  --maxw:      clamp(1120px, 74vw, 1800px);

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
          "Hiragino Sans GB", "Microsoft YaHei", system-ui, sans-serif;
  /* ⚠️ 2026-10-25：原来这条一个中文字体都没有。
     全站 79 处 font-family: var(--mono)，其中大部分渲染的是中文标签
     （"进入知识库"、"本站研究"、"12 / 24 已提交"...）。
     中文 fallback 到系统 monospace（Windows 上常是宋体/等线），
     12~14px 下笔画细如发丝 —— 这就是"又细又小"的直接原因。

     修法：在 monospace 之前插入中文字体。
     顺序很重要 —— monospace 是通用族名，放在前面会先把中文吃掉。
     这样：英文/数字仍走等宽，中文走雅黑/苹方。中文本身是全角，
     加进来不会破坏等宽的观感。 */
  --mono: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas,
          "Microsoft YaHei", "PingFang SC", "Hiragino Sans GB", monospace;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  /* 一整页均质的黑 = 平的。加一道极淡的顶光，
     页面才有“光从上面来”的纵深；而且它给紫色一个出处 ——
     紫不是刷上去的，是这道光照在表面上的反射。 */
  background:
    radial-gradient(130% 62% at 50% -14%,
      rgba(139, 92, 246, .13) 0%,
      rgba(139, 92, 246, .05) 38%,
      rgba(8, 7, 14, 0) 66%),
    var(--bg);
  background-attachment: fixed;
  color: var(--ink);
  font-family: var(--font);
  font-size: 14px;
  /* 中文行高提到 1.75 —— CJK 的字面更高，1.65 在中文里偏挤。 */
  line-height: 1.75;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* 用 clip 而不是 hidden。
     hidden 会把 body 变成"滚动容器"，于是里面所有 position: sticky
     的定位基准就从视口变成了 body —— 侧栏会跟着页面一起滚走，
     看起来就像 sticky 没生效（这个坑我踩过一次，调了很久）。
     clip 只裁剪、不创建滚动容器，sticky 才能正常。 */
  overflow-x: clip;
}

a { color: inherit; text-decoration: none; }
button { font-family: inherit; font-size: inherit; cursor: pointer; border: none; background: none; color: inherit; }
input, textarea, select { font-family: inherit; font-size: inherit; }
::selection { background: rgba(168,85,247,.32); }

/* ═══ 布局 ═══ */
/* ── 布局：从「居中一个容器」改成「两边固定内边距」──
   居中容器在 1440 屏上没问题（两边各空 160px），
   但在 2700 屏上会空 800px —— 整页像贴在正中，left 侧完全浪费。
   参考站的写法是：容器不限宽，两侧留固定内边距，内容顶着边缘排。
   这样大屏上左边有字、右边有字，页面才是"铺开"的。 */
:root { --pad-x: clamp(20px, 4.4vw, 88px); }

.wrap {
  width: 100%;
  max-width: none;
  margin: 0;
  padding-left: var(--pad-x);
  padding-right: var(--pad-x);
}


/* 关于页：居中阅读栏，900。
   ⚠️ 别把它"统一"成 1400。
   试过一次：容器放宽到 1400 之后，文字块只有 544，靠左，
   右边空 900 —— 比 900 居中时更空。
   关于页是混合宽度的页面（段落要 680、网格要宽），
   一个容器宽度满足不了三种需求，而它又没有知识库那样的右轨去填右边。
   900 居中在 2764 上两侧各空 930，看着空，但那是阅读页的正常样子。
   判断依据不是"跟别的页一致"，是"这页是干什么的"。 */
.wrap-narrow {
  max-width: 900px; margin: 0 auto;
  padding: 0 var(--pad-x);
}

/* ═══ 顶栏：一条线，不要阴影 ═══ */
.nav {
  position: sticky; top: 0; z-index: 60;
  background: rgba(10,11,14,.86);
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  border-bottom: 1px solid var(--rule);
}
.nav-in {
  /* 居中容器已废弃 —— 大屏上会空掉两侧。改成固定内边距，内容顶边缘排。 */
  width: 100%; padding: 0 var(--pad-x);
  height: 58px; display: flex; align-items: center; gap: 30px;
}
.nav-brand {
  display: flex; align-items: center; gap: 9px;
  font-size: 14px; font-weight: 640; letter-spacing: .13em;
}
.nav-brand .mark { width: 19px; height: 19px; flex: none; }

/* ═══ Logo 位图 ═══
   品牌原图是黑底的，已经在构建时抠成透明 PNG（见 public/logo-*.png）：
   亮度低于 18 的像素 alpha=0，高于 56 的 alpha=255，中间平滑过渡。
   所以这里不需要混合模式，直接放就行。

   （试过 mix-blend-mode: screen，但原图的黑不是纯 0，
     混合后会留一个比背景略亮的方块，看得见。抠 alpha 更干净。） */
.mark { display: block; }
.nav-links { margin-left: auto; display: flex; align-items: center; gap: 2px; }
.nav-links a {
  padding: 6px 12px; border-radius: var(--r-s);
  font-size: 14px; color: var(--ink-3);
  transition: color .15s, background .15s;
}
.nav-links a:hover { color: var(--ink); background: var(--surface); }
.nav-links a.on { color: var(--ink); }

/* ═══ 模块栏：第二层导航 ═══
   顶栏管"整个平台"，这一条管"当前模块里能干什么"。
   左边一个模块铭牌（名字 + 英文代码），右边是模块内的入口。 */
.modbar { border-top: 1px solid var(--rule); background: rgba(6,7,9,.6); }
.modbar-in {
  /* 居中容器已废弃 —— 大屏上会空掉两侧。改成固定内边距，内容顶边缘排。 */
  width: 100%; padding: 0 var(--pad-x);
  height: 44px; display: flex; align-items: center; gap: 24px;
}
.modtag {
  display: inline-flex; align-items: baseline; gap: 7px;
  font-size: 14px; font-weight: 620; color: var(--ink);
}
.modtag i {
  font-style: normal; font-family: var(--mono);
  font-size: 12px; letter-spacing: .2em; color: var(--ink-4);
}
.modnav { display: flex; align-items: center; gap: 2px; margin-left: auto; }
.modnav a {
  padding: 5px 11px; border-radius: var(--r-s);
  font-size: 14px; color: var(--ink-3);
  transition: color .15s, background .15s;
}
.modnav a:hover { color: var(--ink); background: var(--surface); }
.modnav a.on { color: var(--a2); }
@media (max-width: 640px) {
  .modbar-in { padding: 0 20px; gap: 14px; }
  .modnav a { padding: 5px 9px; font-size: 12px; }
}

/* ═══ 按钮：小圆角、无阴影、无渐变（除非主按钮）═══ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 9px 18px; border-radius: var(--r);
  /* 2026-10-25：560 → 600。
     ✅ 微软雅黑只有 400 / 700 两档，560 会被量化到 400 —— 按钮字看着发细。
     ✅ 600 会走合成加粗，落在两者之间，正是想要的厚度。
     ⚠️ 这条和"大标题 720→540"不冲突：那条只在 60px 以上成立，
        小字号必须加重，否则笔画会糊。字号越小，字重越要重。 */
  font-size: 14px; font-weight: 600; letter-spacing: .005em;
  transition: background .15s, border-color .15s, color .15s, opacity .15s;
  white-space: nowrap;
}
.btn:disabled { opacity: .4; cursor: not-allowed; }

/* 主按钮：唯一允许用渐变的地方，而且只有一处 */
.btn.primary {
  /* 淡蓝实心 + 深藏青的字。
     浅底按钮上如果还用白字，对比度会掉到 2:1 以下 —— 浅底要配深字。 */
  background: linear-gradient(180deg, #a8dcf7 0%, #6cbdea 100%);
  color: #06202f; font-weight: 620;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5), 0 6px 18px rgba(108, 189, 234, .22);
}
.btn.primary:hover { filter: brightness(1.08); }

.btn.ghost { border: 1px solid var(--rule-2); color: var(--ink-2); }
.btn.ghost:hover { border-color: #3a4150; color: var(--ink); background: var(--surface); }

.btn.plain { color: var(--ink-3); }
.btn.plain:hover { color: var(--ink); }

.btn.danger { color: var(--danger); }
.btn.danger:hover { background: rgba(232,84,92,.09); }

.btn.sm { padding: 6px 12px; font-size: 14px; border-radius: var(--r-s); }
.btn.block { width: 100%; }

/* ═══ 页头：大标题要敢大 ═══ */
.page-head { padding: 68px 0 34px; }
.page-head h1 {
  font-size: clamp(32px, 5vw, 52px);
  font-weight: 700; letter-spacing: -.035em; line-height: 1.1;
}
.page-head h1 em {
  font-style: normal;
  background: var(--grad); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.page-head p {
  color: var(--ink-2); margin-top: 16px; max-width: 34em;
  font-size: 16px; line-height: 1.75;
}

/* 小标题：等宽 + 极宽字距 —— 这是"工具感"的来源 */
.shead {
  display: flex; align-items: center; gap: 16px;
  font-family: var(--mono);
  font-size: 12px; letter-spacing: .22em; text-transform: uppercase;
  color: var(--ink-4); margin: 44px 0 18px;
}
.shead::after { content: ""; flex: 1; height: 1px; background: var(--rule); }

/* ═══ 面板：直角 + 细线，不用圆角卡片 ═══ */
.panel {
  background: var(--surface); border: 1px solid var(--rule);
  padding: 26px 28px;
}
.panel + .panel { border-top: none; }   /* 相连的面板共用一条线，不要双线 */

/* ═══ 表单 ═══ */
/* 注意：这里叫 .field（表单字段的包装）。
   背景那个声场底纹叫 .soundfield —— 两者曾经同名，
   结果表单里每个字段都被当成 1600×1600 的固定定位背景，
   整个表单看不见了。改名字的时候要小心这种撞车。 */
.field { margin-bottom: 20px; }
.field label {
  display: block; font-size: 12px; color: var(--ink-3);
  margin-bottom: 8px; letter-spacing: .04em;
}
.field .hint { font-size: 12px; color: var(--ink-4); margin-top: 7px; line-height: 1.6; }

.input, .textarea, .select {
  width: 100%; padding: 10px 13px;
  background: var(--bg-deep); color: var(--ink);
  border: 1px solid var(--rule-2); border-radius: var(--r-s);
  outline: none; transition: border-color .15s, background .15s;
}
.input::placeholder, .textarea::placeholder { color: var(--ink-4); }
.input:focus, .textarea:focus, .select:focus {
  border-color: rgba(168,85,247,.6);
  background: #0b0c11;
}
.textarea { resize: vertical; min-height: 88px; line-height: 1.7; }
.select { appearance: none; cursor: pointer; }

/* ═══ 标签：方角、等宽 ═══ */
.chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; border-radius: 4px;
  font-size: 12px; letter-spacing: .03em;
  border: 1px solid var(--rule-2); color: var(--ink-3);
  background: var(--bg-deep);
}
.chip.accent { border-color: rgba(168,85,247,.4); color: var(--a2); background: rgba(168,85,247,.07); }

/* ═══ 提示条 ═══ */
.toast {
  position: fixed; left: 50%; bottom: 34px; transform: translate(-50%, 12px);
  background: var(--surface-2); border: 1px solid var(--rule-2);
  color: var(--ink); padding: 10px 20px; border-radius: var(--r);
  font-size: 14px; z-index: 200; opacity: 0; pointer-events: none;
  transition: opacity .18s, transform .18s;
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }
.toast.err { border-color: rgba(232,84,92,.5); }

/* ═══ 空状态 ═══ */
.empty {
  padding: 72px 24px; text-align: center;
  border: 1px solid var(--rule); background: var(--surface);
  /* 这个面板是【替代 feed 列表】的，所以它应该占列表的位置 ——
     左边和标题对齐、右边到页面的内边距。
     试过两版都不对：
       ① 铺满整屏（2652）—— 太宽，五个字像掉进广场
       ② 1080 + 自身居中 —— 不歪了，但变成一块飘在中间的盒子，
          和左边贴着边缘的标题完全脱开
     现在：宽度就是内容区的宽度（自动对齐标题），文字在里面居中。
     这样左边有对齐、右边有边距、文字在正中，三件事同时成立。 */
  max-width: none;
}
.empty .big { font-size: 16px; color: var(--ink-2); margin-bottom: 8px; letter-spacing: -.01em; }
.empty .sub { font-size: 14px; color: var(--ink-4); }

/* ═══ 入场：只在首屏用，而且极轻 ═══ */
/* ═══════════════════════════════════════════════════════════
   入场：从左浮入，慢一点
   ───────────────────────────────────────────────────────────
   两个改动，都是"别让人以为是刷新"：

   ① 方向从「往下 12px」改成「从左侧 30px 过来」。
      纵向位移在深色页面上几乎看不出来，容易被读成"页面闪了一下"；
      横向位移有方向感，一眼就知道是【动画】不是【重载】。

   ② 时长 .55s → .95s（位移）/.6s（淡入），错开间隔 55ms → 105ms。
      再快就像刷新；这个区间是"看得见但不等"。

   ③ 位移用的曲线 y 峰值 1.21 —— 会越过终点再弹回来。
      "向前顶一下"就是这个过冲。实测：
        (.34,1.56,.64,1)  2.9px   太含蓄，看不出来
        (.20,1.90,.40,1)  7.7px   ← 用这个
        (.15,2.40,.30,1) 14.6px   太像玩具
      7.7px 在 116px 的标题上很明显，但不至于弹成弹簧。

   淡入单独用 .6s 的普通曲线、比位移早结束 ——
   元素先亮起来，再慢慢落位，看起来是"东西在动"，不是"画面在渐变"。
   ═══════════════════════════════════════════════════════════ */
.rv {
  opacity: 0;
  transform: translateX(var(--rv-from, -36px));
  transition:
    /* 淡入：先结束 —— 元素先亮起来，再慢慢落位 */
    opacity   var(--rv-fade, .60s) cubic-bezier(.30, 0, .40, 1),
    /* 位移：曲线的 y 值可以 > 1，于是会【越过终点】再弹回来。
       每个元素可以单独指定 --rv-dur / --rv-ease / --rv-delay，
       没指定就走这里的默认值。 */
    transform var(--rv-dur, .95s) var(--rv-ease, cubic-bezier(.20, 1.90, .40, 1));
  transition-delay: var(--rv-delay, calc(var(--rv-i, 0) * 105ms));
  will-change: opacity, transform;
}
.rv.in { opacity: 1; transform: translateX(0); will-change: auto; }
.rv.in { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .rv { opacity: 1; transform: none; transition: none; } }

/* ═══ 声场底纹 ═══
   品牌副标题是 IMMERSIVE SOUND FIELD LAB，所以背景讲的是"声场"：
   从一点向外扩散的同心圆，像声波，也像录音棚测量用的图。

   三条硬规矩（不然就廉价了）：
     ① 极低对比 —— 看不清才对，看清了就抢内容
     ② 不放音符图标 —— 那是模板味，不是品牌味
     ③ 可以动，但周期要长（几十秒一轮），不动时几乎察觉不到

   纯 CSS 画的，零图片、零授权风险、手机上也流畅。 */
.soundfield {
  position: fixed; z-index: 0; pointer-events: none;
  top: 50%; left: 50%;
  width: 1600px; height: 1600px;
  margin: -800px 0 0 -800px;
  opacity: .5;
}
.soundfield .ring {
  position: absolute; inset: 0; margin: auto;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,.055);
  transform-origin: center;
}
/* 一圈一圈，间隔越来越远 —— 像声音衰减，不是等距的靶子 */
.soundfield .r1 { width: 200px;  height: 200px;  border-color: rgba(255,255,255,.10); }
.soundfield .r2 { width: 400px;  height: 400px;  border-color: rgba(255,255,255,.085); }
.soundfield .r3 { width: 640px;  height: 640px;  border-color: rgba(255,255,255,.072); }
.soundfield .r4 { width: 920px;  height: 920px;  border-color: rgba(255,255,255,.058); }
.soundfield .r5 { width: 1240px; height: 1240px; border-color: rgba(255,255,255,.04); }
.soundfield .r6 { width: 1600px; height: 1600px; border-color: rgba(255,255,255,.028); }

/* 极慢的呼吸。30 秒一轮，你盯着看才会发现它在动。 */
@keyframes fieldBreathe {
  0%, 100% { transform: scale(1);     opacity: .55; }
  50%      { transform: scale(1.035); opacity: .85; }
}
.soundfield { animation: fieldBreathe 30s ease-in-out infinite; }

/* 中心一点微光，把视线往下拉 */
/* 中心那团紫色光晕去掉了 —— 用户要的是纯黑背景。
   它原来长这样：
     background: radial-gradient(circle, rgba(192,132,252,.16) 0%, transparent 70%);
   留个空规则，免得以后有人以为漏了什么。 */
.soundfield::after {
  content: none;
  display: none;
}

@media (prefers-reduced-motion: reduce) { .soundfield { animation: none; } }

/* 页面内容要压在底纹上面 */
main, footer { position: relative; z-index: 1; }

/* ═══ 品牌标识块（用在首屏）═══
   把 Logo 图形放大当视觉锚点，旁边是字标。 */
.crest { display: flex; align-items: center; gap: 15px; }
.crest .glyph { flex: none; }
.crest .word { line-height: 1.15; }
.crest .word .n {
  font-size: 14px; font-weight: 720; letter-spacing: .13em; color: var(--ink);
}
.crest .word .t {
  font-family: var(--mono); font-size: 12px; letter-spacing: .24em;
  color: var(--ink-4); margin-top: 6px;
}
/* 一个大号的纯图形版本，当"章节封面"用 */
.crest-hero { display: flex; align-items: center; gap: 26px; margin-bottom: 40px; }
.crest-hero .word .n {
  font-size: 20px; font-weight: 720; letter-spacing: .12em;
  background: var(--grad); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.crest-hero .word .t {
  font-family: var(--mono); font-size: 12px; letter-spacing: .26em;
  color: var(--ink-4); margin-top: 8px;
}

/* ═══ 小工具 ═══ */
.row { display: flex; align-items: center; gap: 12px; }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.muted { color: var(--ink-3); }
.small { font-size: 14px; }
.mono { font-family: var(--mono); }
.mt-s { margin-top: 10px } .mt { margin-top: 19px } .mt-l { margin-top: 34px }
.mb-s { margin-bottom: 10px } .mb { margin-bottom: 19px }

/* 分隔线 */
.hr { height: 1px; background: var(--rule); border: none; }

@media (max-width: 640px) {
  .wrap, .wrap-narrow, .nav-in { padding-left: 20px; padding-right: 20px; }
  .page-head { padding: 42px 0 26px; }
  .panel { padding: 22px 20px; }
}
/* ═══════════════════════════════════════════════════════════════
   大屏适配（2026-10-18 加）
   ───────────────────────────────────────────────────────────────
   问题：--maxw 锁死 1120px，在 2560 / 3440 的显示器上
        内容只占 44% / 33%，两边大片空白，像一张纸条挂在中间。

   修法不是"把文字拉满整屏"（那样一行太长没法读），而是：
     · 容器随屏幕分级放大
     · 正文类的行宽仍然受限（.hero .lede 的 31em 不动）
     · .mods 用的是 auto-fill，容器一变宽自动加列，不用管

   为什么分级而不用一条 clamp：
     1440 以下的观感是调好的，不能动。
     用 clamp(1120px, 72vw, 1800px) 在 1440 也是 1120，确实等价；
     但标题字号没法用同一条式子平滑过渡，所以两种一起用分级更清楚。
   ═══════════════════════════════════════════════════════════════ */

/* ⚠️ 2026-10-25：原来这里有三档 @media（1600/2000/2400 → 1280/1480/1680）。
   它们和上面 :root 里的 clamp 在同一条属性上抢权，而且方向是反的 ——
   clamp 已经把大屏撑到 1800，断点又把它按回 1280。

   删掉的理由和你 2026-10-24 自己写的那段注释（"这三条已删除"）完全一样：
   **同一条属性只有一处该负责。**

   现在大屏的宽度全靠 --maxw 一条 clamp：
       1440   →  1120  （78%，和以前完全一样，小屏观感不动）
       1920   →  1421  （74%）
       2512   →  1800  （72%）
   ============================================================ */

/* 这三条已删除。
   它们是"基准 720px 时代"的遗留：大屏上从 720 逐级放宽到 900。
   现在基准改成 1400（跟知识库正文统一），这三条反而会在宽屏上
   把容器【收窄】回 900 —— 表现就是 1440 上是 1400、2764 上却是 900。
   删除后 1400 在 1440 和 2764 上都成立。 */
/* ═══════════════════════════════════════════════════════════
   跨页转场：多页站也能有「旧页淡出 / 新页淡入」
   ───────────────────────────────────────────────────────────
   这个站是多页 HTML，每点一次导航浏览器都要重新请求文档。
   以前看到的就是白屏 + 瞬间出现。

   下面这几行让浏览器在【两个文档之间】做交叉淡入。
   纯 CSS，没有 JS，没有改架构。

   ⚠️ 不支持的浏览器（含微信内置 X5）会直接忽略 ——
      页面照常跳转，只是没有转场。不会坏，只是没有。
   ═══════════════════════════════════════════════════════════ */
@view-transition { navigation: auto; }

/* 顶栏在两页之间是同一个东西 —— 让它别参与淡入淡出，看起来像"内容在换" */
.nav { view-transition-name: site-nav; }

::view-transition-old(root) { animation-duration: .18s; animation-timing-function: cubic-bezier(.2, .7, .3, 1); }
::view-transition-new(root) { animation-duration: .26s; animation-timing-function: cubic-bezier(.2, .7, .3, 1); }

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
}

/* 兜底：正文和侧栏无论挂着什么动画类，都必须可见、且没有位移。
   如果上面的改动被回退，这条会挡住那个 -36px。 */
.kbody, .ktree {
  opacity: 1;
  transform: none;
}
