/* Shared PPT geometry. The page and video renderer both load these tokens. */

/* v0.33：中文改**宋体**，贴近原卷印刷体（原卷中文是宋体、公式是衬线斜体）。
   只作用于题面渲染面（PPT 卡片 / 题目录入的题面预览），应用外壳的按钮菜单仍是系统无衬线；
   数学公式由 MathJax 自带字体渲染，不受这里影响。
   字体栈按可用性回退：macOS 自带 Songti SC，Windows 有 SimSun，Linux 上若无中文字体则回落 serif。 */
.ppt-card, .ppt-question-area { font-family: "Songti SC", "STSong", "SimSun", "Noto Serif CJK SC", "Source Han Serif SC", serif; }
.ppt-card { container-type: size; --title-font: 1.484375cqw; --content-font: 1.484375cqw; --ppt-horizontal-pad: 2.2cqw; --ppt-inset-left-px: 0px; --ppt-inset-right-px: 0px; --ppt-inset-top-px: 0px; --ppt-inset-bottom-px: 0px; aspect-ratio: 16 / 9; background: #fff; border: 1px solid var(--line); border-radius: 10px; box-shadow: 0 4px 14px rgba(31, 41, 55, .06); overflow: hidden; }
/* v0.38：模板的「内容边距」四边内缩由 `--ppt-inset-*-px` 驱动，默认 0——未选模板、未调框
   （含全部存量课程）时下面所有 padding 的取值与 v0.37 完全一致。
   这四个变量由渲染侧按卡片**实测尺寸**写成 px（页面见 shared/ui/use-ppt-content-insets，
   视频见 renderFrames），**不用 cq* 也不用百分比**：
   - `.ppt-card` 带 container-type: size，元素不能做自己的容器，写在它身上的 cq* 会去量别的容器
     （实测页面版 1cqh = 3.39px，而卡片高 475px，底部内边距只剩应有的 71%）；
   - padding 百分比一律按**宽度**解析，纵向会差近一倍。
   **内缩加在内层（题干区 + 内容区）而不是卡片自身**：卡片是 flex 容器，给它内边距会先吃掉
   子元素的可用高度，内容再溢出到卡片外（实测正文被挤出卡片 76px）。加在内层则
   「正文区的边界」就是内缩后的边界，也正是「框内区域＝正文占位区」的口径。 */
/* v0.39 回归修正：四个 `--ppt-inset-*-px` 一律带 `0px` 兜底。
   它们只在渲染侧（页面 `.ppt-card` 的 use-ppt-content-insets / 视频帧内联样式）写进 DOM；
   题目录入预览的容器是 `.ppt-question-area`，没有 hook 可挂，若这里不兜底，
   `calc()` 里出现未定义的自定义属性会让**整条 padding 声明**在计算值阶段失效并回落到 0，
   表现为「题干贴到卡片边框上、题面预览的边距整个消失」（v0.38 起的真实回归，
   见 test/ui/question-area-margins.test.ts）。兜底值不影响渲染侧显式写入的 px。

   v0.39 同时修正左右内缩写反：padding 简写按 上 右 下 左 解析，`.ppt-headline` 与 `.ppt-content`
   原本把第 2 个值写成左内缩、第 4 个值写成右内缩，于是左右内容边距不对称的模板（模板框偏一侧）
   在页面与成片上会把左右留白对调。左右两侧一律「第 2 个值取右内缩、第 4 个值取左内缩」。 */
.ppt-headline { position: sticky; top: 0; z-index: 2; min-height: 20%; display: grid; grid-template-columns: minmax(0, 1fr) minmax(120px, 38%); column-gap: 1.4em; align-items: start; padding: .9em calc(var(--ppt-horizontal-pad) + var(--ppt-inset-right-px, 0px)) .8em calc(var(--ppt-horizontal-pad) + var(--ppt-inset-left-px, 0px)); margin: var(--ppt-inset-top-px, 0px) 0 0; /* v0.33：题目栏改白底——题图多为白底，浅蓝底会把题图的白底凸显成一块。 */
  background: #fff; border-bottom: 1px solid var(--line); font-size: var(--title-font); line-height: 1.42; text-align: left; }
.ppt-card .ppt-headline .math-text { display: block; font-size: 1em !important; font-weight: 400; }
.ppt-card .ppt-headline-main { grid-column: 1; min-width: 0; }
.ppt-card .ppt-headline-main .math-text { width: auto; min-width: 0; margin: 0; }
.ppt-card .ppt-headline-label .math-text { color: var(--muted); }
/* 选择题选项网格（无容器前缀的通用规则）：三种容器都要生效——PPT 页面 .ppt-card、
   题目录入预览 .ppt-question-area，以及视频帧 .video-frame .ppt-card。
   v0.32 回归教训：合并 CSS 时曾把这几条（页面上带 .ppt-card 前缀的版本）当成重复删掉，
   结果题目录入预览里选项退化成块级堆叠，标号与内容被拆成两行。 */
/* v0.49 题目区改渲染录入版式（`layout_html`）：单列承载，不再为右栏题图/表格留位。
   版式自带字号有两种来源（`.paper{font-size:16px}` 规则与内联 `font-size:15px`），
   `!important` 是必需的——否则内联那一种不受控，字号会跟着版式走、溢出题目区。
   题目带仍受 40% 上限约束（上下版式）；左右分栏页的左栏不上限。 */
.ppt-headline-question-layout { grid-template-columns: minmax(0, 1fr); }
/* 上下版式的题目带**按内容**占高：字号由产物按「题目高 + 板书高 ≤ 舞台高」解出，固定 40% 会把
   板书用不掉的空白白白留在下面（2026-10-10 验收反馈「字太小、底下板书还有很多空白」）。
   `overflow:hidden` 仅作兜底：真超了由视频帧的检查明确失败，不会静默裁掉题面。 */
.ppt-headline-question-layout:not(.ppt-headline-split) { height: auto; min-height: 20%; max-height: none; overflow: hidden; }
/* 字号写在容器上、由版式根继承：版式自带的绝对字号已在注入前去掉（`normalizeLayoutFontSize`），
   子元素一律用相对字号，因此不需要 `!important` 去打平它们。 */
.ppt-question-layout { min-width: 0; overflow: hidden; font-size: var(--question-font); width: var(--question-width, 100%); }

.ppt-headline-options { display: grid; gap: 2px 1.2em; align-items: start; margin-top: .35em; }
.ppt-headline-option { display: flex; min-width: 0; gap: .35em; align-items: baseline; }
.ppt-option-label { flex: none; font-weight: 600; color: #1e3a8a; }
/* 行内显示：覆盖上面 .ppt-headline .math-text 的 display:block，否则标号会与内容换行。 */
.ppt-headline-option .math-text { display: inline-block; min-width: 0; margin: 0; font-size: 1em !important; }

/* v0.40 图形选项：字母在上、图在下，图**按高度**等比缩放（选项简图多为细高形，按宽度缩会变得很小）。
   `max-width:100%` 保证不越出所在列；`object-fit: contain` 保证整图可见、不裁切。
   图高与 `shared/content/ppt-metrics.OPTION_FIGURE_HEIGHT`（100 设计单位 ≈ 5.3em）对应。 */
.ppt-headline-option.with-figure { flex-direction: column; align-items: center; gap: .15em; }
.ppt-option-figure { display: inline-block; width: auto; max-width: 100%; min-width: 0; height: 5.3em; object-fit: contain; object-position: center; margin: 0; }
/* 图形选项的字母按卷面惯例放在图的正下方居中（不带句点，与文字选项的「A．」区分）。 */
.ppt-headline-option.with-figure .ppt-option-label { text-align: center; }
/* 选项是图形时，题干区**不设高度上限**：40% 上限会把细高的选项图裁掉下半（实测物理 6 选项图被截断）。
   这是对 v0.33「题干区不得超 40%」的一处显式例外——选项是题面的一部分，宁可题干区变高。 */
.ppt-headline.has-figure-options { height: auto; min-height: 20%; max-height: none; overflow: visible; }

/* 选择题选项网格：优先 4 列，逐行排布，所有选项等宽、等高；与题干同排布在题干区（标题网格第 1 列）、紧贴题干、位于题图左侧；放不下时由排版层降为 2 列/1 列。 */
.ppt-card .ppt-headline-options { display: grid; gap: 2px 1.2em; align-items: start; margin-top: .35em; }
.ppt-card .ppt-headline-option { display: flex; min-width: 0; gap: .35em; align-items: baseline; }
.ppt-card .ppt-option-label { flex: none; font-weight: 600; color: #1e3a8a; }
.ppt-card .ppt-headline-option .math-text { display: inline-block; min-width: 0; margin: 0; font-size: 1em !important; }
/* v0.40 图形选项（带容器前缀的版本，与上面通用规则成对，见文件顶部 v0.32 的回归说明）。 */
.ppt-card .ppt-headline-option.with-figure { flex-direction: column; align-items: center; gap: .15em; }
.ppt-card .ppt-option-figure { display: inline-block; width: auto; max-width: 100%; min-width: 0; height: 5.3em; object-fit: contain; object-position: center; margin: 0; }
.ppt-card .ppt-headline-option.with-figure .ppt-option-label { text-align: center; }
.ppt-card .ppt-headline.has-figure-options { height: auto; min-height: 20%; max-height: none; overflow: visible; }
.ppt-card .ppt-headline:has(.question-header-visuals) { height: auto; min-height: 20%; max-height: 40%; overflow: hidden; }
/* v0.33：内嵌题图的题干区同样受 40% 上限约束（原先只有右栏题图那条选择器命中，
   内嵌页面无人兜底，实测水波题题干到 44%）。这里的上限是**兜底**：字号计算已经保证不超，
   真超了也让题干自身滚动，而不是把内容区挤没。 */
.ppt-card .ppt-headline-inline { height: auto; min-height: 20%; max-height: 40%; overflow-y: auto; }
/* v0.38：`.ppt-content` 必须**受高度约束并自己滚动**，页面与成片都是如此。
   改造前这条只在 video.ts 的 frameCss 里（选择器带 .video-frame），于是页面版的正文由内容
   自然撑高、直接把卡片顶破——表现为「设了底部边距但正文仍越过边距压住水印」。
   这里只放结构性约束（收在卡片高度内 + 内滚）；**字幕避让高度仍留在视频侧**
   （成片底部有字幕带，页面没有）。 */
.ppt-content { flex: 1 1 auto; min-height: 0; max-height: var(--ppt-content-max-height-px, none); overflow-y: auto; overflow-x: hidden; padding: .5em calc(var(--ppt-horizontal-pad) + var(--ppt-inset-right-px, 0px)) var(--ppt-inset-bottom-px, 0px) calc(var(--ppt-horizontal-pad) + var(--ppt-inset-left-px, 0px)); }
/* v0.55：回顾反思页没有题目区（`.ppt-card-no-question`），模板的上内缩改由内容区承担——
   有题目区时它是 `.ppt-headline` 的 margin-top，删了题面不能连模板边距一起丢。 */
.ppt-card-no-question > .ppt-content { margin-top: var(--ppt-inset-top-px, 0px); }
/* 固定图列形态：滚动交给图列旁的板书（同样是页面与成片共用）。 */
.ppt-figure-body { min-width: 0; height: 100%; min-height: 0; overflow-y: auto; overflow-x: hidden; }
/* 分栏页：题干在左栏内、内容在右栏内，纵向内缩由两栏各自的 padding 承担（不再用卡片 padding）。 */
.ppt-card-split > .ppt-inner-split { padding: var(--ppt-inset-top-px, 0px) var(--ppt-inset-right-px, 0px) var(--ppt-inset-bottom-px, 0px) var(--ppt-inset-left-px, 0px); }
/* v0.49：分栏页的横向内缩已由 `.ppt-inner-split` 的 padding 承担，题目栏不再吃第二遍。
   曾经两边都加：同一份题目版式在页面上比在成片帧里窄 6.6%，多折约 7% 的行——
   题目区字号按帧判定就会在页面上溢出（v0.49 实测）。 */
.ppt-card-split > .ppt-inner-split > .ppt-headline { margin: 0; padding-left: var(--ppt-horizontal-pad); padding-right: var(--ppt-horizontal-pad); }
.ppt-inner { font-size: var(--content-font); line-height: 1.5; }
.ppt-inner-single { display: block; }
.ppt-inner-double { display: flex; gap: 1.4em; }
.ppt-col { flex: 1; min-width: 0; }
.ppt-card .mapped-line { margin: 0; padding: 0; border: 0; border-radius: 6px; position: relative; font-size: 1em; line-height: 1.5; }
.ppt-card .mapped-line-sub { padding-left: 1.4em; }
.ppt-card .mapped-line-heading { margin: .3em 0 .2em; color: #1e3a8a; font-size: 1.2em; font-weight: 700; }
/* v0.44：页标题比正文小标题再大一级（同色系）——它是页面的标题，不是页内分块。 */
.ppt-card .mapped-line-page-title { margin: 0 0 .35em; color: #1e3a8a; font-size: 1.45em; font-weight: 700; }
.ppt-card .mapped-line-answer { font-weight: 600; }
.ppt-card .formula-block { margin: .1em 0; padding: 0; border: 0; background: transparent; font-size: 1em; line-height: 1.35; max-width: 100%; min-width: 0; overflow-x: auto; }
.ppt-card .formula-block mjx-container { max-width: 100%; line-height: 1.35 !important; overflow-x: auto !important; }
.ppt-card .formula-block mjx-container[display="true"] { margin: 0 !important; text-align: left !important; }
.ppt-card .rich-line { min-height: 0; }
/* 题干里的嵌套小问（(i)(ii)…）右缩进一级：题面预览（容器是 .ppt-question-area，没有 .ppt-card）、
   PPT 卡片、视频帧三处共用这一条，因此选择器不挂 .ppt-card 前缀。
   缩进量取 TEXTBOOK_PROFILES.question.level2IndentEm（1.8em），与题面原有层级口径一致；
   (1)(2)(3) 这类一级小问（level 1）仍顶格，不缩进。 */
.rich-line-level-2 { padding-left: 1.8em; }
.ppt-card .rich-spacer { height: .1em; min-height: 0; }
.ppt-card .rich-table { max-width: 100%; margin: .3em 0; overflow-x: auto; }
.ppt-card .rich-table .shared-table { border-collapse: collapse; min-width: 320px; }
.ppt-card .rich-table .shared-table td { border: 1px solid #98a2b3; padding: .18em .55em; text-align: center; }
.ppt-card .ppt-headline .rich-table { width: fit-content; max-width: 68%; }
.ppt-card .ppt-headline .rich-table .shared-table { min-width: 0; width: auto; font-size: max(12px, .78em); }
.ppt-card .ppt-headline .rich-table .shared-table td { padding: .12em .38em; }
.ppt-card .ppt-inner .rich-table { width: fit-content; max-width: 72%; }
.question-header-visuals { grid-column: 2; grid-row: 1; display: flex; align-items: flex-start; gap: 16px; width: 100%; height: auto; max-height: calc(40cqh - 1.7em); min-width: 0; min-height: 0; margin-top: 0; transform-origin: top right; overflow: visible; }
.question-header-figure { flex: 1 1 0; display: block; width: 100%; height: auto; max-width: min(100%, calc(100% * var(--figure-scale, 1))); max-height: min(calc(40cqh - 1.7em), calc((40cqh - 1.7em) * var(--figure-scale, 1))); min-width: 0; min-height: 0; object-fit: contain; object-position: top center; }
.question-header-table { flex: 1 1 0; width: 100%; height: auto; max-height: calc(40cqh - 1.7em); min-width: 0; min-height: 0; overflow: visible; display: flex; align-items: flex-start; justify-content: flex-start; }
.question-header-table .shared-table { display: table; width: auto; max-width: 100%; font-size: .92em; margin: 0; border-collapse: collapse; }
.question-header-table .shared-table td { border: 1px solid #98a2b3; padding: .35em .8em; text-align: center; }
/* 兼容旧缓存：历史 result 仍为 SVG 表格时按原尺寸缩放，避免放大溢出。 */
.question-header-table svg { display: block; width: 100%; height: auto; max-width: 100%; max-height: calc(40cqh - 1.7em); object-fit: contain; object-position: top center; }
.ppt-card .rich-heading { margin: .2em 0 .1em; color: #344054; font-size: 1em; font-weight: 700; }
.ppt-card .rich-list-item { display: flex; gap: .42em; align-items: flex-start; margin: .05em 0; }
.ppt-card .list-marker { color: var(--blue); font-weight: 700; }
.ppt-card .line-hidden { visibility: hidden; opacity: 0; }
.ppt-card .line-entering { opacity: var(--motion-progress, 1); transform: translateY(var(--motion-offset, 0)); }
.ppt-card .hl-group { display: flow-root; width: fit-content; max-width: 100%; padding: 0 .18em; border-radius: 6px; background: rgba(239, 246, 255, var(--highlight-progress, 1)); box-shadow: 0 0 0 2px rgba(147, 197, 253, var(--highlight-progress, 1)); }

/* ===== v0.32 题图内嵌与长题干左右分栏 =====
   以下是 PPT 几何的**唯一真源**：网页端（globals.css @import 本文件）与视频渲染页
   （frameCss + 本文件）都从这里取规则。新增几何只允许写在这里，否则会出现
   「页面一个样、成片另一个样」而不报错。 */

/* v0.46：题目录入页在题图右侧加一组按钮（大小 / 上传替换 / 调整裁切）。
   PPT 页面与视频帧不传这组节点，所以这两个类不会出现在成片里。 */
.question-inline-figure { display: flex; align-items: center; gap: 8px; }
.question-figure-actions { display: flex; flex-direction: column; gap: 6px; flex: 0 0 auto; align-items: stretch; }

/* 内嵌在题干段落之间的题图：整行、宽度吃满题干区、保持原始宽高比。
   与右栏题图（.question-header-visuals 里的 .question-header-figure）互斥：
   同一张图只会走其中一条路径。 */
.question-header-figure-inline { display: block; width: 100%; max-width: min(100%, calc(var(--figure-inline-width, 100%) * var(--figure-scale, 1))); height: auto; margin: .35em auto; object-fit: contain; object-position: center top; }

/* 带内嵌题图的题干：不再为右栏预留列，整行铺满，题图与文字同处一条流。 */
.ppt-headline-inline { display: block; }
.ppt-headline-inline .ppt-headline-main { width: 100%; }

/* 左右分栏：题干与选项在左栏（40% 宽），本页内容在右栏（60% 宽），两栏等高。
   栏宽用百分比表达，页面与视频卡片都带 container-type，所以 cqw 字号在两处都正确。 */
.ppt-headline-split { display: flex; }
.ppt-card .ppt-headline-split { position: static; min-height: 0; max-height: none; height: auto; overflow: hidden; }
.ppt-headline-split .ppt-headline-main { width: 100%; }
.ppt-card .ppt-content-split { flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; }

/* 分栏页的题干与内容由 .ppt-card 内的两栏网格承接；左栏（题目区）自己滚动。
   高度上限仍是卡片高度（不是 40%）——40% 只是「进不进分栏」的判据，不是分栏后的容器高度。 */
.ppt-card-split { display: flex; flex-direction: column; }
.ppt-card-split > .ppt-inner-split { flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: minmax(0, 40%) minmax(0, 1fr); column-gap: 1.4em; align-items: stretch; }
.ppt-card-split > .ppt-inner-split > .ppt-headline { min-height: 0; height: auto; max-height: 100%; overflow-y: auto; overflow-x: hidden; background: transparent; }
/* v0.35：左右版式**两栏一律顶部对齐**。
   左栏：题干在分栏页从栏顶开始排（上下版式仍保留题干区内的垂直居中，见 globals.css 的
   `.ppt-card .ppt-headline { align-content:center }`，这里的规则只作用于分栏页）。
   右栏：板书也从栏顶开始排；v0.33 曾经的「短内容垂直居中」按验收反馈取消——同一门课、同一版式下
   两栏的起始位置必须一致，短内容下方留白是接受的代价。 */
.ppt-card-split > .ppt-inner-split > .ppt-headline { align-content: start; }
/* v0.33：左右分栏之间加一条分割线。
   只画在**右栏左缘**（录入预览的左右布局没有右栏，因此不会出现一条悬空的竖线）；
   用负 margin + 等量 padding 把线推进栏间距正中，分隔感更自然。 */
.ppt-card-split > .ppt-inner-split > .ppt-content-split { border-left: 1px solid var(--line); margin-left: -0.7em; padding-left: calc(0.7em + .5em); }
/* 分栏页的右栏板书：顶部对齐、内容比栏高时可滚动（两栏都从栏顶排布）。 */
.ppt-card-split > .ppt-inner-split > .ppt-content-split { display: flex; flex-direction: column; justify-content: flex-start; }

/* ===== v0.35 讲解配图的两种形态 =====
   讲解配图的几何同样只有这一份真源：页面（React）与视频渲染页都从这里取规则。
   形态由排版产物的 `figure.form` 给出，CSS 不判定版式，只按类名套用几何。 */

/* 形态一：固定图列（上下版式）——下栏左边放图、右边板书单栏。
   图列比例由 `--figure-ratio`（占**内容区宽**的百分比）给出。
   注：视频渲染页的 frameCss 只覆写尺寸与滚动行为（贴顶、右栏内滚），网格模板只写在这里。 */
.ppt-inner-figure { display: grid; grid-template-columns: var(--figure-ratio, 36%) minmax(0, 1fr); column-gap: 1.4em; align-items: start; }
.ppt-figure { width: 100%; min-width: 0; }
.ppt-figure-body { min-width: 0; }

/* 形态二：右上角浮动配图（左右分栏页）——板书文字环绕。
   宽度基准是**整页宽**：`.ppt-card` 是尺寸容器，所以 `cqw` 就是卡宽，
   30cqw 在 1920×1080 帧里恰为 576px、在任何缩放后的页面上都保持 30% 页宽。
   浮动块必须待在内容流里（`.ppt-content` 的 BFC 会把它的高度算进滚动高度），
   不得再给它 `overflow:hidden` 的祖先——否则图会被裁掉。 */
.ppt-figure-float { float: right; width: var(--figure-float-width, 30cqw); max-width: 100%; margin: 0 0 .5em 1em; }
.ppt-figure-float img { display: block; width: 100%; height: auto; }
.ppt-figure-float .figure-image { width: 100%; height: auto; }
.ppt-figure-float .figure-frame { width: 100%; }

/* ─────────── 录入版式（layout_html）的容器与包裹层补偿 ───────────
   这些规则原本只在工作台的 globals.css 里，于是讲稿页与成片（只加载本文件）拿不到补偿：
   图被本仓包了一层 .ql-figure 后不再是 [data-row] 的直接子元素，服务那条 `[data-row]>img`
   不再命中，图按自己的 cqw 宽度撑出格子、压到下一个选项标号上（v0.47 起在题目环节已修，
   v0.49 版式进成片后在三处都要生效——所以搬到页面与成片共用本文件）。 */
.question-layout-html { color:#1f2733; font-size:15px; line-height:1.65; margin:0 0 8px; overflow-x:auto; }
.question-layout-html p { margin:0 0 7.5px; }
.question-layout-html img { max-width:100%; height:auto; cursor:pointer; }
/* v0.47：版式里的图由本仓托管交互——hover 才出右侧按钮列，不占版面、不放提示语。 */
.question-layout-html .ql-figure { position:relative; display:inline-block; max-width:100%; }
/*
 * v0.48：图被我们包了一层 `.ql-figure`（挂 hover 按钮与框选标记），img 因此不再是 `[data-row]` 的
 * **直接**子元素——服务那条 `[data-row]>img{flex:0 0 auto}` 不再命中，图会被当作与选项标号同级的等分列，
 * 图形选项就变成「A.」在自己那列、图在下一列，两者被整行撑开（2026-10-10 验收反馈）。
 * 把包裹层按「它替换掉的那个 img」同口径处理：不吃 flex 伸缩，宽度由图自己的 cqw 决定。
 */
.question-layout-html [data-row] > .ql-figure { flex:0 0 auto; }
/*
 * 同一行里的文本标号（图形选项的 `A.` `B.` `C.` `D.`）也收回自身宽度：服务的 `[data-row]>*{flex:1 1 0}`
 * 是为「等分列」设计的，图形选项行里它会把「A.」撑成一整列，标号与图之间隔着半列空白。
 * 只作用于**含包裹图的那些行**，并排除 `[data-text]`（那种单元格要占满剩余宽度，服务另有规则）。
 */
.question-layout-html [data-row]:has(> .ql-figure) > div:not([data-text]) { flex:0 0 auto; }
/* 独图行（整行只有一张图）要保住既有观感：包裹层仍铺满整行，图靠服务给它的 auto margin 居中/靠左。 */
.question-layout-html [data-row] > .ql-figure:only-child { flex:1 1 auto; }
.question-layout-html .ql-figure-actions { position:absolute; right:6px; top:6px; display:none; flex-direction:column; gap:6px; align-items:stretch; }
.question-layout-html .ql-figure:hover .ql-figure-actions { display:flex; }

/* 同时带 `.ppt-question-layout` 时（讲稿页 PPT 卡片与视频帧），容器几何以题目区为准：
   字号由产物给、不横向滚动、不留段落外边距、图不可点（成片里没有框选入口）。 */
.ppt-question-layout.question-layout-html { font-size: var(--question-font); overflow: hidden; margin: 0; }
.ppt-question-layout.question-layout-html img { cursor: default; }
