Prologue

UI Standard · v1

设计系统与 UI 标准

颜色、字体、形状、动效、组件与交互的唯一事实来源。本页的每个色板、每个数值都直接读取生产globals.css的 CSS 变量,与线上页面同源 —— 改 CSS,本页自动跟随,不存在第二份手写数值。

读取方式
运行时 getComputedStyle + CSSOM 主题作用域
双主题
Light / Dark 并排,不随当前主题漂移
维护成本
只维护 token 名;值一律不复制
01

Colour

颜色方案

两套语义色板共享同一组 token 名。左 :root、右 .dark,右侧面板读取的是 .dark 作用域声明,所以即使当前页面是亮色,也能看到暗色真值;文字色的 WCAG 比率按各自面板的 --background 计算。

Light 模式

:root

对比度对 --background

背景与表面

页面底色与三档表面:白卡只出现在 --surface 上,输入框与复制字段用 --surface-2,内嵌块用 --surface-3。

  • --background

    页面底色

    读取中…

  • --surface

    卡片 / 面板底色

    读取中…

  • --surface-2

    输入框、复制字段

    读取中…

  • --surface-3

    内嵌块、骨架屏

    读取中…

文字

正文与元信息的四级文字。比率对当前面板的 --background 计算;--faint 允许低于 AA,因为它只承载别处也有的元信息。

  • --foreground

    正文 / 标题

    读取中…

  • --muted

    次要文字、excerpt

    读取中…

  • --faint

    日期、计数等元信息

    读取中…

  • --accent

    界面装饰文字(eyebrow、hover 标题)

    读取中…

  • --secondary

    次级强调文字

    读取中…

  • --on-accent

    主按钮上的文字

    读取中…

主色与辅色

填充色与 pastel 装饰色。承载文字的主按钮使用 --accent-strong → --secondary-strong 渐变;pastel 只做渐变与描边,不承载正文。

  • --accent-strong

    主按钮/链接 ink

    读取中…

  • --accent-soft

    主色淡底

    读取中…

  • --accent-pastel

    淡紫装饰

    读取中…

  • --secondary-strong

    辅色 ink

    读取中…

  • --secondary-soft

    辅色淡底

    读取中…

  • --secondary-pastel

    淡粉装饰

    读取中…

  • --sky

    第四色(仅渐变与光标光)

    读取中…

  • --color-brand-lavender

    历史来源色,不直接消费

    读取中…

  • --color-brand-pink

    历史来源色,不直接消费

    读取中…

  • --color-brand-stone

    历史来源色,不直接消费

    读取中…

边框与投影

1px 内描边就是本站在静止态的“高度”。阴影一律由 --shadow-tint 着色,随主题变化。

  • --border

    分隔线 / 卡片内描边

    读取中…

  • --border-strong

    hover 时的中性描边

    读取中…

  • --shadow-tint

    阴影着色

    读取中…

  • --shadow-card

    静止卡片:1px 内描边

    读取中…

  • --shadow-card-hover

    hover / 浮起

    读取中…

  • --shadow-pop

    弹层 / 模态

    读取中…

渐变

填充渐变给装饰块,文字渐变只能用于大字号(--gradient-brand-text)。首页 hero 只用底色,没有叠加光晕。

  • --gradient-brand

    品牌填充渐变(三色)

    读取中…

  • --gradient-brand-text

    标题文字渐变

    读取中…

悬停系统(卡片 07 · 标签 C)

颜色以裸 RGB 三元组存储:一套色同时驱动卡片的外圈 / 内描边 / 柔光,以及标签的外圈。标签另用三个 alpha token 分开控制静止底色、外圈和描边。

  • --glow-sky

    青 · 外圈扇形 / 柔光外晕

    读取中…

  • --glow-lav

    紫 · 外圈扇形 / 柔光核心

    读取中…

  • --glow-pink

    粉 · 外圈扇形

    读取中…

  • --glow-ring-a

    外圈透明度

    读取中…

  • --glow-hairline-a

    内描边透明度

    读取中…

  • --glow-glow-a

    柔光核心透明度

    读取中…

  • --glow-glow-2-a

    柔光外晕透明度

    读取中…

  • --glow-shadow

    hover 的双层外投影 + 内描边

    读取中…

  • --card-lift

    hover 时卡片底色混入比例

    读取中…

  • --chip-wash-a

    标签静止底色透明度

    读取中…

  • --chip-ring-a

    标签外圈透明度(1px 线要更高)

    读取中…

  • --chip-hairline-a

    标签静止描边透明度

    读取中…

Dark 模式

.dark

对比度对 --background

背景与表面

页面底色与三档表面:白卡只出现在 --surface 上,输入框与复制字段用 --surface-2,内嵌块用 --surface-3。

  • --background

    页面底色

    读取中…

  • --surface

    卡片 / 面板底色

    读取中…

  • --surface-2

    输入框、复制字段

    读取中…

  • --surface-3

    内嵌块、骨架屏

    读取中…

文字

正文与元信息的四级文字。比率对当前面板的 --background 计算;--faint 允许低于 AA,因为它只承载别处也有的元信息。

  • --foreground

    正文 / 标题

    读取中…

  • --muted

    次要文字、excerpt

    读取中…

  • --faint

    日期、计数等元信息

    读取中…

  • --accent

    界面装饰文字(eyebrow、hover 标题)

    读取中…

  • --secondary

    次级强调文字

    读取中…

  • --on-accent

    主按钮上的文字

    读取中…

主色与辅色

填充色与 pastel 装饰色。承载文字的主按钮使用 --accent-strong → --secondary-strong 渐变;pastel 只做渐变与描边,不承载正文。

  • --accent-strong

    主按钮/链接 ink

    读取中…

  • --accent-soft

    主色淡底

    读取中…

  • --accent-pastel

    淡紫装饰

    读取中…

  • --secondary-strong

    辅色 ink

    读取中…

  • --secondary-soft

    辅色淡底

    读取中…

  • --secondary-pastel

    淡粉装饰

    读取中…

  • --sky

    第四色(仅渐变与光标光)

    读取中…

  • --color-brand-lavender

    历史来源色,不直接消费

    读取中…

  • --color-brand-pink

    历史来源色,不直接消费

    读取中…

  • --color-brand-stone

    历史来源色,不直接消费

    读取中…

边框与投影

1px 内描边就是本站在静止态的“高度”。阴影一律由 --shadow-tint 着色,随主题变化。

  • --border

    分隔线 / 卡片内描边

    读取中…

  • --border-strong

    hover 时的中性描边

    读取中…

  • --shadow-tint

    阴影着色

    读取中…

  • --shadow-card

    静止卡片:1px 内描边

    读取中…

  • --shadow-card-hover

    hover / 浮起

    读取中…

  • --shadow-pop

    弹层 / 模态

    读取中…

渐变

填充渐变给装饰块,文字渐变只能用于大字号(--gradient-brand-text)。首页 hero 只用底色,没有叠加光晕。

  • --gradient-brand

    品牌填充渐变(三色)

    读取中…

  • --gradient-brand-text

    标题文字渐变

    读取中…

悬停系统(卡片 07 · 标签 C)

颜色以裸 RGB 三元组存储:一套色同时驱动卡片的外圈 / 内描边 / 柔光,以及标签的外圈。标签另用三个 alpha token 分开控制静止底色、外圈和描边。

  • --glow-sky

    青 · 外圈扇形 / 柔光外晕

    读取中…

  • --glow-lav

    紫 · 外圈扇形 / 柔光核心

    读取中…

  • --glow-pink

    粉 · 外圈扇形

    读取中…

  • --glow-ring-a

    外圈透明度

    读取中…

  • --glow-hairline-a

    内描边透明度

    读取中…

  • --glow-glow-a

    柔光核心透明度

    读取中…

  • --glow-glow-2-a

    柔光外晕透明度

    读取中…

  • --glow-shadow

    hover 的双层外投影 + 内描边

    读取中…

  • --card-lift

    hover 时卡片底色混入比例

    读取中…

  • --chip-wash-a

    标签静止底色透明度

    读取中…

  • --chip-ring-a

    标签外圈透明度(1px 线要更高)

    读取中…

  • --chip-hairline-a

    标签静止描边透明度

    读取中…

规则:装饰色(pastel / sky / glow)不承载正文;正文链接使用 --accent(4.15:1,界面级放宽); 主按钮文字 --on-accent 落在 --accent-strong 上(5.35:1)。新增文字 token 必须在本页比率 ≥ 4.5:1。

02

Typography

字体与排版

8 级字号阶梯,全部来自文本工具类;下面的 px / 行高 / 字重由浏览器在渲染后实测。整站只使用系统字体栈,0 个 webfont 请求。

字号阶梯 · 8 级 / 4px 基线体系

字体栈首项:读取中…· 只使用系统字体,整站 0 个 webfont 请求

  • Display

    首页大标题(仅一处)

    设计系统 Design System 0123

    读取中….text-display

  • H1

    页面主标题

    设计系统 Design System 0123

    读取中….text-h1

  • H2

    文章内二级标题

    设计系统 Design System 0123

    读取中….text-h2

  • Title

    区块标题

    设计系统 Design System 0123

    读取中….text-title

  • Lead

    导语 / 描述

    设计系统 Design System 0123

    读取中….text-lead

  • Base

    正文

    设计系统 Design System 0123

    读取中….text-base

  • SM

    卡片摘要、控件

    设计系统 Design System 0123

    读取中….text-sm

  • Caption

    日期、标签、eyebrow

    设计系统 Design System 0123

    读取中….text-caption

文章排版 .prose

文章正文由 markdown 管线输出,统一套用 .prose 样式;行内链接使用语义色链接,代码与公式分别走 Shiki 与原生 MathML。

中英文混排时,标题使用 tracking-tight;正文行高 1.75 左右,保证长文可读。

  • 列表、引用、表格都映射到语义色 token。
  • 不引入 webfont;不使用字距夸张的全大写小标题。
元素规则
标题字重 600,tracking-tight
正文--foreground / --muted 两档
03

Shape

形状、阴影与容器

半径、容器宽度和阴影全部来自 token;右侧数值同样是浏览器计算后的结果。

圆角

三级圆角 + 全圆。控件用 control,卡片用 card,弹层用 panel。

  • --radius-control

    按钮 / 输入框

    读取中…

  • --radius-card

    卡片

    读取中…

  • --radius-panel

    模态 / 大面板

    读取中…

  • --radius-pill

    药丸 / chip / 图标按钮

    读取中…

容器与高度

页面最大宽度与三档内容宽度;--nav-height 是吸顶导航的实测高度。

  • --container-page

    页面容器(.shell)

    读取中…

  • --container-archive

    归档页

    读取中…

  • --container-read

    阅读宽度

    读取中…

  • --nav-height

    吸顶导航高度

    读取中…

阴影

阴影一律由 --shadow-tint 着色,随主题变化;卡片静止态只有 1px 内描边。

  • --shadow-card

    静止卡片

    读取中…

  • --shadow-card-hover

    hover / 浮起

    读取中…

  • --shadow-pop

    弹层 / 模态

    读取中…

04

Motion

动效

没有动画库:入场、主题揭示、滚动进度和 hover 全部是 CSS。动效使用同一条 ease-out-expo 曲线与五个时长 token,系统开启“减少动态效果”时由全局媒体查询降级。

时长与缓动

整站只有一条缓动曲线和五个时长;hover 时长在行内悬停时预览。

  • --ease-out-expo

    唯一缓动曲线

    读取中…

  • --duration-instant

    即时反馈

    读取中…

  • --duration-fast

    hover / 颜色

    读取中…

  • --duration-base

    卡片 / 展开

    读取中…

  • --duration-enter

    入场动画

    读取中…

  • --duration-slow

    主题揭示

    读取中…

两个动画皆为纯 CSS,无动画库;重播 = 重新挂载节点。

.reveal-rise

入场:上移 6px + 淡入

var(--duration-enter) 260ms · var(--ease-out-expo)

当前小节

.toc-pill

与右上角同一个组件:圆形 view-transition 揭示(0.618s),揭示期间冻结全站过渡, 并对吸顶玻璃头临时关闭 backdrop-filter。

ThemeSwitch

页面级动效:route-transition(旧页 150ms 淡出 / 新页 260ms 淡入 + 6px 上移)。 滚动进度条与玻璃头的抬升阴影使用 animation-timeline: scroll(),不监听滚动事件。

05

Components

组件

全部是 globals.css 里真实的组件类,直接在页面上跑 hover / focus / active 状态。

.btn-primary / .btn-ghost / .btn-icon;hover 位移 1px,active 缩放 0.98。

填充渐变使用两个 strong ink,保证两端都过 AA;不使用 pastel 作为文字底色。

.input;focus 时 accent 描边 + 22% 焦点环。

.nav-item;当前页 aria-current=page + data-active=true 为三段渐变填充。

.chip 静止 6% 三色 wash + 1px 淡紫描边;hover 时 1px 三色外圈旋转(5.5s)+ 两颗星点闪烁(1.7s),文字 → --accent-strong。

药丸太小,放不下卡片那种双层柔光,所以沿用卡片 07 的外圈语言:同一套 conic 三色 + mask-composite 1px 裁切,只是把旋转放慢到 5.5s、加了两颗 1px 星点。把指针移上来试试 —— 这是全站唯一带持续动效的 hover。

.eyebrow(渐变短线 + 文字)与 .section-label(渐变竖条 + 文字)。

Section Eyebrow

不做大写、不做宽字距:标签是中文字符,两者只会降低可读性。

.link 正文链接;.text-gradient 仅用于大字号标题。

正文中的行内链接使用可访问的 accent ink,hover 更亮。

渐变标题文字

文字渐变必须使用 --gradient-brand-text(两个 ink),不能用 pastel 填充渐变。

.copy-field + useCopy():空闲 / 已复制 / 复制失败三态。

https://prologue-blog-demo.prologue.dev/rss

.card:1px 内描边就是全部高度;hover 效果在 06 节。

2026-11-04 · 约 6 分钟

一张卡片的解剖

元信息、标题、摘要与标签;整卡是一个链接(stretched link),标签浮在其上。

阅读设计

.modal-panel + modal.js 打开:遮罩、Esc、焦点陷阱、滚动锁。

.glass-header:76% 背景 + 14px 模糊;滚动时抬升阴影由 scroll() 驱动。

prologue.dev
归档关于

.search-dialog-*;桌面面板 760px,移动端结果改 S2 三段式(标题 / 摘要 / 日期),日期独占整行且 nowrap。点导航栏放大镜或按 ⌘K/Ctrl+K 打开真实面板。

A 书脊:年份在卡片前,每个年份一条独立脊线;完整页年份吸顶,首页 compact 保持静态。卡片内只有 Oct. 4 这样的 month.day,没有年份和序号。卡片带文章同款 hover 光效,但文字/空白仍不可点击,只有图片打开灯箱。

  1. 年份是这条脊线的起点:它站在第一张卡片前面,而不是躲在卡片里。

  1. 下一年重新起一条线;年份在滚动中留在导航下方。

L1:友链页底部的 banner;复用 .card / card-interactive / card-spotlight,CTA 用 .btn-ghost。页脚另有同一 URL 的内联 .link(F1),不加新行、不加新颜色。

Ten years

十年之约 · 虫洞

随机去一位十年之约成员博客看看。每一次点击,都是一次真实的到访。

开始漫游
06

Interaction

卡片悬停:双描边柔光 07

卡片:1px 三色 conic 外圈随指针旋转、1px 内描边、跟随指针的柔光、上浮 2px。标签沿用同一套外圈语言,只是放慢成自转并加了两颗星点(见 05 的 chip 标本)。左右分别是 Light 与 .dark 作用域下的同一个组件。

Light 模式

rest

双描边柔光 · 07

移动指针,观察描边旋转

外圈是 1px 三色 conic 渐变,从指针方向起算;内描边与柔光跟随指针位置,卡片只上浮 2px。

青 · sky紫 · lavender粉 · pink
--spot-ang
—
外圈起角 from
—
--spot-x
—
--spot-y
—

外圈顺序(自指针方向顺时针):青 → 紫 → 粉。静止时不绘制任何颜色。

青 sky紫 lavender粉 pink

Dark 作用域

rest

双描边柔光 · 07

移动指针,观察描边旋转

外圈是 1px 三色 conic 渐变,从指针方向起算;内描边与柔光跟随指针位置,卡片只上浮 2px。

青 · sky紫 · lavender粉 · pink
--spot-ang
—
外圈起角 from
—
--spot-x
—
--spot-y
—

外圈顺序(自指针方向顺时针):青 → 紫 → 粉。静止时不绘制任何颜色。

青 sky紫 lavender粉 pink
  • ::before 外圈:conic-gradient 三色,用 mask-composite: exclude 裁成 1px 边框;from = --spot-ang + 90deg,指针方向为扇区起点。
  • ::after 柔光:两层同心径向渐变,圆心 = --spot-x / --spot-y,140ms 缓动。
  • 内描边:hover 的 box-shadow 里的一层 inset,与中性描边叠成“双描边”。
  • 卡片只上浮 2px;标题颜色不变,文字永远在上层,不被染色。

<article className="card card-interactive card-spotlight relative flex flex-col p-5"> … </article>

Light hover 平均亮度 L
0.967(静止 0.999)
Light 峰值色度 C
0.090
Dark hover 平均亮度 L
0.275(静止 0.241,+0.034)
标题颜色
hover 前后一致

hover 只在 (hover: hover) and (pointer: fine) 下启用; 外圈颜色由 --glow-sky / --glow-lav / --glow-pink 三个 RGB 三元组驱动。

07

Rules

规范与维护

这些规则保证新页面落在同一套系统里;其中几条是历史 bug 的结论,不要“简化”掉。

  • 颜色一律引用语义 token,组件里不出现 hex / rgb 字面量。
  • 新文字色必须先在本页确认对比度 ≥ 4.5:1(大字 3:1)。
  • 优先复用 .btn / .card / .chip / .nav-item / .input / .eyebrow / .section-label / .link。
  • 圆角、时长、缓动使用 token;新值先加 token 再用。
  • hover 与指针交互包在 (hover: hover) and (pointer: fine) 内。
  • 装饰动效用纯 CSS;reduced-motion 沿用全局降级。
  • 新组件先在本页加一个 specimen,再进真实页面。
  • 不新增动画库;不引入 webfont(0 请求是基线)。
  • pastel / 渐变只做描边、填充与光标光,不承载正文。
  • 不给卡片子元素加 position: relative —— 会缩小整卡点击区。
  • 不手写 -webkit-backdrop-filter(Lightning CSS 会丢掉标准属性)。
  • 不改 hover 装饰层而不重测:Light ≥ 0.95 L,Dark ≤ +0.04 L。
  • 不在预渲染期读时钟 / 随机数(cacheComponents 会直接失败)。

src/app/globals.css —— 唯一的 token 与组件类来源(本页从它的 :root / .dark 规则里取值)。

src/lib/css-probe.js —— 运行时读取器:CSSOM 建立双主题作用域 + getComputedStyle 解析 var()。

src/components/ui-standard/*.js —— 各分区的预览组件;src/app/ui/page.js 是这一页。

新增 token 的三步:

  1. 在 globals.css 的 :root(与 .dark)里定义。
  2. 在本页对应分区的 GROUPS 里加一行(只写 token 名与用途)。
  3. 跑 yarn build + yarn lint;不需要改任何数值。

本页故意不写死任何颜色或尺寸:只要 token 还在,预览就是对的;token 被删掉,对应行会显示“读取中…”, 这也是一次免费的回归检查。

页面路径 /ui · 与线上 CSS 同源 · 变更随 globals.css 自动生效。最后同步:悬停系统 07 上线时。