zz design system
mono & squared
基础 / 色彩

颜色

颜色的主体是 17 个 token,分三组:面与线承担层级,文字三级承担信息优先级,品牌与状态承担语义。手写 CSS 一律引用 var(--zz-*),不写死色值,也不引用--color-zz-*(那是 Tailwind 工具类专用的 inline token,不保证作为运行时变量存在)。

面与线

面从深到浅共四级,线有两种。色块背景即 token 的真实值,标签是 token 名与用途。

--zz-bg-deep

凹槽:代码块、媒体井、页脚

--zz-bg

页面地面:body、内容列

--zz-surface

面板:卡片、弹层、表头

--zz-surface-2

悬停面:hover 底色、当前项、行内 code

--zz-border-subtle

发丝线:区块分隔、表格线

--zz-border-strong

控件描边:输入框、描边按钮

注意:深色主题里 --zz-border-subtle 与 --zz-surface-2 取同一个值, 所以发丝线落在悬停面上时几乎看不见——这是有意的,分隔线不该抢过交互反馈。

层级用途链

四级面按固定顺序使用,任何组件都从这条链上取面,不要自造中间色。

层级token用途典型位置
bg-deep--zz-bg-deep凹槽,比页面更深代码块、媒体井、页脚、安装命令条
bg--zz-bg页面地面body、内容列、半透明遮罩底
surface--zz-surface抬起的面板卡片、弹层、表头、描边按钮底
surface-2--zz-surface-2再抬一级 = 交互悬停面hover 底色、导航当前项、行内 code 底

surface · 面板

bg-deep · 凹槽(代码块 / 媒体井)
surface-2 · 悬停面

面板底用 --zz-surface,凹槽用 --zz-bg-deep;两者嵌在页面 --zz-bg 之上。

发丝线与控件描边

两种线各有明确职责,不要混用:分隔用 --zz-border-subtle, 控件轮廓用 --zz-border-strong。前者几乎不可见,只负责"分块";后者必须能被看见,负责"这是一个可操作的东西"。

分隔:1px solid var(--zz-border-subtle)

上面一行内容
下面一行内容

控件:1px solid var(--zz-border-strong)

清单:区块分隔、表格单元格、卡片内分隔、页脚顶线 → border-subtle; 输入框、Select、描边按钮、下拉面板外框 → border-strong。 强调容器用 2px,引用块左线用 2px(见「间距与层级」页的描边规范表)。

文字三级

三档都是独立挑选的实色,不是同一色的 alpha 派生——所以每一档在各自主题下的对比度都受控。

--zz-text

主文本:标题、当前项

--zz-text-secondary

次级文本:正文、导航标签

--zz-text-muted

弱文本:元信息、图注、占位符

主文本:页面标题、当前项、正文里的强调

次级文本:正文段落默认走这一档

弱文本:2026-10-15 · 4 分钟 · 1 个依赖

用色选择:正文 --zz-text-secondary,标题与需要抓住注意力的行 --zz-text, 元信息、日期、计数、占位符 --zz-text-muted。不要为了"弱一点"给文字叠透明度。

品牌与状态

--zz-brand 是唯一强调色,只用在五处:主按钮填充、焦点环、链接下划线、进度条、当前项标记。 状态色取自固定色板,跨主题恒定,保证"红就是危险、绿就是成功"在任何主题下都成立。

--zz-brand

强调色:主按钮填充、焦点环、链接下划线

--zz-brand-soft

brand 的 12% 透明版:选中底、当前项底

--zz-brand-ink

brand 填充上的文字色

--zz-danger

危险:删除、错误

--zz-warning

警告:注意、降级

--zz-success

成功:完成、通过

--zz-info

信息:提示、中性说明

--zz-accent

点缀:次要分类标记

--zz-brand-soft 是 brand 的 12% 透明版,由 color-mix 派生: 换主色时它自动跟着变,不需要手改。它是"选中底 / 当前项底",不是描边色。

--zz-brand-soft: color-mix(in srgb, var(--zz-brand) 12%, transparent);

换主色

品牌色只落在两个 token 上。只改这两个值,其余全部自动跟随:焦点环、链接下划线、--zz-brand-soft、滚动条交互态都引用 var(--zz-brand)。

/* 暗色主题:换成紫色主色 */
:root,
[data-theme='dark'] {
  --zz-brand: oklch(0.72 0.17 300);
  --zz-brand-ink: oklch(0.16 0.02 300);
}

/* 亮色主题:同一支,但明度更低、填充上的文字改成白 */
[data-theme='light'] {
  --zz-brand: oklch(0.52 0.15 300);
  --zz-brand-ink: oklch(0.99 0.005 300);
}

--zz-brand-ink 是 brand 填充之上的文字色:亮色主色通常需要白色文字,深色主色需要近黑文字。 改完这两个值后,把这个页面和「按钮」页过一遍,确认焦点环在两种主题下都还看得见。

可访问性

  • 文字只用三档实色,避免"叠加透明度后对比度不可控";正文与背景的对比度取向见「动效与可访问性」页。
  • 焦点环固定 2px solid var(--zz-brand) + 2px 偏移,因此 brand 对背景的对比度需达到 3:1。
  • 颜色从不单独承担语义:危险按钮同时有文案,当前项同时有 aria-current。