# 落地页契约

> 落地页数据、内置区块注册表、语言解析、运行时、无障碍与输出的维护者契约。

---

LLMS 索引： [llms.txt](/zh/llms.txt)

---

> [!NOTE] OINK 1.3.1 契约
> 本契约描述 OINK v1.3.1。主题开发使用同级 checkout；发布验收在关闭替换与
> 工作区后验证公开模块。消费站升级与部署分别检查。

共享规则见[架构契约](/zh/docs/design/architecture/)与
[组件契约](/zh/docs/design/components/)；迁移行为属于
[迁移边界](/zh/docs/design/migration/)。

## 外壳与数据 {#shell-and-data}

任何普通页面都可以声明 `layout: landing`。它渲染顶部导航栏、全宽画布与页脚，
不显示 docs 侧栏或 TOC 导轨。首页继续把 `data/home/<lang>.yaml` 作为兼容的创作
路径，并通过同一个渲染器处理。

非首页依次从内联 front matter、`data/landing/<key>/<lang>.yaml`、单个
`data/landing/<key>.yaml` 中精确匹配语言的条目，以及英文或无后缀本地数据中
解析 `sections`。落地页绝不抓取可变事实；星标数、价格、截图与头像必须在 Hugo
运行前提交或生成。

`params.ui.landing_search` 默认为 true，而且只有启用 `offline_search` 时才打开
既有本地命令面板。`params.ui.github_stars` 与 `params.ui.alt_site` 是可选的本地
界面事实。

## 区块注册表 {#section-registry}

注册表恰好有 22 种内置区块：

- `hero`、`metrics`、`capabilities`、`principles`、`cards`、`logo-wall`、
  `gallery`、`testimonials`、`contributors`、`faq`、`markdown`、`cta`；
- `pricing`、`pricing-compare`、`command-box`、`steps`、`timeline`、
  `code-plate`、`preview`、`case-study`、`download`、`bar-chart`。

条目可以是类型字符串，也可以是包含 `type`、`key`、`id`、`enabled`、内联
`data` 或有意指定的本地 `partial` 的 map。作者提供唯一 ID，OINK 把它规范为
锚点安全值。未知类型遵循共享的警告与安全回退策略，绝不静默消失；发布时
`--panicOnWarning` 会拒绝它。内置区块由 `landing/` partial 负责；已经移除的
`home/` partial 名称不是 API。

`preview` 通过站点渲染钩子，把 Markdown `source` 放在 `RenderString` 输出旁，
因此其内容会登记与 docs 内容相同的运行时。源码面板使用 Chroma，并带默认值为
`page.md` 的 `file` 名称。Markdown 输出使用四个反引号包围的 `markdown` 围栏；
RSS 省略它。面板标签来自主题 i18n。

`hero.align` 可取 `start` 或 `center`。Center 只适用于文本；与图片组合时会警告，
并回退到 `start`，同时保留图片。`download` 消费与 shortcode 相同的
`data/download/<key>.yaml` 结构，不引入第二套 channel、版本、发布或插值模型。

## 语言、运行时与无障碍 {#language-runtime-and-accessibility}

叙述文件可以按语言拆分。共享事实字段依次解析 `<field>_<exact language>`——其中
`-` 规范为 `_`——再解析 `<field>_<primary language>`，最后解析无后缀字段。
不接受 camelCase 别名。叙述字段通过站点渲染钩子渲染行内或区块 Markdown；复用
为无障碍名称的值会转为纯文本。区块文案属于站点数据；只有主题控件使用 OINK
i18n。

每次内置 Markdown 渲染都有稳定的区块、条目和字段作用域。重复正文和跑马灯
副本使用不同的自动代码 ID，复制按钮、标题、视口和行链接也随之对应。作用域
不依赖渲染次序或输出次序。显式代码 ID 保持不变；整页出现重复显式 ID 时会
警告，严格构建会失败。自定义 partial 重复调用 Markdown 辅助模板时，应为
每个渲染位置传入不同且稳定的 `scope`。

区块 Markdown 正文使用共享 `.td-content` 组件作用域，并登记实际内容所需的
运行时。代码折叠、表格、图片及其他内容组件在落地页内保留正常样式。该作用域
仅包围正文，不改变外层营销标题或网格。

交互式 HTML 设置 `hasLanding`，从而只按需添加 `landing.js`。运行时复用
`OinkSurfaceCoordinator`，负责出现动画、数字递增、复制、紧凑菜单与主题图片
增强。没有 JavaScript 或 Landing 脚本加载失败时，服务端输出仍然完整可见。
出现动画的候选元素默认可见，只有成功安装观察器后才标记为等待动画。数字指标
由服务端按配置输出完整的数字格式、前缀和后缀，递增动画的最后一帧使用同一显示文本。

交互式 HTML 中的代码面板可通过键盘聚焦，包括 `capabilities` 的代码视图与
`code-plate` 的逐行代码。读者可以用 Tab 进入长行区域，再用方向键滚动，不依赖
浏览器自动把滚动容器加入焦点顺序。这两种逐行渲染器不为静态 Print 输出添加
焦点入口。

跑马灯只用 CSS 复制；副本带 `aria-hidden` 与 `inert`，本地化复选框无需
JavaScript 也能持久保存暂停状态。减少动画会停用动画，强制颜色保留控件，主题
图片响应共享主题事件。顶部导航栏的 mega 面板与其 `columns` 参数已退役：仍然配置 `columns` 的菜单会告警并保持单列。紧凑菜单使用真实链接
与按钮，不捕获焦点，也不复制桌面导航树。

## 输出与兼容性 {#outputs-and-compatibility}

| 输出 | 契约 |
| --- | --- |
| HTML | 完整静态区块加渐进增强 |
| Print | 静态网格与内容，移除控件 |
| Markdown | 不带主题 class 的标题、正文、列表、表格与代码 |
| RSS | 配置后输出有效 RSS 文档；省略落地页区块 |

非 HTML 输出不设置 Landing 标志或运行时。根相对链接与资源遵循部署子路径；普通
构建不下载图片。

启用 RSS 时使用共享 feed 渲染器，实际输出与 HTML head 公布的 feed 地址一致。
章节与首页 feed 保留普通子页面摘要；显式启用 RSS 的普通页面可以输出空 channel。
省略落地页区块不等于生成空文件，也不能公布不存在的 feed。

已经移除的 0.4 组件形态属于迁移工具，不是并行的落地页实现。OINK 不增加价格
周期切换、远程事实 API、热点编辑器、可视化构建器或第二套注册表。既有首页数据
与显式自定义区块 partial 继续有效。

## 视觉预设 {#visual-presets}

Paper 去掉首屏网格与光晕，使用暖色阴影、Plex Sans 展示标题和链接色主按钮。
Slate 保留技术网格、光晕、Chakra Petch 标题与原有主按钮颜色。两者共用分区结构，
不改变密度。手机抽屉包含共用外观表单，参见[外壳契约](/zh/docs/design/shell/#appearance-control)。

显式开启的 Ink/Terminal 实验也去掉网格、光晕与阴影。Ink 使用高字重 Inter 标题、
直角卡片与红色主按钮；Terminal 使用等宽标题、2 px 圆角、琥珀主按钮与静态光标形
装饰。两者都不新增动画，不改变分区列结构。

---

反链：

- [设计](/zh/docs/design/)
- [视觉预设](/zh/docs/design/proposals/visual-presets/)
