/* ============================================================
   研伴官网 · 首页与法务页共用样式
   规范见 ../DESIGN.md。改颜色去 tokens.css，这里不硬编码色值。
   ============================================================ */

/* Display 层字符子集。Android 没有任何一支中文宋体（Songti SC / STSong /
   SimSun 都是 macOS 与 Windows 的字，Georgia 只覆盖拉丁字母），
   没有这一层，宋体标题在安卓上会静默变成黑体。
   子集必须随文案重新生成 —— 见 tools/build-font.sh。 */
@font-face {
  font-family: "Yanban Display";
  src: url("../assets/fonts/yanban-display.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

/* ---------- 基础 ---------- */

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

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

body {
  /* 显式写死纸底：本站只做浅色，不提供深色分支。
     不写这一行，深色偏好的浏览器会给出深底 + 深墨字的不可读组合。 */
  background-color: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1.0625rem;   /* 17px：主场景是手机上读长条款 */
  line-height: 1.75;
  margin: 0;
  text-rendering: optimizeLegibility;
}

h1, h2, h3 {
  font-family: var(--font-title);
  font-weight: 600;
  font-synthesis: none;   /* 拿不到衬线时不要合成假粗体，交给显式降级 */
  text-wrap: balance;
  margin: 0;
}

p { margin: 0; text-wrap: pretty; }

a { color: inherit; }

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

.sr {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

.skip {
  position: absolute; left: var(--s-4); top: var(--s-4);
  z-index: var(--z-menu);
  background: var(--card); color: var(--ink);
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: var(--s-3) var(--s-4);
  /* 位移用 transform 而不是 top —— top 是布局属性，动它会触发重排。
     这是全站唯一一处曾经动布局属性的地方。 */
  transform: translateY(-300%);
  transition: transform var(--dur-state) var(--ease-out);
}
.skip:focus { transform: none; }

:where(a, button):focus-visible {
  outline: 2px solid var(--seal);
  outline-offset: 2px;
  border-radius: 2px;
}

.wrap {
  max-width: 40rem;                        /* ≈ 36 个汉字的行长 */
  margin-inline: auto;
  padding-inline: clamp(var(--s-5), 6vw, var(--s-7));
}

/* 结构靠线，不靠影。
   注意不要给它 margin：相邻两个 section 的 padding-block 已经各出一半留白，
   线正好落在中间。再加 margin-top 会变成上 192px、下 96px 的偏心间距。 */
.rule {
  border: 0;
  border-top: 1px solid var(--border);
  max-width: 40rem;
  margin: 0 auto;
}

section.wrap { padding-block: clamp(var(--s-7), 11vw, var(--s-9)); }

/* 用后代选择器而不是 `>`：入口区的 h2 嵌在 .enter-pending / .enter-live 里，
   直接子选择器匹配不到它，表现是那一个 h2 丢掉字号、字距和下间距。
   全站只有入口区的 h2 是嵌套的，所以放宽到后代不会误伤别的东西。 */
section.wrap h2,
.spread h2 {
  font-size: clamp(1.375rem, 3.5vw, 1.75rem);
  line-height: 1.45;
  letter-spacing: 0.04em;
  margin-bottom: var(--s-4);
}

/* 只给无类名的正文段落上色。写成 `section.wrap > p` 会把 .seal-mark、.lede
   这些自带颜色的元素一起吃掉（权重 0,1,2 压过 0,1,0）—— 印上白就是这么丢的。 */
section.wrap > p:not([class]) { color: var(--ink-2-text); }

/* ---------- 页眉 ---------- */

.topbar { border-bottom: 1px solid var(--border); }

.topbar-in {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  min-height: 56px;
}

.wordmark {
  font-family: var(--font-title);
  font-weight: 600;
  font-size: 1.125rem;
  letter-spacing: 0.16em;   /* 中文标题字距放开，不收紧 */
  text-decoration: none;
  /* 两个汉字 + 字距实测只有 42px 宽，差 2px 不够 44 的点击区。
     补横向 padding 并用等量负 margin 抵回，视觉左对齐不变。 */
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: var(--s-2);
  margin-left: calc(var(--s-2) * -1);
}

.topbar nav { display: flex; gap: var(--s-2); }

.topbar nav a,
.footer nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;          /* 最小点击区，不靠字号凑 */
  padding-inline: var(--s-2);
  font-size: 0.9375rem;
  color: var(--ink-2-text);
  text-decoration: none;
  transition: color var(--dur-state) var(--ease-out);
}
.topbar nav a:hover,
.footer nav a:hover { color: var(--seal); }

/* ---------- 跨页 ----------
   北极星是「一册摊开的讲义」。摊开就是跨页：窄屏下它折叠成单页（左页在上、
   右页在下、书脊收起），宽屏下才真正摊开成左右两页。
   PC 是这个站的主画布 —— 小程序官网的核心转化是扫码，而扫码要求页面和手机
   不在同一块屏上。手机端是这套版式折叠下来的结果，不是反过来。 */

.spread {
  max-width: 40rem;
  margin-inline: auto;
  padding-inline: clamp(var(--s-5), 6vw, var(--s-7));
}


@media (min-width: 1024px) {
  .spread {
    display: grid;
    grid-template-columns: 1fr 1fr;   /* 书脊不占列：它画在 .spread::after 上，跑满整屏高 */
    /* 这两条是跨页成立的关键，不能换成 align-items: center：
       align-content 把整个跨页块在屏内居中，align-items: start 让左右两页
       共用同一条天头线。各自居中的话，两页的文字起点会错开，就不是一册书
       摊开的样子，而是两个无关的盒子并排。 */
    align-content: center;
    align-items: start;
    max-width: var(--spread-w);
    padding-inline: var(--s-5);
    /* 首屏必须整个落在一屏里。svh 而不是 vh：移动端地址栏收放时 vh 会跳。 */
    min-height: calc(100svh - var(--topbar-h));
    padding-block: var(--s-6);
  }

  /* 栏格：讲义纸上极淡的横栏线，只铺在版心里，不铺到版心外的纸底上。
     isolation 让下面的 z-index:-1 落在 .spread 自己的弧度底色之上、内容之下。
     上下用 mask 淡出 —— 和弧度那条一样，直接截断会在首屏底边留一道硬边，滚动时一眼假。
     线色 alpha 0.03（≤3%，复核给的上限）。横排文字不可能对齐任意栏线，
     所以它只能当纸纹看待，不承担任何对齐功能。
     **变暗预算只有这么多**：--ink-2-text 在纸底上 4.75:1，底子再暗约 0.03 alpha 就跌破 4.5。
     栏线自己用掉了全部 0.03（线上 4.52）。曾经叠过一层噪点纸纹，最坏像素跌到 4.40，
     而噪点要压到能共存的深度（~0.005）就等于看不见 —— 所以纸纹删了，不是漏了。 */
  .spread { position: relative; isolation: isolate; }
  .spread::before {
    content: "";
    position: absolute;
    z-index: -1;
    inset: 0 var(--s-5);
    background-image: repeating-linear-gradient(to bottom,
      transparent 0 31px,
      rgba(58, 52, 43, 0.03) 31px 32px);
    /* 遮罩只读 alpha，颜色无意义；用 --ink 只是因为它不透明且在色板里 */
    -webkit-mask-image: linear-gradient(to bottom, transparent, var(--ink) 14%, var(--ink) 86%, transparent);
            mask-image: linear-gradient(to bottom, transparent, var(--ink) 14%, var(--ink) 86%, transparent);
    pointer-events: none;
  }

  /* 纸面弧度：书摊开时靠近书脊的纸卷下去，那一带略暗。是纸的曲率，不是投影，
     所以用暖褐渐变而不是 box-shadow（线装律）。三个约束，都是踩出来的：
     ① 宽度只有 110px、居中压在书脊上 —— 对比度审计读 background-color，看不见渐变，
        铺到正文底下会得到假通过。实测左页正文最右 x=662，暗带从 x=658 起，重叠 4px，alpha≈0.003；
     ② 不能只有内容那一行高 —— 那样上下两条硬边会把它渲染成一个灰方块；
     ③ 上下两端要和书脊、栏格一样淡出 —— 直接铺到跨页底边，最后一屏下面接平的地脚时，
        暗带会在那里一刀切断。每一屏是独立摊开的一页，三样东西都该在页边淡出。 */
  .spread::after {
    content: "";
    position: absolute;
    z-index: -1;
    inset: 0;
    /* 三层，从上到下：订孔点 · 装订线 · 纸面弧度。
       书脊做成伪元素而不是一个 <div>：做成元素时只有首屏放了它，第二到第六屏全漏了。
       挂在 .spread 上，以后新加的跨页自动带书脊。订孔点用 --ink-3 的 60%（纯装饰）。 */
    background-image:
      radial-gradient(circle, rgba(179, 169, 149, 0.6) 1.5px, transparent 1.6px),
      linear-gradient(to right, transparent 50%, var(--border) 50%, var(--border) calc(50% + 1px), transparent calc(50% + 1px)),
      linear-gradient(to right,
        transparent calc(50% - 55px),
        rgba(90, 74, 50, 0.04) 50%,
        transparent calc(50% + 55px));
    background-size: 5px 30px, auto, auto;
    background-position: calc(50% + 0.5px) 15px, 0 0, 0 0;
    background-repeat: repeat-y, no-repeat, no-repeat;
    -webkit-mask-image: linear-gradient(to bottom, transparent, var(--ink) 10%, var(--ink) 90%, transparent);
            mask-image: linear-gradient(to bottom, transparent, var(--ink) 10%, var(--ink) 90%, transparent);
    pointer-events: none;
  }

  .page-l { padding-inline: clamp(var(--s-6), 3.5vw, var(--s-8)); }
  .page-r { padding-inline: var(--s-5); }

  /* 书脊 = 一条装订线 + 一列订孔点。这是「装订」，不是阴影，所以不碰 box-shadow。
     订孔用 --ink-3：它在本系统里本来就只许做装饰（2.05:1），正好对口。 */

}

/* 页眉在 PC 上跟版心走，不再卡在 640px 的旧单栏里：
   左缘对齐左页文字（跨页内边距 + 左页内边距），右缘对齐右页版心。 */
@media (min-width: 1024px) {
  .topbar-in {
    max-width: var(--spread-w);
    padding-left: calc(var(--s-5) + clamp(var(--s-6), 3.5vw, var(--s-8)));
    padding-right: calc(var(--s-5) * 2);
  }
}

/* ---------- Hero ---------- */

.hero { padding-block: clamp(var(--s-7), 12vw, var(--s-9)) clamp(var(--s-7), 10vw, var(--s-8)); }



/* 全站唯一的品牌动作：印落下。只动 transform ——
   即使动画不执行，印章也始终可见（可见即默认律）。 */
.seal-mark {
  width: 66px; height: 66px;
  display: flex; align-items: center; justify-content: center;
  background: var(--seal, #A5382C);
  /* 带回退：var() 解析失败时整条声明作废并继承父级墨色 —— 在这里就是
     深墨压朱砂（1.88:1）。压在有色底上的字必须给回退，不能裸奔。 */
  color: var(--seal-foreground, #FDF9EF);
  border-radius: 10px;            /* 方的，不是圆的 —— 印章是方的 */
  font-family: var(--font-title);
  font-size: 34px;
  font-weight: 600;
  line-height: 1;
  margin: 0 0 var(--s-5);
  animation: seal-drop var(--dur-gesture) var(--ease-out) both;
}

@keyframes seal-drop {
  from { transform: translateY(-6px) scale(1.04); }
  to   { transform: none; }
}

.hero h1 {
  font-size: clamp(2rem, 6vw, 3.25rem);
  line-height: 1.3;
  letter-spacing: 0.02em;
  margin-bottom: var(--s-4);
}
/* 分句成块：换行只能落在两句之间 */
.hero h1 span { display: inline-block; }

.lede {
  font-size: 1.125rem;
  color: var(--ink-2-text);
  max-width: 34em;
}

.hero-act { margin-top: var(--s-6); }

/* PC 跨页下的 hero 覆盖。**必须整块放在上面所有 .hero 基础规则之后** ——
   媒体查询不提升特异性，写在前面会被后面同特异性的基础规则覆盖回去
   （踩过一次：h1 的 3.5rem 被 clamp 的 3.25rem 吃掉）。 */
@media (min-width: 1024px) {
  .hero { padding-block: var(--s-6); }

  /* 左页有整页宽度，标题再压一档分量 */
  .hero h1 { font-size: 3.5rem; }

  /* 右页：只放今日页复刻，居中摆在页上。 */
  .page-r .screen { margin: 0 auto; }
  /* 图注跟卡片同宽，不横跨整页 */
  .page-r .screen figcaption {
    max-width: 26rem;
    margin-inline: auto;
    text-align: left;
  }
}

/* ---------- 封面（2026-10-21） ----------
   一册合着的线装讲义：磁青书衣 + 左侧四眼订线与包角 + 右上竖排题签 + 押角朱印。
   左订右开：本站正文横排、从左往右读，掀角也是从右下角掀，所以订口在左，
   题签按古籍「贴在开口一侧的上角」的规矩，镜像到右上。
   窄屏：一本立着的小书放在页首。PC：和跨页同样大小，书模式下第一下掀开的就是它。 */
.cover {
  position: relative;
  display: block;
  aspect-ratio: 3 / 4;
  max-width: min(24rem, calc(100% - 2 * var(--s-5)));
  margin: var(--s-6) auto var(--s-7);
  padding: 0;
  border-radius: var(--radius-cell);
  color: var(--paper);
  /* 书衣：深青底 + 两层 SVG 噪声（细的是纸纤维，粗的是染色不匀的斑驳）+ 订口一侧略暗 */
  background-color: var(--cover);
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='f'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .55 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23f)' opacity='.12'/%3E%3C/svg%3E"),
    radial-gradient(ellipse 60% 50% at 28% 22%, rgba(255, 255, 255, 0.05), transparent 70%),
    radial-gradient(ellipse 70% 60% at 82% 88%, rgba(35, 44, 56, 0.16), transparent 70%),
    linear-gradient(115deg, transparent 35%, rgba(255, 255, 255, 0.035) 48%, transparent 60%),
    linear-gradient(to right, rgba(35, 44, 56, 0.18), transparent 9%);
  box-shadow:
    0 2px 0 0 var(--paper), 0 3px 0 0 #DDD2BB, 0 5px 0 0 var(--paper), 0 6px 0 0 #D6CAB0,
    0 20px 34px -16px rgba(35, 30, 24, 0.45);
}
.cover::before, .cover::after { content: none; }

/* 订口：一条丝线沿订线走，四个订眼，每个眼都有一道线绕过书背；上下两角包着深色绫子（包角） */
.cover-bind {
  position: absolute;
  inset: 0 auto 0 0;
  width: 13%;
  max-width: 64px;
  background:
    linear-gradient(var(--cover-deep), var(--cover-deep)) 0 0 / 100% 7% no-repeat,
    linear-gradient(var(--cover-deep), var(--cover-deep)) 0 100% / 100% 7% no-repeat;
}
.cover-bind::before {          /* 顺着订线的那一道 */
  content: "";
  position: absolute;
  left: 56%; top: 13%; bottom: 13%;
  border-left: 2.5px solid var(--thread);
  opacity: 0.85;
}
.cover-bind i {
  position: absolute;
  left: 0;
  width: 56%;
  height: 2.5px;
  background: var(--thread);
  opacity: 0.85;
}
.cover-bind i::after {         /* 订眼 */
  content: "";
  position: absolute;
  right: -4px; top: -3px;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--cover-deep);
  box-shadow: inset 0 1px 1px rgba(35, 44, 56, 0.5);
}
.cover-bind i:nth-child(1) { top: 13%; }
.cover-bind i:nth-child(2) { top: 37.7%; }
.cover-bind i:nth-child(3) { top: 62.3%; }
.cover-bind i:nth-child(4) { top: 87%; }

/* 题签组：签在右，副题一列贴在它左边（竖排从右往左读：先书名、后副题） */
.cover-label {
  position: absolute;
  top: 8%;
  right: 12%;
  display: flex;
  flex-direction: row-reverse;
  align-items: flex-start;
  gap: 0.9rem;
}
/* 题签：一条旧纸色长签，双边框（外粗内细），书名竖排 */
.cover-slip {
  position: relative;
  padding: 10px;
  background: var(--slip);
  box-shadow: 0 1px 2px rgba(35, 44, 56, 0.25);
}
.cover-slip::before {
  content: "";
  position: absolute;
  inset: 5px;
  border: 1.5px solid rgba(58, 52, 43, 0.55);
  outline: 0.5px solid rgba(58, 52, 43, 0.4);
  outline-offset: -4px;
  pointer-events: none;
}
.cover-title {
  writing-mode: vertical-rl;
  font-family: var(--font-title);
  font-weight: 600;
  font-synthesis: none;
  font-size: clamp(2.5rem, 11vw, 3.5rem);
  line-height: 1;
  letter-spacing: 0.35em;
  padding: 0.5em 0.42em 0.15em;   /* 竖排里 letter-spacing 加在每个字下面，最后一个字的那份要从底边扣回来 */
  color: var(--ink);
}
/* 副题：紧贴题签左侧，一列小字竖排，墨换成纸色 */
.cover-sub {
  margin-top: 1.1rem;
  writing-mode: vertical-rl;
  font-family: var(--font-title);
  font-weight: 600;
  font-synthesis: none;
  font-size: 0.9375rem;
  letter-spacing: 0.4em;
  line-height: 1;
  color: rgba(245, 240, 230, 0.78);
}
.cover-seal.seal-mark {
  position: absolute;
  margin: 0;
  width: 44px; height: 44px;
  font-size: 22px;
  border-radius: var(--radius);
  right: -20px;         /* 押角：压住题签右下角，一半在签上一半在书衣上（左下角会压到副题） */
  bottom: -20px;
  box-shadow: 0 0 0 1px rgba(35, 44, 56, 0.06);
}
.cover-hint { display: none; }
/* 落款：书衣左下，订口旁一列竖排小字，只写时间和地点（丙午 = 2026）。不再加印：这一面已有题签上那一方 */
.cover-colophon {
  position: absolute;
  left: calc(13% + 18px);
  bottom: 9%;
  writing-mode: vertical-rl;
  font-family: var(--font-title);
  font-weight: 600;
  font-synthesis: none;
  font-size: 0.8125rem;
  letter-spacing: 0.35em;
  line-height: 1;
  color: rgba(245, 240, 230, 0.72);   /* 同封面提示：窗影下仍 >5:1 */
}

@media (min-width: 1024px) {
  /* PC：和跨页一样大（版心宽 × 一屏高），书模式下由书台统一定高 */
  .cover {
    aspect-ratio: auto;
    max-width: calc(var(--spread-w) - 2 * var(--s-5));
    min-height: calc(100svh - var(--topbar-h) - 2 * var(--s-6));
    margin: var(--s-6) auto;
  }
  .cover-bind { width: 64px; }
  .cover-colophon { left: 100px; bottom: 56px; font-size: 1rem; }
  .cover-label { top: 72px; right: 14%; gap: 1.25rem; }
  .cover-slip { padding: 14px; }
  .cover-title { font-size: 5.25rem; }
  .cover-sub { margin-top: 1.5rem; font-size: 1.25rem; }
  .cover-seal.seal-mark { width: 60px; height: 60px; font-size: 30px; border-radius: var(--radius); right: -28px; bottom: -28px; }
  main.book .cover-hint {
    display: block;
    position: absolute;
    left: 0; right: 0; bottom: 36px;
    text-align: center;
    font-size: 0.875rem;
    letter-spacing: 0.3em;
    color: rgba(245, 240, 230, 0.72);   /* 0.6 时在窗影最深处只有 4.23:1；0.72 是 6.13，窗影下仍 >5 */
  }
}

/* PC 首屏的竖排主句（C「把字放大」）：左页右侧立两列宋体大字，紧挨书脊，从右往左读；
   引言和按钮落在左下，和主句的底边对齐——竖排的阅读顺序是右→左，所以它们排在主句之后、主句左边。
   窄屏仍是横排（两列竖排在 375 宽里只能缩到 40px 左右，失去分量）。 */
@media (min-width: 1024px) {
  .hero .page-l {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-rows: 1fr auto auto;
    column-gap: var(--s-7);
    align-self: stretch;
  }
  .hero h1 {
    grid-column: 2;
    grid-row: 1 / -1;
    writing-mode: vertical-rl;
    font-size: 4.75rem;
    line-height: 1.32;
    letter-spacing: 0.06em;
    margin: 0;
  }
  .hero h1 span { display: block; }
  .hero .lede { grid-column: 1; grid-row: 2; font-size: 1.1875rem; line-height: 1.85; max-width: 12em; }
  .hero .hero-act { grid-column: 1; grid-row: 3; margin-top: var(--s-5); }
}

/* ---------- 对照（第二屏） ---------- */

/* 窄屏：跨页折叠成单页，补上和 section.wrap 一样的上下留白 */
.compare { padding-block: clamp(var(--s-7), 11vw, var(--s-9)); }
.compare .page-r { margin-top: var(--s-7); }

/* 展品上的小标签。Label 层：宋体 13px + 放开字距，短则有力。 */
.exhibit-tag {
  font-family: var(--font-title);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  color: var(--ink-2-text);
  margin-bottom: var(--s-3);
}

/* <figure> 自带浏览器默认 margin: 1em 40px，不清掉两件展品都会往里缩 40px、和页上文字对不齐 */
.plain-plan, .real-plan { margin: var(--s-6) 0 0; }

/* 左：别人的计划表。装在框里（它是个 App），全是一个调子 ——
   科目和时长同色同号，没有任何东西在告诉你今天具体干什么。灰，空。
   方框而不是圆圈：和研伴的勾选圈区分开，一眼看出不是同一个东西。 */
.plain-plan ul {
  list-style: none;
  margin: 0;
  padding: var(--s-2) var(--s-5);
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.plain-plan li {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  min-height: 56px;
  color: var(--ink-2-text);
  border-bottom: 1px solid var(--border);
}
.plain-plan li:last-child { border-bottom: 0; }
.plain-plan .sq {
  flex: 0 0 auto;
  width: 18px; height: 18px;
  border: 1px solid var(--ink-3);
  border-radius: 2px;      /* DESIGN.md 圆角刻度的 sm 档，和「推荐」小红章同一档 */
}
.plain-plan .pt { margin-left: auto; }

.compare-note,
.compare-lede,
.compare-sum { color: var(--ink-2-text); }
.compare-note { margin-top: var(--s-5); font-size: 1rem; }
.compare-lede { margin-bottom: var(--s-6); }
.compare-sum  { margin-top: var(--s-5); font-size: 1rem; }

/* 右：研伴排出来的条目。不装框，直接印在讲义纸上 —— 研伴就是这本讲义。
   比首屏卡片里的字大一档（那里是缩小的手机屏，这里是放大的细节）。
   条目之间不画分隔线：页上已经有栏格，再画一套对不齐的横线会打架。 */
.real-plan dl { margin: 0; }
.real-plan .grp { padding-block: var(--s-2); }   /* 原 12px：第二屏在 827 高的笔记本上超出 54px，收一点 */
.real-plan dt {
  font-family: var(--font-title);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  color: var(--ink-2-text);
}
.real-plan dd {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin: var(--s-2) 0 0;
  font-size: 1.1875rem;
  color: var(--ink);
}
.real-plan .chk {
  flex: 0 0 auto;
  width: 24px; height: 24px;
  border: 1px solid var(--ink-3);
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px;
  color: var(--seal-foreground, #FDF9EF);   /* 竹青底上的 ✓ 必须有回退 */
}
.real-plan .done .chk { background: var(--bamboo); border-color: var(--bamboo); }
.real-plan .done .rl { text-decoration: line-through; color: var(--ink-2-text); }
.real-plan .rm { margin-left: auto; font-size: 0.9375rem; color: var(--ink-2-text); }

@media (min-width: 1024px) {
  .compare { padding-block: var(--s-6); }
  .compare .page-r { margin-top: 0; }

  /* 两页共享 7 条行轨：标题/说明 · 展品标签 · 英语 · 数学 · 政治 · 专业课 · 注脚。
     页 → figure → ul/dl 三层嵌套 subgrid，让左页每一行和右页同科那一组等高：
     右边英语有两条任务，左边「英语 2 小时」那一行就被撑高，里面却还是只有三个字
     —— 空洞在同一行里自己显出来，左框也自然和右边一样高，不会在底下留一个大洞。
     不支持 subgrid 的浏览器只是不对齐，内容照常显示。 */
  .compare { grid-template-rows: repeat(7, auto); }
  .compare .page {
    grid-row: 1 / span 7;
    display: grid;
    grid-template-rows: subgrid;
  }
  .compare .plain-plan,
  .compare .real-plan {
    grid-row: 2 / span 5;
    display: grid;
    grid-template-rows: subgrid;
  }
  .compare .plain-plan ul,
  .compare .real-plan dl {
    grid-row: 2 / span 4;
    display: grid;
    grid-template-rows: subgrid;
  }
  /* subgrid 下容器的上下内边距会吃进首尾两条行轨，左框首行就比右边晚起笔 9px。
     PC 上清零，行内留白交给每个 li 自己的 padding-block。 */
  .compare .plain-plan ul { padding-block: 0; }
  /* 左行内容贴顶，和右边同科的科目名同一高度起笔 */
  .compare .plain-plan li {
    align-items: flex-start;
    min-height: 0;
    padding-block: var(--s-3);
  }
  /* 贴顶后方框要和第一行文字居中：(行高 17×1.75≈30 − 方框 18) ÷ 2 ≈ 6px */
  .compare .plain-plan .sq { margin-top: 6px; }
  .compare h2 { margin-bottom: 0; align-self: end; }
  .compare-lede { margin-bottom: 0; align-self: end; }
}

/* ---------- 断了三天（第三屏） ---------- */

.breaks { padding-block: clamp(var(--s-7), 11vw, var(--s-9)); }
.breaks .page-r { margin-top: var(--s-7); }
.breaks-lede { color: var(--ink-2-text); }

/* 日历复刻。照 plan.vue 画：周一开头、四档热力底色、宋体日期、今天一圈朱砂、
   计划范围外（开始之前 / 考试日之后）无底色、数字用 --border 几乎看不见。
   只裁掉了小程序里外面那层卡片框 —— 这块网格直接印在讲义页上。 */
.cal { margin: 0; }
.cal-title {
  font-family: var(--font-title);
  font-weight: 600;
  font-size: 1.125rem;
  letter-spacing: 0.04em;
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--border);
}
.cal-nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--s-3) var(--s-2);
}
.cal-arrow { font-size: 1.375rem; line-height: 1; color: var(--seal); padding-inline: var(--s-4); }
.cal-month { font-family: var(--font-title); letter-spacing: 0.04em; }

.cal-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: clamp(3px, 0.6vw, 6px);
}
.cal-grid .wd {
  text-align: center;
  font-size: 0.75rem;
  color: var(--ink-2-text);
  padding-bottom: var(--s-1);
}
.cd {
  /* 小程序里是 64rpx 高、宽约 41px，宽高比约 1.3；放大后保持这个比例 */
  aspect-ratio: 1.3;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-cell);
  font-family: var(--font-title);
  font-size: clamp(0.75rem, 1.1vw, 0.9375rem);
  color: var(--ink);
}
.cd.done  { background: var(--heat-done); }
.cd.part  { background: var(--heat-part); }
.cd.miss  { background: var(--heat-miss); }
.cd.empty { background: var(--heat-empty); }
/* 今天：一圈朱砂。小程序用 inset box-shadow 画这圈；这里用负偏移 outline，
   效果相同，且不碰 box-shadow（线装律：投影不在选项里，哪怕它只是被借来画描边）。 */
.cd.today { outline: 2px solid var(--seal); outline-offset: -2px; }
/* 计划范围外：无底色，数字是 --border（对纸底 1.2:1）。这是照搬小程序的「几乎看不见」，
   属于界面截图里的附带文字（WCAG 1.4.3 对「图片中的附带文字」豁免），整块网格已 aria-hidden，
   读屏走上面那段 .sr 摘要。 */
.cd.out   { color: var(--border); }

/* 图例：网页上的说明，不属于复刻。颜色之外还有文字，红绿色觉障碍也分得清。 */
.cal-key {
  list-style: none;
  margin: var(--s-5) 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-5);
  font-size: 0.875rem;
  color: var(--ink-2-text);
}
.cal-key li { display: flex; align-items: center; gap: var(--s-2); }
.cal-key .sw { width: 14px; height: 14px; border-radius: 2px; }
.cal-key .sw.done  { background: var(--heat-done); }
.cal-key .sw.part  { background: var(--heat-part); }
.cal-key .sw.miss  { background: var(--heat-miss); }
.cal-key .sw.empty { background: var(--heat-empty); }

.cal figcaption {
  margin-top: var(--s-4);
  font-size: 0.9375rem;
  color: var(--ink-2-text);
}

@media (min-width: 1024px) {
  .breaks { padding-block: var(--s-6); }
  .breaks .page-r { margin-top: 0; }
  /* 左页的说明列表比首屏左页密：这一页本来就是「讲义正文」那一类页 */
  .breaks .plain { margin-top: var(--s-5); }
}

/* 跨页之间不画那条 640px 的短横线：每个跨页本身就是一屏，
   栏格和书脊在上下边缘自己淡出，翻页感已经有了，再加一条线是多余的。 */
@media (min-width: 1024px) {
  .spread + .rule { display: none; }
}

/* ---------- 按钮 ---------- */

.btn-ghost,
.btn-copy {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: var(--s-3) var(--s-6);
  background: var(--card);
  color: var(--ink);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-family: var(--font-title);
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-decoration: none;
  cursor: pointer;
  transition: border-color var(--dur-state) var(--ease-out),
              color var(--dur-state) var(--ease-out);
}
.btn-ghost:hover,
.btn-copy:hover { border-color: var(--seal); color: var(--seal); }

.btn-copy {
  font-size: 0.9375rem;
  padding-inline: var(--s-4);
  margin-left: var(--s-2);
}

/* ---------- 今日页复刻（签名组件） ----------
   朱印节制律的唯一豁免：整件占一处名额，内部朱砂不单独计数。 */

/* 这一屏是全页的重心：给它比相邻区块更大的天头地脚和更宽的版心。
   六个区块节奏完全一样时，没有任何东西在说「这一屏最重要」。 */
#what { padding-block: clamp(var(--s-8), 14vw, 7rem); }

.screen { margin: clamp(var(--s-7), 10vw, var(--s-8)) 0 0; }

.screen-card {
  max-width: 26rem;
  margin-inline: auto;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--s-5);
  box-shadow: var(--shadow-paper);   /* 不给回退：解析失败只是没影子，纯装饰，不影响可读性 */
}

.screen-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3);
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--border);
}

.day-no {
  font-family: var(--font-title);
  font-size: 1.125rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.countdown {
  font-family: var(--font-title);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--seal);
}

.screen-sum {
  font-size: 0.8125rem;
  color: var(--ink-2-text);
  padding-block: var(--s-2);
}

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

.task {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding-block: var(--s-3);
  border-bottom: 1px solid var(--border);
}
.task:last-child { border-bottom: none; }

.chk {
  flex: 0 0 auto;
  width: 22px; height: 22px;
  border: 1px solid var(--ink-3);
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px;
  color: var(--seal-foreground, #FDF9EF);   /* 同上：竹青底上的 ✓ 必须有回退 */
}
/* 完成态同时有颜色和记号 —— 朱砂与竹青是红绿对，不能只靠颜色 */
.task.done .chk { background: var(--bamboo); border-color: var(--bamboo); }
.task.done .task-l { text-decoration: line-through; color: var(--ink-2-text); }

.task-l { flex: 1 1 auto; font-size: 0.9375rem; line-height: 1.5; }
.task-m { flex: 0 0 auto; font-size: 0.75rem; color: var(--ink-2-text); }

.screen-next {
  margin-top: var(--s-3);
  padding-top: var(--s-3);
  border-top: 1px solid var(--border);
  font-size: 0.8125rem;
  color: var(--ink-2-text);
}

.screen figcaption {
  margin-top: var(--s-4);
  font-size: 0.9375rem;
  color: var(--ink-2-text);
  text-align: center;
  max-width: 30em;
  margin-inline: auto;
}

/* ---------- 说明列表（不是图标卡） ---------- */

.plain { margin: var(--s-6) 0 0; }

.plain dt {
  font-family: var(--font-title);
  font-weight: 600;
  font-size: 1.125rem;
  letter-spacing: 0.02em;
  margin-top: var(--s-5);
}
.plain dt:first-of-type { margin-top: 0; }

.plain dd {
  margin: var(--s-2) 0 0;
  text-wrap: pretty;      /* 避免「那儿。」「不动。」这种两三个字单独掉一行 */
  color: var(--ink-2-text);
}

/* ---------- 四科：四个分册（第四屏） ---------- */

.vols-spread { padding-block: clamp(var(--s-7), 11vw, var(--s-9)); }
.vols-sub { color: var(--ink-2-text); }

.vols { list-style: none; margin: var(--s-6) 0 0; padding: 0; }
.page-r .vols { margin-top: 0; }

/* 窄屏：每册一行，题签竖在左，说明在右 —— 像一排书脊 */
.vol {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s-4);
  align-items: start;
  padding-block: var(--s-5);
  border-top: 1px solid var(--border);
}
.vol p { color: var(--ink-2-text); text-wrap: pretty; }

/* 题签：线装书封面上那条竖写的纸签。细框 + 卷面白底，像一条贴上去的纸。
   框线用 --ink-3：纯装饰，本系统里它只准干这个。 */
.vol-tag {
  writing-mode: vertical-rl;
  margin: 0;
  padding: var(--s-3) var(--s-2);
  background: var(--card);
  border: 1px solid var(--ink-3);
  border-radius: var(--radius-cell);
  font-size: 1.125rem;
  font-weight: 600;
  letter-spacing: 0.3em;
  line-height: 1;
}

@media (min-width: 1024px) {
  /* 三行轨：标题与引言 · 题签 · 说明。
     题签不强行等高 —— 真的题签本来就随书名长短不一，硬拉成一样高，两个字的签
     下半截全是空框，像没贴完。用 subgrid 让「说明」这一行在四栏里同一条线起笔，
     签多长都不影响。标题与引言只在左页；右页第一行留白，像章首那页的天头。 */
  .vols-spread {
    padding-block: var(--s-6);
    grid-template-rows: auto auto auto;
  }
  .vols-spread .page {
    grid-row: 1 / span 3;
    display: grid;
    grid-template-rows: subgrid;
  }
  .vols-spread .page-l { padding-right: var(--s-5); }
  .vols-spread .vols {
    grid-row: 2 / span 2;
    margin: var(--s-6) 0 0;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-rows: subgrid;
  }
  .vols-spread .vol {
    grid-row: span 2;
    display: grid;
    grid-template-columns: minmax(0, 1fr);   /* 清掉窄屏的 auto 1fr：PC 上题签在上、说明在下 */
    grid-template-rows: subgrid;
    gap: 0;
    border-top: 0;
    padding: 0 var(--s-5);
  }
  .vol:first-child { padding-left: 0; }
  .vol + .vol { border-left: 1px solid var(--border); }   /* 界行 */
  /* 贴着书脊和外缘的那一侧不再加栏内边距：页本身已经有边距，叠上去会把数学那栏压到 202px */
  .page-l .vol:last-child,
  .page-r .vol:last-child { padding-right: 0; }

  .vol-tag { justify-self: start; align-self: start; }
  .vol p { margin-top: var(--s-5); }
}

/* ---------- 凭什么信：扉页（第五屏） ---------- */

.title-spread { padding-block: clamp(var(--s-7), 11vw, var(--s-9)); }

/* 扉页：整张居中。成绩在书名的位置，学校在出版者那一行。
   居中排的正文只在这一处 —— 扉页本来就是居中的，别处不学。 */
.title-page {
  text-align: center;
  margin-top: var(--s-7);
  padding-block: var(--s-6);
  border-block: 1px solid var(--border);
}
.tp-scores { margin: 0; display: grid; gap: var(--s-6); }
.tp-item dt {
  font-family: var(--font-title);
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: 0.3em;
  color: var(--ink-2-text);
}
/* 扉页数字：DESIGN.md 里专门加的一档，只给这两个成绩用。
   字距放开一点点，数字之间要有铅字排出来的呼吸。 */
.tp-num {
  margin: var(--s-1) 0 0;
  font-family: var(--font-title);
  font-weight: 600;
  font-size: clamp(3rem, 9vw, 4rem);
  line-height: 1.05;
  letter-spacing: 0.06em;
  color: var(--ink);
}
.tp-school {
  margin-top: var(--s-7);
  font-family: var(--font-title);
  font-size: 1.125rem;
  font-weight: 600;
  letter-spacing: 0.3em;
}
.tp-note {
  /* 24em 让这 46 个字正好排成两行；22em 时第三行只剩「东西。」两个字 ——
     Chrome 的 text-wrap: pretty 对中文不生效，只能靠宽度。 */
  max-width: 24em;
  margin: var(--s-5) auto 0;
  font-size: 0.9375rem;
  color: var(--ink-2-text);
  text-wrap: pretty;
}

@media (min-width: 1024px) {
  .title-spread { padding-block: var(--s-6); }
  .title-page { margin-top: 0; }
}

/* ---------- 入口槽位 ---------- */

/* 槽位开关只有一处：改 section 上的 data-launch。别再叠 hidden 属性。 */
.enter[data-launch="pending"] .enter-live { display: none; }
.enter[data-launch="live"] .enter-pending { display: none; }
.enter[data-launch="live"] .enter-live { display: block; }

.qr {
  width: 200px; height: 200px;
  margin: var(--s-6) 0 var(--s-4);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
}

/* 任何时刻只显示一句话。JS 未执行时保持 desktop 一档。 */
.enter-hint { display: none; color: var(--ink-2-text); }
:root:not([data-env]) .enter-hint[data-when="desktop"],
:root[data-env="desktop"] .enter-hint[data-when="desktop"],
:root[data-env="wechat"]  .enter-hint[data-when="wechat"],
:root[data-env="mobile"]  .enter-hint[data-when="mobile"] { display: block; }



/* ---------- 版权页（第六屏） ---------- */

.colophon-spread { padding-block: clamp(var(--s-7), 11vw, var(--s-9)); }
.colophon-spread .page-r { margin-top: var(--s-7); }

/* 版框：两道细线（3px double = 两条 1px 线夹一条 1px 缝），旧书版权页那种「子母线」框。
   框线用 --ink-3：纯装饰。印在页上，不铺卷面底 —— 它是这一页本身，不是一张贴上去的卡片。 */
.colophon {
  position: relative;
  padding: var(--s-6) var(--s-5) var(--s-5);
  border: 3px double var(--ink-3);
  /* 铺纸色（不是卷面白）：只为盖住页上的栏格。框里每行自带分隔线，
     栏格再从底下穿过来就是两套对不齐的横线打架。看上去仍是印在页上。 */
  background: var(--paper);
}
.colophon dl { margin: 0; }
.colophon dl > div {
  display: grid;
  grid-template-columns: 4.5em minmax(0, 1fr);
  gap: var(--s-4);
  padding-block: var(--s-3);
  border-top: 1px solid var(--border);
}
.colophon dl > div:first-child { border-top: 0; padding-top: 0; }
.colophon dt {
  font-family: var(--font-title);
  font-weight: 600;
  font-size: 0.9375rem;
  letter-spacing: 0.3em;
  color: var(--ink-2-text);
  padding-top: 2px;
}
.colophon dd { margin: 0; color: var(--ink); text-wrap: pretty; }

.colophon-links { display: flex; flex-wrap: wrap; gap: 0 var(--s-4); }
.colophon-links a {
  display: inline-flex; align-items: center;
  min-height: 44px;
  margin-block: -10px;          /* 凑够 44px 点击区，但不撑开这一行的行高 */
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: color var(--dur-state) var(--ease-out);
}
.colophon-links a:hover, .colophon-links a:active { color: var(--seal); }

/* 印花：旧时版权页上贴印花证明正版。这一屏唯一的朱砂，静止 ——
   全站会「落下」的只有首屏那一枚（两个动作律）。半压在版框上、略歪一点，像真盖上去的。 */
.colophon-seal {
  position: absolute;
  top: -22px;
  right: var(--s-5);
  width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  background: var(--seal, #A5382C);
  color: var(--seal-foreground, #FDF9EF);   /* 有色底上的字必须给回退 */
  border-radius: var(--radius);   /* 首屏 66px 印配 10px 圆角，按比例缩到 44px≈6.7px，取刻度里最近的 7px */
  font-family: var(--font-title);
  font-size: 22px;
  font-weight: 600;
  line-height: 1;
  transform: rotate(-4deg);
}

/* 地脚：备案号居中。第 33 号令第十三条要求「主页底部的中央位置」。
   首页专用；法务页仍用左对齐的 .footer。 */
.footer.foot-center {          /* 双类名：.footer 写在后面且带 border-top，同特异性会把这里盖回去 */
  border-top: 0;
  text-align: center;
  padding-block: var(--s-3) calc(var(--s-5) + env(safe-area-inset-bottom));
}
.foot-center .beian { margin-top: 0; }

@media (min-width: 1024px) {
  /* 最后一个跨页 + 地脚 = 正好一屏 */
  .colophon-spread {
    padding-block: var(--s-6);
    min-height: calc(100svh - var(--topbar-h) - var(--foot-h));
  }
  .colophon-spread .page-r { margin-top: 0; padding-top: 22px; }   /* 给半压在框上的印让出位置 */

  /* 地脚在 PC 上「规定」就是 --foot-h 高，内容垂直居中。
     不写死实测高度：换字体、改行高，实测值就漂，最后一屏又会多出几像素。 */
  .foot-center {
    height: var(--foot-h);
    padding-block: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
  }
}

/* ---------- 竖排大标题（C「把字放大」，2026-10-21） ----------
   PC 上第二到第六屏的左页标题一律竖排宋体大字，像线装书的书名、章名那样立在页上。
   分句用 <span> 断成列（第一个 span 在最右，竖排从右往左读）；窄屏 span 是行内的，文字照常横排。
   竖排里的阿拉伯数字用 .tcy 直立合排（纵中横），不然会躺倒。
   摆位有两种：页上还有别的内容时，标题立在左页外侧，内容在它右边横排；
   左页只有标题时（扉页对面那页），标题靠书脊立着，和首屏同一个摆法。 */
.tcy { text-combine-upright: all; }

@media (min-width: 1024px) {
  .spread .v-title {
    writing-mode: vertical-rl;
    font-size: 4rem;
    line-height: 1.3;
    letter-spacing: 0.08em;
    margin: 0;
    text-wrap: nowrap;
  }
  .v-title > span { display: block; }
  .v-title .sp { display: none; }   /* 横排时数字两边的空格；竖排里它会变成一整块空白 */

  /* 第二屏：标题占左页第一栏、跨满七条行轨；右边那栏照旧和右页按 subgrid 对齐 */
  .compare .page-l { grid-template-columns: auto minmax(0, 1fr); column-gap: var(--s-6); }
  .compare .page-l > h2 { grid-column: 1; grid-row: 1 / -1; align-self: start; }
  .compare .page-l > .plain-plan { grid-column: 2; }
  .compare .page-l > .compare-note { grid-column: 2; grid-row: 7; }

  /* 第三屏 */
  .breaks .page-l {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-rows: auto 1fr;
    column-gap: var(--s-6);
  }
  .breaks .page-l { column-gap: var(--s-5); }
  .breaks .page-l > h2 { grid-row: 1 / -1; font-size: 3.5rem; }   /* 这一页左栏要排四条说明，书名让出一档 */
  .breaks .page-l > :not(h2) { grid-column: 2; }

  /* 第四屏：书名立在左页外侧，副题一列小字立在右页外侧当边注，四个分册在两者之间一字排开。
     标题和边注都只跨「题签 + 说明」两条行轨（第一条行轨空着就收成 0），顶边和题签齐平。 */
  .vols-spread .page-l { grid-template-columns: auto minmax(0, 1fr); column-gap: var(--s-6); }
  .vols-spread .page-r { grid-template-columns: minmax(0, 1fr) 1.5rem; column-gap: var(--s-6); position: relative; }
  /* 高度记 0：竖排书名比四册长，若参与行高会把「题签」那一行撑高，题签和说明之间空出一大段。
     让它从题签顶边起往下溢出，页下方本来就有天地。 */
  .vols-head { grid-column: 1; grid-row: 2 / -1; height: 0; }
  /* 边注同理不能参与行高：绝对定位钉在自己那一栏（网格区域就是它的定位框），从题签顶边往下排 */
  .vols-spread .page-r .vols-sub {
    grid-column: 2;
    grid-row: 2 / -1;
    position: absolute;
    top: 0; right: 0;
    white-space: nowrap;      /* 一列到底，不在网格区域的高度处折成两列 */
    writing-mode: vertical-rl;
    font-family: var(--font-title);
    font-weight: 600;
    font-size: 0.9375rem;
    letter-spacing: 0.16em;
    line-height: 1.6;
  }
  .vols-spread .page-l .vols { grid-column: 2; margin-top: 0; }
  .vols-spread .page-r .vols { grid-column: 1; margin-top: 0; }
  .vols-spread .vol-tag { font-size: 1.375rem; padding: var(--s-4) var(--s-2); }

  /* 第五屏：左页只有书名，靠书脊立着、上下居中；右页的两个成绩放到整页主角的大小 */
  .title-spread .page-l { display: flex; justify-content: flex-end; align-items: center; align-self: stretch; }
  .title-spread .v-title { font-size: 4.75rem; line-height: 1.32; letter-spacing: 0.06em; }
  .title-page { padding-block: var(--s-7); }
  .tp-scores { gap: var(--s-5); }
  .tp-num { font-size: 8.5rem; line-height: 1; letter-spacing: 0.04em; margin-top: var(--s-2); }
  .tp-school { margin-top: var(--s-6); font-size: 1.25rem; }

  /* 首屏右页：今日卡和 76px 的竖排主句同处一个跨页，原尺寸压不住，下面空着约 200px。整块（含图注）放大一档 */
  .hero .page-r .screen { zoom: 1.12; }

  /* 第六屏右页：旧书的版权页印在页的下部。沉到页底，和左页竖排书名的底边齐 */
  .colophon-spread .page-r { align-self: end; }

  /* 第六屏：入口槽位里的标题拆出来立在外侧，说明、码、联系方式在右边横排 */
  .colophon-spread .page-l {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    column-gap: var(--s-6);
    align-content: start;
  }
  .enter[data-launch="pending"] .enter-pending,
  .enter[data-launch="live"] .enter-live { display: contents; }
  .colophon-spread .page-l h2 { grid-column: 1; grid-row: 1 / span 8; align-self: start; }
  .colophon-spread .page-l .enter-pending > p,
  .colophon-spread .page-l .enter-live > :not(h2),
  .colophon-spread .page-l .contact { grid-column: 2; }
  .colophon-spread .contact { margin-top: var(--s-6); }
}

/* ---------- 页码（2026-10-22） ----------
   每个跨页两枚，印在左右两页外侧的下角，中文数字（一 … 十二），封面不编页。
   让人知道这是一本有前后的书、自己翻到了哪里——是真实的顺序，不是区块编号。
   宋体小字属于 Label 那类短标记（宋体不下沉律的例外）。读屏不念（aria-hidden），窄屏没有跨页，不印。 */
.folio { display: none; }
@media (min-width: 1024px) {
  .folio {
    display: block;
    position: absolute;
    bottom: var(--s-4);
    font-family: var(--font-title);
    font-weight: 600;
    font-synthesis: none;
    font-size: 0.9375rem;      /* 13px 时「一」就是一条短横，认不出是页码；15px 起才像字 */
    letter-spacing: 0.2em;
    line-height: 1;
    color: var(--ink-2-text);
    pointer-events: none;
  }
  .folio-l { left: calc(var(--s-5) + clamp(var(--s-6), 3.5vw, var(--s-8))); }
  .folio-r { right: calc(var(--s-5) * 2 - 0.2em); }   /* 减掉字距落在最后一个字后面的那份，右缘才和正文齐 */
}

/* ---------- 联系方式槽位 ---------- */
/* 换芯开关只有一处：改 .contact 上的 data-contact。同入口槽位。 */
.contact[data-contact="email"] .contact-group { display: none; }
.contact[data-contact="group"] .contact-group { display: block; }

.contact {
  margin-top: var(--s-6);
  padding-top: var(--s-5);
  border-top: 1px solid var(--border);
}
.contact-mail { color: var(--ink-2-text); font-size: 0.9375rem; }
.contact-group p { color: var(--ink-2-text); font-size: 0.9375rem; margin-top: var(--s-3); }

.mail-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;              /* 独占一行，凑够点击区；行内链接挤不出 44px */
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: color var(--dur-state) var(--ease-out);
}
.mail-link:hover { color: var(--seal); }

/* ---------- 法务长文 ----------
   全站唯一允许长文的地方。用户协议和隐私政策是要逐字读完的，
   所以这里字号不缩、行高放宽、次要文字一律用 --ink-2-text（4.75:1），
   绝不用 --ink-2（3.67:1）。 */

.legal { padding-block: clamp(var(--s-7), 9vw, var(--s-8)); }

.legal h1 {
  font-size: clamp(1.625rem, 5vw, 2.25rem);
  line-height: 1.35;
  letter-spacing: 0.03em;
  margin-bottom: var(--s-3);
}

/* 生效日期与主办单位：读者判断"这份文件新不新"的第一落点，放在标题正下方 */
.legal-meta {
  font-size: 0.9375rem;
  color: var(--ink-2-text);
  line-height: 1.9;
  padding-bottom: var(--s-5);
  border-bottom: 1px solid var(--border);
}

/* 摘要：法务文本的开头应该是人话，不是"鉴于"。 */
.legal-lede {
  margin-top: var(--s-5);
  font-size: 1.0625rem;
  line-height: 1.9;
}

/* 目录。长文里找"怎么删我的数据"不该靠滚动。 */
.legal-toc { margin-top: var(--s-6); }
.legal-toc ol {
  margin: 0;
  padding-left: 1.4em;
  color: var(--ink-2-text);
}
.legal-toc li { margin-bottom: 0; }
/* 44px 而不是 32px：这是本站自己定的下限，不给目录开例外。
   12 条 × 44px 比原来只多 120px，在一份 8000px 长的文件里不值得为它破规则。 */
.legal-toc a {
  display: inline-flex; align-items: center;
  min-height: 44px;
  min-width: 44px;      /* 两个字的条目（如「费用」）只有 34px 宽，44×44 是两个方向都要 */
  color: var(--ink);
  transition: color var(--dur-state) var(--ease-out);
}
.legal-toc a:hover, .legal-toc a:active { color: var(--seal); }

.legal section { margin-top: var(--s-7); }

.legal h2 {
  font-size: 1.25rem;
  line-height: 1.5;
  letter-spacing: 0.04em;
  padding-top: var(--s-5);
  border-top: 1px solid var(--border);
  margin-bottom: var(--s-4);
}

/* 目录标题必须比条款标题轻。放在 .legal h2 之后 —— 两者特异性同为 (0,1,1)，
   靠源码顺序决胜；写在前面会被无声覆盖，目录就和条款一样重了。
   同时复位 .legal h2 带来的上边线和上内距。 */
.legal-toc h2 {
  font-size: 1rem;
  letter-spacing: 0.16em;
  color: var(--ink-2-text);
  border-top: 0;
  padding-top: 0;
  margin-bottom: var(--s-3);
}

.legal h3 {
  font-size: 1.0625rem;
  letter-spacing: 0.03em;
  margin-top: var(--s-5);
  margin-bottom: var(--s-2);
}

.legal p { margin-bottom: var(--s-4); line-height: 1.9; }
.legal p:last-child { margin-bottom: 0; }

.legal ul, .legal ol { margin: 0 0 var(--s-4); padding-left: 1.4em; line-height: 1.9; }
.legal li { margin-bottom: var(--s-2); }
.legal li:last-child { margin-bottom: 0; }

.legal strong { font-weight: 600; }

/* 术语表：名词在前，解释在后。比括号夹注好读。 */
.legal dl { margin: 0 0 var(--s-4); }
.legal dt {
  font-family: var(--font-title);
  font-weight: 600;
  letter-spacing: 0.04em;
  margin-top: var(--s-4);
}
.legal dt:first-child { margin-top: 0; }
.legal dd {
  margin: var(--s-1) 0 0;
  padding-left: var(--s-4);
  border-left: 1px solid var(--border);
  line-height: 1.9;
}

/* 重点框。用整圈细线，不用侧边色条（那是绝对禁令）。
   全篇最多出现两处，多了就不是重点了。 */
.legal-box {
  margin: var(--s-5) 0;
  padding: var(--s-5);
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.legal-box > :last-child { margin-bottom: 0; }
.legal-box h3 { margin-top: 0; }

.legal a {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.legal a:hover, .legal a:active { color: var(--seal); }
/* 目录链接不要下划线：一屏十几条下划线是噪音。放在 .legal a 之后覆盖。 */
.legal-toc a { text-decoration: none; }
.legal-toc a:hover { text-decoration: underline; text-underline-offset: 3px; }

/* 行内代码：政策里会出现 openid、getUserProfile 这类字面标识符，需要和正文区分。
   但**不换字族** —— 一册线装讲义不会突然切到 Courier，而且 brand.md 明确把
   「等宽字当技术感的廉价符号」列为禁令。区分靠色与字距，不靠换字。 */
.legal code {
  color: var(--ink-2-text);
  letter-spacing: 0.03em;
  word-break: break-all;
}

/* 邮箱这类要点的链接单独占行，凑够 44px 点击区 */
.legal .mail-link { font-size: 1.0625rem; }

/* ---------- 页脚 ---------- */

.footer {
  border-top: 1px solid var(--border);
  padding-block: var(--s-6) calc(var(--s-6) + env(safe-area-inset-bottom));
  font-size: 0.9375rem;
  color: var(--ink-2-text);
}

.footer nav { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-left: calc(var(--s-2) * -1); }

.beian { margin-top: var(--s-2); }
.beian a {
  display: inline-flex; align-items: center; min-height: 44px;
  color: var(--ink-2-text);
  transition: color var(--dur-state) var(--ease-out);
}
.beian a:hover { color: var(--seal); }

.copyright {
  font-family: var(--font-title);
  letter-spacing: 0.16em;
  color: var(--ink-2-text);   /* --ink-3 是 2.05:1，只能做装饰，不能承载文字 */
}

/* ---------- 书：滚动翻页（PC） ----------
   作者 2026-10-20：前三版都「没有翻书页的感觉」——它们只是让页面歪一下再放平，那是晃，不是翻。
   翻书页 = 一张纸绕书脊整张翻过去，翻到一半立在中间，正面是这一页、背面是下一页的左页。
   做法：PC 上把所有跨页叠进一个吸顶的「书台」里，滚动距离驱动翻页角度（滚多少翻多少、手停纸停），
   画面本身不往上滚。不吸附（吸附跟触控板惯性对着干，作者否决过）。
   像纸不像板：纸分内外两段、外段带着角度差（翻到一半是弯的）；翻面靠书脊侧变暗；
   纸立起来时在下面那页投影，翻过中线后影子换到左页。
   书台由 index.html 末尾的脚本搭起来；没有 JS、手机、矮屏、减弱动态效果时，这里的规则一条都不生效，
   页面就是普通的逐屏滚动（可见即默认律）。 */

@media (min-width: 1024px) and (min-height: 720px) {
  .topbar {
    position: sticky;
    top: 0;
    z-index: var(--z-sticky);
    background: var(--paper);
  }
  html { scroll-padding-top: var(--topbar-h); }
  body { overflow-x: clip; }
}

main.book { position: relative; }
main.book > .rule { display: none; }

.book-stage {
  position: sticky;
  top: var(--topbar-h);
  height: calc(100svh - var(--topbar-h));
  overflow: clip;
  background: var(--desk);   /* 书摊在桌上：桌面比纸深一档，书才有轮廓 */
}

/* 书台里所有跨页叠在一起。当前页在上；掀角时下一页在它下面露出来。
   不用 visibility:hidden ——那会把其它页从读屏和 Tab 顺序里拿掉；这里只是看不见，
   焦点进来时脚本会翻到那一页。 */
.book-stage > .spread {
  position: absolute;
  top: var(--book-inset, 0px); left: 0; right: 0;   /* 上下各留一道桌面，书的边和影子才露得出来 */
  margin-inline: auto;
  background-color: var(--paper);   /* 叠在一起时要不透明，否则下一页的字会从当前页透出来 */
  border-radius: 2px;
  /* 书口：底边露出一摞纸的厚度（纸色和暗线交替），再往外是书压在桌上的影子 */
  box-shadow:
    0 1px 0 0 #E2D8C3, 0 2px 0 0 var(--paper), 0 3px 0 0 #DDD2BB, 0 4px 0 0 var(--paper), 0 5px 0 0 #D6CAB0,
    0 20px 34px -16px rgba(58, 52, 43, 0.32);
  opacity: 0;
  pointer-events: none;
}
.book-stage > .cover { margin: 0 auto; max-width: var(--spread-w); min-height: 0; background-color: var(--cover); }
.book-stage > .spread.on    { opacity: 1; pointer-events: auto; z-index: 2; }
.book-stage > .spread.under { opacity: 1; pointer-events: auto; z-index: 1; }

/* 整本书统一缩放：跨页盒子设成「书台高 ÷ 缩放比」，再按缩放比缩回来，正好占满书台。
   掀角层用同一套几何，所以它的坐标和跨页的本地坐标完全一致。缩放比和书台高由脚本写入。 */
.book-stage > .spread,
.book-peel {
  height: calc(var(--book-h, 100%) / var(--book-s, 1));
  transform: scale(var(--book-s, 1));
  transform-origin: 50% 0;
}

/* 掀角（2026-10-20）：从右下角掀起，沿对角线往上卷走，露出下一页——翻台历的动作，方向向上。
   纯平面几何：每帧由脚本算出一条折线，当前页只留折线这一侧（clip-path），
   另一侧按折线镜像成翻起来的纸角（matrix 反射），带折痕高光；露出来的下一页上有投影。 */
.book-peel {
  position: absolute;
  top: var(--book-inset, 0px); left: 0; right: 0;
  margin-inline: auto;
  max-width: var(--spread-w);
  z-index: 3;
  pointer-events: none;
  visibility: hidden;
}
.book-peel.on { visibility: visible; }
.book-peel-cast { position: absolute; inset: 0; }                         /* 纸角投在下一页上的影子 */
.book-flapwrap  { position: absolute; inset: 0; filter: drop-shadow(0 6px 14px rgba(58, 52, 43, 0.22)); }
.book-flap      { position: absolute; inset: 0; background: var(--paper); transform-origin: 0 0; }
/* 透背：薄纸翻过来，背面隐约看得到正面的字——镜像是反射矩阵自带的，不用另做 */
.book-flap-ink  { position: absolute; inset: 0; opacity: 0.07; }
.book-flap-ink > .spread { position: absolute; inset: 0; height: 100%; margin: 0; max-width: none; }
.book-flap-shade { position: absolute; inset: 0; }

/* ---------- 纸上的光（2026-10-21，B） ----------
   书房窗外的直棂与竹影，固定在视口上（光在屋里，书在光下翻），正片叠底压在整页上。
   为什么敢叠在字上面：multiply 把纸和字按同一比例压暗，对比度几乎不变——
   最深处透光 0.89 时 --ink-2-text 从 4.75 只掉到约 4.66，铺在字底下同样深度会掉到 4 以下。
   页眉在它上面（z 高一层）：页眉是界面，不是纸。打印时不要。 */
.sunlight { display: none; }
/* 只在 PC 上：手机竖屏裁出来的是最密的那丛竹叶，正压在正文上，太花 */
@media (min-width: 1024px) { .sunlight {
  display: block;
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-sticky) - 1);
  background: url("../assets/light.jpg") 100% 0 / cover no-repeat;
  mix-blend-mode: multiply;
  pointer-events: none;
} }
@media print { .sunlight { display: none; } }

/* ---------- 减弱动效不是可选项 ---------- */

/* 按下反馈。触屏上没有 hover，:active 是移动端唯一的即时确认，
   缺了它点下去会觉得"没反应"。透明度用小程序已经在跑的那一档
   （App.vue 的 .btn-main:active { opacity: .85 }）—— 对齐既有体系，不新造。
   这不违反「两个动作律」：那条管的是品牌动作与入场编排，不管状态反馈。 */
.btn-ghost:active,
.btn-copy:active { opacity: 0.85; }

.topbar nav a:active,
.footer nav a:active,
.mail-link:active,
.beian a:active { color: var(--seal); }

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