475 lines
13 KiB
CSS
475 lines
13 KiB
CSS
/*!
|
|
* 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;
|
|
}
|