/* ============================================================================
   agentcss / 03-patterns / content / content.css
   内容渲染样式 —— 接管 CommonMark / GFM 的标准输出

   依赖：01-tokens/tokens.css
   版本：A ✅ / B ✅ / C ✅

   🔴 本文件最重要的设计决定：**不发明任何类名**。

      结构由渲染器（CommonMark / GFM 规范）决定，
      样式由本文件按**元素选择器**接管。
      所以从任何 CommonMark 兼容渲染器拿到的 HTML，
      **不需要任何后处理**就能正确显示。

      只有一个自定义类名：`.prose` —— 用于限定作用域。
      它不改变任何语义，只是"这块是正文"的标记。

   依据：本文件顶部列出的渲染约定
   ========================================================================= */

.prose {
  /* 正文行长：走语言感知令牌。
     🔴 0.8.9 修（外部审计 P0-1b 发现）：原来这里硬写 `max-width: 68ch`，
        而 68ch 是 tokens.css 里**拉丁语系**那一档的值
        （中文下 --measure-prose 是 34em，拉丁下才是 68ch）
        ⇒ 中文读者拿到的是拉丁的行宽，正文一行太长，扫视吃力。
        ⇒ measure-gate 把扫描范围从 *.html 扩到 *.css 之后
           才第一次看见这处硬写。 */
  max-width: var(--measure-prose);
  color: var(--text-primary);
}

/* ---------------------------------------------------------------- 元素间距
   用兄弟选择器统一控制，不给每个元素写 margin。
   这是"接管"的正确姿势 —— 渲染器不排版，排版归我们。 */
.prose > * + * { margin-top: var(--sp-4); }

/* ---------------------------------------------------------------- 标题
   结构必须是 <h1>-<h6>，不能是 <div class="heading">。
   层级不跳级由 a11y.py 门禁检查。 */
.prose > h1,
.prose > h2,
.prose > h3,
.prose > h4,
.prose > h5,
.prose > h6 {
  font-family: var(--sans);
  font-weight: 500;
  line-height: var(--lh-tight);
  letter-spacing: -0.008em;
  margin: var(--sp-7) 0 0;
}
.prose > h1 { font-size: var(--fs-2xl); margin-top: 0; }
.prose > h2 {
  font-size: var(--fs-lg);
  padding-top: var(--sp-5);
  border-top: 2px solid var(--accent);
  /* 短线段 + 通栏细线：既有分隔又不像卡片那样"框住" */
  max-width: 92%;
}
.prose > h3 { font-size: var(--fs-md); }
.prose > h4, .prose > h5, .prose > h6 {
  font-size: var(--fs-base);
  color: var(--text-secondary);
}

/* ---------------------------------------------------------------- 段落与行内 */
.prose > p { margin: 0; line-height: 1.75; }

/* 行内代码：衬线底 + 细边
   ⚠️ 中文正文里的 `code` 通常是函数名/参数名，用等宽更清楚。 */
.prose > code,
.prose > li > code,
.prose > td > code,
.prose > th > code {
  font-family: var(--mono);
  font-size: 0.88em;
  background: var(--surface-sunken);
  border: 1px solid var(--border-decor);
  border-radius: 3px;
  padding: 0.05em 0.3em;
}

/* 🔴 代码块内的 <code> 必须排除行内样式。
   CommonMark 两种代码块都输出 <pre><code>，不排除的话
   代码块里的每行都会带上行内代码的边框和底色。 */
.prose > pre > code,
.prose > pre {
  font-family: inherit;
  font-size: inherit;
  background: none;
  border: none;
  padding: 0;
  border-radius: 0;
}

/* ---------------------------------------------------------------- 列表
   CommonMark 的嵌套列表是 <li> 内直接嵌 <ul>，靠缩进表达层级。 */
.prose > ul,
.prose > ol { padding-inline-start: 1.5em; margin: 0; }
.prose > ul { list-style: disc; }
.prose > ol { list-style: decimal; }
.prose li + li { margin-top: var(--sp-2); }
.prose li > ul,
.prose li > ol { margin-top: var(--sp-2); }
.prose li > ul { list-style: circle; }   /* 二级用空心圆，三级会自动变方块 */

/* ---------------------------------------------------------------- 引用
   CommonMark 输出 <blockquote><p>…</p></blockquote> */
/* 🔴 为什么这里**保留**竖条（0.8.4 · 全库竖条政策）
   本库的整体立场是「去掉纯装饰的竖条」（见 typography.css / form-validation.css
   各自的删除记录）：竖条在页面上拉出一条与内容无关的硬边。
   ⇒ 但**引语与代码块是例外**，因为它们的竖条是**内容属性**、不是装饰：
     · 引语 = "这是别人说的话" → 竖条是引用边界的视觉标记，
       与学术排版的惯例一致，读者已经建立这个预期
     · 代码块 = "这是原文"→ 同理，与 Markdown/Pandoc 的渲染结果一致
   去掉它们，用户反而要靠缩进去猜"这段是引的还是正文"。*/
.prose > blockquote {
  margin: var(--sp-5) 0;
  padding: 0 0 0 var(--sp-4);
  border-inline-start: 3px solid var(--accent);
}
.prose > blockquote > p {
  color: var(--text-secondary);
  font-size: var(--fs-md);
  line-height: 1.6;
}
/* 引用里再套引用 */
.prose > blockquote > blockquote { margin: var(--sp-3) 0; }

/* ---------------------------------------------------------------- 代码块
   两种都输出 <pre><code>；围栏的带 class="language-xxx"，缩进的不带。
   🔴 不给缩进代码块硬加 class —— 规范说它没有。 */
/* 🔴 同上：代码块保留竖条的理由见上方 .prose > blockquote 的注释
   （竖条在这里表示"这是原文"，属内容标记而非装饰）。*/
.prose > pre {
  margin: 0;
  padding: var(--sp-4);
  background: var(--surface-sunken);
  border-inline-start: 3px solid var(--border-decor-str);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  overflow-x: auto;
  font-family: var(--mono);
  font-size: var(--fs-xs);
  line-height: 1.6;
  tab-size: 4;
  -webkit-overflow-scrolling: touch;
}
/* 缩进代码块没有左边框语言标记，给个更淡的，暗示"这是次要代码" */
/* 🔴 逻辑属性：与上面 .prose > pre 的 border-inline-start 同侧。 */
.prose > pre:not([class]) { border-inline-start-color: var(--border-decor); }

/* ---------------------------------------------------------------- 表格（GFM）
   🔴 必须是 <table>，不能用 div 模拟 —— div 会让屏幕阅读器读不出行列关系。 */
.prose > table {
  width: 100%;
  border-collapse: collapse;
  table-layout: auto;          /* ⚠️ 有 <colgroup> 时改用 fixed */
  font-size: var(--fs-sm);
}
.prose > table th,
.prose > table td {
  text-align: start;
  padding: var(--sp-2) var(--sp-4) var(--sp-2) 0;
  border-bottom: 1px solid var(--border-decor);
  vertical-align: top;
}
.prose > table th {
  font-weight: 500;
  font-size: var(--fs-xs);
  color: var(--text-secondary);
}
.prose > table tbody tr:last-child td { border-bottom: 1px solid var(--border-decor-str); }

/* ---------------------------------------------------------------- 其他元素 */
.prose > hr {
  margin: var(--sp-7) 0;
  border: 0;
  border-top: 1px solid var(--border-decor);
  height: 0;                /* 🔴 hr 默认有 inset 边框，必须清掉 */
}

/* 🔴 必须是**后代**选择器，不是 `> img` —— 和下面 `.prose a` 同一条教训。
 *
 *   Markdown / CommonMark 渲染图片出来是 `<p><img></p>`，图片的父节点是 `<p>`，
 *   不是 `.prose` 的直接子代 ⇒ `> img` **一条都匹配不上**，
 *   于是 `max-width:100%` 从未生效。
 *   实测（外部审计 F1）：`04-recipes/longform/content.html` 里
 *   `<p><img width="600">`，375px 溢出 246px、320px 溢出 301px。
 *   对"给用户和 AI 照抄的配方页"来说，这个缺陷会被原样复制出去。
 *
 *   `> a` → `a` 早在 0.9 就踩过一次（段落里的链接落到浏览器默认蓝，
 *   暗色对比度 1.91:1）。同一个坑换了标签又踩一次，所以这次把范围写宽：
 *   正文里任何位置的图片都受同一条约束。 */
.prose img {
  max-width: 100%;
  height: auto;
  display: block;
  /* 🔴 每个 img 必须有显式宽高（CLS）——
     这条由 viewport.py 门禁检查，本 CSS 不兜底 */
  border-radius: var(--r-sm);
}
/* 🔴 必须是**后代**选择器，不是 `> a`：正文链接几乎都在 `<p>` 里，
   `> a` 只覆盖直接子链接 ⇒ 段落里的链接落到浏览器默认蓝，
   暗色下对比度 1.91:1（`dark-contrast` 实测抓到）。 */
.prose a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
}
@media (hover: hover) and (pointer: fine) {
.prose a:hover { color: var(--text-primary); }
}
.prose a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* 外链可访问性：新窗口打开必须告知 */
.prose > a[target="_blank"]::after {
  content: " ↗";
  font-size: 0.8em;
  vertical-align: 0.1em;
}

/* GFM 删除线
   🔴 实测：markdown-it 输出 `<s>`，GitHub/GFM 规范规定 `<del>`。
      两者都是合法 HTML（`<s>`=不再准确，`<del>`=已删除）但语义不同。
      ⇒ 样式必须同时支持，否则换渲染器就掉样式。
      查证所用渲染器：markdown-it-py（commonmark preset + strikethrough）。 */
.prose > del,
.prose > s,
.prose > li > del,
.prose > li > s { color: var(--text-tertiary); }

/* GFM 任务列表
   CommonMark 核心不产出这个，GFM 扩展才有：
   <li class="task-list-item"><input type="checkbox" disabled> … */
.prose .task-list-item { list-style: none; margin-inline-start: -1.5em; }
.prose .task-list-item input[type="checkbox"] {
  margin-inline-end: var(--sp-2);
  vertical-align: middle;
}
.prose .task-list-item input[disabled] {
  /* disabled 的复选框不可改，但必须仍能看出状态 —— 不用 opacity */
  accent-color: var(--accent);
}

/* ---------------------------------------------------------------- 无障碍兜底 */
.prose :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ============================================================================
   反模式
   =========================================================================
   1. 给每个元素加类（.prose h2、.prose p2 …）
      渲染器输出没有这些类，样式接不上。**按元素选择器接管**。

   2. <div class="code-block"> 装代码
      渲染器不认。用 <pre><code class="language-x">。

   3. <div class="table"> 模拟表格
      🔴 最严重：辅助技术会当普通 div 念，屏幕阅读器用户拿不到行列关系。

   4. <div class="heading"> 代替标题
      文档大纲全废，屏幕阅读器的"跳到标题"功能失效。

   5. 缩进代码块硬加 class="language-"
      CommonMark 规定它没有 class。

   6. <b> / <i> 代替 <strong> / <em>
      <b> 只是"视觉加粗"，无语义。

   7. hr 不清 height 和 border-top
      默认 hr 有 inset 边框，会出现双线。

   8. 依赖行内 <code> 样式而不排除代码块内的
      代码块每行都会带上边框和底色。
   ========================================================================= */

/* ============================================================================
   链接
   ============================================================================
   暗色下浏览器默认链接蓝只有 1.91:1，几乎看不见 ⇒ 需要设 color。

   🔴🔴 但**必须限定作用域**，不能写裸 `a {}`
      裸标签选择器会命中**宿主页面的每一个链接** ——
      也就是说：使用者引入本库后，自己站点所有 <a> 的颜色都会被改掉。
      这正是「改一处、全库变样」的污染源之一。

      正解：挂到本组件自己的根选择器上。作用域与组件一致，组件外完全不受影响。

   🔴 修：这里原写 `.content a`，而本组件根类是 **`.prose`** ——
     `.content` 全库 0 处出现 ⇒ 整段是死规则，而注释还写着它是根类。
     文档说一套、代码是另一套 ⇒ "链接已处理"这个判断一直是假的。
   ============================================================================ */
.prose a:visited {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}
