V 设计系统 v1.0

把已经统一的东西
写下来

这不是新设计。全库 572 个人写的 css/html、71 个定义了变量的项目扫了一遍, 这里只收已经事实统一、只是没落成文件的那些,加上必须补的几档。 新项目从这里起手;⛔ 56 个线上页面一个都不改。

0 全库 tokens.css 数量 同一套八色被手抄了 33 遍,谁都不是真源
13 统计块实现 同一个「大数字+标签」写了 13 遍
175 底色取值 坍缩成 28 簇,最大一簇吃掉 50 个项目
1 有字号阶梯的文件 818 处 clamp,0 个可复用
51项目 描边已经统一 1px solid var(--line),全库最健康的一层
01

色彩

点任意一块复制变量名。表面/文字/描边这三层是收口的(同一个意图的手抖版本), 强调色不收口——它承载项目身份,收的只是命名和档位。

表面与文字

这四组在 20+ 文件里零分叉,等于事实上已经是标准。 对比度是实测值,不是估的。

描边

全库最健康的一层1px solid var(--line) 一个组合覆盖 51 个项目、1031 处, 而且真的走了变量。唯一杂音是 --line 分裂成 rgba(46 项目) 和 hex(29 项目),这里统一取 rgba 版。

强调色 · 每个都有两版

左边是原色(只做填充/底/图标块/装饰),右边是压暗的 -ink 版(做文字/链接/小图标)。 这不是重复:7 个强调色当文字一个都不达标,压暗版才 AA。 深色主题下 -ink 自动换成提亮版,同名覆写。

强调色底上永不压白字。纯白 #fff 实测:salmon 2.76、teal 2.86、gold 1.60 —— 七个全不合格,差得不是一点。 ⚠️ 报这组数字必须说清白是哪个白:压 --ink-invert(#fcfbf7 暖白)会小一点点(salmon 2.67、gold 1.55),两把尺子都对,混在一句话里才是错。
强调色底上压 --on-accent salmon 5.37 AA / teal 5.18 AA / gold 9.25 AAA。 ⛔ 不是 --ink:深色主题下 ink 翻成浅色,而强调色原底两个主题同一个颜色 ⇒ salmon 底上只剩 2.35 ✗。--on-accent 故意不翻,所以两个主题都是 5.37。 主按钮仍然是墨底白字,不是强调色底白字。
02

语义色

全库 71 个项目只有 6 个定义过语义色(8%)⇒ 这一档是新建的, 但值不是新发明的:ok 复用 teal、warn 复用 gold、bad 取 Demo Night 系已在用的 #e5484d。

⚠️
红底上不放小字。 --bad 底上压纯白 #fff 3.91、压 --ink-invert(暖白)3.78、压 --on-accent(深墨)3.79 —— 三个都不合格,这个底怎么放字都不行。 ⇒ 红色只做 7px 圆点、细条、图标;状态标一律「浅底 + ink 版文字 + 原色圆点」。 08-27 修:唯一的例外(直播角标 .v-agenda-live)原来是 --bad 底压纸白 3.78 ✗,当时用「大字号口径 3.0」放行——那条口径要 ≥18.66px 粗体或 ≥24px,10px 的角标怎么算都不是大字。现在改压 --bad-ink 打底 = 5.80 AA(深色 8.07 AAA),⛔ 别再拿「字少所以没关系」放宽口径。
别再另发明绿和黄。 成功态就是 teal,警告态就是 gold。多一个色号就多一处要跟着改的地方。
03

排版

字体族取全库前 4 名(62/46/42/39 个项目在用),不是审美挑的。 ⛔ Cormorant Garamond(9)、ZCOOL XiaoWei(2)、Nunito(1) 是单页口味,不进标准。

五个角色

角色本身全库很清楚,乱的是命名:同一个角色平均有 8-10 种取值、4-6 种变量名 (等宽一个角色就有 --mono --font-mono --f-mono --vt-mono --ns-mono --fx-mono 六种写法)。

字号阶梯

这是全库最大的单点缺口:demo-night 有 818 处 clamp 字号、0 个字号 token。 大标题保留 clamp(她的习惯,固定 px 会打架),但上下限都写死;正文档固定不跟视口变。

04

尺度

圆角/描边/动效这三档是她已经收敛好的,直接固化。间距和 z-index 是新建的。

圆角

12-13 个项目独立收敛到同一组数字,不是巧合:pill 999 / xl 34 / lg 24 / md 18。 sm 档全库没共识,取声明数最高的 12px。

间距 · 2px 网格

这不是 4/8 网格。实测 14px 出现 809 次比 16px 的 694 次还多, 14/18/22 三个奇数档和 16/24 平级。⛔ 按 4/8 制重排会和现存 1600+ 处声明打架。

阴影

色调已经统一(暖褐 tint rgba(53,42,33,·) 在 8-11 个项目复现), 几何完全没统一(902 个不同取值--shadow 一个名字下 73 个值)。 ⇒ 固定 tint + 三档 blur。

动效

180ms 是事实默认(35 项目/307 处)。120-200 挤了 6 个档、肉眼无差 ⇒ 收成 3 档。 expo-out 曲线有 12 个项目独立选中。⚠️ 53 个项目还在用裸 ease(浏览器默认、观感最平)——新页面别再写。

05

组件

全是活的,可以直接点。每一件都标了「原来写了几遍」和母本出处—— ⛔ 没有一件是新设计的。

统计块 · 复用价值最高

原来 13 套实现同一个东西。数字用 <b> 不用 <div>, 等宽 tabular-nums 一列数才对得齐。母本 opening-market。

28收到反馈全系列最高做出来率
9.46加权均分
92.9%做出来率
<div class="v-stat-grid">
  <div class="v-stat">
    <b class="v-stat-value">28<i>份</i></b>
    <span class="v-stat-label">收到反馈</span>
    <span class="v-stat-note">可选注释</span>
  </div>
</div>

<!-- 带占比条的版本 -->
VK.barRow('#bars', [
  { label: '线上', value: 18, note: '64%' },
  { label: '线下', value: 10, note: '36%' },
]);

Chip / Tag / Badge · 同一个原子的三种角色

69 个目录命中。筛选 chip 必须是 <button> 且带 aria-pressed—— 六个画廊版本里这个属性每次都得重写一遍,必漏。计数 <b> 也别省。

默认 二次开发 线上 获奖 新人 特别企划 分组 未填
已确认 待补充 已撤回 还没做
VK.filters('#filters', {
  items: [{ key: 'all', label: '全部' }, { key: 'a', label: '赛道 A' }],
  countOf: (k) => counts[k],          // 渲染成 <b>
  onChange: (keys) => render(keys),
});
VK.hint('#hint', shown, total, '份');  // 「已显示 N / M」

<span class="v-tag c-salmon">二次开发</span>
<span class="v-badge" data-state="ok">已确认</span>

卡片壳

画廊 6 版 + 18 处独立实现。 47 个 .gal-* 类名在三个版本里完全一致 ⇒ 壳子早就冻结了,只是没落成文件。 字段映射 {no, title, by, intro, tags[], badges[], shot, href}。 ⛔ 视觉变体别往这加(拼贴风、纸片风是她的创作面)。

控件条 · 搜索 + 筛选 + 排序 + 视图

六个画廊版本完全同构。交互细节(命中说明行、「已显示 N/M」)重写必漏。母本 gallery.html:79-108。

模态

51 个目录各写一遍,每次手写必漏一项。 这四件在 kit.js 里已经做好了:焦点陷阱 / Esc 关闭 / 点背板关闭 / 关闭后焦点还给触发元素, 外加左右键翻页。

const m = VK.modal('#detail');
m.onNav = (dir) => show(idx + dir);   // ← → 翻页
m.open(detailHtml(item));

<div class="v-modal" id="detail">
  <button class="v-modal-back" data-close aria-label="关闭"></button>
  <div class="v-modal-inner" role="dialog" aria-modal="true">
    <button class="v-modal-x" data-close aria-label="关闭">×</button>
    <div data-modal-body></div>
  </div>
</div>

议程卡

7 版各写一遍,每期活动必有。单日/双日退化逻辑用 :has() 处理—— 这段重写必错,照抄。母本 opening-market/app.js:667。

Day 1 · 周六

10:40
12:00

组队与开工

没组到队的人由志愿者兜底配对。

页面骨架 / 按钮 / 空态

topbar + brand-mark 在 10 个 html 里逐字相同; section-head 三件套 13 个 css 各写一遍;sticky 全库 178 个文件、层级各写各的 ⇒ 一律走 --z-sticky。入场动画 data-reveal 在 ~25 个 js 里各写一遍,现在自动接线。

还没有内容换个筛选条件,或者等数据回流
这是提示条。⛔ 空态永远不许显示成 0 或空白——存在的东西不许显示成 0%。
警告态:口径有争议的数字,标出来别硬凑。
06

图表基元

全库只有 1 处用了图表库,其余全部手写、四种流派。 现在每做一个新数据页要从零写 750-975 行 app.js ⇒ 这 5 件省 700+ 行。 母本 time-art-history/site/app.js。

const c = VK.cv('#holder', { h: 220, minW: 640, draw(c) {
  VK.axisY(c, 40, c.w, 12, c.hh - 24, max);
  data.forEach((d, i) => {
    // …画你的图元…
    c.push(x, y, w, h, [d.value + ' 份', d.label]);   // 登记命中区,自动接 tooltip
  });
}});
VK.legend('#legend', [{ c: 'var(--teal)', t: '线上' }]);
VK.table('#t', ['场次','份数'], rows, ['合计','28'], [1]);  // [1] = 第 2 列是数字列
⚠️
两个踩过的坑已经写进封装,别改回去。 ① 构造里同步调 draw ⇒ draw 闭包用到的变量必须在 new 之前声明(TDZ)。 ② 容器宽度可能是 0(tab 隐藏/刚 reload)⇒ 取不到宽就退到 minW,⛔ 不按 0 布局
日期轴必须是完整日历,永不「只画有数据的天」。 断更的那几天不画出来,图就在替你撒谎。
静默兜底会把数据 bug 变成一张看起来合理的图。 取不到值就显式报错,别默默填 0。VK.pct() 已经处理了「存在但 <0.1%」这种情况。
07

视觉层

海报、形象、漫画、现场物料这一层。它和网页层唯一真的对齐了的规范是字体: Noto Serif SC + IBM Plex Mono 两族跨层共用(107 / 137 个文件)。其余都还各自一套。

形象硬规则 · 六条

每一条都是被她当场否决过才校准出来的,不是我解读定妆图得来的。 判据锚=以她认可的成品为准。有效打法是双参考(定妆十二格 + 她认可的那张定稿), prompt 写 match reference 2's exact face style,一轮就对。

形象不外借。 配色、版式、物料形式随便学,商用也行,署名是唯一硬条件——但 vivi 小人形象除外。 风格可以借,人不外借。
形容词对模型没有约束力。 「不超过 5 笔」「零渐变」「不要炸毛」全都无效。实测唯一有效的杠杆是参考图锚定 (同一句 prompt 带锚 vs 不带锚:墨量 36.5%→14.5%,高饱和面积 41.8%→18.0%)。 写法要落成可数上限 + 一个允许的画法,不是再加一句「不要」。

两套合法画风 · ⛔ 拿错基准=连翻两轮

这是视觉层最贵的一个坑:风格没错、基准拿错,出来就是废的。开工前先确认这一件事。

色板:现在是三套,互不相通

「已经有一套统一四色」这个前提不成立。 三套之间没有一个共同的 token 名,也没有任何一处把它们互指。 风格指南那套最成熟(带活动线映射 + 「一张物料只用一个主色」的使用规则), ⇒ 最小动作=把它升成 token 名,另两套标「待归一」,⛔ 不要一次全改

一张物料只用一个主色。 活动线映射:Demo Night 疯狂红 · BFL 暖橙 · MBTI 迷幻紫 · Workshop 松石绿 · 特别企划玫粉。 这条规则本身是全库最成熟的视觉规范,网页层反而还没有对应物。

物料尺寸规格表

原来散在各处。「1086×1448 vs 1080×1440」这种差 6px 的历史遗留最容易在贴回坐标上出事 ⇒ 收成一张表。images.edit 默认吐 1024×1536,必须显式传 size="auto"

质检闸口 · 已内置,不用手动补

这一层是「我能自己验的」和「只有她能判的」之间的分界线。 ⚠️ 视觉核验在本环境是永久断链的:Read 读图常空返、截图工具也返回空图 ⇒ 颜色/构图/像不像本人只有她能判,⛔ 别假装验过。 所以规则必须写成能用 OCR / 像素扫描量的形式。

08

禁忌

这一节是整个设计系统里最有价值的部分:不是审美偏好,是踩过的事故。 「能做什么」可以现场判断,「不能做什么」重写一遍必犯。

她本人否决过的 · 原话有据

⛔ 别再试第二遍。列出原话是为了让下一个会话不需要重新挨一次骂才知道。

工程红线 · 踩过事故

这些和审美无关,是结构性会再犯的。 共同形状是:判据写死了、真源有两份、或者兜底把 bug 变成了看起来合理的结果。

高频翻车字 · 凡出现必查

治法=写字形拆解 + 逐个禁写法,禁写法必须填上一轮实际画错的那个字 (「桥 is 木+乔 — ⛔NEVER 梯, ⛔NEVER 杨」)。泛泛禁没用。 小字混排拉丁+中文是模型最弱项,有效打法不是加禁令,是清空竞争元素

字符集判据核不出错字。 内容→内客 混过去过,因为「客」在「黑客松」里合法出现过。 真判据是「合法的半读必须是文案的子序列」
OCR 必须关掉语言纠正。 usesLanguageCorrection=false,否则它把错字自动纠正成对的=白查一遍。

网页层三条硬红线

公开页面的注释view-source 就能看见,写在注释里不等于藏起来了。

微信号不进任何公共页面。 现在已经在 5 个网页文件里手写了 ⇒ 别再扩散,新页面一律不写。
票数不对外发;报名表「不公开破冰信息」的名单要过滤。 这两条在任何画廊/集市/复盘页上都成立。
公共画廊页不许出现通往评委通道的任何入口,也不许描述评委码长什么样。 举例、「全拼」、加日期都算,HTML 注释也算。评委走单独私发的链接。
09

怎么用

新项目四行接上。⛔ 已上线的 56 个页面一个都不动—— v- 前缀就是为了保证跟 .gal-* / .stat-card / .chip 零冲突。

cp -r event-os/design-system/kit  你的新项目/

<link rel="stylesheet" href="kit/tokens.css">
<link rel="stylesheet" href="kit/atoms.css">
<link rel="stylesheet" href="kit/components.css">
<script src="kit/kit.js" defer></script>
<body class="v-body">   <!-- 别忘这个 class -->

四层,各管一件事

三件还没收口的事 · 摆出来不动手

这三个都是同一个东西有两份真源,改一处另一处照样再犯。 ⛔ 我没去改——它们都牵着已上线的东西,得她点头。

⚠️
奖状 0801 定稿没流回模板。 starter-kit 的 templates/certificates/ 还是老版,下一期从模板起手会拿到旧的那份。
⚠️
matrix.js 分叉了 4 行。 两份互相抄,看起来一样,实际不是同一个文件。
⚠️
两个项目的变量表是同一份。 vivi-creative-wonderland(42 个变量)= curator-hub-playland(52 个)减掉它自己那 10 个 ⇒ 双真源,谁都不敢当准。

两件只有她能拍板的

⚔️
厂牌名和 logo 都没定稿 ⇒ 站上那个「V」只是占位标记, ⛔ 不要当 logo 用在对外印刷物料上
⚔️
字标层现在无法合法交付。 20 款候选字体 0 款可做 logo 字标(14 款明确禁令 + 6 款未知)——中文字库普遍把商标授权单独拎出来卖。 这是外部采购决策(买授权 / 找设计师手绘 / 接受 OFL 兜底),不是能靠重出解决的。
已复制