/* ============================================================================
   report.css — 报告版式系统 v1（Report Design System）
   ============================================================================

   🔴 它**不是**什么（边界写清楚，免得被当成万能模板）
   ---------------------------------------------------------------------------
     不是 CMS / 不是出版引擎 / 不是「传个 Markdown 就出 PDF」的黑箱。
     它只负责**一件**事：把"有结论、有数据、有出处"的内容排成能读、
     且能被人逐条核对的样子。

   🔴 它**是**什么
   ---------------------------------------------------------------------------
     ① 一份**共享基础**：字体角色、正文行长、页面网格、间距层级、
        图表/表格说明、来源脚注 —— 六种东西，六种写法，一次定好
     ② 一个**科研 / 技术报告 profile**：图与表自动编号、章节可编号
     ③ 三套**版式**：杂志编辑 / 科研技术 / 金融研究
        每套都有自己的取舍，README.md 里逐条写明"它放弃了什么"

   🔴🔴 本轮**明确不做**（不要当成"还没实现"）
   ---------------------------------------------------------------------------
     · 分页 PDF / 印刷分页（页眉页脚、页边距、跨页不断行、孤行寡行控制）
       ⇒ 那是**独立目标**：它需要 @page / 实物打样 / PDF 引擎验证，
          本文件一行都没有写，也不假装支持。
     · 自动目录、脚注尾注、交叉引用、参考文献样式（BibTeX 之类）
     ⇒ 现在能给的只有 @media print 的**最小可读保障**
       （去掉屏幕专属装饰、表格与图表不跨撕裂），那是"不更糟"，不是"能出版"。

   依赖：01-tokens/tokens.css（颜色、间距、字号、行长全部走令牌）
   用法：ES3 级 CSS，零运行时依赖，纯样式
   ========================================================================== */

/* ==========================================================================
   一 · 共享基础（三套版式共用，profile 只改变量与少数特性）
   ========================================================================== */

.rep {
  /* --------- 六个可变量：改这六个就能换一套版式 --------- */
  --rep-measure: var(--measure-prose);   /* ① 正文行长：整套系统最关键的一个数 */
  --rep-body-fs: var(--fs-base);         /* ② 正文字号（金融版会往下压） */
  --rep-title-fs: var(--fs-2xl);         /* ③ 标题字号 */
  --rep-lead-fs: var(--fs-lg);           /* ④ 导语字号 */
  --rep-body-lh: var(--lh-base);         /* ⑤ 行距 */
  --rep-sec-num: '';                     /* ⑥ 章节是否编号（''= 不编号） */

  font-family: var(--sans);
  color: var(--text-primary);
  font-size: var(--rep-body-fs);
  line-height: var(--rep-body-lh);
  max-width: 100%;

  /* 🔴 边注列宽必须**在这里就地**收窄，不能沿用 --measure-aside（32em）。
     把账算给自己看：库的标准页宽 `--measure-page` = 832px，
     而正文 + 边注 + 间距 **共享这 832px**。取 32em(=576px) 当边注时，
     正文只剩 832 − 576 − 36 = **220px ≈ 12em**（一行 12 个字，读不了）。
     ↑ 这是实测值不是推测：门禁里有一条判据专门盯这个数。
     ⇒ 边注定为 **14em**：832 − 252 − 36 = 544px ≈ **30em**，正文这一档才立得住。
     代价：**14em 装不下大图表** ⇒ 大图请放进正文流里出血，别塞进边注。 */
  --measure-aside: 14em;
}

/* --------- 字体角色：六种，不多不少 ---------
   ⭐ 为什么钉死六种：报告里每多一种"自创角色"，读者的解读负担就多一分。
      发现自己在写第七种时，应该回头用**结构**（列表、表格、引用）而不是字号表达。 */
.rep__kicker,          /* 眉题 / 栏目名 */
.rep__meta,            /* 作者 · 日期 · 版本 */
.rep__cap,             /* 图表说明 */
.rep__source,          /* 来源脚注 */
.rep__note,            /* 编者注 / 译者注 */
.rep__risk {           /* 风险 / 合规披露 */
  font-size: var(--fs-xs);
  color: var(--text-secondary);
  line-height: var(--lh-base);
}

/* 🔴🔴 专门写成 `.rep .rep__title`（0,2,0）而不是 `.rep__title`（0,1,0）：
      下面是一个世纪的坑 —— 后文的 `.rep h2` / `.rep h3` 是 (0,1,1)，
      **单类名选择器会被它们压过去**。写成一层类是不够的，必须靠 descendant 提权，
      否则 `--rep-title-fs` 这个「换版式的关键变量」会静默失效，标题被钉死在 fs-lg。
      （实测取证：三套 profile 的标题都变成同一个 24px，变量一个都没生效。） */
.rep .rep__title {
  font-size: var(--rep-title-fs);
  line-height: var(--lh-tight);
  letter-spacing: -0.01em;
  max-width: var(--measure-title);       /* 标题比正文窄：大字长时间扫视会累 */
  margin: var(--sp-2) 0 0;
  font-weight: 700;
}

.rep__kicker {
  margin: 0;
  color: var(--text-tertiary);
  font-weight: 600;
  letter-spacing: .06em;
}

.rep__standfirst,                        /* 导语 / 摘要首段 */
.rep__lede {
  font-size: var(--rep-lead-fs);
  line-height: var(--lh-loose);
  max-width: var(--measure-lede);
  color: var(--text-secondary);
  margin: var(--sp-3) 0 0;
}

.rep__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1) var(--sp-3);
  margin: var(--sp-3) 0 0;
  padding: 0;
  list-style: none;
  color: var(--text-tertiary);
}

/* --------- 页面网格：正文 + 边注 ---------
   🔴 `minmax(0, 1fr)` 不是笔误：`1fr` 的最小值是 `auto`，
      遇到宽表格会把整页撑出横向滚动条（本库踩过，analysis-report 里写明了）。 */
.rep__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-4);
  margin-top: var(--sp-5);
}

@media (min-width: 62rem) {
  .rep__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, var(--measure-aside));
    gap: var(--sp-6);
    align-items: start;
  }
}

/* --------- 行长：施加在**内容块**上，不是施加在列容器上 ---------
   🔴 为什么不能在 .rep__body 上压 max-width（0.11.2 改）
      容器一压，任何子元素都不可能比它更宽 —— 于是 `.rep__fig--wide`
      （README 里写着"大图请放进正文流"）**永远是个空类**：
      `max-width:none` 对一个本来就比父容器窄的元素毫无作用。
      实测：金融版行长 30em@14px = 420px，1800 宽的折线图被压到 420px，
      刻度字缩到 6px。当时是靠"把 --rep-measure 改成 50em"绕过去的，
      那等于**把整页正文也放宽** —— 用错误换错误。
   ⇒ 正确做法：行长逐块施加（这也是 tokens.css 里 h1/p 的既有写法）。
      文字保持 30em，图/表默认跟行长，加 `--wide` 才用满正文列。
   ⚠️ 只施加在 **font-size = 基准** 的块上：`30em` 里的 em 跟着**元素自身**
      字号走，套到 h2（1.5rem）上会静默变成 30×1.5rem=720px。
      标题本来就由 `--measure-title` 管，这里不重复。 */
.rep__body { max-width: none; }

.rep__body p,
.rep__body ul,
.rep__body ol,
.rep__body dl,
.rep__body .rep__fig,
.rep__body .table,
.rep__body .kf,
.rep__body .accordion,
.rep__body .rep__note,
.rep__body .rep__risk,
.rep__body .rep__keyline { max-width: var(--rep-measure); }

/* ⭐ 宽图 / 宽表通道：唯一的开关。
   默认跟行长（读者不必左右甩头），需要看清细节时才用满正文列。
   ⚠️ 它只放宽到**正文列**为止，不越过边注 —— 越过边注是整页版式的事，
      不是一张图的事。
   🔴 特异性必须写成 `.rep__body .rep__wide`（0,2,0）而不是裸类（0,1,0）：
      上面那条压缩正文的规则是 0,2,0，裸类压不过它 ——
      **加了 class 却没生效**，是比没有这个 class 更难查的一种失败。
      （实测：写成裸类时 `.rep__fig--wide` 的量出来还是 420px。） */
.rep__body .rep__fig--wide,
.rep__body .rep__wide { max-width: none; }
.rep__aside { color: var(--text-secondary); }

/* --------- 间距层级：五级，全部走令牌 ---------
   section > figure > paragraph。**层级之间用间距表达**，不靠加分割线。 */
.rep__sec { margin-top: var(--sp-7); }
.rep__sec > :first-child { margin-top: 0; }

/* --------- 小节标题：只支持两级（h2 用作文章标题，h3 用作小节）---------
   🔴 为什么钉死两级：报告里出现第四级标题，通常意味着该拆的是**文档**，
      而不是再给一级字号。这里刻意**不给 h4 及更深层级写任何规则** ——
      没定义就是没定义，不要靠浏览器默认值蒙混过去。 */
.rep h2 {
  font-size: var(--fs-xl);
  line-height: var(--lh-tight);
  margin: 0 0 var(--sp-3);
  max-width: var(--measure-title);
}

.rep h3 {
  font-size: var(--fs-lg);
  line-height: var(--lh-tight);
  margin: var(--sp-5) 0 var(--sp-2);
}

.rep__body p { margin: 0 0 var(--sp-3); }
.rep__body p:last-child { margin-bottom: 0; }

/* --------- 图表与表格的说明：说明不是装饰，是**可核对性** ---------
   ⭐ 一条说明必须回答三件事：这是什么、数从哪来、有没有被处理过。
      三件事少一件，这张图就没法被别人复核。 */
.rep__fig {
  margin: var(--sp-5) 0;
  padding: 0;
}

/* 🔴 图必须被容器约束（内容不许溢出）。
   `.prose img` 早有这三条，`.rep__fig` 漏了 ⇒ 1920px 截图在纸上按原始像素铺开、
   溢出页面（2026-11-06 实体打样实测）。取证见 CHANGELOG 0.27.4。 */
.rep__fig img,
.rep__fig > svg,
.rep__fig > picture > img {
  max-width: 100%;
  height: auto;
  display: block;
}

/* 包表格的图容器：表题在上、表在中间、脚注在下。
   🔴 它存在的主要理由是**分页**（见下方 @media print），但类本身必须在
      打印块之外有定义 —— 否则 `print-policy-gate` 的 L0 会判"隐藏了一个
      库里不存在的东西"，而那正是过去 .overlay 那个 bug 的形状。
   屏幕上它与 `.rep__fig` **完全一致**（连块距都不改）—— 这个修饰符只表达
   一件事：纸上允许断页。任何屏幕差异都会让"加它只是为了分页"变得含糊。 */
.rep__fig--table {
  margin: var(--sp-5) 0;
}

/* 🔴 表题必须跟着表走：父容器 allow-break 后，表题会被留在上一页、表格推到
   下一页（读者先看到「表 1 · …」翻页才有表）。break-inside 管不了兄弟块。
   放 print 块外是因为 break-* 只对分页生效 —— 顺带免一条 printPolicy 认领。 */
.rep__fig--table > .rep__cap--table { break-after: avoid; }

.rep__cap {
  margin: var(--sp-2) 0 0;
  /* 🔴 technical profile 会在这里加"图 N ·"前缀（见下） */
}

.rep__source {
  margin: var(--sp-2) 0 0;
  padding: var(--sp-2) 0 0;
  border-top: 1px solid var(--border-decor);
  color: var(--text-tertiary);
}

.rep__source ol,
.rep__source ul { margin: var(--sp-1) 0 0; padding-inline-start: 1.4em; }
.rep__source li { margin-bottom: var(--sp-1); }

/* --------- 来源脚注（整篇）：列编号，方便别人按号去查 --------- */
.rep__sources { margin-top: var(--sp-7); }

/* ==========================================================================
   二 · profile：科研 / 技术报告
   --------------------------------------------------------------------------
   启用的两件事：**图/表自动编号** + **章节编号**。
   代价：正文行长被压到最窄、行距最松 —— 这是故意的，
   技术报告的正确读法是被逐段核对，不是被快速通读。
   ========================================================================== */

.rep--technical {
  --rep-measure: var(--measure-prose);
  --rep-body-lh: var(--lh-loose);
  --rep-sec-num: counter(rep-sec, decimal) ' · ';
  counter-reset: rep-sec rep-fig rep-tab;
}

/* 🔴 只对**正文小节**编号，不编号文章标题（`h2.rep__title`）、也不编号
      边注与来源区。写成 `.rep__sec > h3` 而不是 `h3`：前者表达的是
      「属于正文的一个小节」，后者会把边注里的「关键读数」也算成第几节。 */
.rep--technical .rep__sec > h3::before {
  content: var(--rep-sec-num);
  counter-increment: rep-sec;
  color: var(--text-tertiary);
  font-variant-numeric: tabular-nums;
}

.rep--technical .rep__cap::before {
  content: '图 ' counter(rep-fig) ' · ';
  counter-increment: rep-fig;
  font-weight: 600;
  color: var(--text-tertiary);
  font-variant-numeric: tabular-nums;
}

/* 表格说明单独一路计数：图 3 和表 3 不是同一个东西 */
.rep--technical .rep__cap--table::before {
  content: '表 ' counter(rep-tab) ' · ';
  counter-increment: rep-tab;
}

/* ==========================================================================
   三 · profile：杂志 / 编辑向
   --------------------------------------------------------------------------
   取舍：行长放宽（读起来快）、标题最大、允许跨栏出血的宽图与引语块。
   **不给图编号**（编号是技术文档的语法，放在这里只会打断阅读节奏）。
   ⇒ 代价：不适合承担审计级追溯。要追溯请换 technical。
   ========================================================================== */

.rep--magazine {
  --rep-measure: 42em;
  /* 刻意**不改** --rep-title-fs：基础值（fs-2xl）已经是三套里最大的一档，
     杂志版的气口在「行长放宽 + 导语放大 + 出血图」三处，不在标题字号。
     🟡 上一版这里把 fs-2xl 抄了一遍 = 与基础值重复，删掉：重复的声明
        会让人误以为「杂志版专门调过标题」，实际调是没调。 */
  --rep-lead-fs: var(--fs-xl);
}

/* 🟡 删掉 `.rep--magazine .rep__fig--wide { max-width: none }`（0.11.2）：
   它注释写着"出血：图可以比正文宽"，但当时正文列整体被压到 42em，
   子元素再宽的 max-width 也越不过父容器 ⇒ 这条规则**从来没有生效过**。
   现在宽图通道在基础层统一实现（见上方 `.rep__fig--wide, .rep__wide`），
   三个 profile 共用，不需要每套再写一遍。 */

/* 🔴 为什么这里保留彩色竖条（0.8.4 · 全库竖条政策）
   本库整体立场是去掉纯装饰竖条（见 typography.css 的删除记录）。
   引语块是**例外**，因为竖条在这里是**内容标记**：
   "这是摘出来的原话"，与 `.prose > blockquote`（content.css）同一个惯例。
   去掉它，引语就只是"字号大一点的正文"，读者要靠缩进猜它是引的。 */
.rep__pull {
  margin: var(--sp-5) 0;
  padding-inline-start: var(--sp-4);
  border-inline-start: 3px solid var(--accent);
  font-size: var(--fs-xl);
  line-height: var(--lh-tight);
  color: var(--text-primary);
  max-width: var(--measure-pull);
}

/* ==========================================================================
   四 · profile：金融研究
   --------------------------------------------------------------------------
   取舍：字号与行距往下压 ⇒ 一屏塞得下更多数字；
        正文列更窄 ⇒ 读者能在数字和文字之间快速来回。
   **必须有风险披露区** —— 没有它的研究报告是不完整的作品。
   ⇒ 代价：不适合长论证。超过两屏的推理在这里会被读者跳过。
   ========================================================================== */

.rep--finance {
  --rep-measure: 30em;
  --rep-body-fs: var(--fs-sm);
  --rep-body-lh: var(--lh-base);
  --rep-title-fs: var(--fs-xl);
}

/* 关键数字条：整篇的结论先摆在前面（AI 和人都先看这行） */
.rep__keyline {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: var(--sp-3);
  margin: var(--sp-4) 0;
  padding: var(--sp-3);
  background: var(--surface-sunken);
  border-radius: var(--r-md);
}

.rep__keyline dt {
  font-size: var(--fs-xs);
  color: var(--text-tertiary);
  margin: 0;
}

.rep__keyline dd {
  margin: var(--sp-1) 0 0;
  font-size: var(--fs-lg);
  font-weight: 700;
  font-variant-numeric: tabular-nums;   /* 数字要能竖着比 */
}

.rep__risk {
  margin-top: var(--sp-5);
  padding: var(--sp-3);
  border: 1px solid var(--border-decor);
  border-radius: var(--r-md);
  color: var(--text-secondary);
}

.rep__risk strong { color: var(--text-primary); }

/* ==========================================================================
   五 · 打印：只做"不更糟"，**不做分页**
   --------------------------------------------------------------------------
   ⚠️ 这是本轮对打印的全部承诺：**去掉屏幕专属装饰**、
      **图表与表格不跨撕裂**。关于 @page / 页眉页脚 / 页码 / 跨页控制，
      本版本一律不管 —— 那是独立的"分页 PDF"目标。
   ========================================================================== */
@media print {
  .rep__aside { display: none; }          /* 屏幕边注在纸上没地方放 */
  .rep__grid { display: block; }
  .rep__fig,
  .rep table { break-inside: avoid; }
  /* 🔴 包表格的图容器不要整块 avoid。
     表格自己有行级 avoid（`tr`）+ 表头重复（`thead`），已经能安全跨页；
     整块 avoid 的代价是**放得下的表也被推到下一页**：实测 p1 余 200pt、
     表只有 179pt，仍然整块跳到第 2 页，留一页空白。
     用户侧写法：`<figure class="rep__fig rep__fig--table">`。 */
  .rep__fig--table { break-inside: auto; }
  .rep__pull { border-inline-start-width: 2px; }
  /* 孤行寡行：段首/段尾不要只留一行在另一页。
     ⚠️ 必须带 `.rep` 前缀 —— 裸 `p` / `li` 会改掉宿主页面所有段落，
        那是 `bleed-gate` 的硬红线（组件只影响自己）。
     其他配方 / 使用者的页面要这一条，自己写同样的三行即可。 */
  .rep p, .rep li, .rep blockquote { orphans: 2; widows: 2; }

  /* --------- 图框：纸面必须是一条实线 ---------
     🔴 2026-11-06 实体打样：图框用 `--border-decor` + 0.5pt，纸上几乎不可见。
        原因不是"颜色浅"，是**覆盖率**：0.5pt 在 600dpi 下只有 4 个点厚，
        73% 覆盖 ⇒ 每 4 个点留 1 个白点 ⇒ 打出来是半色调虚边。
        0.7pt + #b5bcc3（52%）更糟，等于没有。

     所以图框走 `--rule-hair`（纸面纯黑，100% 覆盖），并且：
       · 用 `outline` 不用 `border` —— border 会撑大盒子，100% 宽的图会溢出
       · 0.5pt 是下限：再细的线在激光上会被纸纹吃掉
       · 只限 `.rep__fig` 内的图，不改宿主页面里的裸 `img`（bleed-gate 红线） */
  .rep__fig img,
  .rep__fig > svg,
  .rep__fig > picture > img {
    outline: 0.5pt solid var(--rule-hair);
    outline-offset: 0;
  }
}
