/* ============================================================================
   LAYOUT CANON · canon.css
   设计系统 / Design system
   ----------------------------------------------------------------------------
   视觉概念：一张工程图纸 + 一本当代艺术展图录。
   界面外壳是深色的测量仪器，内容纸面是暖白的制图纸；
   两者之间用一条 1px 的标尺线缝合。所有的强调色都来自"标注"这件事本身：
   青柠 = 当前状态，珊瑚 = 错误 / 警告，琥珀 = 数值读数。

   Zero dependencies. No webfonts. No build step.
   ========================================================================== */

/* ---------------------------------------------------------------------------
   1 · 设计令牌 Design tokens
   ------------------------------------------------------------------------ */
:root {
  /* --------------------------------------------------------------------------
     材料：纸、墨、两管颜料
     --------------------------------------------------------------------------
     配色不来自"深色模式 + 一个霓虹强调色"那套科技惯用法，而来自纸本印刷：
     暖白纸面、炭黑墨，两支有出处的颜料——
       群青 ultramarine（1826 年合成，取代了比黄金还贵的青金石）
       赤铁红 haematite（从赭石到威尼斯红，最古老的人造颜料）
     加一支褪色青做第三色。全部低饱和、偏暖，为长文阅读服务。

     外壳与纸面同源：外框是"上了墨的炭纸"，内容区是"没上墨的白纸"，
     两者是同一种材料的两面，而不是深色 UI 叠一张白卡。
     ------------------------------------------------------------------------ */

  /* 炭纸 charcoal shell — 上报的墨色纸 */
  --ink-0: #191410;
  --ink-1: #201a14;
  --ink-2: #282119;
  --ink-3: #322a20;
  --ink-4: #3d3428;
  --ink-line: rgba(240, 232, 218, 0.13);
  --ink-line-2: rgba(240, 232, 218, 0.30);

  /* 纸面 paper —— 暖一些、脏一点，避免"米白模板"的寡淡 */
  --paper: #ece5d8;
  --paper-2: #e2d9c8;
  --paper-card: #f4eee1;
  --paper-sunk: #d5cab5;

  /* 墨 ink */
  --tx: #171310;
  --tx-2: #4a4136;
  --tx-3: #7d7160;
  --tx-inv: #ede6da;
  --tx-inv-2: rgba(237, 230, 218, 0.64);
  --tx-inv-3: rgba(237, 230, 218, 0.36);

  /* 颜料 pigments —— 一套暖调 + 唯一一支冷色
     --------------------------------------------------------------------
     上一版用"暖纸 + 冷群青 + 暖赤铁"，三套色温互相抵消，画面没有主张。
     现在收成：暖调承担全部结构，冷墨蓝是唯一冷色，因而自动成为强调。
     赤铁红只在"出错"时出现，平时不参与画面。 */
  --acc: #26407f;           /* 冷墨蓝 · 当前 / 正确 / 命中 */
  --acc-deep: #1c3268;
  --acc-wash: rgba(38, 64, 127, 0.12);
  --sig: #9c3b2a;           /* 赤铁红 · 仅用于错误 / 越界 */
  --sig-wash: rgba(156, 59, 42, 0.12);
  --num: #7d5a1c;           /* 赭石 · 数值读数 */
  --num-wash: rgba(125, 90, 28, 0.14);
  --key: #4c6b4a;           /* 橄榄绿 · 链接 / 次要标注（同属暖调家族） */
  --key-wash: rgba(76, 107, 74, 0.13);

  /* 线 rules —— 纸上的压痕，不是灰边框 */
  --line: #cfc5b0;
  --line-2: #b5a992;
  --line-hard: #171310;

  /* 代码版面 code plate —— 炭纸上的暖色语法，不用霓虹 */
  --code-bg: #16130f;
  --code-line: rgba(233, 224, 209, 0.07);
  --c-cmt: #7d7264;
  --c-kw: #c9728f;
  --c-str: #94a862;
  --c-num: #c08a3e;
  --c-fn: #6f9bb5;
  --c-prop: #c8a464;
  --c-sel: #7d9bc4;
  --c-tag: #b5714f;
  --c-op: #95897a;

  /* 演示舞台 demo stage —— 制图台：炭纸 + 淡网格 */
  --st-bg: #1a1611;
  --st-canvas: #221d17;
  --st-surf: #2a241d;
  --st-line: rgba(233, 224, 209, 0.15);
  --st-line-soft: rgba(233, 224, 209, 0.075);
  --st-tx: #ece4d6;
  --st-tx-2: rgba(236, 228, 214, 0.62);
  --st-tx-3: rgba(236, 228, 214, 0.35);
  --st-a: #7d9bc4;          /* 正确 / 当前 */
  --st-a-soft: rgba(125, 155, 196, 0.20);
  --st-b: #8fa87a;          /* 第二组 */
  --st-b-soft: rgba(143, 168, 122, 0.20);
  --st-c: #c8a464;          /* 读数 */
  --st-c-soft: rgba(200, 164, 100, 0.20);
  --st-d: #c05a48;          /* 错误 / 越界 */
  --st-d-soft: rgba(192, 90, 72, 0.20);
  --st-e: #a58aa8;          /* 第三组 */
  --st-e-soft: rgba(165, 138, 168, 0.20);

  /* 字体 type families */
  /* 正文：中性无衬线，中文走系统黑体 */
  --f-sans: "Helvetica Neue", -apple-system, BlinkMacSystemFont, "Segoe UI",
            "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", Roboto, Arial,
            sans-serif;
  /* 显示字：同一族的紧排版本，标题靠字号与字距出气势，不靠换字体 */
  --f-disp: "Helvetica Neue", -apple-system, BlinkMacSystemFont, "Segoe UI",
            "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", Roboto, Arial,
            sans-serif;
  /* 衬线：只用在几个地方——章节编号、数字、引文。
     这几个地方一换字体，整页的"手作感"就出来了。 */
  --f-serif: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua",
             Georgia, "Songti SC", "Source Han Serif SC", "Noto Serif SC",
             "Times New Roman", serif;
  /* 等宽：标签、代码、坐标 */
  --f-mono: "SF Mono", ui-monospace, SFMono-Regular, Menlo, Consolas,
            "Liberation Mono", "Noto Sans Mono CJK SC", monospace;
  /* 数字：等宽数位 + 衬线，读数才有"印刷表格"的味道 */
  --f-fig: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia,
           "Songti SC", Georgia, "Times New Roman", serif;

  /* 尺度 space & shape */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;
  --sp-7: 48px;
  --sp-8: 64px;
  --sp-9: 96px;
  --sp-10: 144px;

  --r-1: 1px;
  --r-2: 2px;
  --r-3: 3px;
  --r-4: 4px;
  --r-pill: 999px;

  --rail: 288px;             /* 侧栏宽度 */
  --bar: 56px;               /* 顶栏高度 */
  --measure: 74ch;           /* 正文最佳行长 */

  /* 动效 motion */
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --t-fast: 0.14s;
  --t: 0.26s;
  --t-slow: 0.6s;

  color-scheme: light;
}

/* ---------------------------------------------------------------------------
   2 · 基础重置 Reset
   ------------------------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--bar) + 24px);
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--tx);
  font-family: var(--f-sans);
  font-size: 16px;
  line-height: 1.72;
  font-feature-settings: "kern" 1, "liga" 1, "cv05" 1, "ss01" 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

body.is-dark { background: var(--ink-1); }

h1, h2, h3, h4, h5 { margin: 0; font-weight: 620; line-height: 1.18; letter-spacing: -0.022em; }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; }
img, svg, canvas { display: block; max-width: 100%; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: 0; padding: 0; }
a { color: inherit; text-decoration: none; }
table { border-collapse: collapse; width: 100%; }
code, kbd, pre, samp { font-family: var(--f-mono); }

::selection { background: var(--acc); color: #f2ede3; }

/* 纸纹：一层几乎看不见的纤维噪点。
   渐变是"均匀"的，而纸不是——手感的差别就在这一点不均匀。
   噪点用 SVG 分形噪声内联生成，不增加任何请求。 */
/* 注意 z-index 的取值。
   这一层必须夹在"正文"与"外壳"之间：
     · 低于顶栏(100) / 侧栏 / 演示控件，才不会盖住交互元素；
     · 高于正文，才能给纸面加上纹理。
   最初写成 9999，结果整页的 elementFromPoint 全部返回 null——
   看不见的覆盖层照样参与命中测试，控件就"点不动"了。
   挂在 html 上而不是 body 上，是为了让它不参与 body 的层叠排序。 */
html::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.5;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='0.32'/%3E%3C/svg%3E");
  background-size: 180px 180px;
}
@media print { html::after { display: none; } }

:focus-visible {
  outline: 2px solid var(--key);
  outline-offset: 2px;
  border-radius: var(--r-1);
}

/* 滚动条 —— 细，克制 */
* { scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: var(--line-2);
  border: 3px solid transparent;
  background-clip: content-box;
  border-radius: var(--r-pill);
}
*::-webkit-scrollbar-thumb:hover { background: var(--tx-3); background-clip: content-box; }

/* ---------------------------------------------------------------------------
   3 · 通用排版原语 Type primitives
   ------------------------------------------------------------------------ */
.mono {
  font-family: var(--f-mono);
  font-size: 0.78em;
  letter-spacing: 0.02em;
  font-variant-ligatures: none;
}

/* 数字：换用衬线 + 等宽数位。
   整页的技术感来自等宽标签，而"人的手感"来自这一处——
   编号、读数、计量一旦用衬线数字排，就像印刷品的表格而不像仪表盘。
   刻意不全站换字体：只在数字上换，对比才成立。 */
.fig, .stat__v, .rail__num, .card__no, .opener__no,
.readout__v, .ctrl__val, .bar__head b, .code__gutter i,
.hero__stats b, .footnav small b {
  font-family: var(--f-fig);
  font-variant-numeric: lining-nums tabular-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
  letter-spacing: -0.01em;
}

/* 制图标签：出现在每一个结构块前面 [ 01 ] */
.tag {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--f-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--tx-3);
}
.tag::before {
  content: "";
  width: 14px;
  height: 1px;
  background: currentColor;
  opacity: 0.55;
  flex: none;
}
.tag::after { content: none; }
.tag--acc { color: var(--acc-deep); }
.tag--sig { color: var(--sig); }
.tag--num { color: #a8701a; }
.tag--inv { color: var(--tx-inv-3); }
.tag--inv.tag--acc { color: var(--acc); }
.tag--inv.tag--sig { color: var(--sig); }
.tag--inv.tag--num { color: var(--num); }

/* 徽标 */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 22px;
  padding: 0 9px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-pill);
  font-family: var(--f-mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--tx-2);
  background: var(--paper-card);
  white-space: nowrap;
}
.chip--acc { border-color: color-mix(in srgb, var(--acc) 55%, transparent); background: var(--acc-wash); color: #0f7a38; }
.chip--sig { border-color: color-mix(in srgb, var(--sig) 50%, transparent); background: var(--sig-wash); color: #c03a1e; }
.chip--num { border-color: color-mix(in srgb, var(--num) 50%, transparent); background: var(--num-wash); color: #96631a; }
.chip--ink {
  background: var(--ink-2); border-color: var(--ink-line-2); color: var(--tx-inv-2);
}

/* 分隔线 */
.rule { height: 1px; background: var(--line); border: 0; margin: var(--sp-7) 0; }
.rule--hard { background: var(--line-hard); }
.rule--dash {
  height: 0; border: 0; border-top: 1px dashed var(--line-2); background: none;
}

/* 高亮标记 */
mark.hl {
  background: linear-gradient(transparent 62%, color-mix(in srgb, var(--acc) 42%, transparent) 62%);
  color: inherit;
  padding: 0 1px;
}
mark.hl--sig { background: linear-gradient(transparent 62%, color-mix(in srgb, var(--sig) 35%, transparent) 62%); }
u.wavy {
  text-decoration: underline wavy var(--sig);
  text-underline-offset: 4px;
  text-decoration-thickness: 1.5px;
}

/* 行内代码 */
.ic {
  font-family: var(--f-mono);
  font-size: 0.855em;
  padding: 0.14em 0.42em;
  border: 1px solid var(--line);
  border-radius: var(--r-2);
  background: var(--paper-2);
  color: var(--tx);
  white-space: nowrap;
  font-variant-ligatures: none;
}

/* ---------------------------------------------------------------------------
   4 · 顶栏 Topbar —— 仪器条
   ------------------------------------------------------------------------ */
.topbar {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  height: var(--bar);
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  padding: 0 var(--sp-5);
  background: color-mix(in srgb, var(--ink-0) 82%, transparent);
  backdrop-filter: blur(20px) saturate(1.5);
  -webkit-backdrop-filter: blur(20px) saturate(1.5);
  border-bottom: 1px solid var(--ink-line);
  color: var(--tx-inv);
}

.topbar__brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--f-disp);
  font-weight: 640;
  font-size: 14px;
  letter-spacing: -0.01em;
  white-space: nowrap;
}
.topbar__glyph {
  width: 22px; height: 22px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  gap: 2px;
  flex: none;
}
.topbar__glyph i {
  background: var(--tx-inv-3);
  border-radius: 1px;
  transition: background var(--t) var(--ease);
}
.topbar__glyph i:nth-child(1) { background: var(--acc); }
.topbar__brand:hover .topbar__glyph i:nth-child(2) { background: var(--tx-inv); }
.topbar__brand:hover .topbar__glyph i:nth-child(4) { background: var(--tx-inv); }
.topbar__brand small {
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  color: var(--tx-inv-3);
  text-transform: uppercase;
  font-weight: 400;
}

.topbar__nav {
  display: flex;
  align-items: center;
  gap: 2px;
  margin-left: auto;
  overflow-x: auto;
  scrollbar-width: none;
}
.topbar__nav::-webkit-scrollbar { display: none; }
.topbar__nav a {
  padding: 6px 10px;
  border-radius: var(--r-2);
  font-family: var(--f-mono);
  font-size: 11.5px;
  letter-spacing: 0.03em;
  color: var(--tx-inv-2);
  white-space: nowrap;
  transition: color var(--t-fast), background var(--t-fast);
}
.topbar__nav a:hover { color: var(--tx-inv); background: rgba(255, 255, 255, 0.07); }
.topbar__nav a.is-current { color: var(--acc); background: rgba(46, 224, 106, 0.1); }

/* 语言开关 */
.lang {
  position: relative;
  display: flex;
  align-items: center;
  padding: 2px;
  border: 1px solid var(--ink-line-2);
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, 0.03);
  flex: none;
}
.lang::before {
  content: "";
  position: absolute;
  top: 2px; left: 2px;
  width: calc(50% - 2px);
  height: calc(100% - 4px);
  border-radius: var(--r-pill);
  background: var(--tx-inv);
  transition: transform var(--t) var(--ease-out);
}
.lang[data-lang="en"]::before { transform: translateX(100%); }
.lang button {
  position: relative;
  z-index: 1;
  min-width: 42px;
  padding: 4px 10px;
  font-family: var(--f-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.05em;
  color: var(--tx-inv-2);
  transition: color var(--t) var(--ease);
}
.lang button[aria-pressed="true"] { color: var(--ink-0); }

.topbar__prog {
  position: absolute;
  left: 0; bottom: -1px;
  height: 1.5px;
  width: 0;
  background: linear-gradient(90deg, var(--acc), var(--num));
  transition: width 0.1s linear;
  box-shadow: 0 0 12px color-mix(in srgb, var(--acc) 60%, transparent);
}

/* ---------------------------------------------------------------------------
   5 · 外壳布局 Shell
   ------------------------------------------------------------------------ */
.shell {
  display: grid;
  grid-template-columns: var(--rail) minmax(0, 1fr);
  min-height: 100vh;
  padding-top: var(--bar);
}
/* 网格子项默认 min-width:auto —— 等于内容的 min-content，
   于是"内部可以横向滚动的长列表"会反过来把整个布局撑破。
   这条规则正是第 2 章讲的内容，这里用在自己身上。 */
.shell > * { min-width: 0; }

/* ---- 侧栏 rail ---- */
.rail {
  position: sticky;
  top: var(--bar);
  align-self: start;
  height: calc(100vh - var(--bar));
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--sp-6) var(--sp-5) var(--sp-8);
  background: var(--ink-1);
  border-right: 1px solid var(--ink-line);
  color: var(--tx-inv);
}
.rail__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: var(--sp-5);
}
.rail__title {
  font-family: var(--f-mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--tx-inv-3);
}
.rail__count {
  font-family: var(--f-mono);
  font-size: 10.5px;
  color: var(--acc);
  letter-spacing: 0.04em;
}
.rail__list { list-style: none; display: flex; flex-direction: column; gap: 1px; }
.rail__list a {
  display: grid;
  grid-template-columns: 30px minmax(0, 1fr);
  align-items: start;
  gap: 10px;
  padding: 9px 10px 9px 8px;
  border-radius: var(--r-2);
  position: relative;
  transition: background var(--t-fast);
}
.rail__list a:hover { background: rgba(255, 255, 255, 0.045); }
.rail__num {
  font-size: 13px;
  font-weight: 500;
  color: var(--tx-inv-3);
  padding-top: 1px;
  transition: color var(--t-fast);
  position: relative;
  padding-left: 12px;
}
/* 目录刻度：一条 1px 的短线，像目录页的行首标尺 */
.rail__num::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 6px;
  height: 1px;
  background: currentColor;
  opacity: 0.5;
}
.rail__txt {
  font-size: 13.5px;
  line-height: 1.42;
  color: var(--tx-inv-2);
  transition: color var(--t-fast);
}
.rail__en {
  display: block;
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 0.02em;
  color: var(--tx-inv-3);
  margin-top: 3px;
}
.rail__list a::before {
  content: "";
  position: absolute;
  left: 0; top: 10px; bottom: 10px;
  width: 2px;
  border-radius: 2px;
  background: transparent;
  transition: background var(--t-fast);
}
.rail__list a.is-active { background: rgba(46, 224, 106, 0.09); }
.rail__list a.is-active::before { background: var(--acc); }
.rail__list a.is-active .rail__num { color: var(--acc); }
.rail__list a.is-active .rail__txt { color: var(--tx-inv); }
.rail__list a.is-done .rail__num::after {
  content: "·";
  color: var(--acc);
  margin-left: 2px;
}

/* 侧栏小节标题 */
.rail__sec {
  margin: var(--sp-6) 0 var(--sp-3);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--ink-line);
  font-family: var(--f-mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--tx-inv-3);
}
.rail__meta { display: flex; flex-direction: column; gap: 7px; }
.rail__meta a {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--f-mono);
  font-size: 11.5px;
  color: var(--tx-inv-2);
  padding: 5px 0;
  transition: color var(--t-fast);
}
.rail__meta a:hover { color: var(--acc); }
.rail__meta a span:first-child { color: var(--tx-inv-3); }
.rail__pager {
  display: flex;
  flex-direction: column;
  gap: 1px;
  margin-top: var(--sp-5);
}
.rail__pager a {
  display: block;
  padding: 10px 12px;
  border: 1px solid var(--ink-line);
  border-radius: var(--r-2);
  transition: border-color var(--t-fast), background var(--t-fast);
}
.rail__pager a:hover { border-color: var(--acc); background: rgba(46, 224, 106, 0.06); }
.rail__pager small {
  display: block;
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--tx-inv-3);
  margin-bottom: 3px;
}
.rail__pager b { font-size: 13px; font-weight: 500; color: var(--tx-inv); }
.rail__pager .is-next { text-align: right; }
.rail__pager .is-next small { color: var(--acc); }

/* ---- 主内容 main ---- */
.main { min-width: 0; display: flex; flex-direction: column; }
.page { padding: var(--sp-8) var(--sp-8) var(--sp-10); max-width: 1180px; width: 100%; }
.page--wide { max-width: 1420px; }

/* ---------------------------------------------------------------------------
   6 · 章节首屏 Chapter opener
   ------------------------------------------------------------------------ */
.opener {
  position: relative;
  padding-bottom: var(--sp-7);
  margin-bottom: var(--sp-7);
  border-bottom: 1px solid var(--line-hard);
}
.opener::after {
  content: "";
  position: absolute;
  left: 0; bottom: -1px;
  width: 84px; height: 4px;
  background: var(--acc);
}
.opener__kicker {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: var(--sp-5);
  flex-wrap: wrap;
}
.opener__no {
  font-family: var(--f-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.16em;
  color: var(--tx-inv);
  background: var(--line-hard);
  padding: 4px 10px;
  border-radius: var(--r-1);
}
.opener h1 {
  font-family: var(--f-disp);
  font-size: clamp(36px, 5vw, 70px);
  font-weight: 640;
  line-height: 1.02;
  letter-spacing: -0.035em;
  margin-bottom: var(--sp-4);
  text-wrap: balance;
}
/* 章节编号用衬线大字压在标题左上，像书页的章序号 */
.opener__no {
  font-family: var(--f-serif);
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0.1em;
}
.opener__en {
  font-family: var(--f-mono);
  font-size: clamp(12px, 1.3vw, 15px);
  letter-spacing: 0.02em;
  color: var(--tx-3);
  margin-bottom: var(--sp-5);
  text-transform: uppercase;
}
.opener__lede {
  max-width: 48ch;
  font-family: var(--f-serif);
  font-size: clamp(19px, 1.8vw, 25px);
  line-height: 1.5;
  color: var(--tx);
  letter-spacing: -0.006em;
}
.opener__facts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-top: var(--sp-5);
}

/* ---------------------------------------------------------------------------
   7 · 三 Tab 讲解 / 关键代码 / 演示
   ------------------------------------------------------------------------ */
.tabs {
  position: sticky;
  top: var(--bar);
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 0;
  margin: 0 0 var(--sp-7);
  padding: 0;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-bottom: 1px solid var(--line-2);
}
.tabs__btn {
  position: relative;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 14px 20px 15px;
  font-size: 14.5px;
  font-weight: 520;
  letter-spacing: -0.006em;
  color: var(--tx-3);
  transition: color var(--t) var(--ease);
  white-space: nowrap;
}
.tabs__btn:hover { color: var(--tx); }
.tabs__btn::after {
  content: "";
  position: absolute;
  left: 12px; right: 12px; bottom: -1px;
  height: 2px;
  background: var(--tx);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t) var(--ease-out);
}
.tabs__btn.is-active { color: var(--tx); }
.tabs__btn.is-active::after { transform: scaleX(1); background: var(--acc-deep); }
.tabs__idx {
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  color: var(--tx-3);
  opacity: 0.75;
}
.tabs__btn.is-active .tabs__idx { color: var(--acc-deep); opacity: 1; }
.tabs__spacer { margin-left: auto; padding-right: 4px; display: flex; align-items: center; gap: 8px; }
/* 吸顶之后才出现投影：条与内容之间需要一条"分离感" */
.tabs.is-stuck {
  border-bottom-color: var(--line);
  box-shadow: 0 10px 24px -18px rgba(13, 16, 23, 0.5);
}
.tabs.is-stuck .tabs__btn.is-active::after { box-shadow: 0 1px 0 var(--acc-deep); }

/* 面板入场：只做透明度，绝对不碰 transform。
   两个理由，都跟第 5 章要讲的内容直接相关：
     1. 只要 transform 不是 none，这个元素就成为 position: fixed 后代的
        包含块，并新建一个层叠上下文——页面外壳自己不能先违反它要教的规则。
     2. 带 fill-mode 的动画会把结束帧的"已解析值"继续留在元素上，
        恒等矩阵 matrix(1,0,0,1,0,0) 一样会俘获 fixed 后代，
        于是演示量出来的包含块会变成 .panel 而不是视口。
   位移感交给内部内容，外壳在几何上保持"透明"。 */
.panel { display: none; }
.panel.is-active { display: block; }
/* 这里刻意**不加**任何入场动画。
   最初写的是 opacity + translateY，两处都出问题：
     · transform 不是 none → 面板成为 fixed 后代的包含块、并新建层叠上下文；
       第 5 章整章在讲这条规则，外壳不能自己先违反它。
     · 即使改成只动 opacity，只要动画带 fill-mode，结束帧的解析值就会留在
       元素上（opacity < 1 同样会新建层叠上下文）；而在无头 / 虚拟时间下
       动画可能停在第一帧，于是演示量到的祖先链里会多出一个 opacity: 0 的面板。
   面板切换本身是即时反馈，动画带来的收益远小于它造成的干扰。 */

/* 讲解面板内部：单栏阅读 + 可选浮动图注 */
.prose { max-width: var(--measure); }
.prose > * + * { margin-top: var(--sp-4); }

/* ---------------------------------------------------------------------------
   8 · 讲解内容块 Content blocks
   ------------------------------------------------------------------------ */
.h2 {
  font-family: var(--f-disp);
  font-size: clamp(22px, 2.4vw, 30px);
  font-weight: 620;
  letter-spacing: -0.028em;
  line-height: 1.2;
  margin: var(--sp-8) 0 var(--sp-4);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--line);
  scroll-margin-top: calc(var(--bar) + 80px);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.h2:first-child { margin-top: var(--sp-5); padding-top: 0; border-top: 0; }
.h2__en, .h2__no {
  font-family: var(--f-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.14em;
  color: var(--acc-deep);
  margin-bottom: 2px;
  font-variant-numeric: tabular-nums;
}
.h3 {
  font-size: 16.5px;
  font-weight: 640;
  letter-spacing: -0.012em;
  margin: var(--sp-6) 0 var(--sp-3);
}

.p { font-size: 16px; line-height: 1.78; color: var(--tx-2); max-width: var(--measure); }
.p strong, .p b { color: var(--tx); font-weight: 620; }
.p + .p { margin-top: var(--sp-4); }

.ul, .ol {
  max-width: var(--measure);
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-left: 0;
  list-style: none;
  font-size: 15.5px;
  line-height: 1.7;
  color: var(--tx-2);
}
.ul li, .ol li { position: relative; padding-left: 26px; }
.ul li::before {
  content: "";
  position: absolute;
  left: 4px; top: 0.72em;
  width: 10px; height: 1px;
  background: var(--tx-3);
}
.ul li.is-ok::before { background: var(--acc-deep); height: 2px; }
.ul li.is-no::before { background: var(--sig); height: 2px; }
.ol { counter-reset: ol; }
.ol li { counter-increment: ol; }
.ol li::before {
  content: counter(ol, decimal-leading-zero);
  position: absolute;
  left: 0; top: 0.08em;
  font-family: var(--f-mono);
  font-size: 11px;
  color: var(--tx-3);
}

/* 表格 —— 印刷图录式 */
/* 印刷表格只有横线：表头上方一条重线、表头下方一条细线、表体下方一条重线。
   没有竖线、没有外框——外框是电子表格的语言，横线是排版的语言。 */
.tablewrap {
  overflow-x: auto;
  border: 0;
  border-radius: 0;
  background: none;
  max-width: 100%;
  border-top: 2px solid var(--line-hard);
  border-bottom: 2px solid var(--line-hard);
  margin: var(--sp-6) 0;
}
.tbl { font-size: 14px; min-width: 520px; }
.tbl caption {
  caption-side: top;
  text-align: left;
  padding: 10px 0 12px;
  font-family: var(--f-mono);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--tx-3);
}
.tbl th {
  text-align: left;
  padding: 9px 22px 9px 0;
  font-family: var(--f-mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--tx-3);
  background: none;
  border-bottom: 1px solid var(--line-hard);
  white-space: nowrap;
}
.tbl td {
  padding: 13px 22px 13px 0;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
  line-height: 1.6;
  color: var(--tx-2);
}
.tbl th:last-child, .tbl td:last-child { padding-right: 0; }
.tbl tr:last-child td { border-bottom: 0; }
.tbl tbody tr { transition: background var(--t-fast); }
.tbl tbody tr:hover { background: rgba(23, 19, 16, 0.035); }
.tbl td strong { color: var(--tx); font-weight: 600; }
.tbl td:first-child { color: var(--tx); font-weight: 520; }

/* 旁注 note / 陷阱 pitfall / 要点 key */
/* 批注，不是卡片。
   一个装满内容的长页面如果每一段都套一个矩形，读者看到的是 30 个盒子；
   把矩形去掉，只留一条 2px 的竖线和一个小型大写标签，它才读起来像页边注。 */
.callout {
  position: relative;
  max-width: var(--measure);
  padding: 1px 0 1px var(--sp-5);
  border: 0;
  border-left: 2px solid var(--tx-3);
  border-radius: 0;
  background: none;
  font-size: 15px;
  line-height: 1.74;
  color: var(--tx-2);
}
.callout::before {
  content: attr(data-label);
  display: block;
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--tx-3);
  margin-bottom: 9px;
}
.callout strong { color: var(--tx); font-weight: 620; }
.callout--note { border-left-color: var(--key); }
.callout--note::before { color: var(--key); }
.callout--key { border-left-color: var(--acc); }
.callout--key::before { color: var(--acc); }
.callout--pit { border-left-color: var(--sig); }
.callout--pit::before { color: var(--sig); }
.callout--num { border-left-color: var(--num); }
.callout--num::before { color: var(--num); }

/* 双栏对照 */
.cols { display: grid; gap: var(--sp-5); align-items: start; }
.cols--2 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.cols--side { grid-template-columns: minmax(0, 1fr) minmax(240px, 320px); }
@media (max-width: 900px) { .cols--side { grid-template-columns: 1fr; } }

/* 步骤条 —— 不用圆形徽章，改成目录式的行首序号 + 细分隔线 */
.steps { display: flex; flex-direction: column; gap: 0; max-width: var(--measure); }
.step {
  position: relative;
  display: grid;
  grid-template-columns: 52px minmax(0, 1fr);
  gap: var(--sp-4);
  padding: var(--sp-5) 0;
  border-bottom: 1px solid var(--line);
}
.step:first-child { border-top: 2px solid var(--line-hard); }
.step:last-child { border-bottom: 0; padding-bottom: 0; }
.step__no {
  font-family: var(--f-serif);
  font-size: 26px;
  font-weight: 400;
  line-height: 1;
  color: var(--tx-3);
  font-variant-numeric: lining-nums tabular-nums;
  padding-top: 2px;
}
.step--acc .step__no { color: var(--acc); }
.step__b { padding-top: 1px; }
.step__t { font-weight: 620; font-size: 15.5px; margin-bottom: 5px; letter-spacing: -0.012em; }
.step__d { font-size: 14.5px; line-height: 1.68; color: var(--tx-2); max-width: 58ch; }

/* 大数字 / 指标 —— 一条重线开场，数字直接用衬线，不再套格子 */
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(158px, 1fr));
  gap: var(--sp-6);
  background: none;
  border: 0;
  border-radius: 0;
  border-top: 2px solid var(--line-hard);
  padding-top: var(--sp-5);
  margin: var(--sp-6) 0;
}
.stat { background: none; padding: 0; }
.stat__v {
  font-family: var(--f-serif);
  font-size: 44px;
  font-weight: 400;
  letter-spacing: -0.035em;
  line-height: 0.94;
  margin-bottom: 10px;
  font-variant-numeric: lining-nums tabular-nums;
}
.stat__v small { font-size: 0.42em; font-weight: 400; color: var(--tx-3); letter-spacing: 0; margin-left: 2px; }
.stat__k { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--tx-3); }
.stat__d { font-size: 13px; line-height: 1.6; color: var(--tx-2); margin-top: 8px; }
.stat--acc .stat__v { color: var(--acc); }
.stat--sig .stat__v { color: var(--sig); }
.stat--num .stat__v { color: var(--num); }

/* 公式 / 定义式 */
.formula {
  font-family: var(--f-mono);
  font-size: 13.5px;
  line-height: 1.95;
  padding: var(--sp-5) 0;
  border: 0;
  border-top: 1px solid var(--line-hard);
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  background: none;
  color: var(--tx);
  overflow-x: auto;
  max-width: var(--measure);
  margin: var(--sp-6) 0;
}
.formula b { color: var(--acc); font-weight: 600; }

/* 对照卡（做对 / 做错） */
.versus {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 0;
  max-width: var(--measure);
  border-top: 2px solid var(--line-hard);
  border-bottom: 1px solid var(--line);
}
.vs { border: 0; border-radius: 0; background: none; overflow: visible; }
.vs + .vs { border-left: 1px solid var(--line); }
.vs__h {
  display: block;
  padding: 12px 0 10px;
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  border-bottom: 1px solid var(--line);
  color: var(--tx-3);
}
.vs + .vs .vs__h, .vs + .vs .vs__b { padding-left: var(--sp-5); }
.vs__h { padding-right: var(--sp-5); }
.vs--bad .vs__h { color: var(--sig); }
.vs--good .vs__h { color: var(--acc); }
.vs__b { padding: 14px var(--sp-5) 18px 0; font-size: 14.5px; line-height: 1.68; color: var(--tx-2); }

/* 术语表 */
.terms {
  display: flex;
  flex-direction: column;
  gap: 0;
  background: none;
  border: 0;
  border-top: 2px solid var(--line-hard);
  border-radius: 0;
  overflow: visible;
  max-width: var(--measure);
  margin: var(--sp-6) 0;
}
.term {
  background: none;
  padding: var(--sp-4) 0;
  display: grid;
  grid-template-columns: minmax(112px, 0.3fr) minmax(0, 1fr);
  gap: var(--sp-5);
  border-bottom: 1px solid var(--line);
}
.term:last-child { border-bottom: 0; }
.term dt { font-weight: 620; font-size: 15px; color: var(--tx); letter-spacing: -0.01em; }
.term dt span { display: block; font-family: var(--f-mono); font-size: 10px; color: var(--tx-3); letter-spacing: 0.08em; text-transform: uppercase; margin-top: 4px; font-weight: 400; }
.term dd { margin: 0; font-size: 14.5px; line-height: 1.68; color: var(--tx-2); }

/* ---------------------------------------------------------------------------
   9 · 代码图版 Code plate
   ------------------------------------------------------------------------ */
.code {
  position: relative;
  margin: var(--sp-5) 0;
  border: 1px solid #1c212c;
  border-radius: var(--r-3);
  background: var(--code-bg);
  overflow: hidden;
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.04), 0 18px 40px -22px rgba(10, 12, 17, 0.5);
}
.code__head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 14px;
  border-bottom: 1px solid var(--code-line);
  background: rgba(255, 255, 255, 0.017);
}
.code__file {
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: 0.03em;
  color: rgba(255, 255, 255, 0.5);
}
.code__file b { color: var(--tx-inv); font-weight: 500; }
.code__note {
  margin-left: auto;
  font-family: var(--f-mono);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--acc);
}
.code__copy {
  display: flex; align-items: center; gap: 6px;
  margin-left: auto;
  font-family: var(--f-mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.42);
  padding: 4px 9px;
  border: 1px solid var(--code-line);
  border-radius: var(--r-2);
  transition: color var(--t-fast), border-color var(--t-fast), background var(--t-fast);
}
.code__note + .code__copy { margin-left: 12px; }
.code__copy:hover { color: var(--acc); border-color: color-mix(in srgb, var(--acc) 45%, transparent); background: var(--acc-wash); }
.code__copy.is-done { color: var(--acc); border-color: var(--acc); }

.code__body {
  display: grid;
  grid-template-columns: 46px minmax(0, 1fr);
  font-family: var(--f-mono);
  font-size: 13px;
  line-height: 1.78;
  overflow-x: auto;
}
.code__gutter {
  padding: 14px 10px 14px 0;
  text-align: right;
  color: rgba(255, 255, 255, 0.2);
  user-select: none;
  border-right: 1px solid var(--code-line);
  font-size: 12px;
  background: rgba(255, 255, 255, 0.012);
  font-variant-numeric: tabular-nums;
}
.code__gutter i { display: block; font-style: normal; }
.code__pre {
  margin: 0;
  padding: 14px 18px;
  overflow: visible;
  color: #d7dde8;
  tab-size: 2;
  font-variant-ligatures: none;
}
.code__pre code { font-family: inherit; font-size: inherit; line-height: inherit; white-space: pre; }
/* 代码行：可带 ⭐ 标记与行内注释 */
.code__pre .ln { display: block; padding: 0 4px; margin: 0 -4px; border-radius: var(--r-1); }
.code__pre .ln--star { background: linear-gradient(90deg, rgba(46, 224, 106, 0.11), transparent 72%); box-shadow: inset 2px 0 0 var(--acc); }

.code__pre .cmt { color: var(--c-cmt); font-style: italic; }
.code__pre .kw  { color: var(--c-kw); }
.code__pre .str { color: var(--c-str); }
.code__pre .num { color: var(--c-num); }
.code__pre .fn  { color: var(--c-fn); }
.code__pre .cls { color: var(--c-prop); }
.code__pre .prop{ color: var(--c-prop); }
.code__pre .sel { color: var(--c-sel); }
.code__pre .tag { color: var(--c-tag); }
.code__pre .atr { color: var(--c-prop); }
.code__pre .op  { color: var(--c-op); }
.code__pre .var { color: #e6e9ef; }
.code__pre .star { color: var(--acc); margin-right: 6px; font-size: 11px; vertical-align: 1px; }

.code__foot {
  padding: 11px 14px;
  border-top: 1px solid var(--code-line);
  font-family: var(--f-mono);
  font-size: 11px;
  line-height: 1.65;
  color: rgba(255, 255, 255, 0.4);
  display: flex;
  gap: 10px;
  align-items: flex-start;
  background: rgba(255, 255, 255, 0.012);
}
.code__foot b { color: var(--acc); font-weight: 500; flex: none; }

/* 代码组 */
.codestack { display: flex; flex-direction: column; gap: var(--sp-6); }
.codestack > .codepart > .h3 { margin-top: 0; }
.codepart__purpose {
  font-size: 14.5px;
  line-height: 1.7;
  color: var(--tx-2);
  max-width: var(--measure);
  padding-left: 14px;
  border-left: 2px solid var(--line-2);
  margin-bottom: var(--sp-3);
}

/* ---------------------------------------------------------------------------
   10 · 演示舞台 Demo stage
   ------------------------------------------------------------------------ */
.demo {
  border: 1px solid var(--st-bg);
  border-radius: var(--r-4);
  background: var(--st-bg);
  overflow: hidden;
  color: var(--st-tx);
  box-shadow: 0 30px 70px -40px rgba(6, 7, 10, 0.7);
}
.demo + .demo { margin-top: var(--sp-6); }

.demo__head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 18px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.07);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.035), transparent);
  flex-wrap: wrap;
}
.demo__dots { display: flex; gap: 5px; flex: none; }
.demo__dots i { width: 8px; height: 8px; border-radius: 50%; background: rgba(255, 255, 255, 0.16); }
.demo__dots i:first-child { background: var(--sig); }
.demo__dots i:nth-child(2) { background: var(--num); }
.demo__dots i:nth-child(3) { background: var(--acc); }
.demo__title { font-size: 14px; font-weight: 560; letter-spacing: -0.008em; }
.demo__title span { font-family: var(--f-mono); font-size: 10.5px; color: var(--st-tx-3); letter-spacing: 0.06em; text-transform: uppercase; display: block; margin-top: 2px; font-weight: 400; }
.demo__id {
  margin-left: auto;
  font-family: var(--f-mono);
  font-size: 10.5px;
  letter-spacing: 0.1em;
  color: var(--st-tx-3);
  text-transform: uppercase;
  flex: none;
}
.demo__hint {
  padding: 12px 18px;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--st-tx-2);
  border-bottom: 1px solid rgba(255, 255, 255, 0.07);
  background: rgba(255, 255, 255, 0.018);
  display: flex;
  gap: 9px;
}
.demo__hint::before { content: "▸"; color: var(--acc); flex: none; }

/* .demo 自己是一列 flex：.demo__body 永远是那"一块舞台"，
   控件条无论被插到 body 之前还是之后都能正确落在上/下——
   用 order 而不是依赖 DOM 顺序，这样各章的演示作者
   不必关心自己把 ctrl 插到了哪里。 */
.demo { display: flex; flex-direction: column; }
.demo__head, .demo__hint { order: 0; }
.demo__body { order: 1; display: grid; grid-template-columns: minmax(0, 1fr); min-width: 0; }
.demo > .ctrl { order: 2; }
.demo > .ctrl--top { order: 0; }
/* 控件条紧贴舞台时不要出现"双线" */
.demo__body + .ctrl { border-top: 1px solid rgba(255, 255, 255, 0.07); }
/* 舞台与读数显式占位，不依赖自动放置。
   这样即使演示把控件条插进 .demo__body（第 5 章就是这么写的，
   并且用 stage.parentNode 去找控件），
     · 控件条带 grid-column: 1 / -1 → 独占一整行，不会挤动舞台
     · 舞台永远在第 1 列、读数在第 2 列，与 DOM 顺序无关 */
.demo__body > .demo__stage { grid-column: 1; grid-row: 1; }
.demo__body > .demo__meters { grid-column: 2; grid-row: 1; }
.demo__body > .ctrl { grid-column: 1 / -1; grid-row: auto; }
.demo--split .demo__body { grid-template-columns: minmax(0, 1fr) 300px; }
@media (max-width: 1080px) {
  /* 单列：舞台、读数、控件条依次堆叠 */
  .demo--split .demo__body { grid-template-columns: minmax(0, 1fr); }
  .demo__body > .demo__stage { grid-column: 1; grid-row: 1; }
  .demo__body > .demo__meters { grid-column: 1; grid-row: 2; }
  .demo__body > .ctrl { grid-column: 1; grid-row: auto; }
}

.demo__stage {
  position: relative;
  padding: 22px;
  min-height: 180px;
  background-color: var(--st-canvas);
  background-image:
    radial-gradient(circle at 1px 1px, rgba(255, 255, 255, 0.075) 1px, transparent 0);
  background-size: 22px 22px;
  background-position: -1px -1px;
  overflow: hidden;
}
.demo__stage--plain { background-image: none; }
.demo__stage--tall { min-height: 320px; }

/* 读数侧栏 —— 演示的"仪表盘" */
.demo__meters {
  border-left: 1px solid rgba(255, 255, 255, 0.07);
  background: rgba(0, 0, 0, 0.22);
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  overflow-y: auto;
  max-height: 620px;
}
.demo__meters h5 {
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--st-tx-3);
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 8px;
}
.demo__meters h5::after { content: ""; flex: 1; height: 1px; background: rgba(255, 255, 255, 0.08); }

/* 读数行 */
.readout { display: flex; flex-direction: column; gap: 5px; }
.readout__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  font-family: var(--f-mono);
  font-size: 11.5px;
  padding: 4px 0;
  border-bottom: 1px dashed rgba(255, 255, 255, 0.06);
}
.readout__row:last-child { border-bottom: 0; }
.readout__k { color: var(--st-tx-3); }
.readout__v { color: var(--st-tx); font-variant-numeric: tabular-nums; }
.readout__v--acc { color: var(--st-a); }
.readout__v--sig { color: var(--st-d); }
.readout__v--num { color: var(--st-c); }

/* 数值条 —— 让读数可以被"看"到 */
.bars { display: flex; flex-direction: column; gap: 8px; }
.bar__head { display: flex; justify-content: space-between; font-family: var(--f-mono); font-size: 10.5px; color: var(--st-tx-3); margin-bottom: 4px; }
.bar__head b { color: var(--st-tx); font-weight: 500; font-variant-numeric: tabular-nums; }
.bar__track { height: 5px; background: rgba(255, 255, 255, 0.07); border-radius: 3px; overflow: hidden; }
.bar__fill { height: 100%; background: var(--st-a); border-radius: 3px; transition: width 0.3s var(--ease-out); }
.bar__fill--b { background: var(--st-b); }
.bar__fill--c { background: var(--st-c); }
.bar__fill--d { background: var(--st-d); }

/* 控制条 */
.ctrl {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  padding: 14px 18px;
  border-top: 1px solid rgba(255, 255, 255, 0.07);
  background: rgba(0, 0, 0, 0.3);
}
.ctrl--top { border-top: 0; border-bottom: 1px solid rgba(255, 255, 255, 0.07); }
.ctrl__group { display: flex; align-items: center; gap: 10px; min-width: 0; flex-wrap: wrap; }
.ctrl__label {
  font-family: var(--f-mono);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--st-tx-3);
  white-space: nowrap;
}
.ctrl__val {
  font-family: var(--f-mono);
  font-size: 11.5px;
  color: var(--st-c);
  font-variant-numeric: tabular-nums;
  min-width: 62px;
  text-align: right;
}
.ctrl__sep { width: 1px; align-self: stretch; background: rgba(255, 255, 255, 0.08); }

/* 按钮 */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 13px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: var(--r-2);
  font-family: var(--f-mono);
  font-size: 11.5px;
  letter-spacing: 0.03em;
  color: var(--st-tx-2);
  background: rgba(255, 255, 255, 0.03);
  transition: all var(--t-fast) var(--ease);
  white-space: nowrap;
}
.btn:hover { color: var(--st-tx); border-color: rgba(255, 255, 255, 0.35); background: rgba(255, 255, 255, 0.07); }
.btn.is-on { color: #04140a; background: var(--st-a); border-color: var(--st-a); font-weight: 600; }
.btn--sig.is-on { background: var(--st-d); border-color: var(--st-d); color: #1a0703; }
.btn--ghost { border-color: transparent; }
.btn--ghost:hover { border-color: rgba(255, 255, 255, 0.2); }

/* 纸面按钮（非演示区） */
.abtn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 12px 20px;
  border-radius: var(--r-2);
  border: 1px solid var(--line-hard);
  background: var(--line-hard);
  color: var(--tx-inv);
  font-size: 14.5px;
  font-weight: 520;
  letter-spacing: -0.008em;
  transition: all var(--t) var(--ease);
}
.abtn:hover { background: transparent; color: var(--tx); transform: translateY(-1px); }
.abtn--ghost { background: transparent; color: var(--tx); border-color: var(--line-2); }
.abtn--ghost:hover { border-color: var(--line-hard); background: var(--paper-card); }
.abtn--acc { background: var(--acc-deep); border-color: var(--acc-deep); color: #fff; }
.abtn--acc:hover { background: #0f7a38; color: #fff; }

/* 滑杆 */
input[type="range"].rng {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  min-width: 110px;
  height: 20px;
  background: transparent;
  cursor: grab;
}
input[type="range"].rng:active { cursor: grabbing; }
input[type="range"].rng::-webkit-slider-runnable-track {
  height: 3px;
  background: rgba(255, 255, 255, 0.16);
  border-radius: 2px;
}
input[type="range"].rng::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 13px; height: 13px;
  margin-top: -5px;
  border-radius: 50%;
  background: var(--st-a);
  border: 2px solid var(--st-canvas);
  box-shadow: 0 0 0 1px var(--st-a), 0 0 14px rgba(46, 224, 106, 0.5);
  transition: transform var(--t-fast);
}
input[type="range"].rng::-webkit-slider-thumb:hover { transform: scale(1.18); }
input[type="range"].rng::-moz-range-track { height: 3px; background: rgba(255, 255, 255, 0.16); border-radius: 2px; }
input[type="range"].rng::-moz-range-thumb {
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--st-a); border: 2px solid var(--st-canvas);
}

/* 舞台内的通用构件 */
.box {
  border: 1px solid var(--st-line);
  background: rgba(255, 255, 255, 0.045);
  border-radius: var(--r-2);
  display: grid;
  place-items: center;
  font-family: var(--f-mono);
  font-size: 12px;
  color: var(--st-tx);
  transition: background var(--t) var(--ease), border-color var(--t) var(--ease), flex-basis var(--t) var(--ease), width var(--t) var(--ease), height var(--t) var(--ease);
  min-width: 0;
  min-height: 0;
  position: relative;
  overflow: hidden;
}
.box--a { background: var(--st-a-soft); border-color: color-mix(in srgb, var(--st-a) 55%, transparent); color: #b9ffd0; }
.box--b { background: var(--st-b-soft); border-color: color-mix(in srgb, var(--st-b) 55%, transparent); color: #cdd6ff; }
.box--c { background: var(--st-c-soft); border-color: color-mix(in srgb, var(--st-c) 55%, transparent); color: #ffe0ac; }
.box--d { background: var(--st-d-soft); border-color: color-mix(in srgb, var(--st-d) 55%, transparent); color: #ffc9bd; }
.box--e { background: var(--st-e-soft); border-color: color-mix(in srgb, var(--st-e) 55%, transparent); color: #e6d4ff; }
.box--ghost { background: repeating-linear-gradient(45deg, rgba(255,255,255,.035) 0 6px, transparent 6px 12px); border-style: dashed; color: var(--st-tx-3); }
.box--solid { background: rgba(255, 255, 255, 0.1); }

/* 容器（舞台内的父级） */
.frame {
  border: 1px dashed color-mix(in srgb, var(--st-b) 60%, transparent);
  border-radius: var(--r-2);
  position: relative;
}
.frame__tag {
  position: absolute;
  top: -9px; left: 10px;
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  padding: 1px 6px;
  background: var(--st-canvas);
  color: var(--st-b);
  border-radius: var(--r-1);
  white-space: nowrap;
}
/* 剩余空间斜纹 */
.hatch {
  background-image: repeating-linear-gradient(-45deg, rgba(255,255,255,.09) 0 1px, transparent 1px 7px);
}

/* 尺寸标注 */
.dim {
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 0.04em;
  color: var(--st-c);
  display: inline-flex;
  align-items: center;
  gap: 5px;
  white-space: nowrap;
}
.dim::before, .dim::after { content: ""; height: 1px; width: 10px; background: currentColor; opacity: 0.5; }
.dim--x::before, .dim--x::after { display: none; }

/* 日志窗 —— 演示里的 console */
.console {
  font-family: var(--f-mono);
  font-size: 11.5px;
  line-height: 1.7;
  background: #08090d;
  border: 1px solid rgba(255, 255, 255, 0.09);
  border-radius: var(--r-2);
  padding: 12px 14px;
  max-height: 220px;
  overflow-y: auto;
  color: var(--st-tx-2);
}
.console__line { display: flex; gap: 10px; padding: 1px 0; }
.console__line b { color: var(--st-a); font-weight: 500; flex: none; }
.console__line i { color: var(--st-c); font-style: normal; font-variant-numeric: tabular-nums; }
.console__line--warn b { color: var(--st-c); }
.console__line--bad b { color: var(--st-d); }

/* 舞台上的浮层标签 */
.stagelabel {
  position: absolute;
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--st-tx-3);
  padding: 2px 7px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: var(--r-1);
  background: rgba(13, 16, 22, 0.85);
  backdrop-filter: blur(4px);
  pointer-events: none;
}

/* 舞台内网格切换格 */
.toggle {
  display: inline-flex;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: var(--r-2);
  overflow: hidden;
  /* 窄屏时控件组会超出舞台宽度：允许它内部横滚，
     而不是把整个演示撑破。 */
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: none;
  flex: none;
}
.toggle::-webkit-scrollbar { display: none; }
.toggle button { flex: none; }
.toggle button {
  padding: 6px 11px;
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: 0.03em;
  color: var(--st-tx-3);
  border-right: 1px solid rgba(255, 255, 255, 0.1);
  transition: all var(--t-fast);
  white-space: nowrap;
}
.toggle button:last-child { border-right: 0; }
.toggle button:hover { color: var(--st-tx); background: rgba(255, 255, 255, 0.06); }
.toggle button.is-on { color: #04140a; background: var(--st-a); font-weight: 600; }

/* 舞台内可交互高亮 */
.hot { cursor: pointer; }
.hot:hover { outline: 1px solid var(--st-a); outline-offset: 2px; }
.is-flash { animation: flash 0.6s var(--ease-out); }
@keyframes flash {
  0% { box-shadow: 0 0 0 0 rgba(46, 224, 106, 0.55); }
  100% { box-shadow: 0 0 0 18px rgba(46, 224, 106, 0); }
}

/* 演示内的迷你排版 */
.demo__stage h4 { font-size: 13px; font-weight: 600; margin-bottom: 10px; color: var(--st-tx); font-family: var(--f-mono); letter-spacing: 0.04em; text-transform: uppercase; }
.demo__stage .mini-note { font-family: var(--f-mono); font-size: 10.5px; color: var(--st-tx-3); margin-top: 10px; line-height: 1.6; }

/* ---------------------------------------------------------------------------
   11 · 门户 Portal
   ------------------------------------------------------------------------ */
.hero {
  position: relative;
  background: var(--ink-0);
  color: var(--tx-inv);
  padding: calc(var(--bar) + var(--sp-8)) var(--sp-8) var(--sp-8);
  overflow: hidden;
  isolation: isolate;
}

/* 版面：不是"深色背景 + 大字"，而是一张印张。
   三条线索把它从通用 hero 拉回印刷品：
     1. 四角的裁切标记（crop marks）
     2. 一条横穿版心的细线，标题压在它上面
     3. 右侧竖排的版次信息
   装饰全部用背景渐变画，不加任何 DOM 元素。 */
.hero__grid {
  position: absolute;
  inset: 22px;
  z-index: -2;
  pointer-events: none;
  background-image:
    /* 裁切标记：四条短横 + 四条短竖 */
    linear-gradient(var(--ink-line-2), var(--ink-line-2)),
    linear-gradient(var(--ink-line-2), var(--ink-line-2)),
    linear-gradient(var(--ink-line-2), var(--ink-line-2)),
    linear-gradient(var(--ink-line-2), var(--ink-line-2)),
    linear-gradient(var(--ink-line-2), var(--ink-line-2)),
    linear-gradient(var(--ink-line-2), var(--ink-line-2)),
    linear-gradient(var(--ink-line-2), var(--ink-line-2)),
    linear-gradient(var(--ink-line-2), var(--ink-line-2)),
    /* 横穿版心的细线：向左延伸出副文的缩进，与标题左边缘对齐 */
    linear-gradient(var(--ink-line), var(--ink-line));
  background-repeat: no-repeat;
  background-size:
    22px 1px, 1px 22px,      /* 左上 */
    22px 1px, 1px 22px,      /* 右上 */
    22px 1px, 1px 22px,      /* 左下 */
    22px 1px, 1px 22px,      /* 右下 */
    100% 1px;
  background-position:
    0 0, 0 0,
    100% 0, 100% 0,
    0 100%, 0 100%,
    100% 100%, 100% 100%,
    0 47%;
}

/* 用两团极低饱和的墨晕代替霓虹辉光：
   颜色取自纸面本身，只是更深——像宣纸背面透过来的水痕。 */
.hero__glow {
  position: absolute;
  z-index: -1;
  width: 1100px; height: 900px;
  right: -360px; top: -420px;
  background: radial-gradient(circle, rgba(240, 232, 218, 0.075), transparent 62%);
  pointer-events: none;
  animation: drift 30s var(--ease) infinite alternate;
}
.hero__glow--2 {
  left: -420px; right: auto; top: 30%;
  width: 800px; height: 800px;
  background: radial-gradient(circle, rgba(47, 79, 168, 0.16), transparent 66%);
  animation-duration: 40s;
  animation-direction: alternate-reverse;
}
@keyframes drift {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to { transform: translate3d(-60px, 50px, 0) scale(1.12); }
}

.hero__inner { max-width: 1220px; margin: 0 auto; position: relative; }

/* 竖排版次：写在版心右侧的窄栏里，像版权页的边注 */
.hero__marginalia {
  position: absolute;
  right: -14px;
  top: 0;
  writing-mode: vertical-rl;
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--tx-inv-3);
  display: flex;
  align-items: center;
  gap: 18px;
}
.hero__marginalia::before {
  content: "";
  width: 1px;
  height: 54px;
  background: var(--ink-line-2);
}
@media (max-width: 1180px) { .hero__marginalia { display: none; } }
.hero__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 0;
  border: 0;
  font-family: var(--f-mono);
  font-size: 10.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--tx-inv-3);
  margin-bottom: var(--sp-8);
}
.hero__eyebrow::after {
  content: "";
  width: 72px;
  height: 1px;
  background: var(--ink-line-2);
}
.hero__eyebrow i {
  width: 5px; height: 5px;
  border-radius: 50%;
  background: #c9a55c;
  flex: none;
}
@keyframes pulse {
  0%, 100% { box-shadow: 0 0 0 3px rgba(46, 224, 106, 0.18); }
  50% { box-shadow: 0 0 0 7px rgba(46, 224, 106, 0.03); }
}

.hero h1 {
  font-family: var(--f-disp);
  font-size: clamp(46px, 8.2vw, 124px);
  font-weight: 660;
  line-height: 0.99;
  letter-spacing: -0.042em;
  margin-bottom: var(--sp-6);
  text-wrap: balance;
}
.hero h1 em {
  font-style: normal;
  color: #c9a55c;
  position: relative;
}
/* 强调行下面压一条短横线，宽度只有字宽的一部分——
   印刷品里的下划线从不跟满整行 */
.hero h1 em::after {
  content: "";
  position: absolute;
  left: 0.04em;
  bottom: 0.06em;
  width: 62%;
  height: 0.022em;
  background: currentColor;
  opacity: 0.5;
}
.hero h1 .outline {
  -webkit-text-stroke: 1.2px rgba(237, 230, 218, 0.42);
  color: transparent;
}
/* 副文不跟标题左对齐，而是向右缩进一格。
   整块版心因此有了"大标题压在左上、正文落在右下"的斜向关系，
   而不是每一样东西都从同一条竖线开始。 */
.hero__sub {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(272px, 1fr));
  gap: var(--sp-7);
  max-width: 980px;
  margin-left: clamp(0px, 14vw, 208px);
  margin-bottom: var(--sp-8);
  padding-top: var(--sp-6);
  border-top: 1px solid var(--ink-line);
}
@media (max-width: 760px) { .hero__sub { margin-left: 0; } }
.hero__sub p {
  font-size: clamp(15.5px, 1.35vw, 18px);
  line-height: 1.68;
  color: var(--tx-inv-2);
  letter-spacing: -0.008em;
}
.hero__sub p strong { color: var(--tx-inv); font-weight: 560; }
.hero__sub .mono { color: var(--tx-inv-3); font-size: 11px; }

.hero__cta { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; margin-bottom: var(--sp-9); }
.abtn--inv { background: var(--tx-inv); border-color: var(--tx-inv); color: var(--ink-0); }
.abtn--inv:hover { background: var(--acc); border-color: var(--acc); color: #04140a; }
.abtn--onink { background: transparent; color: var(--tx-inv); border-color: var(--ink-line-2); }
.abtn--onink:hover { border-color: var(--acc); color: var(--acc); background: rgba(46, 224, 106, 0.06); }

/* 门户统计条 */
.hero__stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 0;
  margin-top: var(--sp-8);
  margin-bottom: var(--sp-6);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--ink-line);
  border-bottom: 1px solid var(--ink-line);
}
.hero__stats div {
  padding: var(--sp-4) var(--sp-5) var(--sp-4) 0;
  border-right: 1px solid var(--ink-line);
}
/* 统计条之后留足空间：紧随其后的案例面板里有绝对定位的角标 */
.hero__stats { margin-bottom: var(--sp-6); }
.hero__stats div:last-child { border-right: 0; }
.hero__stats div + div { padding-left: var(--sp-5); }
.hero__stats b {
  display: block;
  font-family: var(--f-serif);
  font-size: clamp(38px, 4.6vw, 62px);
  font-weight: 400;
  letter-spacing: -0.035em;
  line-height: 0.92;
  margin-bottom: 10px;
  font-variant-numeric: lining-nums tabular-nums;
}
.hero__stats span {
  font-family: var(--f-mono);
  font-size: 10.5px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--tx-inv-3);
  line-height: 1.5;
  display: block;
}

.section { padding: var(--sp-9) var(--sp-8); }
.section--paper { background: var(--paper); }
.section--soft { background: var(--paper-2); }
.section--ink { background: var(--ink-1); color: var(--tx-inv); }
.section__inner { max-width: 1220px; margin: 0 auto; }
.section__head { margin-bottom: var(--sp-7); max-width: 62ch; }
.section__head h2 {
  font-family: var(--f-disp);
  font-size: clamp(28px, 3.6vw, 46px);
  font-weight: 640;
  letter-spacing: -0.032em;
  line-height: 1.08;
  margin: var(--sp-3) 0 var(--sp-4);
}
.section__head p { font-size: 16.5px; line-height: 1.7; color: var(--tx-2); }
.section--ink .section__head p { color: var(--tx-inv-2); }
.section--ink .tag { color: var(--tx-inv-3); }
/* 深色区里的演示自动切换为暗面读数样式（演示组件只认令牌，不认页面） */
.section--ink, .hero {
  --paper: var(--ink-2);
  --paper-2: var(--ink-3);
  --paper-card: var(--ink-2);
  --paper-sunk: var(--ink-1);
  --tx: var(--tx-inv);
  --tx-2: var(--tx-inv-2);
  --tx-3: var(--tx-inv-3);
  --line: var(--ink-line-2);
  --line-2: var(--ink-line-2);
  --line-hard: var(--tx-inv-3);
  --acc-deep: var(--acc);
}

/* 章节索引 —— 不是卡片网格，是目录页
   ----------------------------------------------------------------------------
   先说清楚为什么不画框：把每章装进一个带边框的矩形，是最省事也最模板化的
   做法——它用 14 个相同的矩形替代了排版本身的工作。真正的目录页（书前的
   contents、展览图录的清单）靠的是：一条重线开场、条目之间的细线、编号与
   标题的字号对比、以及足够大的行距。这里照做。
   编号退到左侧窄栏，用衬线大字；标题占主栏；两栏之间留出真正的空白。 */
.cardgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
  column-gap: var(--sp-8);
  row-gap: 0;
  border-top: 2px solid var(--line-hard);
  margin-top: var(--sp-5);
}
.card {
  position: relative;
  display: grid;
  grid-template-columns: 74px minmax(0, 1fr);
  column-gap: var(--sp-3);
  align-items: start;
  padding: var(--sp-6) 0 var(--sp-6) 0;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--line);
  transition: none;
}
/* 悬停：不是整块变色，而是编号与标题一起向强调色靠拢，
   并在左边缘拉出一条短竖线——像目录里被手指按住的那一行 */
.card::before {
  content: "";
  position: absolute;
  left: -18px;
  top: var(--sp-6);
  bottom: var(--sp-6);
  width: 2px;
  background: var(--acc);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform var(--t) var(--ease-out);
}
.card:hover::before { transform: scaleY(1); }
.card__top { display: contents; }
.card__no {
  font-family: var(--f-serif);
  font-size: 32px;
  white-space: nowrap;
  font-weight: 400;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--tx-3);
  background: none;
  padding: 0;
  font-variant-numeric: lining-nums tabular-nums;
  transition: color var(--t) var(--ease);
}

.card:hover .card__no { color: var(--acc); }
.card__arrow {
  position: absolute;
  right: 0;
  top: var(--sp-6);
  color: var(--tx-3);
  font-size: 14px;
  opacity: 0;
  transform: translateX(-6px);
  transition: opacity var(--t) var(--ease-out), transform var(--t) var(--ease-out), color var(--t);
}
.card:hover .card__arrow { opacity: 1; transform: none; color: var(--acc); }
.card h3 {
  grid-column: 2;
  font-family: var(--f-disp);
  font-size: 22px;
  font-weight: 620;
  letter-spacing: -0.026em;
  line-height: 1.16;
  margin-bottom: 3px;
}
.card h3 span {
  display: block;
  font-family: var(--f-mono);
  font-size: 9.5px;
  letter-spacing: 0.09em;
  line-height: 1.5;
  text-transform: uppercase;
  color: var(--tx-3);
  margin-top: 7px;
  font-weight: 400;
}
.card__d {
  grid-column: 2;
  font-size: 14px;
  line-height: 1.66;
  color: var(--tx-2);
  max-width: 34ch;
  margin: var(--sp-3) 0 var(--sp-4);
}
.card__tags { grid-column: 2; display: flex; flex-wrap: wrap; gap: 6px 14px; }
.card__tags .chip {
  border: 0;
  background: none;
  padding: 0;
  height: auto;
  color: var(--tx-3);
  font-size: 10px;
  letter-spacing: 0.06em;
}
.card__tags .chip::before { content: "· "; opacity: 0.6; }
.card__foot {
  grid-column: 2;
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin-top: var(--sp-4);
  padding-top: 0;
  border-top: 0;
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--tx-3);
}
.card__foot span:first-child { min-width: 0; }
.card__foot span:last-child { flex: none; }
/* 悬停提示收进标题右侧，不再是一条浮在角上的小字 */
.card__hint {
  grid-column: 2;
  margin-top: 10px;
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--acc);
  opacity: 0;
  transform: translateY(-3px);
  transition: opacity var(--t) var(--ease-out), transform var(--t) var(--ease-out);
  pointer-events: none;
}
.card:hover .card__hint { opacity: 1; transform: none; }
.card--ink .card__hint { color: var(--acc); }

.card--ink { background: none; border-color: var(--ink-line); color: var(--tx-inv); }
.card--ink .card__d { color: var(--tx-inv-2); }
.card--ink h3 span { color: var(--tx-inv-3); }
.card--ink .card__no { background: var(--acc); color: #04140a; }
.card--ink .card__foot { border-top-color: var(--ink-line); color: var(--tx-inv-3); }
.card--ink:hover { background: var(--ink-3); }

/* 理论索引 */
.theorygrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(258px, 1fr)); gap: var(--sp-6) var(--sp-6); }
.theory { padding-top: 16px; border-top: 2px solid var(--line-hard); }
.theory__y {
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--acc-deep);
  display: block;
  margin-bottom: 8px;
}
.theory h4 { font-size: 16px; font-weight: 620; letter-spacing: -0.014em; margin-bottom: 6px; }
.theory p { font-size: 13.5px; line-height: 1.6; color: var(--tx-2); max-width: 38ch; }
.theory__where {
  display: inline-block;
  margin-top: 10px;
  font-family: var(--f-mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--tx-3);
}

/* 案例预览（门户里的"丑页面"演示） */
.casepanel {
  border: 1px solid var(--ink-line-2);
  border-radius: var(--r-3);
  overflow: hidden;
  background: var(--ink-2);
}
.casepanel__bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--ink-line);
  font-family: var(--f-mono);
  font-size: 11px;
  color: var(--tx-inv-3);
}
.casepanel__bar b { color: var(--tx-inv-2); font-weight: 500; }
.casepanel { position: relative; }

/* ---------------------------------------------------------------------------
   12 · 对比滑块 Before / After
   ------------------------------------------------------------------------ */
.compare {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-3);
  border: 1px solid var(--st-line-soft);
  touch-action: none;
  cursor: ew-resize;
  user-select: none;
  background: var(--st-canvas);
}
.compare__pane { position: absolute; inset: 0; }
.compare__pane--after { clip-path: inset(0 0 0 var(--split, 50%)); }
.compare__handle {
  position: absolute;
  top: 0; bottom: 0;
  left: var(--split, 50%);
  width: 2px;
  background: var(--st-a);
  box-shadow: 0 0 18px rgba(46, 224, 106, 0.6);
  pointer-events: none;
}
.compare__handle::after {
  content: "⇄";
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 30px; height: 30px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--st-a);
  color: #04140a;
  font-size: 13px;
  font-weight: 700;
}
.compare__tag {
  position: absolute;
  top: 10px;
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: var(--r-1);
  background: rgba(8, 9, 13, 0.8);
  border: 1px solid var(--st-line-soft);
  color: var(--st-tx-2);
  pointer-events: none;
}
.compare__tag--l { left: 10px; }
.compare__tag--r { right: 10px; color: var(--st-a); border-color: color-mix(in srgb, var(--st-a) 45%, transparent); }

/* ---------------------------------------------------------------------------
   13 · 页脚 / 翻页 Footer
   ------------------------------------------------------------------------ */
.footnav {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1px;
  background: var(--line);
  border-top: 1px solid var(--line);
  margin-top: var(--sp-9);
}
.footnav a {
  background: var(--paper);
  padding: var(--sp-6);
  display: flex;
  flex-direction: column;
  gap: 6px;
  transition: background var(--t) var(--ease);
}
.footnav a:hover { background: var(--paper-card); }
.footnav small {
  font-family: var(--f-mono);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--tx-3);
}
.footnav b { font-family: var(--f-disp); font-size: 19px; font-weight: 620; letter-spacing: -0.02em; }
.footnav b span { display: block; font-family: var(--f-mono); font-size: 11px; color: var(--tx-3); font-weight: 400; margin-top: 4px; letter-spacing: 0.03em; }
.footnav .is-next { text-align: right; align-items: flex-end; }
.footnav .is-next small { color: var(--acc-deep); }

.sitefoot {
  background: var(--ink-0);
  color: var(--tx-inv-3);
  padding: var(--sp-8);
  font-family: var(--f-mono);
  font-size: 11.5px;
  line-height: 1.8;
}
.sitefoot__inner {
  max-width: 1220px;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-5);
  justify-content: space-between;
  align-items: flex-end;
}
.sitefoot b { color: var(--tx-inv-2); font-weight: 500; }
.sitefoot a:hover { color: var(--acc); }

/* ---------------------------------------------------------------------------
   14 · 工具类 Utilities
   ------------------------------------------------------------------------ */
.sr {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
/* 跳转链接：只在键盘聚焦时出现（WCAG 2.4.1 Bypass Blocks） */
a.sr:focus {
  position: fixed;
  top: 10px; left: 10px;
  width: auto; height: auto;
  margin: 0; padding: 10px 16px;
  clip: auto; overflow: visible;
  z-index: 200;
  background: var(--acc);
  color: #04140a;
  font-family: var(--f-mono);
  font-size: 12px;
  font-weight: 600;
  border-radius: var(--r-2);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}
.mt-2 { margin-top: var(--sp-2); }
.mt-4 { margin-top: var(--sp-4); }
.mt-5 { margin-top: var(--sp-5); }
.mt-6 { margin-top: var(--sp-6); }
.mt-7 { margin-top: var(--sp-7); }
.mt-8 { margin-top: var(--sp-8); }
.center { text-align: center; }
.nowrap { white-space: nowrap; }
.stack { display: flex; flex-direction: column; gap: var(--sp-4); }
.row { display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: center; }
.grow { flex: 1; min-width: 0; }

/* 进入视口时的揭示动画 */
.reveal { opacity: 0; transform: translateY(14px); }
.reveal.is-in { opacity: 1; transform: none; transition: opacity 0.7s var(--ease-out), transform 0.7s var(--ease-out); }
@media (prefers-reduced-motion: reduce) {
  .reveal, .reveal.is-in { opacity: 1; transform: none; transition: none; }
  * { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; }
  html { scroll-behavior: auto; }
}

/* ---------------------------------------------------------------------------
   15 · 响应式 Responsive
   ------------------------------------------------------------------------ */
@media (max-width: 1180px) {
  :root { --rail: 232px; }
  .page { padding: var(--sp-7) var(--sp-6) var(--sp-9); }
  .hero, .section { padding-left: var(--sp-6); padding-right: var(--sp-6); }
}

@media (max-width: 900px) {
  .shell { grid-template-columns: 1fr; }
  .rail {
    position: static;
    height: auto;
    max-height: none;
    border-right: 0;
    border-bottom: 1px solid var(--ink-line);
    padding: var(--sp-4) var(--sp-5);
  }
  .rail__list { flex-direction: row; overflow-x: auto; gap: 8px; padding-bottom: 4px; max-width: 100%; }
  .rail__list li { flex: none; }
  .rail__list a { grid-template-columns: auto; min-width: 168px; border: 1px solid var(--ink-line); border-radius: var(--r-2); }
  .rail__list a::before { display: none; }
  .rail__sec, .rail__meta, .rail__pager { display: none; }
  .rail__en { display: none; }
  .topbar__nav { display: none; }
  .demo--split .demo__body { grid-template-columns: 1fr; }
  .hero__stats { grid-template-columns: repeat(2, 1fr); }
  .term { grid-template-columns: 1fr; gap: 4px; }
  .step { grid-template-columns: 34px minmax(0, 1fr); gap: 12px; }
  .step__no { width: 28px; height: 28px; font-size: 11px; }
  .step::before { left: 14px; }
}

@media (max-width: 620px) {
  body { font-size: 15.5px; }
  /* 表格在窄屏改为内部横滚，并给出可见的滚动提示 */
  .tablewrap { position: relative; }
  .tablewrap::after {
    content: "→";
    position: sticky;
    right: 8px;
    float: right;
    top: 8px;
    font-family: var(--f-mono);
    font-size: 11px;
    color: var(--tx-3);
    pointer-events: none;
  }
  .page { padding: var(--sp-5) var(--sp-4) var(--sp-8); }
  .hero, .section { padding-left: var(--sp-4); padding-right: var(--sp-4); }
  .hero { padding-top: calc(var(--bar) + var(--sp-7)); }
  .sitefoot { padding: var(--sp-6) var(--sp-4); }
  .opener h1 { font-size: clamp(30px, 9vw, 44px); }
  .tabs__btn { padding: 12px 13px 13px; font-size: 13.5px; }
  .tabs__idx { display: none; }
  .code__body { grid-template-columns: 34px minmax(0, 1fr); font-size: 12px; }
  .code__gutter { padding-right: 7px; }
  .demo__stage { padding: 14px; }
  .ctrl { gap: 10px; padding: 12px 14px; }
  .ctrl__group { gap: 8px; width: 100%; }
  .ctrl__val { margin-left: auto; }
  .demo__meters { max-height: none; border-left: 0; border-top: 1px solid rgba(255, 255, 255, 0.07); }
}

/* 打印 */
@media print {
  .topbar, .rail, .tabs, .footnav, .sitefoot, .demo__meters, .ctrl { display: none !important; }
  .panel { display: block !important; }
  body { background: #fff; }
  .shell { grid-template-columns: 1fr; padding-top: 0; }
  .code { box-shadow: none; break-inside: avoid; }
  .demo { break-inside: avoid; }
}
