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

:root {
  /* —— 配色 ——
     底色统一压到「淡到几乎是纸」的程度，左侧色条相应加深。
     理由：投影仪把浅色整体提亮、把对比压平，五个高彩度底色并排时
     会盖过内容，读起来像「一堆彩色方块」而不是讲义。
     让**色条**承担语义、让**底色**只负责分组，页面立刻安静下来，
     而且打印到黑白激光时底色仍能拉开层次（色条变成不同深浅的灰）。 */
  --c-ink:        #16202e;   /* 正文，比原先再深一档，投影上更实 */
  --c-ink-soft:   #475569;   /* 次要文字 */
  --c-muted:      #64748b;   /* 说明、来源 */
  --c-paper:      #ffffff;
  --c-primary:    #0d4a8b;   /* 复旦蓝，标题与强调 */
  --c-rule:       #dde5ee;   /* 分隔线：比 slate-200 稍冷，与蓝系同族 */

  --c-block-fg:   #1a4faa;   --c-block-bg:   #f4f8fd;  --c-block-br:   #2f6fd0;
  --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;

  /* —— 排版 —— */
  --c-font: "PingFang SC", "Microsoft YaHei", "Source Han Sans SC",
            "Noto Sans SC", "CourseFallbackSC", sans-serif;
  --c-lh: 1.6;               /* 中文正文行高。别调大——一页 25 行时
                                每 +0.02 就多出约 13px，够把贴底的页挤裂 */
  --c-ls: 0.015em;           /* 中文字距 */
  --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 一律不倾斜，改用颜色 + 轻微字距来区分（引用题干、术语首次出现等场景）。
   规则不能限定在 .reveal 内 —— 教师笔记页不在 .reveal 里，也需要同样处理。 */
em {
  font-style: normal;
  color: var(--c-ink-soft);
  letter-spacing: 0.04em;
}

/* 西文书名、期刊名等确实需要斜体的场合，用 .latin-italic 显式声明 */
.latin-italic { font-style: italic; letter-spacing: normal; }
.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 { margin: var(--c-gap) auto; text-align: center; }
.c-fig img {
  max-width: 100%;
  /* ⚠️ 这里曾是 62vh —— 正是坑 4 说的那种错误。reveal 把 1280×720 的画布
     整体 transform 缩放到屏幕，而 vh 按**真实视口**解析：
     窗口高 485px 时这个上限是 300px，接到 1080p 投影全屏时变成 670px，
     而画布本身只有 720px 高，图一大就把标题挤出页外——「有的电脑显示不全」。
     26 张图里有 13 张真的顶到这个上限，所以不是纸面问题。
     导 PDF 时窗口固定为 1280×720，62vh 恰好是 446px；直接写成 446px，
     PDF 一页不变，屏幕上则不再随分辨率漂移。 */
  max-height: 446px;
  border-radius: var(--c-radius);
  box-shadow: 0 2px 10px rgb(0 0 0 / 0.09);
}
.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 属性，否则每页触发一次重排。 */

@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;
  }
  /* 整页淡入。翻页本身不做过渡（见 deck-init.js 里 transition 的注释：
     真正的交叉淡化会让前后两页的中文正文叠印），换页是瞬时的，
     由这一条给新页一次柔和的显影——任何一帧里都只有一页的字。
     它与下面的分块错峰叠加：整页先亮起来，块再依次落位。 */
  .reveal .slides section.present {
    animation: c-fade-in 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-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@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); }

/* 底部进度条。reveal 的默认配色是「白色进度 + 10% 黑底轨道」——
   落在我们的白底上等于看不见，一直白挂着。染成复旦蓝之后它才有用：
   讲到哪了，抬眼一扫就知道，不必去看右下角的页码。
   打印版由 reveal 自己隐藏（html.reveal-print 那条 !important）。 */
.reveal .progress {
  height: 3px;
  color: var(--c-primary);
  background-color: rgb(13 74 139 / .10);
}

/* —— 左侧缩略图栏 —— */
.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);
}
