设计系统

design-system
分类设计
作者Alireza Rezvani
许可MIT
评分4.80/5
使用4.1K

Design System — 引导 + 共享品牌 Token

design-system 技能是 markdown-html 插件的共享品牌所有者。只需运行一次引导程序。每个转换器(md-document, md-review, md-slides)都会通过 config_loader.py 读取生成的配置,并将其 12 个 CSS 自定义属性应用于输出。否则,转换结果将使用占位默认值渲染——虽然技术上可行,但缺乏品牌化。

该技能包含三个 Python 工具:

1. onboard.py — 交互式(或支持 --defaults / --set / --show / --reset)向导。
2. config_loader.py — 可导入的自定义配置加载器,遵循 项目 > 全局 > 默认值的优先级,并支持 MARKDOWN_HTML_NO_CONFIG=1 跳过。
3. brand_palette_validator.py — WCAG-AA 对比度检查器 + HSL 调色板推导器。

这三个工具仅依赖标准库,不包含 LLM 调用(符合 Path-B 确定性原则)。

调用时机

| 现象 | 操作 |
|---|---|
| 用户在该工作区首次要求 "convert this markdown to HTML" | 运行 python3 markdown-html/skills/design-system/scripts/onboard.py |
| ~/.config/markdown-html/design-system.json 不存在 或 setup_completed_at 为空 | 拒绝转换,提示进行引导 |
| 用户希望针对特定仓库覆盖品牌配置 | python3 .../onboard.py --scope project |
| 用户希望以非交互方式修改单个字段 | python3 .../onboard.py --set brand.primary=#FF6B35 |
| 用户希望重置并重新引导 | 运行 python3 .../onboard.py --reset 然后重新执行 |
| 用户需要零接触默认值(CI,临时会话) | python3 .../onboard.py --defaults |
| 无头/容器化运行且应忽略已保存配置 | MARKDOWN_HTML_NO_CONFIG=1 ... |

引导问题集(10 个问题)

| # | 键名 | 选项 / 验证器 | 默认值 |
|---|---|---|---|
| 1 | default_output_dir | 路径; os.access(parent, os.W_OK) | ./markdown-html-out/ |
| 2 | brand.primary | HEX ^#?[0-9a-fA-F]{6}$ | #0A1628 |
| 3 | brand.accent | HEX 或留空(自动推导) | 由主色推导 |
| 4 | typography.heading_font | Google 字体名称(12 个安全默认值) | Inter |
| 5 | typography.body_font | Google 字体名称 | Inter |
| 6 | design_style | editorial / technical / minimal / playful | technical |
| 7 | code_t | (此处文本截断) | |
heme | light / dark / auto | auto |
| 8 |
toc.behavior | sticky-sidebar / collapsible-top / inline / none | sticky-sidebar |
| 9 |
company_name | 字符串 (可为空) | "" |
| 10 |
logo_url | URL 或为空 (渲染时以 base64 嵌入) | "" |

硬性规则

1. 正文文本必须通过 WCAG AA 对比度测试。 每次更改后都会运行 brand_palette_validator.validate()。背景上的正文文本和链接必须达到 4.5:1 的对比度。如果任一项失败,onboard.py 将拒绝保存(退出码 4),并提示用户选择更深的 primary 色,或将 brand.bg/brand.text 留空以由派生机制选择安全组合,或者直接覆盖 brand.text。标准依据:WCAG 2.2 §1.4.3。
2. 输出目录必须可写。
onboard.py 会向上追溯路径以寻找现有的祖先目录并检查 os.W_OK。路径为空或不可写 $\rightarrow$ 退出码 3。编排器的 output_path_resolver.py 在每次转换时遵循同一规则。
3. 自定义必须改变行为,而非仅作为装饰。 每个消费者(md-document, md-review, md-slides)必须读取配置,并在用户更改
design_stylebrand.primarycode_themetoc.behavior 时呈现不同的渲染效果。仅起装饰作用的字段不符合设计规范。
4. 优先级固定。 项目级 > 全局级 > 默认值。深度合并(deep-merge)会保留嵌套键(例如,你可以在项目配置中覆盖
brand.primary 而不会丢失全局配置中的 typography.heading_font)。
5. 环境变量绕过机制有其特定用途。
MARKDOWN_HTML_NO_CONFIG=1 适用于无头 CI、临时测试容器和自动研究风格的评估循环。绝不要在交互式用户界面中静默设置此项。

派生的 12 标记色板

一旦获取用户品牌色,brand_palette_validator.derive_palette() 将生成 12 个 CSS 自定义属性,存储在同一配置文件的 derived_palette 下。每个转换器都会将这些属性内联到其 <style> 块中。

| 标记 (Token) | 用途 | 派生逻辑 |
|---|---|---|
|
--md-bg | 文档背景 | 若为深色则使用 Primary,若为鲜艳色则使用近中性色 |
|
--md-surface | 卡片 / 标注 / 引用块背景 | 背景亮度 $\pm$ 4-6% |
|
--md-border | 细分线、表格边框 | 背景亮度 $\pm$ 8-12% |
|
--md-text | 正文文本 | 深色背景用米白色,浅色背景用近黑色 |
|
--md-text-muted | 标题、元数据、页脚 | rgba(text, 0.68) |
|
--md-accent | 主要 CTA、标注标题、链接强调 | 鲜艳色使用 Primary,深色则进行色相偏移并减淡 |
|
--md-accent-soft | 强调色背景、悬停状态 | rgba(accent, 0.14) |
|
--md-code-bg | 行内代码、代码块背景 | 背景亮度 $\pm$ 4-5% |
|
--md-link | 超链接 | 通过迭代调整以确保在背景上达到 4.5:1 对比度 |
|
--md-link-hover | 悬停状态 | 链接亮度 $\pm$ 6-8% |
|
--md-success | 成功 / 已批准 / 通过 | 以绿色为基准,亮度匹配 |
|
--md-warn | 注意 / 琐碎修改 / TODO | 以琥珀色为基准,亮度匹配 |

强制引导问题库 (Matt Pocock 结合文档的质询模式)

每轮一个问题,提供推荐答案和标准引用。

1. 您的品牌主色是什么? 推荐:您在产品或文档中已使用的 HEX 色值,而非标准的蓝色。标准依据:Aarron Walter, *Designing for Emotion* (颜色承载品牌情感)。
2. 强调色 (Accent) 应该是派生的还是手动设置的? 推荐:首次运行时选择派生(色相偏移 + 减淡可产生协调的配套色);仅在品牌指南有明确规定时才手动设置。标准依据:Adobe Spectrum, *Color Foundations*。
3. 风格是编辑风、技术风、极简风还是俏皮风? 推荐:
techni
technical 用于工程规范/报告,editorial 用于长篇叙事,minimal 用于精简的参考文档,playful 用于营销/落地页内容。参考标准:Ellen Lupton,《Thinking with Type》(风格服务于修辞目的)。
4. 目录(TOC)采用粘性侧边栏还是内联? 建议:800 字以上的文档使用
sticky-sidebar,短文使用 inline。参考标准:Nielsen-Norman,《Table of Contents Best Practices》(2023)。
5. 保存至全局还是单个项目? 建议:默认全局(确保所有工作的一致性);仅当该仓库具有不同品牌标识时,使用
--scope project。参考标准:research-ops 入职模式,research-ops/CLAUDE.md §8。

定制化使用示例(实际操作)

bash
# 首次运行入职引导(交互式,引导完成所有 10 个问题)
python3 markdown-html/skills/design-system/scripts/onboard.py

为 CI / 首次测试提供零接触默认值

python3 .../onboard.py --defaults

仅修改主色调和设计风格

python3 .../onboard.py --set brand.primary=#FF6B35 --set design_style=editorial

针对单个仓库进行覆盖

python3 .../onboard.py --scope project --set design_style=minimal

重置并重新引导

python3 .../onboard.py --reset python3 .../onboard.py

查看生效的配置(优先级:项目 > 全局 > 默认值)

python3 .../config_loader.py --show python3 .../config_loader.py --status

绕过已保存的配置(仅返回 DEFAULTS)

MARKDOWN_HTML_NO_CONFIG=1 python3 .../config_loader.py --show

在确定品牌色前快速检查 WCAG 对比度

python3 .../brand_palette_validator.py --primary "#FF6B35" --accent "#00D4AA"

前提假设

1. 用户至少有一个希望在 HTML 转换中保持一致的品牌 HEX 色值。
2. 用户接受 1-2 分钟的一次性设置。
3. 用户接受使用 Google Fonts 作为字体来源(通过 CDN,无需本地托管字体)。
4. 无障碍标准底线为 WCAG 2.2 AA(正文 4.5:1,大文本/UI 3:1)。AAA (7:1) 不在本次范围之内。

非目标(Non-goals)

  • 不是完整的设计令牌(Design Token)系统(如 Style Dictionary, Theo)。仅包含 12 个令牌,而非上百个。
  • 不是自定义字体托管方案。仅支持 Google Fonts。
  • 转换器中不提供深色/浅色模式切换。code_theme: auto 处理语法高亮的 prefers-color-scheme 情况;布局色板在每次引导后为单模式。
  • 不是无障碍审计套件(请使用 axe-core / pa11y)。我们仅强制执行对比度检查。
  • 不转换现有的 CSS —— 派生色板将被注入到新生成的 HTML 中。

区别于

  • marketing/landing/skills/landing/scripts/brand_palette_validator.py —— 该脚本的 derive_palette() 生成 8 个专为 Hero 页面渲染设计的令牌(--navy, --teal, --card-bg, --card-border)。本脚本生成 12 个专为文档渲染设计的令牌(粘性表面、细边框、代码背景、链接、链接悬停、成功、警告)。两者使用相同的 WCAG + HSL 计算逻辑,但令牌分类不同。
  • research-ops/skills/clinical-research/scripts/onboard.py —— 采用相同的模式(交互式 + --defaults/--set/--show/--reset/--scope),但问题集不同(临床 alpha/power/dropout vs. 品牌色板/字体/布局)。

输出产物

~/.config/markdown-html/design-system.json(全局)或 ./.markdown-html/design-system.json(项目)。JSON 架构定义在 assets/design_system_schema.json

反模式(避免这样做)

  • ❌ 跳过入职引导直接运行带有占位默认值的转换器 —— 输出结果将缺乏品牌感。
  • ❌ 直接将高饱和度的品牌主色选作 brand.bg(会导致文本对比度过低)。应将其用作 ac
改为 cent。
  • ❌ 不要为交互式用户静默设置 MARKDOWN_HTML_NO_CONFIG=1 —— 否则他们会疑惑为什么自己的 token 消失了。
  • ❌ 不要将品牌语义编码在 12 个 token 分类之外的 derived_palette 中。只有在明确定义了名称 + 用途 + 推导规则的情况下,才能添加新 token。

参考资料

  • WCAG 2.2 — §1.4.3 (对比度), §1.4.4 (缩放), §1.4.11 (非文本对比度)
  • Aarron Walter — *Designing for Emotion* (A Book Apart)
  • Ellen Lupton — *Thinking with Type*
  • Adobe Spectrum — *Color Foundations*
  • Nielsen-Norman — *Table of Contents Best Practices* (2023)
  • research-ops 入职模式:research-ops/CLAUDE.md §8
  • 品牌调色盘数学源码:marketing/landing/skills/landing/scripts/brand_palette_validator.py`