DESIGN.md · alpha · 2026-10-18 · sha256 cfcb253fc1a6203b
DESIGN.md alphaA
Immutable. This exact content never changes and is served at /api/v1/blob/cfcb253fc1a6203b.
---
# GENERATED by scripts/sync-brand-tokens.mjs from adonis-brand@270591952823 (projects/skills/DESIGN.md).
# Do not edit by hand: change adonis-brand, then run `pnpm brand:sync`.
version: alpha
name: Nika Skills
description: Catalog site for Nika's agent skills. Near-white warm gray pages, one fresh leaf-green accent used on small areas, and the clay characters Nika and Kiki carrying the brand through every section.
# colors: injected by adonis-skills `pnpm brand:sync` from data/palette.json + projects/skills/theme.json.
# Light roles keep their name; dark roles get a `-dark` suffix. Never write hex here.
colors:
background: "#faf9f6"
foreground: "#1e1c17"
card: "#fefefc"
card-foreground: "#1e1c17"
popover: "#fefefc"
popover-foreground: "#1e1c17"
primary: "#65a01e"
primary-foreground: "#fefefc"
primary-hover: "#5a9419"
secondary: "#eeece7"
secondary-foreground: "#1e1c17"
muted: "#f3f2ee"
muted-foreground: "#5e5a51"
accent: "#e5f5cd"
accent-foreground: "#1d370f"
destructive: "#b8432f"
destructive-foreground: "#fefefc"
border: "#e2dfd8"
input: "#d3cfc6"
ring: "#43721d"
ring-halo: "#badf8a"
link: "#43721d"
hero-art-bg: "#f7f2e8"
attribution: "#7fb685"
chart-1: "#3f8fc4"
chart-2: "#f2b35e"
chart-3: "#7fb685"
chart-4: "#8571b3"
chart-5: "#2ba5a0"
shadow-tint: "#1e1c17"
highlight-tint: "#fefefc"
plate: "#f7f2e8"
plate-border: "#d7ccba"
tint: "#f2fae5"
tint-border: "#badf8a"
background-dark: "#121210"
foreground-dark: "#eeede8"
card-dark: "#181815"
card-foreground-dark: "#eeede8"
popover-dark: "#1c1b18"
popover-foreground-dark: "#eeede8"
primary-dark: "#65a01e"
primary-foreground-dark: "#fefefc"
primary-hover-dark: "#5a9419"
secondary-dark: "#22211d"
secondary-foreground-dark: "#eeede8"
muted-dark: "#1c1b18"
muted-foreground-dark: "#ada99f"
accent-dark: "#1a260e"
accent-foreground-dark: "#b0dc75"
destructive-dark: "#f08a75"
destructive-foreground-dark: "#121210"
border-dark: "#302e2a"
input-dark: "#3a3833"
ring-dark: "#80bf31"
ring-halo-dark: "#304b10"
link-dark: "#b0dc75"
hero-art-bg-dark: "#1a1712"
shadow-tint-dark: "#080705"
highlight-tint-dark: "#eeede8"
plate-dark: "#1a1712"
plate-border-dark: "#3b362d"
tint-dark: "#141a0d"
tint-border-dark: "#304b10"
typography:
display:
fontFamily: Bricolage Grotesque, Noto Sans SC, sans-serif
fontSize: 70px
fontWeight: 800
lineHeight: 1.02
letterSpacing: -0.035em
h2:
fontFamily: Bricolage Grotesque, Noto Sans SC, sans-serif
fontSize: 34px
fontWeight: 750
lineHeight: 1.1
letterSpacing: -0.03em
h3:
fontFamily: Bricolage Grotesque, Noto Sans SC, sans-serif
fontSize: 24px
fontWeight: 750
lineHeight: 1.15
letterSpacing: -0.025em
card-title:
fontFamily: Bricolage Grotesque, Noto Sans SC, sans-serif
fontSize: 16px
fontWeight: 650
lineHeight: 1.3
letterSpacing: -0.01em
body-lg:
fontFamily: Noto Sans SC, sans-serif
fontSize: 18px
fontWeight: 400
lineHeight: 1.6
body:
fontFamily: Noto Sans SC, sans-serif
fontSize: 15px
fontWeight: 400
lineHeight: 1.7
body-sm:
fontFamily: Noto Sans SC, sans-serif
fontSize: 13.5px
fontWeight: 400
lineHeight: 1.55
mono:
fontFamily: IBM Plex Mono, monospace
fontSize: 12.5px
fontWeight: 500
lineHeight: 1.6
wordmark:
fontFamily: Shantell Sans, cursive
fontSize: 20px
fontWeight: 800
lineHeight: 1
letterSpacing: -0.01em
rounded:
xs: 6px
sm: 10px
md: 12px
lg: 16px
xl: 22px
plate: 28px
full: 9999px
spacing:
gutter-mobile: 20px
gutter-desktop: 32px
content-max: 1280px
section: 72px
group: 44px
card-gap: 14px
card-padding: 18px
components:
button-primary:
backgroundColor: "{colors.primary}"
textColor: "{colors.primary-foreground}"
typography: "{typography.body}"
rounded: "{rounded.full}"
height: 46px
padding: 0 20px
button-primary-hover:
backgroundColor: "{colors.primary-hover}"
textColor: "{colors.primary-foreground}"
button-secondary:
backgroundColor: "{colors.card}"
textColor: "{colors.foreground}"
rounded: "{rounded.full}"
height: 46px
padding: 0 20px
skill-card:
backgroundColor: "{colors.card}"
textColor: "{colors.card-foreground}"
rounded: "{rounded.lg}"
padding: "{spacing.card-padding}"
featured-card:
backgroundColor: "{colors.card}"
textColor: "{colors.card-foreground}"
rounded: "{rounded.xl}"
padding: 26px
featured-card-lead:
backgroundColor: "{colors.tint}"
textColor: "{colors.card-foreground}"
rounded: "{rounded.xl}"
padding: 26px
tag:
backgroundColor: "{colors.accent}"
textColor: "{colors.accent-foreground}"
rounded: "{rounded.xs}"
height: 22px
padding: 0 8px
chip:
backgroundColor: "{colors.card}"
textColor: "{colors.muted-foreground}"
rounded: "{rounded.full}"
height: 36px
chip-selected:
backgroundColor: "{colors.accent}"
textColor: "{colors.accent-foreground}"
rounded: "{rounded.full}"
height: 36px
command-box:
backgroundColor: "{colors.background}"
textColor: "{colors.muted-foreground}"
typography: "{typography.mono}"
rounded: "{rounded.md}"
height: 46px
search-bar:
backgroundColor: "{colors.card}"
textColor: "{colors.foreground}"
rounded: 18px
height: 62px
art-plate:
backgroundColor: "{colors.plate}"
rounded: "{rounded.plate}"
footer:
backgroundColor: "{colors.plate}"
textColor: "{colors.foreground}"
---
# Nika Skills 设计规范
给人和 AI agent 共用。本文是唯一来源:放在私有品牌仓库 `adonis-brand/projects/skills/DESIGN.md`,adonis-skills 跑 `pnpm brand:sync` 时把它复制到仓库根目录的 `DESIGN.md`,并把 `colors` 从 `data/palette.json` 和 `projects/skills/theme.json` 注入文件头。格式遵循 [google-labs-code/design.md](https://github.com/google-labs-code/design.md)(`version: alpha`),adonis-skills 的 CI 跑 `designmd lint`。
决策记录:`process/2026-10-18-skills-site-theme.md`(配色第一版)、`process/2026-10-18-skills-site-redesign.md`(v3 改版)。
## Overview
一本摊开的、干净的技能手册:页面几乎无彩,像近白的暖灰纸;唯一的强调色是新芽一样的叶绿,只出现在小面积;暖色和高饱和交给黏土角色尼卡(Nika)和琪琪(Kiki),他们从首屏一直陪到页脚。
- 界面安静,角色热闹。插画是页面里唯一大面积的暖色和高饱和区域。
- 叶绿只做“点亮”:主按钮、选中态、链接、强调词下划线、复制成功、焦点环。整屏绿色面积控制在 5–10%。
- 访客先找到要的 skill,再被品牌打动。目录可读性优先于装饰。
参照:visualgpt.io(绿色用量和冷暖搭配)、Clay.com(黏土角色贯穿全页)、Linear Integrations(按场景分组加一句说明)、Raycast Store(精选层级)。
## Colors
色值只在 `data/palette.json`。界面只引用 12 阶色阶,阶号语义照 Radix(1–2 背景、3–5 组件底、6–8 边框、9–10 实色、11–12 文字)。
| 色阶 | 用途 |
|---|---|
| `stone-*` / `stone-dark-*` | 界面中性色:页面、卡片、边框、文字。近白暖灰,色相约 85°,彩度不超过 0.01 |
| `leaf-*` / `leaf-dark-*` | 唯一强调色:叶绿,色相约 130°,参考 visualgpt.io 的 #74B425 |
| `n-*` / `n-dark-*` | 奶油暖纸:只用于插画衬底和页脚(角色 `plate`),不做页面底 |
语义角色(文件头 `colors` 由同步脚本生成,暗色加 `-dark` 后缀):
| 角色 | 亮色 | 暗色 | 用途 |
|---|---|---|---|
| `background` | stone-2 | stone-dark-1 | 页面 |
| `card` / `popover` | stone-1 | stone-dark-2 / 3 | 卡片、浮层 |
| `muted` | stone-3 | stone-dark-3 | 次级底、命令框计数 |
| `border` / `input` | stone-6 / 7 | stone-dark-6 / 7 | 细边框、可交互边框 |
| `foreground` / `muted-foreground` | stone-12 / 11 | stone-dark-12 / 11 | 正文、次要文字 |
| `primary` / `primary-hover` | leaf-button #65A01E / leaf-button-hover,配 stone-1 白字 | 同亮色 | 主按钮 |
| `accent` / `accent-foreground` | leaf-3 / 12 | leaf-dark-3 / 11 | 标签、选中的 chip |
| `tint` / `tint-border` | leaf-2 / 6 | leaf-dark-2 / 6 | 大面积浅绿:首张精选卡、hero 光晕、搜索框焦点 |
| `link` | leaf-11 | leaf-dark-11 | 链接、强调文字 |
| `ring` / `ring-halo` | leaf-11 / 6 | leaf-dark-9 / 6 | 焦点环 |
| `plate` / `plate-border` | n-2 / 6 | n-dark-2 / 6 | 插画衬底、页脚 |
- 主按钮是稍深的实心叶绿 `leaf-button` 配白字,对比度 3.18:1(悬停 3.69:1)。这是唯一低于 4.5:1 的文字组合:按钮字 600 字重以上,按 WCAG 粗体与非文字 3:1 下限放行,`theme.json` 的 `contrast.exceptions` 写了原因。更亮的 #74B425 配白字只有 2.5:1,不用;亮叶绿配墨色字发闷,被否。
- 主按钮不用近黑色,也不用渐变。
- 蓝 `blue`、琥珀 `amber` 只给角色(logo、插画),界面不用。
- 文字对比度 ≥ 4.5:1,`theme.json` 的 `contrast.pairs` 是检查清单,`pnpm brand:check` 会算。
## Typography
| 用途 | 字体 | 规格 |
|---|---|---|
| 展示标题(拉丁) | Bricolage Grotesque | 800,字距 -0.035em;h2/h3 750 |
| 标题(中文) | Noto Sans SC | 跟随同一 token 的字号,字重 700–900 回退 |
| 正文 | Noto Sans SC | 400,15/1.7;导语 18/1.6;小字 13.5/1.55 |
| 字标 | Shantell Sans | 800,全小写 “nika skills”,只用于字标 |
| 代码、slug、命令 | IBM Plex Mono | 500,12.5/1.6 |
- `font-family` 写成 “拉丁展示字体, Noto Sans SC, sans-serif”:拉丁字形由 Bricolage 渲染,中文自动落到 Noto Sans SC。
- 中文标题不加负字距(负字距只给拉丁),中文正文行高不低于 1.7。
- 标题只用一个强调手法:叶绿手绘下划线(强调词)。不同时用渐变字、描边字。
- slug 一律等宽小字,作为人话名称(Display Name)的副标题,不当标题。
- 所有字体经 fontsource 自托管,构建不访问 Google Fonts。
## Layout
- 内容最大宽 1280px,左右留白手机 20px、桌面 32px,页头与内容左缘对齐。
- 首页顺序:页头 → hero(左文案、右插画,下方大搜索框与场景跳转 chip)→ 3 张精选卡 → 按场景分组的目录 → 安装区 → 页脚。
- 场景分组:桌面左侧 280px 放分组头(插画、编号、组名、一句说明,滚动时吸顶),右侧三列卡片;手机分组头在上,卡片单列。
- 区块之间 72px,分组之间 44px 并用一条 `border` 分隔;同一层级的卡片间距 14px。
- 手机首屏必须看到搜索框和至少一个场景 chip。
## Elevation & Depth
- 分层先靠底色:`background` 上放 `card`,首张精选卡用 `tint`。阴影只做辅助。
- 静止的卡片几乎无阴影(亮色 1px 极淡投影,暗色无)。悬停时上移 2–3px,边框换 `tint-border`,加一层带叶绿色相的柔和外发光。
- 搜索框和主按钮带叶绿色相的柔和投影,是页面里的“发光点”;其他元素的投影用中性色相。
- 不加底部硬边(`0 Npx 0`),按钮不加内侧高光。
- 暗色模式下投影几乎不可见,层级只靠换阶。
## Shapes
| 元素 | 圆角 token |
|---|---|
| 插画衬底 | `plate` 28px |
| 精选卡 | `xl` 22px |
| 普通卡、浮层 | `lg` 16px |
| 命令框、菜单 | `md` 12px |
| 输入框、图标按钮、语言切换 | `sm` 10px |
| 标签 | `xs` 6px |
| 主次按钮、chip、徽标 | `full` |
## Components
- **主按钮** `button-primary`:实心叶绿、白字(字重不低于 600)、全圆;悬停换 `primary-hover` 并上移 1px,按下回落。一屏只放一个主按钮。
- **次按钮** `button-secondary`:`card` 底加 `input` 边框。
- **搜索框** `search-bar`:62px 高,`card` 底,带叶绿柔和投影;聚焦时边框换 `tint-border`,外加一圈 `tint`。右侧显示结果数(等宽小字)。
- **场景 chip** `chip`:左侧 26px 圆形角色头像,组名,等宽计数;选中用 `accent`。
- **精选卡** `featured-card`:编号(`01 / Featured`)、角落徽标(Most used / New loop / Daily driver)、角色插画、人话名称、slug、一句说明、2 条要点、命令框加实心复制按钮。第一张用 `featured-card-lead`(`tint` 底)。
- **普通卡** `skill-card`:人话名称、slug、最多 3 行说明、标签、右下角描边复制按钮;整卡可点进入详情,复制按钮单独可点。精选过的 skill 在分组里加 “Featured” 角标。
- **分组头**:64px 圆形角色插画,`plate` 衬底,编号加数量(`01 · 5 skills`),组名,一句说明。
- **命令框** `command-box`:`background` 底加 `border`,前缀 `$` 用 `link` 色,长命令省略号截断,复制按钮在右侧。
- **标签** `tag`:`accent` 底、`accent-foreground` 字,无边框;第二个及以后的标签可用中性 `muted` 底。
- **页脚** `footer`:`plate` 奶油底,右侧放角色插画。
- **空状态**:120px 角色插画,“没找到”一句话,加一个清空搜索的按钮。
- **焦点**:只在 `:focus-visible` 显示;有边框的控件把边框换成 `ring` 并贴一圈 `ring-halo`,无边框的用 2px `ring` 外描边。
## Illustration
- 黏土质感,光源是尼卡手里的灯(暖黄,从左上照)。
- 所有插画用透明背景,同一张图在亮暗两种模式都能用;需要衬底时由界面的 `plate` 提供,不把衬底画进图里。
- 用到插画的位置:hero、3 张精选卡、6 个场景分组头、空状态、页脚。普通卡不配插画,靠版式和标签区分。
- 出图必须附参考图(`projects/skills/hero/` 与主角设定图),角色颜色、比例不能漂移;图里不出现文字。
- 新 skill 成为精选时再补插画;场景分组新增时补分组插画。
## Dark Mode
- 中性色换成 `stone-dark-*`:近中性的深灰,不用带黄的暖炭,也不用墨蓝。
- 主按钮在暗色里不变(`leaf-button` 配白字);其他叶绿用途换成略提亮的 `leaf-dark-*`。
- 插画衬底 `plate` 换成 `n-dark-2`,插画本身透明,不再出现“浅色方块贴在深底上”。
- hero 光晕和投影在暗色里减弱,层级靠换阶。
## Do's and Don'ts
- Do:页面用 stone,奶油只给插画衬底和页脚。
- Do:叶绿只用在小面积;大面积浅绿用 `tint`。
- Do:卡片标题用人话名称,slug 做等宽副标题。
- Do:按场景分组展示 skill,每组一句说明。
- Don't:近黑主按钮、渐变主按钮、亮叶绿配墨色字的主按钮、按钮字低于 600 字重。
- Don't:组件和页面 CSS 里写 hex、`rgb()`、`color-mix` 或 `/NN` 透明度修饰;层级靠换阶。
- Don't:用蓝、琥珀做界面强调色。
- Don't:在中文上用 Shantell Sans 或 Bricolage Grotesque。
- Don't:在一屏里放两种强调色,或给插画画进不透明衬底。
- Don't:给按钮或卡片加底部硬边阴影。
## Iteration
- 改色只改 `data/palette.json` 或 `theme.json`,写一篇 `process/` 记录,提交品牌仓库,再到 adonis-skills 跑 `pnpm brand:sync` 并提交快照(`brand-link` skill 会列出受影响的使用方)。
- 改本文后同样跑 `pnpm brand:sync`,adonis-skills 根目录的 `DESIGN.md` 会更新,CI 跑 `designmd lint`。
- 一次只改一个组件,改完在亮暗两种模式和 390px 手机宽度下核对。