/* ============================================================
   概率论与数理统计 · HTML 课件设计系统
   13 讲共用。禁止在页面内写内联样式，一切视觉走本文件的类。
   组件清单见 spec §6.1 / §6.2。
   ============================================================ */

:root {
  /* —— 配色 ——
     底色统一压到「淡到几乎是纸」的程度，左侧色条相应加深。
     理由：投影仪把浅色整体提亮、把对比压平，五个高彩度底色并排时
     会盖过内容，读起来像「一堆彩色方块」而不是讲义。
     让**色条**承担语义、让**底色**只负责分组，页面立刻安静下来，
     而且打印到黑白激光时底色仍能拉开层次（色条变成不同深浅的灰）。 */
  --c-ink:        #16202e;   /* 正文，比原先再深一档，投影上更实 */
  --c-ink-soft:   #475569;   /* 次要文字 */
  --c-muted:      #64748b;   /* 说明、来源 */
  --c-paper:      #ffffff;
  --c-primary:    #0e5a63;   /* 石油蓝绿 —— 这门课的识别色，标题与强调。
                                **刻意不是复旦蓝**：同一位老师还在教 course-prob（概率论），
                                那门课用 #0d4a8b。两门都用复旦蓝时，开着两个标签页、
                                或在教室里远看投影，第一眼分不清在放哪一门。
                                选冷色而不是暖色（酒红也试过）是因为主色要和金色配成
                                两序列图表——这门课几乎每张图都是中美对照，
                                冷主色 + 暖金的对比最分明。
                                改这个值时记得同步 site.css 里 .btn--primary:hover
                                的深一档色（CSS 变量做不了 darken）。 */
  --c-gold:       #a8842c;   /* 金色强调：案例决策题、互动徽章。比 FIM 模板的 C9A84C 压深，
                                浅金在投影上会被提亮到看不见 */

  /* 图表配色。chart-kit.js 从这里读，不自己硬编码——否则换主题色时
     图表不跟着变，一页上出现两套蓝，而且没有检查会发现。 */
  /* 五色分类序列，按「一眼能不能分开」选，不是按好看选。
     主色是青绿，所以第二序列必须离开青绿族——原来的 #3f8f97 是浅一档的青，
     和主色、和 insight 的深绿挤在一起，甜甜圈会糊成一团。
     现在是 青绿 / 金 / 石板蓝 / 陶土 / 灰，五个色相互不相邻。 */
  --c-chart-2:         #40628f;   /* 第二序列：石板蓝 */
  --c-chart-3:         #9c6b4f;   /* 第三序列：陶土 */
  --c-chart-mute:      #c3cddb;   /* 「其他」这类不承载论点的块 */
  --c-chart-mute-line: #8fa2ba;
  --c-rule:       #d7e6e8;   /* 分隔线：与主色同族，略偏青 */

  --c-block-fg:   #0b5a63;   --c-block-bg:   #f1fafb;  --c-block-br:   #1c8894;
  --c-insight-fg: #0a6152;   --c-insight-bg: #f2fbf7;  --c-insight-br: #0f9b7e;
  --c-alert-fg:   #96370f;   --c-alert-bg:   #fef8f1;  --c-alert-br:   #e07a25;
  --c-thm-fg:     #55299d;   --c-thm-bg:     #f8f6fd;  --c-thm-br:     #7c53d4;
  --c-recap-fg:   #3b4a5c;   --c-recap-bg:   #f5f7f9;  --c-recap-br:   #8ea0b4;

  /* —— 排版 —— */
  /* 英文为主、行内夹中文术语（pinyin + 汉字）。英文字体排在前面，
     中文字体只接管它覆盖不到的字形，这样英文不会被中文字体的西文部分接管
     ——中文字体的拉丁字形普遍偏窄偏轻，混排时会显得英文「虚」。 */
  --c-font: "Source Sans 3", "Segoe UI", -apple-system, "Helvetica Neue", Arial,
            "PingFang SC", "Microsoft YaHei", "Noto Sans SC", sans-serif;
  --c-lh: 1.45;              /* 英文正文行高。中文那套是 1.6，因为全宽字面笔画密；
                                英文字面疏、有升降部，1.6 会散成一行行孤立的字。
                                同样别调大——一页 25 行时每 +0.02 多出约 12px，
                                够把贴底的页挤裂（见 CLAUDE.md 坑 8）。 */
  --c-ls: 0;                 /* 英文不加字距。中文那 0.015em 是为了拆开全宽字面，
                                加在英文上会让单词内部松散、词间界限反而模糊 */
  --c-ls-cn: 0.015em;        /* 行内中文段落用 .cn 取回字距 */
  --c-radius: 10px;
  --c-gap: 0.62em;

  /* 动效时长。放映工具的动效只该做一件事：告诉眼睛「这里换了内容」。
     超过 0.3s 就开始碍事——讲课时每一页都要等它演完。 */
  --c-t: .22s;
  --c-ease: cubic-bezier(.22, .61, .36, 1);
}

/* 离线包兜底字体子集（spec §4.3）。
   注意：本计划不生成这个文件 —— 字体子集要按全 13 讲的用字集合裁剪，
   只有第 1 讲时裁出来的会缺字，故留到第二份计划的最后一步。
   在此之前浏览器会对它报一次 404，因为 font-display:swap 且它排在字体栈末位，
   系统字体先命中，观感无任何影响。这个 404 是预期的。 */
@font-face {
  font-family: "CourseFallbackSC";
  src: url("../vendor/fonts/course-subset.woff2") format("woff2");
  font-display: swap;
}

/* ============================================================
   1. reveal 基础覆盖
   reveal 默认居中且全大写，对中文教学不合适，全部改掉。
   ============================================================ */

.reveal {
  font-family: var(--c-font);
  font-size: 26px;
  color: var(--c-ink);
  letter-spacing: var(--c-ls);
}

.reveal .slides { text-align: left; }

.reveal .slides section {
  height: 100%;
  padding: 0.3em 0.2em;
  box-sizing: border-box;
}

.reveal h1, .reveal h2, .reveal h3, .reveal h4 {
  font-family: var(--c-font);
  color: var(--c-primary);
  text-transform: none;      /* reveal 默认 uppercase，中文下必须关掉 */
  letter-spacing: var(--c-ls);
  line-height: 1.3;
  margin: 0 0 0.42em;
  text-shadow: none;
}

.reveal h1 { font-size: 1.9em; }
.reveal h2 { font-size: 1.32em; }   /* frametitle 用这一级 */
.reveal h3 { font-size: 1.15em; }

/* 长标题在 1280 画布上常折成两行，浏览器默认会折出「一长一短」。
   balance 让两行等长，标题块看起来是有意排的，不是被挤断的。 */
.reveal h1, .reveal h2 { text-wrap: balance; }

/* frametitle 下面压一条细线。
   幻灯片没有页眉页脚，标题与正文之间只靠一点空白分隔，投影上很容易糊成一片；
   一条 2px 的线就能把「这一页讲什么」钉住。
   ⚠️ 线本身占高度，所以 h2 的下边距同步收掉——净高与改之前一致，
      否则 13 讲里那些贴着页底的页会重新被裁（见 CLAUDE.md 坑 8）。 */
.reveal h2 {
  margin-bottom: 0.2em;
  padding-bottom: 0.16em;
  border-bottom: 2px solid var(--c-rule);
}

/* 行高挂在 .reveal 上，不能只挂 p / li。
   ⚠️ 本项目不加载 reveal 的任何主题 CSS，只加载 reveal.css，
   而 reveal.css 给 `.reveal-viewport`（即 body）写了 `line-height: 1`。
   于是**凡是没被 p / li 包住的文字，行距就是 1.0**——英文里升降部会直接相撞。实测 L01 第 3 页：`<p>` 是 41.6px，
   而同一页 `.c-beat` 里的正文是 26px，差了整整 60%，
   看上去就是「同一块里有的排得开、有的挤成一坨」。
   全 13 讲有 330 多处这样的裸文字：c-beat、c-block、c-insight、
   c-theorem、c-alert、details.c-source、figcaption 都在内。
   把行高提到 .reveal 这一层，所有文字才走同一套行距。 */
.reveal { line-height: var(--c-lh); }
.reveal ul, .reveal ol { margin-left: 1.1em; }
.reveal ul ul, .reveal ol ol { font-size: 0.92em; margin-top: 0.22em; }
.reveal li { margin-bottom: 0.22em; }

/* strong 取所在块的语义色，没有块时回落到复旦蓝。
   改之前 strong 恒为蓝色——橙色的 c-alert、紫色的 c-theorem 里出现蓝色粗体，
   一页上三四种颜色互相打架。让强调跟着容器走，整页只剩一个色调。 */
.reveal strong { color: var(--c-accent, var(--c-primary)); font-weight: 700; }

/* 这门课以英文授课，em 恢复成真斜体——西文有真正的斜体字形，
   期刊名、船名、术语首现都靠它，用颜色代替反而丢掉了排印惯例。
   （course-prob 是中文课，那边 em 不倾斜，因为中文字体只有合成倾斜。） */
em { font-style: italic; }

/* 但行内中文仍不能倾斜：浏览器对中文做合成倾斜，投影上很糊。
   中文术语首现请写 <span class="cn">资管新规</span>，或在 em 里套 .cn。 */
.cn {
  font-style: normal;
  letter-spacing: var(--c-ls-cn);
  font-family: "PingFang SC", "Microsoft YaHei", "Noto Sans SC", sans-serif;
}
em .cn, .cn em { font-style: normal; }

.latin-italic { font-style: italic; }
.reveal a { color: var(--c-block-fg); text-decoration: underline; }

/* 中文与行内公式的基线对齐 —— KaTeX 默认略微上浮 */
.reveal .katex { font-size: 1.02em; vertical-align: -0.06em; }
.reveal .katex-display { margin: 0.5em 0; }

/* KaTeX 自己算好了每个符号的间距，中文字距会整段叠加上去，
   把 $f(x)$ 撑成 $f ( x )$。字距必须在公式边界上归零。
   （规则不限定在 .reveal 内——教师笔记页同样受影响。） */
.katex, .katex * { letter-spacing: normal; }

/* 数字与中文混排时，中文字体的数字往往偏窄偏轻；
   等宽数字让表格里的一列数、以及正文里的年份/页码对得齐。 */
.c-table, .notes-page table { font-variant-numeric: tabular-nums; }

/* 页码与页脚。reveal 把它包成 <a>，会吃到上面那条 a{underline}，
   于是右下角出现一个带下划线的「9 / 27」，很像误点进去的链接。 */
.reveal .slide-number {
  font-size: 0.42em; color: var(--c-muted);
  background: transparent; right: 16px; bottom: 12px;
  font-variant-numeric: tabular-nums;
}
.reveal .slide-number a,
.reveal .slide-number { text-decoration: none; }

/* ============================================================
   2. 语义块（对应 Beamer 的 block / exampleblock / alertblock）
   ============================================================ */

.c-block, .c-insight, .c-alert, .c-theorem, .c-recap,
.c-hook, .c-roadmap, .c-checkpoint, .c-bridge, .c-summary {
  border-left: 5px solid;
  /* 左侧不倒角：圆角会把 5px 的色条两端削成弧形，看着像药丸。
     方头的色条更像书页边上的标注规则线，也更容易在投影上一眼分辨颜色。 */
  border-radius: 0 var(--c-radius) var(--c-radius) 0;
  padding: 0.5em 0.8em;
  margin: var(--c-gap) 0;
}

/* 每个块声明自己的语义色，块内的 strong / 小标题都取它 —— 见上面的 .reveal strong */
.c-block   { --c-accent: var(--c-block-fg);
             background: var(--c-block-bg);   border-color: var(--c-block-br);   }
.c-insight { --c-accent: var(--c-insight-fg);
             background: var(--c-insight-bg); border-color: var(--c-insight-br); }
.c-alert   { --c-accent: var(--c-alert-fg);
             background: var(--c-alert-bg);   border-color: var(--c-alert-br);   }
.c-theorem { --c-accent: var(--c-thm-fg);
             background: var(--c-thm-bg);     border-color: var(--c-thm-br);     }
.c-recap   { --c-accent: var(--c-recap-fg);
             background: var(--c-recap-bg);   border-color: var(--c-recap-br);   }

/* 每个块的小标题 */
.c-block   > .c-title { color: var(--c-block-fg);   }
.c-insight > .c-title { color: var(--c-insight-fg); }
.c-alert   > .c-title { color: var(--c-alert-fg);   }
.c-theorem > .c-title { color: var(--c-thm-fg);     }
.c-recap   > .c-title { color: var(--c-recap-fg);   }

.c-title {
  display: block;
  font-weight: 700;
  font-size: 0.92em;
  margin-bottom: 0.28em;
}

.c-block > *:last-child,
.c-insight > *:last-child,
.c-alert > *:last-child,
.c-theorem > *:last-child { margin-bottom: 0; }

/* 高密度页：装不下的时候，先缩字号，不要压行距。
   ────────────────────────────────────────────────────────────────
   源讲义有些 frame 天生就装得多（定理 + 两道例题 + 一条提醒），
   拆成两页会打断讲课节奏，所以需要一个可以逐页显式声明的密度档。

   这一档最初的做法是「只压间距、不动字号」，理由是怕字号一变、
   公式与正文的比例就乱。**那个顾虑是错的**：KaTeX 的尺寸是 `1.02em`，
   块的 padding/margin 也全是 em——**跟着字号等比缩放，比例根本不会变**。
   而压行距的代价很实：中文是全宽字面、笔画密，行距一紧，
   上下两行就糊在一起，投影上尤其明显（实测 L11 第 11 页正是如此）。

   所以现在反过来：**用字号换空间，把行距还给正文。**
   同样省下一页的高度，「小一号但排得开」比「原大小但挤成一坨」好读得多；
   而且字号一小，折行也跟着变少，省下的高度比 6% 这个数字还多。

   两档：
     .c-dense        字号 0.94em —— 绝大多数页够用
     .c-dense--more  字号 0.86em —— 例题密集、公式多的那几页
   标题（h1/h2）不缩：frametitle 是从教室后排读的，各页必须一样大。 */

.c-dense > *:not(h1):not(h2)       { font-size: 0.94em; }
.c-dense--more > *:not(h1):not(h2) { font-size: 0.86em; }

/* 缩了字号之后，行距按比例已经跟着变小了（1.6 × 更小的字号），
   这里再把块与块之间的留白稍微收一点点——只动块间距，不动行内。 */
.c-dense .c-block, .c-dense .c-insight, .c-dense .c-alert,
.c-dense .c-theorem, .c-dense .c-recap, .c-dense .c-hook,
.c-dense .c-roadmap, .c-dense .c-checkpoint, .c-dense .c-bridge,
.c-dense .c-summary { margin: 0.5em 0; }

/* 定理块的「证明」折叠钮 */
.c-theorem details { margin-top: 0.5em; font-size: 0.9em; }
.c-theorem summary {
  cursor: pointer; color: var(--c-thm-fg);
  font-weight: 600; outline: none;
}
.c-theorem details[open] summary { margin-bottom: 0.4em; }

/* ============================================================
   3. 叙事骨架组件（spec §6.5）
   ============================================================ */

.c-hook     { --c-accent: #92500c; background: #fffcf2; border-color: #e0a020; }
.c-roadmap  { --c-accent: var(--c-primary); background: #f7f9fc; border-color: var(--c-primary); }
.c-checkpoint { --c-accent: var(--c-insight-fg);
                background: var(--c-insight-bg); border-color: var(--c-insight-br); }
.c-bridge   { --c-accent: var(--c-ink-soft);
              background: #f7f9fb; border-color: #b9c6d4; font-style: normal; }
.c-summary  { --c-accent: var(--c-primary); background: #f7f9fc; border-color: var(--c-primary); }

/* c-hook 的三拍：场景 / 冲突 / 悬念。
   原来用 inline-block + min-width 撑出标签栏，可标签都是两个汉字（正好 2em），
   min-width 3.4em 就在标签和正文之间留下一个 1.4em 的空档，像排版失误。
   改成真正的两栏：标签靠上对齐、正文自己成列，两拍之间也就有了统一的左边界。 */
.c-beat { margin: 0.52em 0; }
/* 标签仍是行内的——改成网格两栏会把正文列压窄近 5em，每一拍多折一行，
   三拍下来 hook 页就贴到页底了（13 讲全中）。原来的毛病只是
   min-width:3.4em 在两字标签后留下一个 1.4em 的空档，去掉即可。
   字距拉开 + 略小的字号，让它读起来像书眉而不是正文的一部分。 */
.c-beat > .c-beat-label {
  display: inline-block;
  font-weight: 700;
  /* 与正文**同字号**。原先是 0.86em，想让它读起来像书眉，
     实际效果是「场景 / 冲突 / 悬念」比紧跟其后的正文小一号，
     同一行里两种字号并排，像排版事故而不像层级。
     区分标签靠的是字重、颜色和字距，不该靠缩字号。 */
  font-size: 1em;
  letter-spacing: 0.14em;
  color: var(--c-alert-fg);
  margin-right: 0.5em;
}
.c-beat--suspense { font-size: 1.05em; font-weight: 600; color: var(--c-primary); }
.c-beat--suspense > .c-beat-label { color: var(--c-primary); }

/* c-roadmap 的里程碑 */
.c-milestones { list-style: none; margin-left: 0; counter-reset: ms; }
.c-milestones > li {
  counter-increment: ms;
  padding-left: 2em;
  position: relative;
}
.c-milestones > li::before {
  content: counter(ms);
  position: absolute; left: 0; top: 0.15em;
  width: 1.45em; height: 1.45em; line-height: 1.45em;
  text-align: center; border-radius: 50%;
  background: var(--c-primary); color: #fff;
  font-size: 0.72em; font-weight: 700;
}

/* ============================================================
   3b. 封面页（每讲第一页，<section class="c-cover">）
   ============================================================
   改之前这一页是三行左上角的文字，画布下面 80% 全空——
   而它一学期要放 13 次，是学生对这门课的第一印象。
   现在把它排成一张真正的扉页：竖向居中、讲次做成排印元素、
   底部一条细线压住院系信息。没有装饰，只是把已有的三行摆对位置。 */

/* 不要用 flex 居中：reveal 会给当前页写**内联** display:block，
   内联样式压过任何选择器，flex 根本不生效；而用 !important 抢回来，
   又会让本该 display:none 的隐藏页跟着一起显示。
   改用上三分之一起排——视觉上比正中更稳，屏幕与打印两种模式还完全一致。 */
.reveal .slides section.c-cover {
  padding: 1.7em 0.2em 3.2em;
}

/* 讲次标号：从 h3 里拆不出来，所以用 ::before 挂在 h1 上会脆。
   改为给 h3 排成小字号的书眉，与 h1 拉开三个层级：
   讲名（大）→ 讲次与课程（小、灰）→ 院系（更小、灰、压在线下）。 */
.c-cover h1 {
  font-size: 3.05em;
  line-height: 1.15;
  letter-spacing: 0.02em;
  margin: 0 0 0.28em;
  position: relative;
}
/* 标题上方的短横线。比整幅横线克制，只标出文本块的起点。 */
.c-cover h1::before {
  content: "";
  display: block;
  width: 2.6em;
  height: 5px;
  margin-bottom: 0.42em;
  background: var(--c-primary);
  border-radius: 3px;
}
.c-cover h3 {
  font-size: 1.02em;
  font-weight: 600;
  color: var(--c-ink-soft);
  letter-spacing: 0.06em;
  margin: 0;
}
/* 院系与课号：脱离正文流，压在页脚，与一条发丝线一起 */
.c-cover .c-source {
  position: absolute;
  left: 0; right: 0; bottom: 0.9em;
  margin: 0;
  padding-top: 0.7em;
  border-top: 1px solid var(--c-rule);
  font-size: 0.66em;
  letter-spacing: 0.1em;
  color: var(--c-muted);
}

/* ============================================================
   4. 版面组件
   ============================================================ */

.c-cols { display: flex; gap: 1.1em; align-items: flex-start; }
.c-cols > * { flex: 1 1 0; min-width: 0; }
.c-cols--wide-left  > *:first-child { flex: 2 1 0; }
.c-cols--wide-right > *:last-child  { flex: 2 1 0; }

.c-fig { width: 100%; margin: var(--c-gap) 0; text-align: center; }
.c-fig img {
  /* 高度上限用 px，不能用 vh —— 与图表容器同一个坑：reveal 把 1280×720 的画布
     整体缩放到窗口，vh 量的是窗口而不是画布，打印时两者更是两个坐标系。
     实测 430px 是「图 + 一段文字 + 收尾行 + 来源行」还能放下的高度。 */
  max-width: 100%; max-height: 430px;
  border-radius: var(--c-radius);
  box-shadow: 0 2px 10px rgb(0 0 0 / 0.09);
}
/* 竖长的教材插图（如 Mishkin 图 8.1 的三阶段序列）：整页只有标题、图和来源行，
   430px 会把它压到不可读。给一个显式的档位，而不是让每页各自去猜。 */
.c-fig--tall img { max-height: 560px; }

.c-fig figcaption {
  font-size: 0.72em; color: var(--c-muted);
  margin-top: 0.45em; line-height: 1.5;
}

/* 表格：只留横线。
   原来是四面 1px 的全网格，加上「表头填 --c-block-bg」——
   而表格几乎总是放在 .c-block 里，两者底色同为 --c-block-bg，
   于是**表头的底色完全看不出来**，只剩一圈格线，读起来像电子表格截图。
   改成学术排印的做法：去掉竖线，表头用一条重底线，行间用发丝线。
   底色透明，所以放进任何一种语义块都成立；打印到黑白也不糊。 */
.c-table {
  border-collapse: collapse;
  width: 100%;
  font-size: 0.88em;
  margin: var(--c-gap) 0;
  background: transparent;
}
.c-table th, .c-table td {
  /* 单元格多为单行，行距比正文收一档；折行时仍留得开 */
  line-height: 1.45;
  border: 0;
  border-bottom: 1px solid var(--c-rule);
  padding: 0.42em 0.7em 0.42em 0;
  text-align: left;
  vertical-align: top;
}
.c-table th {
  color: var(--c-accent, var(--c-block-fg));
  font-weight: 700;
  border-bottom: 2px solid currentColor;
  padding-bottom: 0.3em;
}
.c-table tbody tr:last-child > * { border-bottom: 0; }
/* 首列贴左边界，末列不留悬空的右内距 */
.c-table th:not(:first-child), .c-table td:not(:first-child) { padding-left: 0.7em; }

/* 表格里需要标红的格子（如两类错误表中「出错」的那两格）。
   没有竖线之后靠底色区分，所以底色要比正文块更实一点。 */
.c-table td.c-cell-bad {
  background: var(--c-alert-bg);
  color: var(--c-alert-fg);
  font-weight: 600;
  box-shadow: inset 3px 0 0 var(--c-alert-br);
  padding-left: 0.7em;
}

/* 来源标注 */
.c-source { font-size: 0.62em; color: var(--c-muted); margin-top: 0.7em; }
.c-source summary { cursor: pointer; }
.c-source a { color: var(--c-muted); }
.c-source--adapted { color: var(--c-alert-fg); font-weight: 600; }

/* ============================================================
   4b. 动效
   ============================================================
   放映工具的动效只该做一件事：告诉眼睛「这里换了内容」。
   所以只做两处，都在 0.3s 以内：

   1) 换页时，页内的语义块依次浮起 —— 讲课时视线自然从上往下走，
      让版面按同样的顺序落位，比整页同时出现更容易跟。
      只延迟前 6 块，再多就成了等动画。
   2) fragment 出现时带一点上移 —— reveal 默认只改透明度，
      在投影上「淡入」几乎看不出来，加 6px 位移就明确多了。

   三条硬约束：
   · 打印模式（.print-pdf）全部关掉 —— 动画中途截屏会截到半透明的块；
   · prefers-reduced-motion 全部关掉；
   · 只用 transform / opacity，不碰 layout 属性，否则每页触发一次重排。 */

/* 截图与 PDF 导出必须能关掉动画：headless Chrome 的 --virtual-time-budget
   不推进 CSS 动画，定格下来的是 opacity 中途的半透明帧——页面看着「褪色」，
   而且**不报任何错**。deck-init.js 见到 ?still=1 就给 <html> 加 .fim-still。 */
html.fim-still .reveal .slides section > * {
  animation: none !important; opacity: 1 !important; transform: none !important;
}

@media (prefers-reduced-motion: no-preference) {
  .reveal .slides section.present > .c-block,
  .reveal .slides section.present > .c-insight,
  .reveal .slides section.present > .c-alert,
  .reveal .slides section.present > .c-theorem,
  .reveal .slides section.present > .c-recap,
  .reveal .slides section.present > .c-hook,
  .reveal .slides section.present > .c-roadmap,
  .reveal .slides section.present > .c-checkpoint,
  .reveal .slides section.present > .c-bridge,
  .reveal .slides section.present > .c-summary,
  .reveal .slides section.present > .c-cols,
  .reveal .slides section.present > .c-table,
  .reveal .slides section.present > .c-fig {
    animation: c-rise var(--c-t) var(--c-ease) both;
  }
  /* 标题先落，正文跟上 */
  .reveal .slides section.present > h2 { animation: c-rise .18s var(--c-ease) both; }
  .reveal .slides section.present > :nth-child(2) { animation-delay: .04s; }
  .reveal .slides section.present > :nth-child(3) { animation-delay: .09s; }
  .reveal .slides section.present > :nth-child(4) { animation-delay: .14s; }
  .reveal .slides section.present > :nth-child(5) { animation-delay: .18s; }
  .reveal .slides section.present > :nth-child(6) { animation-delay: .21s; }

  /* 封面：横线先画出来，标题再落 */
  .reveal .slides section.c-cover.present h1::before {
    animation: c-draw .34s var(--c-ease) both;
  }

  /* fragment 的入场：reveal 只给 opacity，这里补一点位移 */
  .reveal .slides section .fragment.visible {
    animation: c-rise .2s var(--c-ease) both;
  }
}

@keyframes c-rise {
  from { opacity: 0; transform: translateY(7px); }
  to   { opacity: 1; transform: none; }
}
@keyframes c-draw {
  from { transform: scaleX(0); }
  to   { transform: none; }
}
.c-cover h1::before { transform-origin: left center; }

/* 打印时一律不要动画：导出是逐页截图，动画播到一半就被定格。 */
.print-pdf .reveal *,
.print-pdf .reveal *::before { animation: none !important; }
@media print {
  .reveal *, .reveal *::before { animation: none !important; }
}

/* ============================================================
   5. 交互嵌入
   ============================================================ */

/* 交互 demo 的嵌入：内部视口做宽 + 整体缩放
   ────────────────────────────────────────────────────────────────
   两个坑叠在一起，必须一起解：

   1) 高度不能用 vh。reveal 把 1280×720 的画布 transform 缩放到屏幕，而 vh 按
      真实视口解析，两者不在一个坐标系里——同一份 CSS 在不同分辨率的电脑上
      得到的实际高度完全不同，这就是「有的电脑显示不全」的来源。

   2) demo 用的是 Tailwind 响应式栅格（lg:grid-cols-2 之类），断点按 iframe
      自身的视口宽度算。半栏 iframe 只有 ~600px 宽，永远触发不了 lg 断点，
      于是画布与控制面板永远上下堆叠，内容高度 900–1600px，塞进 400 多 px
      的框里只能看见顶部一条。

   解法：把 iframe 元素做成 1150×800（超过 lg 断点 1024px，栅格转为左右布局），
   再整体 scale 到幻灯片放得下的尺寸。外层 .c-demo-wrap 负责裁切与定位。
   需要看细节时点「全屏」，那时取消缩放、恢复 100%。 */

.c-demo-wrap {
  position: relative;
  height: 449px;
  overflow: hidden;
  border: 1px solid #cbd5e1;
  border-radius: var(--c-radius);
  background: #f8fafc;
}

/* 内部视口 1080px：实测这是让 demo 栅格转为左右布局所需的最小宽度
   （1040px 时 venn 仍为 909px 高，1080px 降到 802px，再宽无收益）。
   宽度取最小值，缩放比就能取最大，按钮文字最清楚。 */
.c-demo-wrap .c-demo-frame {
  position: absolute; top: 0; left: 0;
  width: 1080px;
  height: 810px;
  border: 0;
  transform: scale(0.554);     /* 1080×0.554 ≈ 598px 正好一栏；810×0.554 ≈ 449px */
  transform-origin: top left;
}

/* 打印用静态占位（屏幕隐藏，打印显示）—— 与 print-deck.css 配合 */
.print-only { display: none; }
.c-demo-url {
  font-family: ui-monospace, "SF Mono", Consolas, monospace;
  font-size: 0.62em;
  color: var(--c-muted);
  word-break: break-all;
}

/* ============================================================
   6. 放映导航（返回首页 / 缩略图侧栏）
   仅屏幕放映时出现，打印版由 print-deck.css 隐藏。
   ============================================================ */

.c-navbar {
  position: fixed; top: 10px; left: 12px; z-index: 40;
  display: flex; gap: 6px;
  opacity: 0.25; transition: opacity .18s;
}
.c-navbar:hover { opacity: 1; }

.c-nav-btn {
  font-family: var(--c-font);
  font-size: 13px; line-height: 1;
  padding: 6px 10px;
  border: 1px solid #cbd5e1; border-radius: 7px;
  background: rgb(255 255 255 / .92); color: var(--c-ink-soft);
  text-decoration: none; cursor: pointer;
}
.c-nav-btn:hover { background: #fff; color: var(--c-primary); border-color: var(--c-primary); }

/* —— 左侧缩略图栏 —— */
.c-rail {
  position: fixed; top: 0; left: 0; bottom: 0; z-index: 39;
  width: 260px; padding: 44px 0 12px;
  background: rgb(248 250 252 / .97);
  border-right: 1px solid #cbd5e1;
  overflow-y: auto;
  transform: translateX(-100%);
  transition: transform .2s ease;
}
body.c-rail-open .c-rail { transform: none; }
body.c-rail-open .reveal { padding-left: 260px; box-sizing: border-box; }

.c-rail-title {
  font-family: var(--c-font); font-size: 12px; font-weight: 700;
  color: var(--c-muted); letter-spacing: .08em;
  padding: 0 14px 8px;
}
.c-rail-list { list-style: none; margin: 0; padding: 0; }

.c-rail-item {
  display: flex; gap: 8px; align-items: baseline;
  width: 100%; text-align: left;
  font-family: var(--c-font); font-size: 13px; line-height: 1.45;
  padding: 7px 14px;
  background: none; border: 0; border-left: 3px solid transparent;
  color: var(--c-ink-soft); cursor: pointer;
}
.c-rail-item:hover { background: #eef2f7; color: var(--c-ink); }
.c-rail-item.is-current {
  background: var(--c-block-bg);
  border-left-color: var(--c-primary);
  color: var(--c-primary); font-weight: 700;
}
.c-rail-no {
  flex: 0 0 1.8em; text-align: right;
  font-size: 11px; color: var(--c-muted);
}
.c-rail-item.is-current .c-rail-no { color: var(--c-primary); }
.c-rail-label { flex: 1 1 auto; }

/* —— 全屏按钮 —— */
.c-demo-full {
  position: absolute; top: 6px; right: 6px; z-index: 5;
  font-family: var(--c-font); font-size: 12px; line-height: 1;
  padding: 5px 9px;
  border: 1px solid #cbd5e1; border-radius: 6px;
  background: rgb(255 255 255 / .93); color: var(--c-ink-soft);
  cursor: pointer; opacity: .55; transition: opacity .15s;
}
.c-demo-wrap:hover .c-demo-full { opacity: 1; }
.c-demo-full:hover { color: var(--c-primary); border-color: var(--c-primary); }

/* 全屏态 —— 三个选择器指同一件事：
   `:fullscreen` 是原生全屏（正常路径），`.is-fallback` 是浏览器不给原生全屏时
   把节点搬到 <body> 下的退化路径。
   ⚠️ 别把这三条合成一条选择器列表：浏览器遇到不认识的伪类会**整条丢弃**，
   `:-webkit-full-screen` 在 Firefox 里就会把整组规则连累掉。所以拆开写。 */
.c-demo-wrap:fullscreen,
.c-demo-wrap.is-fallback { --c-demo-full: 1; }
.c-demo-wrap:-webkit-full-screen { --c-demo-full: 1; }

.c-demo-wrap:fullscreen,
.c-demo-wrap:-webkit-full-screen,
.c-demo-wrap.is-fallback {
  width: 100%; height: 100%;
  max-width: none; max-height: none;
  background: #fff;
  padding: 0; border: 0; border-radius: 0;
  overflow: hidden;
}
/* 退化路径要自己铺满视口；原生全屏由浏览器负责，不用也不该加 fixed */
.c-demo-wrap.is-fallback {
  position: fixed; inset: 0; z-index: 9999;
}

/* 全屏时 demo 撑满：取消那个 0.554 的缩放，iframe 直接按真实尺寸铺开，
   这样 1920×1080 的投影上就是一整屏的可交互面积。 */
.c-demo-wrap:fullscreen .c-demo-frame,
.c-demo-wrap:-webkit-full-screen .c-demo-frame,
.c-demo-wrap.is-fallback .c-demo-frame {
  position: static;
  width: 100%; height: 100%;
  transform: none;
  border: 0; border-radius: 0;
}

/* 退出按钮在全屏时常驻，并且做得显眼一点——
   全屏之后没有别的界面元素了，找不到它就只能靠 Esc。 */
.c-demo-wrap:fullscreen .c-demo-full,
.c-demo-wrap:-webkit-full-screen .c-demo-full,
.c-demo-wrap.is-fallback .c-demo-full {
  opacity: 1;
  top: 10px; right: 10px;
  font-size: 13px; padding: 7px 12px;
  box-shadow: 0 2px 8px rgb(0 0 0 / .18);
}

/* ============================================================
   FIM 专用语义块
   Financial Institutions and Markets 的固定叙事需要五类 course-prob
   没有的构件：两次课的分隔、每次课收尾的实名案例、一页一篇的研究卡、
   计划好的互动、以及中美对照。它们都走同一套变量，不引入新配色。
   ============================================================ */

/* —— 1. Meeting / Session 分隔 ——————————————————————————
   一周两次课、每次两个 45 分钟 session。分隔页承担「现在换场了」的信号，
   所以是整页反白，与内容页拉开最大对比。 */
.c-meeting {
  /* ⚠️ 满幅背景不画在 section 上，画在 reveal 自己的 .slide-background 上（见下一条规则）。
     两条走不通的路，别再试：
     ① position:absolute + inset:0 —— 抢了 reveal 给 section 算的 top/left，
        overview 模式和打印分页首先出问题；
     ② 给 section 自己上背景色 —— 屏幕上正常，但打印时 reveal 把 section 包进
        带**内联** height 和内联白底的 .pdf-page，section 高度变成内容高，
        PDF 里就是「半张蓝底」，而且不报任何错。
     reveal 会把 section 的 class 原样复制到它生成的 .slide-background 上，
     那个元素在屏幕和打印下都由 reveal 负责铺满整页——这才是正确的挂载点。 */
  color: #fff;
  justify-content: center;       /* 纵向居中，靠 .reveal .slides section 的 flex 列 */
  padding: 0 1.9em;
}
.c-meeting .c-meeting-no {
  font-size: 0.76em; font-weight: 700; color: var(--c-gold);
  letter-spacing: 0.09em; text-transform: uppercase; margin-bottom: 0.7em;
}
.c-meeting h2 {
  color: #fff; border-bottom: none; margin: 0 0 0.3em;
  padding: 0; font-size: 1.22em; text-wrap: balance;
}
.c-meeting .c-meeting-track {
  font-size: 0.62em; color: #cfe0f2; margin-top: 1.1em; letter-spacing: 0.02em;
}

/* session 小分隔：不反白，只用一条金线 + 标题，避免与 meeting 分隔撞脸。
   （pptx 版这两者都是满蓝，连着两页蓝屏，观感是重复而不是节奏。） */
.c-session {
  border-left: none;
  border-top: 3px solid var(--c-gold);
  padding: 0.6em 0 0;
  margin-top: 1.6em;
}
.c-session .c-session-no {
  font-size: 0.6em; color: var(--c-muted); letter-spacing: 0.08em;
  text-transform: uppercase;
}
.c-session h2 { border-bottom: none; margin: 0.15em 0 0; }

/* —— 2. 案例 —————————————————————————————————————————
   每次 90 分钟的课以一个实名案例收尾，固定三拍：
   Situation → 制度摩擦 → 决策题。决策题用金色，因为它是要学生开口的那一句。 */
.c-case { --c-accent: var(--c-primary); }
/* 标签与正文是两栏，不是 inline-block —— inline-block 只能撑开第一行，
   正文一旦折行就回到左边界，三拍的对齐立刻散掉。
   ⚠️ 正文必须包在 .c-case-say 里。grid 会把**每一个元素子节点**都当成一个格子，
   所以正文里一个 <em> 或 <span class="cn"> 就会自己占掉标签列、单独起一行——
   页面上看起来像排版错乱，而没有任何检查会发现。包一层之后每拍恒为两个格子。 */
.c-case .c-case-beat {
  display: grid;
  grid-template-columns: 6.6em 1fr;
  gap: 0 0.7em;
  margin: 0.45em 0;
}
.c-case .c-case-say { min-width: 0; }
.c-case .c-case-label {
  font-size: 0.66em; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--c-muted);
  padding-top: 0.32em;
}
.c-case .c-case-beat--ask { --c-accent: var(--c-gold); }
.c-case .c-case-beat--ask .c-case-label { color: var(--c-gold); }
.c-case .c-case-beat--ask { font-weight: 600; color: var(--c-primary); }

/* —— 3. Research Spotlight ——————————————————————————————
   一周一页，最多两篇。标题位放的是那句结论，不是论文题目。
   四行固定：Question / Identification / Number / So what。 */
.c-spotlight { --c-accent: var(--c-primary);
  background: var(--c-block-bg); border-color: var(--c-block-br); }
.c-spotlight--alt { --c-accent: var(--c-gold);
  background: #fffdf6; border-color: var(--c-gold); }
.c-spotlight .c-sl-claim {
  display: block; font-size: 1.02em; font-weight: 700; line-height: 1.32;
  color: var(--c-accent); text-wrap: balance;
  padding-bottom: 0.4em; margin-bottom: 0.45em;
  border-bottom: 2px solid var(--c-gold);
}
.c-spotlight dl { margin: 0; display: grid; grid-template-columns: 7.4em 1fr; gap: 0.24em 0.5em; }
.c-spotlight dt {
  font-size: 0.64em; font-weight: 700; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--c-muted); padding-top: 0.32em;
}
.c-spotlight dd { margin: 0; font-size: 0.92em; }
.c-spotlight dd.c-sl-number { font-weight: 700; color: var(--c-accent); }
.c-spotlight .c-source { margin-top: 0.55em; }
/* 两篇并排时整体缩一档，四行结构不变 */
.c-sl-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 0.9em; align-items: start; }
.c-sl-pair .c-spotlight { font-size: 0.86em; margin: 0; }
.c-sl-pair .c-spotlight dl { grid-template-columns: 6.6em 1fr; }

/* —— 4. 计划中的互动 ————————————————————————————————
   每个 45 分钟 session 至少两处。徽章写清形式与分钟数；
   答案不写在页面上——放进 <aside class="notes">，否则学生一眼看到就不猜了。 */
/* 一页的最后一个互动卡沉底。案例页是「三拍 + 提问」，
   提问落在页底比紧跟在正文下方、底下空一大片好看得多。
   ⚠️ 不能只写 :last-child —— <aside class="notes"> 才是 section 真正的最后一个孩子
   （reveal 把它 display:none，但选择器仍然算它）。所以还要一条 :has(+ aside.notes)。
   只有一张互动卡的页面（predict / poll）后面都跟着一句 .c-close，不会被误伤。 */
.c-interaction:last-child,
.c-interaction:has(+ aside.notes) { margin-top: auto; }

.c-interaction {
  --c-accent: var(--c-gold);
  border-left: 5px solid var(--c-gold);
  border-radius: 0 var(--c-radius) var(--c-radius) 0;
  background: #fffdf6; padding: 0.5em 0.85em; margin: var(--c-gap) 0;
}
.c-interaction .c-int-head {
  font-size: 0.62em; font-weight: 700; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--c-gold);
}
.c-interaction .c-int-prompt {
  display: block; font-size: 1.06em; font-weight: 600;
  color: var(--c-ink); margin: 0.28em 0 0.35em; text-wrap: balance;
}
.c-interaction ol, .c-interaction ul { margin: 0.1em 0 0 1.2em; font-size: 0.92em; }
.c-interaction li { margin-bottom: 0.12em; }

/* 小标题条：总结页上「这一周做了什么 / 该带走什么」这类分栏眉。
   比 h2 小、比正文重，用来把一页分成两段而不必再加一个方框。 */
.c-eyebrow {
  font-size: 0.6em; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--c-muted); margin: 0.55em 0 0.15em;
}
.c-eyebrow:first-of-type { margin-top: 0.1em; }

/* 一句话领起：总结页开头那行「这一周走过的路」。比正文稍大、稍浅，
   一行读完，不占方框。 */
.c-lede { font-size: 1.02em; color: var(--c-ink-soft); margin: 0.1em 0 0.7em; }

/* 表格里「学界仍有争议」的一行：不是错，但不该和其它行等重。 */
.c-table td.c-contested { color: var(--c-muted); font-style: italic; }

/* 拼音：汉字旁边的读音。班上基本是留学生，汉字与英文释义都给了，
   仍然缺一样东西——他们没法把这个词念出来，也就没法向别人问起它。
   斜体、比正文小、用弱色，避免和英文释义抢注意力。 */
.c-pinyin {
  font-style: italic; font-size: 0.82em; font-weight: 400;
  color: var(--c-muted); letter-spacing: 0.01em; white-space: nowrap;
}
h2 .c-pinyin { font-size: 0.5em; }

/* —— 4b. 互动页上的 AhaSlides 二维码 ————————————————————
   投影出来的二维码要够大才扫得到，所以宽度写死像素——reveal 把整块画布缩放，
   em/vw 在这里都不是「屏幕上多大」的意思。文字栏 min-width:0，否则长提示语
   会把二维码挤出格子。 */
.c-interaction--qr { display: flex; align-items: flex-start; gap: 1em; }
.c-interaction--qr > div:first-child { flex: 1 1 auto; min-width: 0; }
.c-int-qr { flex: 0 0 auto; text-align: center; }
.c-int-qr img {
  display: block; width: 132px; height: 132px;
  background: #fff; padding: 4px; border-radius: 6px; border: 1px solid var(--c-rule);
}
.c-int-qr span {
  display: block; margin-top: 0.2em; font-size: 0.52em; letter-spacing: 0.06em;
  text-transform: uppercase; font-weight: 700; color: var(--c-gold);
}

/* —— 4b2. AhaSlides 实时视图 ————————————————————————
   投影时把 AhaSlides 的 casting 页嵌进幻灯片，省掉切窗口。

   两件事必须这样写：
   ① iframe 保持原生 960×569，外层裁切 + transform 缩放。直接把 iframe 设成
      653×387 会让 AhaSlides 自己的响应式断点按 iframe 视口重排，词云挤成一列。
      与 .c-demo-wrap 是同一个坑、同一个解法。
   ② 尺寸写死像素。reveal 把 1280×720 整体缩放到屏幕，vw/vh 量的是窗口而不是
      这块画布 —— 和 .c-chart 的高度是同一条规矩。

   iframe 用 data-src 而不是 src：reveal 只在翻到该页时才把它换成 src，
   离开就卸载。三页共用一个 casting 地址，不这样写会同时开三个连接。 */
.c-live-row { display: flex; gap: 0.9em; align-items: flex-start; margin: 0.5em 0 0; }
.c-live-row > .c-interaction { flex: 1 1 auto; min-width: 0; margin: 0; }
.c-live {
  flex: 0 0 auto; position: relative;
  width: 653px; height: 387px; overflow: hidden;
  border: 1px solid var(--c-rule); border-radius: var(--c-radius); background: #fff;
}
.c-live iframe {
  position: absolute; top: 0; left: 0;
  width: 960px; height: 569px; border: 0;
  transform: scale(0.68); transform-origin: top left;
}
/* 断网时 iframe 是一个空白框。给它一句话，免得看起来像坏掉了。 */
.c-live::before {
  content: "AhaSlides live view"; position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 0.62em; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--c-muted); background: var(--c-block-bg);
}
.c-live iframe { position: absolute; z-index: 1; }

/* —— 4c. 资金流向的扁宽版 ————————————————————————————
   Mishkin 图 2.1 是竖版，占掉大半页；直接／间接融资那一页只需要让学生
   想起那张图的骨架，所以这里是同一张图横过来写：两端仍是同样的两方，
   中间并排两条路。上面一条是间接，下面一条是直接——和原图的上下关系一致。 */
.c-funds {
  display: grid; grid-template-columns: 1fr 1.6em 2.1fr 1.6em 1fr;
  align-items: center; gap: 0.3em; margin: 0.8em 0;
}
.c-funds-end {
  border: 1px solid var(--c-rule); border-top: 3px solid var(--c-primary);
  border-radius: 6px; padding: 0.45em 0.55em; text-align: center;
  background: var(--c-block-bg);
}
.c-funds-end strong { display: block; font-size: 0.84em; color: var(--c-primary); }
.c-funds-end span {
  display: block; margin-top: 0.15em; font-size: 0.58em;
  color: var(--c-ink-soft); line-height: 1.35;
}
.c-funds-arrow { text-align: center; font-size: 1.4em; color: var(--c-muted); line-height: 1; }
.c-funds-mid { display: grid; gap: 0.3em; }
.c-funds-route { border-radius: 6px; padding: 0.4em 0.6em; text-align: center; border: 1px solid; }
.c-funds-route strong { display: block; font-size: 0.78em; }
.c-funds-route span {
  display: block; margin-top: 0.1em; font-size: 0.6em;
  color: var(--c-ink-soft); line-height: 1.35;
}
.c-funds-route--ind { border-color: var(--c-gold); background: #fffdf6; }
.c-funds-route--ind strong { color: var(--c-gold); }
.c-funds-route--dir { border-color: var(--c-block-br); background: var(--c-block-bg); }
.c-funds-route--dir strong { color: var(--c-primary); }

/* 只有一个 session 抬头、页面上没有别的内容时（第二节的标题页），
   把抬头竖直居中，否则整页看上去像是没写完。 */
.c-session--solo { margin-top: auto; margin-bottom: auto; }

/* —— 5. 中美对照 ————————————————————————————————————
   这门课的核心分析习惯。两栏等宽，栏头用语义色区分而不是两种蓝。 */
.c-compare { display: grid; grid-template-columns: 1fr 1fr; gap: 0.9em; align-items: start; }
.c-compare > * { margin: 0; }
.c-cmp-head {
  font-size: 0.7em; font-weight: 700; letter-spacing: 0.05em;
  text-transform: uppercase; padding: 0.32em 0.7em; border-radius: 6px 6px 0 0;
  color: #fff;
}
.c-cmp-head--a { background: var(--c-primary); }
/* 第二栏用金色，不用 insight 的深绿——主色换成青绿后两者几乎撞色。
   而且这样与图表里「US = 主色 / China = 金」对齐，
   同一页上双栏和柱状图讲的是同一件事，颜色就该是同一套。 */
.c-cmp-head--b { background: var(--c-gold); }
.c-compare .c-cmp-body {
  border: 1px solid var(--c-rule); border-top: none;
  border-radius: 0 0 6px 6px; padding: 0.55em 0.8em; font-size: 0.94em;
}
.c-compare .c-cmp-body ul { margin-left: 1em; }

/* —— 6. 数据构件 ————————————————————————————————————
   大字号数字卡（一页三张）与「一个数占满一页」。
   FIM 的很多论点就是一个数，给它整页比塞进项目符号有力。 */
.c-stats { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 0.8em; margin: 1em 0; }
.c-stat {
  border-left: 5px solid var(--c-primary);
  border-radius: 0 var(--c-radius) var(--c-radius) 0;
  background: var(--c-block-bg); padding: 0.7em 0.85em;
}
.c-stat--gold { border-color: var(--c-gold); background: #fffdf6; }
.c-stat--alt  { border-color: var(--c-insight-br); background: var(--c-insight-bg); }
.c-stat .c-stat-num {
  display: block; font-size: 1.75em; font-weight: 700; line-height: 1.05;
  color: var(--c-primary); font-variant-numeric: tabular-nums;
}
.c-stat--gold .c-stat-num { color: var(--c-gold); }
.c-stat--alt  .c-stat-num { color: var(--c-insight-fg); }
.c-stat .c-stat-cap { display: block; font-size: 0.72em; color: var(--c-ink-soft); margin-top: 0.25em; }

.c-hero { text-align: center; margin: 1.1em 0 0.6em; }
.c-hero .c-hero-num {
  display: block; font-size: 3.4em; font-weight: 700; line-height: 1;
  color: var(--c-primary); font-variant-numeric: tabular-nums;
}
.c-hero .c-hero-cap { display: block; font-size: 0.96em; color: var(--c-ink); margin-top: 0.35em; }
.c-hero .c-hero-sub { display: block; font-size: 0.72em; color: var(--c-muted); margin-top: 0.3em; }

/* 数据表带 as-of 列时，日期列右对齐并等宽，方便一眼扫「这些数各是什么时候的」 */
.c-table td.c-asof, .c-table th.c-asof {
  text-align: right; white-space: nowrap;
  font-variant-numeric: tabular-nums; color: var(--c-muted); font-size: 0.92em;
}

/* 图表容器：Chart.js 的 canvas 必须有确定高度，否则它按父元素高度自适应，
   在 reveal 画布里会拿到 0 而画不出来。高度一律用 px（坑 4：vh 在 reveal 里失真）。 */
/* ⚠️ 图表容器必须显式给宽，不能靠 margin: … auto 居中。
   section 是 flex 列，横向 auto 外边距会取消 align-self:stretch，容器退化成
   「收缩到内容宽」；canvas 没有固有宽度，于是算成 0，Chart.js 量到 0 就什么都不画
   ——**页面上一片空白，控制台无报错**。（section 还是 display:block 时看不出来，
   flex 一生效就现形。）
   注意这条只对无固有宽度的内容成立：带 max-width 的盒子用 margin:auto 居中没问题，
   收缩到内容宽是有界的。 */
.c-chart { position: relative; width: 100%; margin: 0.6em 0; }
.c-chart canvas { display: block; }

/* ============================================================
   版式与动效 —— 借鉴 Group4 学生 deck 的几个做法
   ============================================================ */

/* —— 页面是纵向 flex，这是「过空」的解药 ————————————————
   pptx 版只能把每个框摆在绝对坐标上，内容自然全堆在顶部、底部空一大片。
   改成 flex 列之后：正文从上往下流，收尾句用 margin-top:auto 钉在页底，
   多出来的空白落在中间——那里空是留白，堆在底部就是没排完。 */
/* ⚠️ 必须挂在 .present 上并带 !important，不能只写 `.reveal .slides section`。
   reveal.css 里有 `.reveal .slides>section.present{display:block}`，特异度 0,3,1；
   `.reveal .slides section` 只有 0,2,1，**当前页永远是 block**——于是
   margin-top:auto 与 justify-content 全部失效，而页面看上去只是「排得靠上」，
   不报任何错。放映时 reveal 还会给切换中的页写内联 display:block，
   所以这里用 !important 才守得住。
   打印模式 reveal 把每个 section 摊成独立一页，另给一条。 */
.reveal .slides > section.present,
.reveal .slides > section.past,
.reveal .slides > section.future,
.reveal .slides > section > section.present {
  display: flex !important;
  flex-direction: column;
}
.print-pdf .reveal .slides section {
  display: flex !important;
  flex-direction: column;
}
.reveal .slides section > * { flex: 0 0 auto; }

/* 收尾句：本页要学生记住的那一行，永远在页底同一位置 */
.c-close {
  margin-top: auto;
  padding-top: 0.5em;
  border-top: 1px solid var(--c-rule);
  font-size: 0.94em;
  color: var(--c-ink);
}
.c-close strong { color: var(--c-primary); }

/* 来源行也钉在页底，每页同一高度。
   ⚠️ 不用 position:absolute——那样它会脱离 flex 流，reveal 量页高时看不见它，
   打印时就会与正文重叠（course-prob 坑 8 的同类问题）。用 auto 外边距即可。 */
.c-src {
  margin-top: auto;
  padding-top: 0.45em;
  border-top: 1px solid rgba(0,0,0,.06);
  font-size: 0.58em;
  line-height: 1.5;
  color: var(--c-muted);
  font-style: italic;
}
/* 同页既有收尾句又有来源行时，只让上面那个吃掉空白 */
.c-close + .c-src { margin-top: 0.5em; border-top: none; padding-top: 0.2em; }

/* —— 内容入场 ——————————————————————————————————————
   reveal 自带的翻页动效负责「页与页之间」，这一条负责「页内内容落位」。
   0.34s 到头：讲课时每页都要等它演完，超过 0.35s 就开始碍事。 */
/* 截图与 PDF 导出必须能关掉动画：headless Chrome 的 --virtual-time-budget
   不推进 CSS 动画，定格下来的是 opacity 中途的半透明帧——页面看着「褪色」，
   而且**不报任何错**。deck-init.js 见到 ?still=1 就给 <html> 加 .fim-still。 */
html.fim-still .reveal .slides section > * {
  animation: none !important; opacity: 1 !important; transform: none !important;
}

@media (prefers-reduced-motion: no-preference) {
  .reveal .slides section.present > h2,
  .reveal .slides section.present > .c-block,
  .reveal .slides section.present > .c-insight,
  .reveal .slides section.present > .c-alert,
  .reveal .slides section.present > .c-case,
  .reveal .slides section.present > .c-spotlight,
  .reveal .slides section.present > .c-interaction,
  .reveal .slides section.present > .c-stats,
  .reveal .slides section.present > .c-compare,
  .reveal .slides section.present > .c-chart,
  .reveal .slides section.present > table,
  .reveal .slides section.present > .c-hero {
    animation: fimRise .34s cubic-bezier(.22,.9,.25,1) both;
  }
  @keyframes fimRise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
}
/* 打印时一律不要动效——动画的 opacity:0 起始帧会被定格成空白页 */
.print-pdf .reveal .slides section > * { animation: none !important; opacity: 1 !important; transform: none !important; }

/* —— 顶部进度条 ————————————————————————————————————— */
.reveal .progress { height: 3px; color: var(--c-gold); }
.reveal .progress span { transition: width .35s ease; }

/* —— Meeting 分隔页的巨型幽灵序号 ————————————————————
   纯色分隔页太安静，学生分不清「这是换场」还是「这页还没加载」。
   一个压到极淡的大数字就够了，不抢内容。 */
/* 满幅底色画在 reveal 的背景层上（class 由 reveal 从 section 复制过来）。 */
.reveal .slide-background.c-meeting { background-color: var(--c-primary); }
.c-meeting { position: relative; overflow: hidden; }
.c-meeting .c-ghost {
  position: absolute; right: 0.35em; bottom: -0.24em;
  font-size: 9.5em; font-weight: 800; line-height: 1;
  color: rgba(255,255,255,.10); letter-spacing: -0.05em;
  pointer-events: none; user-select: none;
}

/* —— 流程图：显式的箭头列 ————————————————————————————
   savers → 系统 → borrowers 这种三段式，用 grid 插两条窄箭头栏，
   比在盒子之间摆绝对定位的箭头稳得多，栏宽变化时箭头自动跟着走。 */
.c-flow { display: grid; align-items: stretch; gap: 0.5em; margin: 0.9em 0; }
.c-flow--3 { grid-template-columns: 1fr 2.2em 1fr 2.2em 1fr; }
.c-flow--2 { grid-template-columns: 1fr 2.2em 1fr; }
/* 四格无箭头：一条时间线上的四个阶段（W05 的非常规工具、框架改革）。
   箭头栏会把每格挤到 20% 以下，四段文字就全部折成六七行；
   四等分＋节点自己的顶边色条已经足够读出顺序。 */
.c-flow--4 { grid-template-columns: repeat(4, 1fr); }
/* 三格无箭头：并列的三样东西（W01 的三种证据），不是一条先后顺序。
   带箭头的 --3 会读成「先理论、再发达市场、最后中国」，那不是这门课的意思。 */
.c-flow--3eq { grid-template-columns: repeat(3, 1fr); }
.c-flow-node {
  border: 1px solid var(--c-rule); border-top: 3px solid var(--c-block-br);
  border-radius: 8px; padding: 0.55em 0.7em; background: var(--c-block-bg);
}
.c-flow-node--key { border-top-color: var(--c-gold); background: #fffdf6; }
.c-flow-node strong { display: block; font-size: 0.98em; color: var(--c-primary); margin-bottom: 0.15em; }
.c-flow-node span { display: block; font-size: 0.72em; color: var(--c-ink-soft); line-height: 1.4; }
/* 说明文字里的 <strong> 是行内强调，不是节点标题 —— 上面那条 display:block
   会把它单独顶成一行（第 1 讲第 37 页的 85% 和 $7.93tn 各占了一行）。 */
.c-flow-node span strong {
  display: inline; font-size: inherit; color: inherit; margin: 0; font-weight: 700;
}
.c-flow-arrow {
  display: flex; align-items: center; justify-content: center;
  color: var(--c-gold); font-size: 1.5em; font-weight: 700;
}

/* —— KPI 行：卡片内的小标签 + 大数字 —————————————————— */
.c-kpi { display: flex; gap: 1.4em; margin-top: 0.55em; padding-top: 0.45em;
         border-top: 1px solid var(--c-rule); }
.c-kpi div { line-height: 1.2; }
.c-kpi strong {
  display: block; font-size: 1.05em; font-weight: 700; color: var(--c-primary);
  font-variant-numeric: tabular-nums;
}
.c-kpi span {
  display: block; font-size: 0.56em; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--c-muted); margin-top: 0.15em;
}

/* —— 扉页 ——————————————————————————————————————————— */
.c-cover .c-kicker {
  font-size: 0.56em; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--c-gold); font-weight: 700;
}
.c-cover .c-rule { width: 78px; height: 4px; background: var(--c-gold); border-radius: 2px; margin: 0.7em 0; }

/* 只有一张互动卡（或很少内容）的页面：整体纵向居中，而不是堆在顶部。
   CSS 量不到「内容够不够满」，所以这是显式开关，不是自动判断。
   predict / poll 这类页面用它；有表格、图表或案例三拍的页面不要用。 */
.reveal .slides > section.c-mid.present { justify-content: center; }
.print-pdf .reveal .slides section.c-mid { justify-content: center; }
