@charset "UTF-8";

/* ==========================================================================
   拾光笔记 — 站点样式表
   纯静态，无外部字体、无外部资源、无构建步骤。

   （注意：页面会加载 assets/js/enhance.js 做文内目录等呈现增强，
   但样式表本身不依赖 JS 生成任何东西——没有它页面同样完整可读。
   那条 JS 的边界写在 enhance.js 与 _internal/内容维护手册.md 第一节。）

   设计方向：中文阅读型博客的编辑排版。
     · 靠留白与细线建立结构，不用卡片、阴影、圆角色块
     · 墨色分近 / 中 / 远三级，层级靠对比度而不是靠加粗
     · 正文行高 1.9、版心约 36 个汉字，为长文阅读设置

   改动本文件前请先读 _internal/内容维护手册.md 第一节，
   以及本节末尾的「不可破坏清单」。
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. 设计令牌
   --------------------------------------------------------------------------

   不可破坏清单（改样式时逐条对照）：

   1. --text-xs 是 13px，这是页脚备案号的**下限**。
      备案编号不得隐藏、遮挡或用极小字号规避，属明确列出的整改触发项。
   2. .skip-link 用的是 position:absolute + left:-9999px，**不能改成 display:none**。
      display:none 的元素不在渲染树里，拿不到焦点，而 :focus 规则正等着它被聚焦，
      会形成死锁 —— 这个 bug 本站修过一次，posts/tech-06 一文里有完整记录。
   3. 页头当前项与目录当前章节都靠属性选择器（aria-current），不要改成类名。
   4. .filing-psb 的规则必须保留（当前无元素使用）。日后取得公安备案号时，
      靠它做纯 HTML 升级，删了就要动样式表。
   5. 所有前景/背景组合的对比度由 tools/contrast.js 实测。
      改任何色值后必须重跑 `node tools/contrast.js`，不靠目测。
   -------------------------------------------------------------------------- */

:root {
  /* --- 颜色：浅色。暖纸底，青作强调色 -----------------------------------
     墨色分近 / 中 / 远三级，靠对比度的差距建立层级，不靠加粗：
       近 16.84:1（正文）— 中 6.57:1（次要）— 远 5.21:1（极淡）
     三级之间的比值约 2.6 / 1.26，在页面上是能看出来的一层台阶。 */

  --bg:          #fcfbf8;   /* 纸色。偏暖，不用纯白 */
  --surface:     #f4f1ea;   /* 抬升底：代码块、表格头、提示块。比纸色沉一档 */
  --ink:         #1a1a18;   /* 近：正文 */
  --ink-muted:   #5d5b53;   /* 中：次要信息、导航、页脚 */
  --ink-faint:   #6e6a61;   /* 远：元信息、标签。5.21:1，仍是可读文字 */

  --rule:        #e3e0d8;   /* 细线。仅作分隔，不承担对比度 */
  --rule-strong: #cbc7bc;   /* 强线：引用条、表格表头下沿 */

  --accent:      #2f6f6b;   /* 青绿。链接、当前项、编号 */
  --accent-hover:#245752;
  --accent-soft: #eaf0ef;   /* 提示块底 */
  --on-accent:   #ffffff;   /* 压在 accent 上的字色（跳过链接） */

  /* --- 字体：全部系统栈，不加载任何外部字体 ----------------------------- */

  --font-ui:   -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB",
               "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC",
               "WenQuanYi Micro Hei", sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas,
               "Liberation Mono", "Courier New", monospace;

  /* --- 字号阶：模数约 1.25，随视口流式变化，无需媒体查询 ----------------
     旧版的四级标题只差 2–4px，挤在一起看不出层级；这里拉开到可感知的跳跃：
     正文 17–18 / h3 19–22 / h2 22–26 / h1 24–32 / 文章标题 28–42。
     中文长文行距给到 1.9 —— 比拉丁文需要更多，方块的密度靠行距化解。 */

  --text-xs:   0.8125rem;                                       /* 13px — 不可再小 */
  --text-sm:   clamp(0.875rem,  0.15vw + 0.84rem, 0.9375rem);   /* 14–15px 辅助文字 */
  --text-base: clamp(1rem,     0.25vw + 0.95rem, 1.0625rem);    /* 16–17px 界面文字 */
  --text-lg:   clamp(1.0625rem,0.30vw + 1rem,    1.125rem);     /* 17–18px 长文正文 */
  --text-h3:   clamp(1.1875rem,0.55vw + 1.08rem, 1.375rem);     /* 19–22px */
  --text-h2:   clamp(1.375rem, 1.00vw + 1.15rem, 1.625rem);     /* 22–26px */
  --text-h1:   clamp(1.5rem,   1.60vw + 1.05rem, 2rem);         /* 24–32px */
  --text-display: clamp(1.75rem, 2.30vw + 1.05rem, 2.625rem);   /* 28–42px 文章标题 */
  --text-num:  clamp(3.5rem,   11vw   + 1rem,    6rem);         /* 404 的数字 */

  /* --- 行高：中文比拉丁文需要更多行距 ----------------------------------- */

  --lh-display: 1.22;   /* 文章标题 */
  --lh-tight:   1.3;    /* 大标题 */
  --lh-snug:    1.45;   /* 小标题 */
  --lh-body:    1.9;    /* 正文 */
  --lh-meta:    1.75;   /* 元信息、页脚 */

  /* --- 间距阶：基于 4px 的整齐阶梯，4 · 8 · 12 · 16 · 24 · 32 · 40 · 56 · 80 */

  --sp-1: 0.25rem;   /*  4px */
  --sp-2: 0.5rem;    /*  8px */
  --sp-3: 0.75rem;   /* 12px */
  --sp-4: 1rem;      /* 16px */
  --sp-5: 1.5rem;    /* 24px */
  --sp-6: 2rem;      /* 32px */
  --sp-7: 2.5rem;    /* 40px */
  --sp-8: 3.5rem;    /* 56px */
  --sp-9: 5rem;      /* 80px */

  /* --- 版心 ------------------------------------------------------------- */

  /* 版心含左右各 1.5rem 的内边距（box-sizing: border-box），
     所以 43rem 的容器在 18px 正文下恰好留出 640px 的正文宽 ≈ 36 个汉字。 */
  --measure-article: 43rem;
  --measure-wide:    58rem;   /* 列表页、合规页 */

  /* --- 粘性页头下的锚点偏移。跳转后标题不能被页头盖住 ------------------- */

  --scroll-offset: 4.5rem;

  --radius: 2px;   /* 几乎不用圆角，保留给极少数的例外 */
}

/* --- 深色：同样走暖调，与浅色的暖纸感呼应，避免明暗切换时观感断裂 -------
   深色的墨色不是浅色取反 —— 浅色下越远离纸色越重，深色下越远离底色越亮，
   三级台阶要单独校核（14.64 / 8.09 / 5.70）。 */

@media (prefers-color-scheme: dark) {
  :root {
    --bg:          #181613;
    --surface:     #221e19;
    --ink:         #eae7e2;
    --ink-muted:   #b2ada4;
    --ink-faint:   #95908a;

    --rule:        #332e28;
    --rule-strong: #474037;

    --accent:      #6fb3ae;
    --accent-hover:#8ec9c4;
    --accent-soft: #1e2b2a;

    /* 深色下强调色是浅青，白字压上去只有 2.4:1，必须改用底色作字色 */
    --on-accent:   #181613;
  }
}

/* --------------------------------------------------------------------------
   2. 基础
   -------------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: var(--text-base);
  line-height: var(--lh-body);
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

::selection {
  background: var(--accent-soft);
  color: var(--ink);
}

/* 焦点轮廓：键盘可见，鼠标不打扰 */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius);
}

a {
  color: var(--accent);
  text-decoration: none;
  text-underline-offset: 0.22em;
  text-decoration-thickness: 1px;
}

/* 正文里的链接给细下划线 —— 编辑排版的典型做法，让链接在静默的正文里可辨 */
.post-body a,
.doc a,
.page-intro a {
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--accent) 35%, transparent);
}

.post-body a:hover,
.doc a:hover,
.page-intro a:hover {
  text-decoration-color: currentColor;
}

img { max-width: 100%; height: auto; }

hr {
  border: 0;
  border-top: 1px solid var(--rule);
  margin: var(--sp-7) 0;
}

/* 跳到主要内容 — 键盘用户第一个 Tab 命中。
   注意：不要改成 display:none，那样它会彻底退出 Tab 顺序。 */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: var(--sp-3) var(--sp-5);
  background: var(--accent);
  color: var(--on-accent);
  font-size: var(--text-sm);
  border-radius: 0 0 var(--radius) var(--radius);
}

.skip-link:focus {
  left: 0;
  text-decoration: none;
}

/* --------------------------------------------------------------------------
   3. 布局
   -------------------------------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: var(--measure-wide);
  margin: 0 auto;
  padding: 0 var(--sp-5);
}

.wrap--article { max-width: var(--measure-article); }

/* 锚点偏移：粘性页头会盖住跳转目标，所有可锚定的元素统一补偿。
   站内被链接的锚点有 30 多个 —— tags.html 的 12 个标签、legal/privacy.html
   的 12 个章节、compliance.html 的 6 个，以及 #main。下面这次选择器
   覆盖全部形态，新增锚点时不必再单独处理。
   注意 .tag-section 用的是 [id].tag-section：实测它没有被 h2[id] 那一条捞到。 */
main,
h2[id],
h3[id],
[id].tag-section,
.doc section[id] {
  scroll-margin-top: var(--scroll-offset);
}

/* --------------------------------------------------------------------------
   4. 页头与导航
   -------------------------------------------------------------------------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--bg);
  border-bottom: 1px solid var(--rule-strong);
}

/* 支持 backdrop-filter 时用半透明 + 模糊，滚动时正文从页头下方透出。
   不支持则保持上面的不透明底 —— 这是渐进增强，不是必需。 */
@supports (backdrop-filter: blur(8px)) {
  .site-header {
    background: color-mix(in srgb, var(--bg) 82%, transparent);
    backdrop-filter: blur(12px) saturate(1.5);
    -webkit-backdrop-filter: blur(12px) saturate(1.5);
  }
}

.header-inner {
  max-width: var(--measure-wide);
  margin: 0 auto;
  padding: var(--sp-4) var(--sp-5);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-2) var(--sp-7);
}

/* 站名：字距拉开、字重压住，与右侧导航形成主次 */
.brand {
  font-size: var(--text-lg);
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--ink);
  white-space: nowrap;
}

.brand:hover { text-decoration: none; color: var(--accent); }

.site-nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1) var(--sp-6);
}

.site-nav a {
  position: relative;
  display: inline-block;
  color: var(--ink-muted);
  font-size: var(--text-sm);
  letter-spacing: 0.04em;
  padding: 0.25em 0;
  white-space: nowrap;
}

.site-nav a:hover {
  color: var(--accent);
  text-decoration: none;
}

/* 当前项：靠字重与颜色，线只画一小段压在文字下方。
   页头自己有底边框，导航再画一条等宽横线会和它连成两道平行线。 */
.site-nav a[aria-current="page"] {
  color: var(--ink);
  font-weight: 600;
}

.site-nav a[aria-current="page"]::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -0.3em;
  height: 2px;
  background: var(--accent);
  border-radius: 1px;
}

/* --------------------------------------------------------------------------
   5. 免责声明条
   常驻显示、不可关闭 —— 无需 JavaScript，且与隐私政策中
   "本站不使用浏览器本地存储"的声明保持一致。

   视觉上是一条页眉下的细提示：去掉色块与左侧色条，只留上线与字色，
   不与正文抢注意力。但字号不减、对比度不降 —— 它是一段需要被读到的声明，
   不是装饰。字号仍由 --text-xs（13px）决定。
   -------------------------------------------------------------------------- */

.disclaimer-bar {
  background: none;
  border-bottom: 1px solid var(--rule);
}

.disclaimer-bar p {
  max-width: var(--measure-wide);
  margin: 0 auto;
  padding: var(--sp-3) var(--sp-5);
  font-size: var(--text-xs);
  line-height: var(--lh-meta);
  letter-spacing: 0.01em;
  color: var(--ink-muted);
}

.disclaimer-bar a {
  color: var(--accent);
  white-space: nowrap;
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--accent) 35%, transparent);
}

.disclaimer-bar a:hover { text-decoration-color: currentColor; }

/* --------------------------------------------------------------------------
   6. 主体内容
   -------------------------------------------------------------------------- */

main {
  display: block;
  padding: var(--sp-8) 0 var(--sp-9);
}

.page-head {
  margin-bottom: var(--sp-7);
  max-width: var(--measure-article);
}

.page-head h1 {
  font-size: var(--text-h1);
  line-height: var(--lh-tight);
  font-weight: 600;
  margin: 0 0 var(--sp-3);
  letter-spacing: 0.02em;
}

/* 导语：用字色与字号和正文拉开，不用斜体（中文没有斜体）。
   与标题之间留一出细线，让「标题 / 一行说明」成为一组。 */
.page-head .lede {
  margin: 0;
  padding-top: var(--sp-4);
  border-top: 1px solid var(--rule);
  color: var(--ink-muted);
  font-size: var(--text-base);
  line-height: var(--lh-meta);
}

/* --------------------------------------------------------------------------
   7. 文章
   -------------------------------------------------------------------------- */

.post-header {
  margin-bottom: var(--sp-6);
}

/* 文章标题用 --text-display，比页面标题再大一档 —— 这是全站层级最高的一行字 */
.post-header h1 {
  font-size: var(--text-display);
  line-height: var(--lh-display);
  font-weight: 600;
  margin: 0 0 var(--sp-5);
  letter-spacing: 0.01em;
}

/* 文章元信息：分类 · 标签 · 日期。
   编辑版式的经典处理 —— 一行小字，等宽数字，宽字距。 */
.post-meta {
  margin: 0;
  padding-top: var(--sp-4);
  border-top: 1px solid var(--rule);
  font-size: var(--text-sm);
  color: var(--ink-muted);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5em 0.8em;
  font-variant-numeric: tabular-nums;
}

.post-meta .sep {
  color: var(--rule-strong);
  user-select: none;
}

.post-meta a { color: var(--ink-muted); }
.post-meta a:hover { color: var(--accent); }

.post-meta time {
  letter-spacing: 0.06em;
  color: var(--ink-faint);
}

.post-category {
  font-weight: 600;
  color: var(--accent) !important;
  letter-spacing: 0.08em;
}

/* --- 文内目录 ------------------------------------------------------------
   这个类服务两种场景，不要为它们分裂成两个类：
     · 文章页：enhance.js 生成 nav.doc-toc > p#toc-title + ol > li > a
     · legal/privacy.html：手写的 div.doc-toc，12 项
   共同的处理是「上下两条细线夹一段横排列表」，项目多时自然折行 ——
   12 项在桌面宽度下折成两行，仍然比纵向列表省掉大半个屏幕。
   注意 li 的序号线：enhance.js 会把标题里的「一、」这类前缀剥掉，
   所以编号只能由 CSS 计数器补回来。
   ------------------------------------------------------------------------ */

.doc-toc {
  margin: 0 0 var(--sp-7);
  padding: var(--sp-4) 0;
  border-top: 1px solid var(--rule-strong);
  border-bottom: 1px solid var(--rule);
  counter-reset: toc;
}

.doc-toc > p {
  margin: 0 0 var(--sp-3);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.2em;
  color: var(--ink-faint);
}

/* 条目排成等宽的自动列：列与列对齐，行与行对齐。
   用 flex-wrap 的话每行宽度不同、左边界参差，12 项的 legal/privacy.html
   会显出这一点；grid 让两种情况都保持一个整齐的方块。 */
.doc-toc ol {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 11.5em), 1fr));
  gap: var(--sp-2) var(--sp-5);
  font-size: var(--text-sm);
  line-height: var(--lh-meta);
}

/* li 不设 flex：序号作为一个行内盒与标题同处一条基线，
   比 flex + baseline 对齐少一层盒子运算，也不会撑高整行。 */
.doc-toc li {
  counter-increment: toc;
  min-width: 0;
}

/* 11px 的纯装饰编号：低于 --text-xs 下限，但它不承载信息 ——
   目录项本身是可读的链接文字，编号只是视觉引导。 */
.doc-toc li::before {
  content: counter(toc, decimal-leading-zero);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  color: var(--rule-strong);
  margin-right: 0.45em;
}

.doc-toc a {
  color: var(--ink-muted);
  /* 长条目让它在自己的格子里折行，而不是把格子撑宽、把邻列挤走 */
  overflow-wrap: anywhere;
}
.doc-toc a:hover { color: var(--accent); }

/* 由 enhance.js 标注的当前章节；无 JS 时目录仍可用，只是不高亮 */
.doc-toc a[aria-current="true"] {
  color: var(--accent);
  font-weight: 600;
}

/* --- 正文 ---------------------------------------------------------------- */

.post-body {
  font-size: var(--text-lg);
  line-height: var(--lh-body);
}

.post-body > * + * { margin-top: var(--sp-5); }

.post-body h2 {
  font-size: var(--text-h2);
  line-height: var(--lh-snug);
  font-weight: 600;
  margin-top: var(--sp-8);
  margin-bottom: 0;
  letter-spacing: 0.01em;
}

.post-body h3 {
  font-size: var(--text-h3);
  line-height: var(--lh-snug);
  font-weight: 600;
  margin-top: var(--sp-6);
  margin-bottom: 0;
}

.post-body p { margin: 0; }

.post-body strong {
  font-weight: 600;
  color: var(--ink);
  /* 中文没有真斜体；用轻微的字距差给强调一点存在感 */
  letter-spacing: 0.01em;
}

/* 列表：标记收成强调色的一个小点，不抢正文 */
.post-body ul,
.post-body ol {
  margin: 0;
  padding-left: 1.4em;
}

.post-body li + li { margin-top: var(--sp-2); }
.post-body li > ul,
.post-body li > ol { margin-top: var(--sp-2); }

.post-body ul > li::marker {
  color: var(--accent);
  font-size: 0.85em;
}

.post-body ol > li::marker {
  color: var(--ink-faint);
  font-family: var(--font-mono);
  font-size: 0.85em;
}

.post-body blockquote {
  margin: 0;
  padding: 0 0 0 var(--sp-5);
  border-left: 2px solid var(--rule-strong);
  color: var(--ink-muted);
}

.post-body blockquote p + p { margin-top: var(--sp-5); }

/* 行内代码：不加边框，靠 --surface 的底与正文分开 */
.post-body code {
  font-family: var(--font-mono);
  font-size: 0.875em;
  background: var(--surface);
  border-radius: var(--radius);
  padding: 0.1em 0.35em;
  word-break: break-word;
}

.post-body pre {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  line-height: 1.8;
  background: var(--surface);
  border-left: 2px solid var(--rule-strong);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: var(--sp-4) var(--sp-5);
  overflow-x: auto;
  margin: var(--sp-5) 0;
  tab-size: 2;
}

.post-body pre code {
  background: none;
  border: 0;
  padding: 0;
  font-size: inherit;
}

/* 表格：去掉外框与竖线，只留行线 —— 编辑式表格 */
.post-body table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
  line-height: var(--lh-meta);
  margin: 0;
}

.post-body th,
.post-body td {
  border: 0;
  border-bottom: 1px solid var(--rule);
  padding: 0.55em 1em 0.55em 0;
  text-align: left;
  vertical-align: top;
}

.post-body th {
  font-weight: 600;
  color: var(--ink);
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
  border-bottom-color: var(--rule-strong);
  padding-bottom: 0.5em;
}

.post-body tr:last-child td { border-bottom: 0; }

/* --- 文章尾注 ------------------------------------------------------------ */

.post-footer {
  margin-top: var(--sp-8);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--rule);
  font-size: var(--text-sm);
  line-height: var(--lh-meta);
  color: var(--ink-muted);
}

.post-footer p { margin: 0 0 var(--sp-3); }
.post-footer p:last-child { margin-bottom: 0; }

/* 授权声明：从"灰底块"改成左侧细线引用式，更轻，不打断阅读 */
.post-footer .license {
  padding: 0 0 0 var(--sp-4);
  background: none;
  border-left: 2px solid var(--rule-strong);
  border-radius: 0;
}

/* --- 上一篇 / 下一篇 ----------------------------------------------------- */

.post-nav {
  margin-top: var(--sp-8);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--rule);
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-5) var(--sp-6);
  justify-content: space-between;
  font-size: var(--text-sm);
  line-height: var(--lh-meta);
}

.post-nav a {
  color: var(--ink);
  max-width: 22rem;
}

.post-nav a:hover { color: var(--accent); }

/* label 与标题拉开：label 是引导语，标题才是链接本身 */
.post-nav .label {
  display: block;
  margin-bottom: var(--sp-2);
  font-size: var(--text-xs);
  font-weight: 400;
  letter-spacing: 0.16em;
  color: var(--ink-faint);
}

/* --------------------------------------------------------------------------
   8. 文章列表
   -------------------------------------------------------------------------- */

.section-block { margin-top: var(--sp-9); }

/* 「小标题」母题：首页分节标题、归档月份、标签名共用一套。
   旧版在三个地方各写了一遍，改一次要改三处。 */
.section-title,
.archive-group h2,
.tag-section h2 {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.2em;
  color: var(--ink-faint);
  margin: 0 0 var(--sp-5);
  padding-bottom: var(--sp-3);
  border-bottom: 1px solid var(--rule-strong);
}

.list-more {
  margin: var(--sp-6) 0 0;
  font-size: var(--text-sm);
  color: var(--ink-muted);
}

/* 首页导语 */
.page-intro p {
  margin: 0 0 var(--sp-4);
  color: var(--ink-muted);
  line-height: var(--lh-body);
}

.page-intro p:last-child { margin-bottom: 0; }

.page-intro strong { color: var(--ink); font-weight: 600; }

/* --- 文章列表：细线分隔 + 大留白 ----------------------------------------
   线只画在每一条的上方（li + li），第一条没有上邻，最后一条不留悬空的线。
   列表项之间靠内边距撑开，不用卡片、阴影、圆角。 */

.post-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.post-list li {
  padding: var(--sp-6) 0;
}

.post-list li + li { border-top: 1px solid var(--rule); }
.post-list li:first-child { padding-top: 0; }
.post-list li:last-child { padding-bottom: 0; }

.post-list h3 {
  margin: 0 0 var(--sp-3);
  font-size: var(--text-h3);
  font-weight: 600;
  line-height: var(--lh-snug);
  letter-spacing: 0.01em;
}

.post-list h3 a { color: var(--ink); }
.post-list h3 a:hover { color: var(--accent); text-decoration: none; }

.post-list .excerpt {
  margin: 0 0 var(--sp-4);
  color: var(--ink-muted);
  font-size: var(--text-sm);
  line-height: var(--lh-body);
  max-width: 44rem;
}

.list-meta {
  margin: 0;
  font-size: var(--text-xs);
  color: var(--ink-faint);
  letter-spacing: 0.08em;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4em 0.9em;
  align-items: center;
  font-variant-numeric: tabular-nums;
}

.list-meta .sep { color: var(--rule-strong); user-select: none; }
.list-meta a { color: var(--ink-faint); }
.list-meta a:hover { color: var(--accent); }
.list-meta time { letter-spacing: 0.08em; }

/* --- 归档：按年月分组 ---------------------------------------------------- */

.archive-group { margin-bottom: var(--sp-8); }

.archive-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.archive-list li {
  display: flex;
  gap: var(--sp-5);
  align-items: baseline;
  padding: var(--sp-3) 0;
}

.archive-list li + li { border-top: 1px solid var(--rule); }

.archive-list time {
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.06em;
}

.archive-list a {
  color: var(--ink);
  line-height: var(--lh-snug);
}

.archive-list a:hover { color: var(--accent); }

/* --------------------------------------------------------------------------
   9. 标签
   -------------------------------------------------------------------------- */

.tag-section {
  padding: var(--sp-7) 0;
}

.tag-section:first-of-type { padding-top: 0; }

.tag-section + .tag-section { border-top: 1px solid var(--rule); }

.tag-section h2 {
  margin-bottom: var(--sp-4);
  display: flex;
  align-items: baseline;
  gap: 0.6em;
}

.tag-count {
  font-size: var(--text-xs);
  font-weight: 400;
  letter-spacing: 0.04em;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}

.tag-section ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.tag-section li + li { margin-top: var(--sp-3); }

.tag-section li a {
  color: var(--ink);
  font-size: var(--text-sm);
  line-height: var(--lh-snug);
}

.tag-section li a:hover { color: var(--accent); }

/* 内联标签（文章元信息与列表里用）。
   旧版是带边框的圆角小块，页面上方框太多；改成纯文字 + 字距，
   靠 # 前缀而不是边框来表明它是标签。 */
.tag-chip {
  display: inline;
  padding: 0;
  border: 0;
  border-radius: 0;
  font-size: inherit;
  letter-spacing: 0.04em;
  color: inherit !important;
  line-height: inherit;
}

.tag-chip::before { content: "#"; opacity: 0.45; margin-right: 0.1em; }

.tag-chip:hover {
  color: var(--accent) !important;
  text-decoration: none;
}

/* --------------------------------------------------------------------------
   10. 合规页 / 法律页
   -------------------------------------------------------------------------- */

.doc > section { margin-bottom: var(--sp-8); }

/* 法律文档需要强分段，所以 h2 的下边界线保留 */
.doc h2 {
  font-size: var(--text-h2);
  line-height: var(--lh-snug);
  font-weight: 600;
  margin: 0 0 var(--sp-5);
  padding-bottom: var(--sp-3);
  border-bottom: 1px solid var(--rule);
}

.doc h3 {
  font-size: var(--text-h3);
  line-height: var(--lh-snug);
  font-weight: 600;
  margin: var(--sp-6) 0 var(--sp-3);
}

.doc p,
.doc ul,
.doc ol { margin: 0 0 var(--sp-4); }

.doc ul,
.doc ol { padding-left: 1.4em; }

.doc li + li { margin-top: var(--sp-2); }

.doc ul > li::marker { color: var(--accent); font-size: 0.85em; }

.doc dt { font-weight: 600; margin-top: var(--sp-3); }
.doc dd { margin: 0 0 0 var(--sp-5); }

/* 定义表：备案信息、许可条件等。同 .post-body table —— 去外框留行线。
   这张表被 7 个文件、多处使用（含 compliance.html 的备案信息表），
   所以 th 的固定宽与不换行在 420px 以下必须放开，否则窄屏会横向溢出。 */
.info-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
  line-height: var(--lh-meta);
  margin: 0 0 var(--sp-5);
}

.info-table th,
.info-table td {
  border: 0;
  border-bottom: 1px solid var(--rule);
  padding: 0.65em 1em 0.65em 0;
  text-align: left;
  vertical-align: top;
}

.info-table tr:last-child th,
.info-table tr:last-child td { border-bottom: 0; }

/* 表头行：小号字距 + 更强的下线，把「字段名」与「字段值」分开 */
.info-table th {
  font-weight: 600;
  color: var(--ink);
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
  white-space: nowrap;
  width: 9em;
  border-bottom-color: var(--rule);
}

/* 表格里如果有链接，给下划线以免和普通文字混淆 */
.info-table a {
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--accent) 35%, transparent);
}

.info-table a:hover { text-decoration-color: currentColor; }

/* 单文件使用：legal/copyright.html 的表格外层容器（旧版没有对应规则，
   这里补上，让它在窄屏可以横向滚动而不是撑破版心） */
.info-table-wrap {
  overflow-x: auto;
  margin: 0 0 var(--sp-5);
}

.info-table-wrap .info-table { margin-bottom: 0; }

/* --- 备案信息卡（compliance.html 专用）----------------------------------
   这是备案信息的展示核心，视觉上要庄重而不是花哨：
   加大留白、居中、备案号用等宽数字。
   上下各一条线把它框成一块「牌子」，不用底色 —— 底色会让它像广告位。 */
.filing-card {
  padding: var(--sp-7) var(--sp-5);
  background: none;
  border: 0;
  border-top: 2px solid var(--ink);
  border-bottom: 1px solid var(--rule-strong);
  border-radius: 0;
  margin: 0 0 var(--sp-6);
  text-align: center;
}

.filing-card .filing-card-label {
  margin: 0 0 var(--sp-4);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.24em;
  color: var(--ink-faint);
}

.filing-card .filing-card-nums {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: var(--sp-3) var(--sp-5);
  font-size: var(--text-base);
  line-height: var(--lh-meta);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}

.filing-card .filing-card-nums a { font-weight: 600; }

.filing-card .filing-card-nums .filing-sep { margin: 0; }

.filing-card .filing-card-note {
  margin: var(--sp-5) 0 0;
  font-size: var(--text-xs);
  line-height: var(--lh-meta);
  color: var(--ink-muted);
}

/* --- 提示块 --------------------------------------------------------------
   底色降到几乎与纸色同调，只留左侧一条细线 —— 在正文里能认出来，
   但不跳脱。对比度由 tools/contrast.js 实测（浅色 15.11 / 5.05，
   深色 11.87 / 6.09）。 */

.callout {
  padding: var(--sp-4) var(--sp-5);
  padding-right: var(--sp-4);
  background: var(--accent-soft);
  border-left: 2px solid var(--accent);
  border-radius: 0 var(--radius) var(--radius) 0;
  font-size: var(--text-sm);
  line-height: var(--lh-body);
  margin: 0 0 var(--sp-5);
}

.callout p { margin: 0; }
.callout p + p { margin-top: var(--sp-3); }

/* --- 可复制模板 ---------------------------------------------------------- */

.template {
  background: var(--surface);
  border-left: 2px solid var(--rule-strong);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: var(--sp-4) var(--sp-5);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  line-height: 1.85;
  white-space: pre-wrap;
  overflow-x: auto;
  margin: 0 0 var(--sp-5);
}

/* --------------------------------------------------------------------------
   11. 404
   -------------------------------------------------------------------------- */

.error-page {
  text-align: center;
  padding: var(--sp-8) var(--sp-5);
}

/* 大号 404 是装饰性数字，用强线的颜色即可，不必按正文字号卡对比度 */
.error-page .code {
  font-family: var(--font-mono);
  font-size: var(--text-num);
  line-height: 1;
  font-weight: 600;
  color: var(--rule-strong);
  margin: 0 0 var(--sp-5);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}

.error-page h1 {
  font-size: var(--text-h2);
  line-height: var(--lh-snug);
  margin: 0 0 var(--sp-4);
}

.error-page p {
  color: var(--ink-muted);
  margin: 0 0 var(--sp-6);
  font-size: var(--text-base);
}

.error-page ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-3) var(--sp-6);
  font-size: var(--text-sm);
}

/* --------------------------------------------------------------------------
   12. 页脚
   底与页面同色，只靠上方一条细线与正文分开 —— 备案信息「坐在页面上」，
   而不是装在一个盒子里。
   -------------------------------------------------------------------------- */

.site-footer {
  border-top: 1px solid var(--rule);
  background: var(--bg);
  margin-top: var(--sp-9);
  padding: var(--sp-7) 0 var(--sp-6);
}

.footer-inner {
  max-width: var(--measure-wide);
  margin: 0 auto;
  padding: 0 var(--sp-5);
}

/* 备案信息区 ---------------------------------------------------------
   办法第十三条要求备案编号标明在「主页底部的中央位置」。
   居中不是装饰，是合规要求 —— 不要改成左对齐或放进侧栏。

   字号由 --text-xs 决定（13px），这是下限。备案编号不得隐藏、遮挡，
   也不得用极小字号规避，那属于明确列出的整改触发项。
   下面 .filing-label 与 .filing-icp 的颜色由 tools/contrast.js 实测：
   浅色 5.21 / 6.57，深色 5.70 / 8.09，均高于 13px 小字要求的 4.5:1。

   .filing-psb / .psb-badge 的规则早已备好，公安备案号落地时只加了 HTML，
   样式表只补了图标本身的处理 —— 布局这条路径没有被改过，
   两个 ICP 号与一个公安号共用同一行、同一字号。
   ---------------------------------------------------------------------- */

.footer-filing {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 0.4rem 0;
  margin: 0 0 var(--sp-5);
  padding-bottom: var(--sp-5);
  border-bottom: 1px solid var(--rule);
  font-size: var(--text-xs);
  line-height: var(--lh-meta);
  letter-spacing: 0.04em;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}

.filing-label {
  margin-right: 1em;
  letter-spacing: 0.2em;
  color: var(--ink-faint);
  user-select: none;
}

.filing-icp,
.filing-psb {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  color: var(--ink-muted);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  padding-bottom: 1px;
}

.filing-icp:hover,
.filing-psb:hover,
.filing-icp:focus-visible,
.filing-psb:focus-visible {
  color: var(--accent);
  border-bottom-color: var(--accent);
  text-decoration: none;
}

.filing-sep {
  margin: 0 0.8em;
  color: var(--rule-strong);
  user-select: none;
}

/* 公安备案徽标。这是一张自带白底的位图（36×40），在暖纸底上有两点要处理：
   一是用 multiply 让白底融进页脚底；
   二是原图的暗部落在 #00011f，纯黑轮廓压在暖纸色上会露出一圈偏蓝的脏边，
     所以加一道极窄的临界色描边，把外缘整体拉成能自洽的暖深色。
   两个颜色都取自已有令牌，由 tools/contrast.js 一并校核；
   打印时下面 @media print 会把描边去掉。
   宽高比必须交给 width:auto —— 原图不是正方形，写死 20×20 会把它横向压扁。 */
.filing-psb .psb-badge {
  display: block;
  width: auto;
  height: 20px;
  flex: 0 0 auto;
  border: 1px solid var(--rule-strong);
  background: var(--bg);
  mix-blend-mode: multiply;
}

.footer-copy,
.footer-note,
.footer-contact {
  margin: 0 0 var(--sp-2);
  text-align: center;
  font-size: var(--text-xs);
  line-height: var(--lh-meta);
  color: var(--ink-muted);
}

.footer-copy { color: var(--ink); }

.footer-contact { margin-bottom: 0; }

.footer-contact a {
  color: var(--ink-muted);
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--ink-muted) 30%, transparent);
}

.footer-contact a:hover {
  color: var(--accent);
  text-decoration-color: currentColor;
}

.footer-legal {
  margin-top: var(--sp-5);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--rule);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-3) var(--sp-7);
}

.footer-legal a {
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  color: var(--ink-muted);
}

.footer-legal a:hover { color: var(--accent); }

/* --------------------------------------------------------------------------
   13. 窄屏
   粘性页头在窄屏吃掉的高度尤其贵，所以压缩内边距、不折行成两排；
   正文内的空行也随视口收一点，但行高 1.9 不动 —— 中文正文的疏朗
   是版式的基础，不能在窄屏被牺牲掉。
   -------------------------------------------------------------------------- */

@media (max-width: 720px) {
  :root { --scroll-offset: 5.5rem; }

  .header-inner {
    padding: var(--sp-3) var(--sp-4);
    gap: var(--sp-1) var(--sp-4);
    flex-wrap: nowrap;
    align-items: center;
  }

  /* 导航允许自己横向滚动，也不折成两行把页头撑高一倍 */
  .site-nav {
    flex: 1 1 auto;
    min-width: 0;
    overflow-x: auto;
    scrollbar-width: none;
  }

  .site-nav::-webkit-scrollbar { display: none; }

  .site-nav ul { flex-wrap: nowrap; gap: var(--sp-1) var(--sp-4); }

  .brand { font-size: var(--text-base); letter-spacing: 0.12em; }

  .site-nav a { font-size: var(--text-xs); }

  .wrap,
  .disclaimer-bar p,
  .header-inner,
  .footer-inner { padding-left: var(--sp-4); padding-right: var(--sp-4); }

  main { padding: var(--sp-6) 0 var(--sp-8); }

  .post-body > * + * { margin-top: var(--sp-4); }

  .post-body h2 { margin-top: var(--sp-7); }

  .post-list li { padding: var(--sp-5) 0; }

  .section-block { margin-top: var(--sp-7); }

  .post-nav {
    flex-direction: column;
    gap: var(--sp-4);
  }

  .post-nav a { max-width: none; }

  .tag-section { padding: var(--sp-6) 0; }

  .error-page { padding: var(--sp-6) var(--sp-4); }
}

@media (max-width: 420px) {
  .footer-filing {
    flex-direction: column;
    gap: var(--sp-2);
  }

  /* 换行后分隔符变成噪音 */
  .filing-sep { display: none; }

  .filing-label { margin: 0 0 var(--sp-1); }

  .post-list .excerpt { font-size: var(--text-xs); }

  .archive-list li {
    flex-direction: column;
    gap: var(--sp-1);
  }

  /* 备案信息表靠 th 的 9em 固定宽维持两栏；窄屏放开成自动宽，
     长值自己换行，避免横向溢出 */
  .info-table th {
    width: auto;
    white-space: normal;
  }

  /* 目录在窄屏横排会碎成很多行，改成单列纵向更省空间 */
  .doc-toc ol { grid-template-columns: 1fr; gap: var(--sp-2); }

  .filing-card { padding: var(--sp-6) var(--sp-4); }
}

/* --------------------------------------------------------------------------
   14. 打印
   备案信息是合规要素，纸质件同样需要可核查 —— 页脚不隐藏。
   -------------------------------------------------------------------------- */

@media print {
  :root { --scroll-offset: 0; }

  .site-header,
  .site-nav,
  .skip-link,
  .post-nav,
  .doc-toc { display: none; }

  body {
    background: #fff;
    color: #000;
    font-size: 11pt;
    line-height: 1.6;
  }

  main { padding: 0; }

  a { color: #000; text-decoration: underline; }

  /* 去底色与细线，避免整页耗墨；法律页的提示块与模板尤其费墨 */
  .disclaimer-bar,
  .site-footer,
  .callout,
  .template,
  .post-body pre,
  .post-body code,
  .filing-card { background: #fff; }

  .callout { border: 0; padding-left: 0; padding-right: 0; }

  .disclaimer-bar,
  .site-footer,
  .callout,
  .template,
  .post-body pre,
  .filing-card,
  .info-table th,
  .info-table td { border-color: #999; }

  .post-body pre,
  .template { border-left-color: #999; }

  /* 公安徽标的临界色描边与 multiply 是为屏幕上的暖纸底调的；
     打印按原样输出更稳（页脚本就要留） */
  .filing-psb .psb-badge {
    border: 0;
    background: none;
    mix-blend-mode: normal;
  }

  /* 备案卡在纸上靠上下两条线成块，去掉粗上线避免像横幅 */
  .filing-card { border-top-width: 1px; }

  /* 标题不要和后面的内容断开在两页 */
  h1, h2, h3 { break-after: avoid; page-break-after: avoid; }

  .post-header,
  .post-footer,
  .filing-card,
  .info-table tr { break-inside: avoid; page-break-inside: avoid; }

  /* 目录是导航，打印出来的纸件上无用（链接跳不动） */
  .doc-toc { display: none; }

  .site-footer { margin-top: 2rem; padding-top: 1rem; }

  /* 打印时页脚备案号仍要在页面底部中央可见 */
  .footer-filing {
    border-bottom-color: #999;
    padding-bottom: 0.75rem;
  }

  .footer-legal { display: none; }
}
