This commit is contained in:
pluv committed 2026-10-08 12:29:59 +08:00
commit 0285b2a5d1
12 files changed
+4243

No files matched your search

+474
View File
@@ -0,0 +1,474 @@
/*!
* Tectonics — 答辩模板主题
*
* @theme tectonics
* @author zhiyu3826
* @size 16:9 1280px 720px
* @size 4:3 960px 720px
* @auto-scaling fittingHeader
*/
/* 以 Marp Core 内置 default 主题为底, 这里只覆盖版式 */
@import-theme "default";
/* ===== 可调参数 ===== */
section {
--tectonics-accent: #004e98; /* 主色: 取自 design.1.png 的色带 */
--tectonics-fg: #393939; /* 封面的深灰文字色 */
--tectonics-sans: "Noto Sans CJK SC", "Source Han Sans SC", "PingFang SC",
"Microsoft YaHei", sans-serif;
--tectonics-serif: "Source Han Serif CN VF", "Source Han Serif CN",
"Noto Serif CJK SC", "Songti SC", SimSun, serif;
--tectonics-header-color: #555; /* 右上角章节名的灰 */
--tectonics-title-size: 34px;
--tectonics-title-rule: 2px;
width: 1280px;
height: 720px;
padding: 48px 64px 44px;
}
/* ===== 正文页: 标题钉在左上角, 内容自上而下 ===== */
section:not(.cover) {
display: flex;
flex-flow: column nowrap;
align-content: flex-start;
justify-content: flex-start;
}
/* 「本页第一个标题」的两种情形:
* 没有页眉时, 标题是 section 的第一个子元素 (:first-child)
* 有页眉时, 框架会把 <header> 插成第一个子元素, 标题紧跟其后
* 所以每条标题规则都要写这两个选择器, 否则加了页眉的页会掉样式。
*/
section:not(.cover):not(.toc) > :is(h1, h2, h3):first-child,
section:not(.cover):not(.toc) > header:first-child + :is(h1, h2, h3) {
flex: none;
margin: 0 0 28px;
padding: 0 0 12px;
border-bottom: var(--tectonics-title-rule) solid var(--tectonics-accent);
font-size: var(--tectonics-title-size);
line-height: 1.25;
}
/* ===== 封面 (对应 design.1.png) =====
* 三行文字 + 一条通栏色带, 位置按设计稿比例量出来的, 单位是 1280x720 画布上的 px
*/
section.cover {
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
padding: 0; /* 让色带通栏 */
text-align: center;
color: var(--tectonics-fg);
}
section.cover > p {
margin: 0;
line-height: 1;
font-family: var(--tectonics-sans);
font-weight: 700;
font-size: 42px;
}
/* 第一行: 顶部小字 */
section.cover > p:first-of-type {
padding-top: 63px;
}
/* 第二行: 通栏色带里的主标题 */
section.cover > :is(h1, h2):first-of-type {
margin: 60px 0 0;
padding: 21px 64px 15px;
background: var(--tectonics-accent);
color: #fff;
font-family: var(--tectonics-serif);
font-size: 70px;
font-weight: 700;
line-height: 1.45;
text-align: center;
}
/* 第三行: 学院 + 姓名 */
section.cover > p:nth-of-type(2) {
margin-top: 30px;
font-size: 37px;
}
/* 第四行: 日期 */
section.cover > p:nth-of-type(3) {
margin-top: 164px;
font-size: 28px;
font-weight: 400;
}
/* ===== 左右两栏: 用 div 包住的内容各占一栏, 其余元素整行 ===== */
section.cols {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem 2rem;
align-content: start;
}
section.cols > :is(h1, h2, h3):first-child,
section.cols > header:first-child + :is(h1, h2, h3),
section.cols > p,
section.cols > ul,
section.cols > ol,
section.cols > blockquote {
grid-column: 1 / -1;
}
section.cols > div {
min-width: 0;
}
/* ===== 块级小工具 =====
* markdown 里用 div 包住段落 (div 标签与文字之间留空行, 段内公式/加粗才会被解析):
* <div class="mid"> … </div> 水平居中
* <div class="bottom"> … </div> 靠底 (正文页是 flex 列, 把该块推到底部)
*/
section .mid {
text-align: center;
}
section .bottom {
margin-top: auto;
}
/* ===== 目录页 (对应 design.2.png) =====
* 左侧大字标题 + 竖直分隔线 + 右侧条目, 位置按设计稿比例量出来的 (1280x720 画布上的 px)
*/
section.toc {
--toc-line-x: 411px; /* 竖线左沿 */
--toc-line-y: 114px; /* 竖线顶端 */
--toc-line-h: 519px; /* 竖线高度 */
--toc-line-w: 4px;
--toc-title-left: 59px; /* 大字标题左沿 (相对版心) */
--toc-title-width: 260px; /* 限制宽度, 让"报告内容"自然折成两行 */
--toc-title-size: 91px;
--toc-title-line: 1.15;
--toc-list-left: 269px; /* 列表相对大字标题右沿的缩进 */
--toc-item-size: 51px;
--toc-item-line: 1.77;
display: flex;
flex-flow: row nowrap;
align-items: center;
padding: 48px 64px 88px;
}
/* 竖直分隔线
* 注意: 不能用 section::after —— 框架把页码也画在 section::after 上, 且它的规则带 id
* 选择器, 优先级压过主题, content 会被换成页码。所以借内容的 ::before 来画
* (它是 static 定位, 绝对定位的包含块仍然是 section)
* 目录条目既可以写成列表 (ul/ol), 也可以写成纯文本行 (p), 两种都挂竖线。
*/
section.toc > :is(ul, ol, p)::before {
content: '';
position: absolute;
top: var(--toc-line-y);
left: var(--toc-line-x);
width: var(--toc-line-w);
height: var(--toc-line-h);
background: var(--tectonics-accent); /* = #004e98 */
}
/* 左侧大字标题 */
section.toc > :is(h1, h2, h3):first-child,
section.toc > header:first-child + :is(h1, h2, h3) {
flex: none;
width: var(--toc-title-width);
margin: 0 0 0 var(--toc-title-left);
padding: 0;
border: none;
font-size: var(--toc-title-size);
font-weight: 700;
line-height: var(--toc-title-line);
text-align: left;
}
/* 右侧条目
* 两种写法都支持:
* 有序列表 —— 序号由主题生成成「一、二、…」(cjk-ideographic)
* list-style-position: outside 时序号挂在左侧空白里, 条目文字的左沿保持在设计稿位置
* 纯文本行 —— 写成连续几行, 渲染成一个 <p>, 条目自带「一、二、…」
*/
section.toc > :is(ul, ol, p) {
margin: 9px 0 0 var(--toc-list-left);
padding: 0;
font-size: var(--toc-item-size);
line-height: var(--toc-item-line);
}
section.toc > ul {
list-style: none;
}
section.toc > ol {
list-style-type: cjk-ideographic;
list-style-position: outside;
}
section.toc > :is(ul, ol) > li {
margin: 0;
}
/* ===== 4:3 (960x720) 下重新量一遍目录页 =====
* 主题元数据里的 @size 已声明 16:9 与 4:3 两种尺寸, Marp 会给每个 section
* 打上 data-size 属性, 所以尺寸适配写在主题里就够 —— markdown 不必再写 <style> 覆盖。
*/
section[data-size='4:3'].toc {
--toc-line-x: 300px; /* 竖线左沿: 紧贴大字标题右沿 */
--toc-line-y: 26%;
--toc-line-h: 42%;
--toc-title-left: 44px;
--toc-title-width: 190px;
--toc-title-size: 68px;
--toc-list-left: 120px; /* 列表相对大字标题右沿的缩进, 由 269 压到 120 */
--toc-item-size: 34px;
}
/* 960px 宽放不下 16:9 的字号, 条目一律不折行 */
section[data-size='4:3'].toc > :is(ul, ol) > li,
section[data-size='4:3'].toc > p {
white-space: nowrap;
}
/* ===== 图片说明/脚注 =====
* markdown 里写成 <p class="caption">…</p>
*/
section p.caption {
margin: 8px 0 0;
color: #666;
font-size: 0.55em;
line-height: 1.4;
}
/* 只放图片的栏: 图片与说明居中 */
section.cols > div.pic {
text-align: center;
}
/* ===== 页眉: 右上角显示当前章节名 (对应 design.3.png) =====
* markdown 里用局部指令设置, 从该页起往后都生效:
* <!-- header: 选题背景与意义 -->
* 位置与左上角的页标题同一水平线, 字号字重也与页标题一致
*/
section header {
position: absolute;
top: 48px;
right: 64px;
left: auto;
margin: 0;
font-size: var(--tectonics-title-size);
font-weight: 600;
line-height: 1.25;
text-align: right;
color: var(--tectonics-header-color);
}
/* 章节分隔页与封面页不显示页眉:
* 页眉是全局指令, 会从设置它的那页一直生效到下次设置为止,
* 若不屏蔽, 章节页会顶着上一章的章节名, 结束页也会继承最后一章的章节名。
*/
section.steps > header,
section.cover > header {
display: none;
}
/* ===== 简易流程图 (纯 CSS 画, 不依赖 mermaid) =====
* markdown 里:
* <div class="flow">
* <div class="flow-box is-bad">…</div>
* <div class="flow-arrow">→</div>
* <div class="flow-box is-good">…</div>
* </div>
*/
section .flow {
display: flex;
flex-flow: row nowrap;
align-items: stretch;
gap: 0.6rem;
margin: 1.6rem 0 1rem;
}
section .flow-box {
flex: 1 1 0;
min-width: 0;
display: flex;
flex-flow: column nowrap;
justify-content: center;
padding: 0.7rem 0.9rem;
border: var(--tectonics-title-rule) solid var(--tectonics-accent);
border-radius: 8px;
background: #f2f7fc;
color: #1a1a1a;
font-size: 0.85em;
line-height: 1.35;
text-align: center;
}
section .flow-box.is-bad {
border-color: #9aa3ad;
background: #f5f6f7;
color: #6b7280;
}
section .flow-arrow {
flex: none;
display: flex;
align-items: center;
color: var(--tectonics-accent);
font-size: 1.3em;
font-weight: 700;
}
/* ===== mermaid 图 =====
* 由 tools/marp-mermaid-engine.mjs 在构建时把 ```mermaid 渲染成内联 SVG
*/
section .mermaid-diagram {
margin: 1.6rem 0 1rem;
}
section .mermaid-diagram svg {
display: block;
height: auto;
margin: 0 auto;
}
/* ===== 章节页的小节列表 (对应 design.4.png) =====
* 用法: 本页第一行加 _class 指令 steps, 正文写成有序列表:
* <!-- _class: steps -->
* ## 一、选题背景与意义
* 1. 研究背景
* 2. 研究现状
* 序号由主题生成成 01 02 03..., 呈蓝底白字的方块 + 灰底条
*/
section.steps {
--step-row-w: 600px; /* 整条宽度 (居中) */
--step-row-h: 56px; /* 每条高度 */
--step-gap: 54px; /* 条与条的间距 */
--step-badge-w: 172px; /* 左侧蓝块宽度 */
--step-badge-size: 26px; /* 蓝块里的数字字号 */
--step-label-size: 32px; /* 右侧文字字号 */
--step-label-pad: 32px; /* 文字距蓝块的间距 */
--step-bar-color: #e0e0e0; /* 灰底 */
--step-bar-color-label: #333333; /* 文字色 */
}
section.steps > ol {
width: var(--step-row-w); /* 整条宽度, 居中 */
margin: 24px auto 0;
padding: 0;
list-style: none;
counter-reset: step;
}
section.steps > ol > li {
position: relative;
display: flex;
align-items: center;
min-height: var(--step-row-h);
margin: 0 0 var(--step-gap);
padding: 0 var(--step-label-pad) 0 calc(var(--step-badge-w) + var(--step-label-pad));
background: var(--step-bar-color);
color: var(--step-bar-color-label);
font-size: var(--step-label-size);
font-weight: 400;
line-height: 1.2;
}
section.steps > ol > li:last-child {
margin-bottom: 0;
}
section.steps > ol > li::before {
counter-increment: step;
content: counter(step, decimal-leading-zero);
position: absolute;
top: 0;
bottom: 0;
left: 0;
width: var(--step-badge-w);
display: flex;
align-items: center;
justify-content: center;
background: var(--tectonics-accent);
color: #fff;
font-size: var(--step-badge-size);
font-weight: 700;
letter-spacing: 0.06em;
}
/* ===== 强调文字 =====
* markdown 里写成:
* <p class="point">…</p> 整段: 红色 + 居中 (问题 / 风险 / 需要强调的结论)
* <p class="key">…</p> 整段: 主色蓝 + 居中 (关键论点)
* <span class="red">…</span> 行内: 红色
* <span class="blue">…</span> 行内: 主色蓝
*/
section {
--tectonics-red: #c00000;
}
section p.point,
section p.key {
margin: 0.9rem 0 0;
font-size: 1.06em;
font-weight: 700;
line-height: 1.35;
text-align: center;
}
section p.point {
color: var(--tectonics-red);
}
section p.key {
color: var(--tectonics-accent);
}
section .red {
color: var(--tectonics-red);
}
section .blue {
color: var(--tectonics-accent);
}
/* ===== 密集内容: 表格/栏目内容偏多时, 整体缩一档字号 =====
* 用法: 用 div 包住要缩放的内容 (不要在 markdown 里写内联 style)
* <div class="tight"> …表格… </div> 缩到 0.85em
* <div class="tighter"> …表格… </div> 缩到 0.78em
*/
section div.tight {
font-size: 0.85em;
}
section div.tighter {
font-size: 0.78em;
}
/* ===== 代码块 =====
* 字号 60%, 无圆角, 打开自动折行, 字体用系统里的 Cascadia Code (Nerd Font 版)
* 注意: 主题元数据里 @auto-scaling 只保留 fittingHeader, 关掉了代码块的自动缩放 ——
* 否则内容会被放进 SVG 里按 max-content 排版, 长行只会被整体缩小而不折行。
*/
section :is(pre, marp-pre) {
font-family: "CaskaydiaCove Nerd Font Mono", "CaskaydiaCove Nerd Font",
"CaskaydiaMono Nerd Font Mono", var(--fontStack-monospace, monospace);
font-size: 60%;
line-height: 1.15;
padding: 20px 24px;
border-radius: 0;
white-space: pre-wrap;
overflow-wrap: anywhere;
}
section :is(pre, marp-pre) > code {
white-space: pre-wrap;
overflow-wrap: anywhere;
}