Hallmark F4 Step Sequence 组件实战:用编号阶段流呈现产品工作流(附源码级解析)
导读:F4 Step sequence(步骤序列)是 Hallmark 反 AI 模板化设计体系中六大 Feature 组件之一,专为"产品即流程(workflow)"的场景设计——用
1.0 → 2.0 → 3.0这类编号阶段纵向排布,每个阶段包含标题、段落与可选的小视觉元素。本文以 F4 组件规范 为骨架,结合仓库中 Tracejam SaaS 示例 与 Workbench 重构输出 的源码级实现,讲解 F4 的适用边界、DOM 结构、变体旋钮(Knobs)、移动端折叠策略,以及它与 F2 Sticky-scroll 的关键区分,帮助你直接在 Claude Code、Cursor、Codex 中复用它。
一、组件定位:当产品是一条工作流,而不是一个瞬间
Hallmark(SKILL.md)是一套面向 AI 编程助手的"反 AI 味"设计技能,其核心主张是结构多样性:两页不同需求的页面不应共享同样的 hero → 3 个 feature → CTA → footer 节奏。为此,它在 component-cookbook.md 中定义了 36 个组件原型(archetype),每个原型都自带明确的"何时使用(Use when)"与"不要混淆(Don't confuse with)"。
F4 Step sequence 在其中归属于 Feature blocks(功能块) 类别,它的定位可以浓缩成三句话:
- 形态:编号阶段(
1.0 → 2.0 → 3.0)纵向流动,每个阶段有一个标题、一段说明,有时附带一个小视觉。 - 适用场景:Use when: the product is a workflow, not a single moment. —— 当你的产品本质是一条"工作流"而非"单点功能"时使用。
- 区分边界:Don't confuse with: F2 Sticky-scroll (which doesn't number stages). —— 不要与 F2 粘性滚动堆栈 混淆,后者不编号阶段,而是让左栏粘性固定、右栏滚动轮播相关截图。
为什么"编号"是 F4 的灵魂? 编号把一组并列的 feature 块"升级"成一条有先后顺序的流程。读者看到
01 → 02 → 03,自然理解这是"先做 A,再做 B,最后做 C",而非"A、B、C 三个并列卖点"。这是语义(semantics)层面的差异,也是 F4 与普通 feature 列表最本质的区别。
二、F4 的官方 DOM 骨架
F4 规范给出了最小可用结构——一个有序列表 <ol>,每个 <li> 内含一个阶段编号 <span class="stage"> 与阶段标题 <h3>:
<ol class="steps">
<li><span class="stage">1.0</span><h3>Intake.</h3><p>…</p></li>
<li><span class="stage">2.0</span><h3>Plan.</h3><p>…</p></li>
</ol>
要点拆解:
- 使用
<ol>而非<div>堆叠:语义化有序列表天然表达"顺序",对屏幕阅读器友好,也是 SEO 友好的标记选择。 - 阶段编号是独立元素:
.stage通常以等宽数字(tabular numerals)呈现,如1.0、2.0、3.0,与标题分离,便于独立定位和样式化。 - 每个阶段 = 标题 + 段落:保持"一句标题 + 一段解释"的稳定节奏;可选的第三项是"小视觉"(如截图、代码块、图标),规范用
sometimes a small visual表明它是加分项而非必需项。
三、仓库源码级实现:Tracejam 的 Workbench 步骤流
F4 规范只有骨架,真正的血肉在仓库的示例实现里。最完整的一处是 site/_tests/05-tracejam-saas/index.html —— 一个分布式追踪 SaaS 的落地页,其 Workbench 区块把 F4 与"粘性边栏"组合成了完整的操作台:
<section class="workbench" id="walkthrough">
<div class="steps">
<article class="step">
<p class="step__num">step 01 · open</p>
<h2 class="step__head">Open the trace, not a dashboard.</h2>
<p class="step__body">
Drop a trace ID, a request URL, or a five-second time window. Tracejam pulls the spans
from your collector and renders them inline — no dashboard hop, no link to Grafana,
no separate logs window. The trace is the unit of work.
</p>
<div class="step__code"><span class="c"># by trace id</span><br/><span class="k">$</span> tracejam open 9c3a72ef</div>
</article>
<article class="step">
<p class="step__num">step 02 · find</p>
<h2 class="step__head">Find the regressed span.</h2>
<p class="step__body">
Tracejam ranks spans by <strong>p99 deviation against your service's seven-day baseline</strong>.
The first one in the list is almost always the problem. No filters to set; the baseline
is precomputed every five minutes per service.
</p>
<div class="step__code"><span class="c"># top 3 regressed spans this hour</span><br/><span class="k">$</span> tracejam top --window 1h</div>
</article>
<article class="step">
<p class="step__num">step 03 · read</p>
<h2 class="step__head">Read why, in plain text.</h2>
<p class="step__body">
Each span carries an <strong>auto-generated explainer</strong>: which dependency
regressed, which version of which service, which deploy correlates, the last clean run,
and the diff between then and now. Plain text, copy-paste ready into a post-mortem.
</p>
<div class="step__code"><span class="c"># dump the explainer</span><br/><span class="k">$</span> tracejam why <span class="s">"pricing.quote"</span></div>
</article>
</div>
<aside class="pinned" aria-label="Pinned trace panel">…</aside>
</section>
对照官方骨架,可以看到生产级实现做了三处关键扩展:
| 官方骨架元素 | Tracejam 实现 | 作用 |
|---|---|---|
<ol class="steps"> |
<div class="steps"> 包裹三个 <article class="step"> |
article 让每个阶段成为独立文档单元,语义更丰富 |
<span class="stage">1.0</span> |
<p class="step__num">step 01 · open</p> |
编号 + 动词短语,形成"流程叙事"(open → find → read) |
<h3> / <p> |
<h2 class="step__head"> / <p class="step__body"> |
标题 + 正文,正文内用 <strong> 高亮关键指标(p99 deviation、seven-day baseline) |
| (无) | <div class="step__code"> 终端代码块 |
每阶段附加一个"小视觉"——命令行示例,让工作流可执行 |
3.1 阶段编号的"流程叙事"手法
注意 Tracejam 的编号不是干巴巴的 1.0 / 2.0 / 3.0,而是 step 01 · open、step 02 · find、step 03 · read。编号(01/02/03)负责顺序语义,动词(open/find/read)负责把每个阶段压缩成一句动作。三步合起来恰好就是产品的核心工作流:打开 trace → 找到异常 span → 读懂原因。这一手法把"功能列表"升维成了"产品故事",也正是 F4 区分于普通 feature 网格的价值所在。
在 site/_tests/verbs/redesign/output.html 的重构输出中,同样的结构被复用于不同的产品(step 01 · onboard → step 02 · scale → step 03 · ship),证明该模式具备跨产品迁移的通用性。
3.2 阶段内的小视觉:step__code 代码块
每个阶段的"小视觉"选择了终端代码块,配合行内着色 token(.k 关键字、.c 注释、.s 字符串),把抽象的流程说明落到可执行的命令上:
.step__code {
background: var(--color-paper-2);
border: 1px solid var(--color-rule);
border-radius: 4px;
padding: var(--space-sm) var(--space-md);
font-family: var(--font-display);
font-size: 0.8125rem;
line-height: 1.6;
color: var(--color-ink);
overflow-x: auto;
}
.step__code .k { color: var(--color-accent); }
.step__code .c { color: var(--color-ink-muted); }
.step__code .s { color: var(--color-warn); }
(见 site/_tests/05-tracejam-saas/style.css)
这里的 .step__code 完全通过 var(--color-paper-2)、var(--color-rule)、var(--color-accent) 等命名 token 引用颜色,符合 Hallmark"锁定 token、禁止中途即兴取色"的纪律(见 SKILL.md 的 Discipline 3)。
四、F4 的变体旋钮(Within-archetype variation knobs)
Hallmark 的防模板化策略有两层:第一层是"选不同的原型",第二层是"同一个原型用不同的旋钮值"。F4 在 component-cookbook.md 中定义了三个旋钮:
| 旋钮 | 可选值 | 说明 |
|---|---|---|
| Numbering(编号风格) | I/II/III · 01/02/03 · 1.0/2.0/3.0 |
决定顺序语义的视觉表达:罗马数字更正式,01/02/03 更工具化,1.0/2.0/3.0 更像版本/阶段 |
| Layout(布局) | vertical stack · horizontal flow · diagonal | 纵向堆叠(默认、最稳妥)· 横向流动(步骤较少时)· 斜向(少见,戏剧化) |
| Connector(连接器) | line · arrow · none | 阶段之间的视觉连线:细线 · 箭头 · 无 |
使用纪律:选择 F4 时,必须在宏结构戳记(macrostructure stamp)中写明所选旋钮值,例如:
/* Hallmark · macrostructure: Workbench · F4 knobs: numbering=01/02/03,
layout=vertical-stack, connector=line · theme: Studio · ... */
(戳记格式参考 component-cookbook.md)
反模式提醒:连续两次输出若选了完全相同的旋钮值(比如都是 numbering=1.0/2.0/3.0, layout=vertical, connector=none),这与重复选同一个原型一样属于模板化——至少更换一个旋钮值。
五、F4 与 F2 Sticky-scroll 的边界:什么时候用哪个
这是最容易踩坑的区分点,两份规范文件互相引用、互为对照:
| 维度 | F4 Step sequence | F2 Sticky-scroll stack |
|---|---|---|
| 核心机制 | 编号阶段线性排列 | 左栏 position: sticky 固定,右栏滚动轮播截图 |
| 阶段编号 | 有(1.0 → 2.0 → 3.0) | 无(linear sequence,不编号) |
| 适用场景 | 产品是工作流,用户按顺序完成多个动作 | 功能有多个子状态值得依次展示(如多张截图、多个视图) |
| 小视觉 | 可选(sometimes a small visual) | 必需(右栏本身就是视觉轮播) |
| 信息结构 | 流程叙事:先 A 后 B 再 C | 并列展开:一个功能的多个侧面 |
一句话决策规则:如果你需要表达"顺序"(step 1 → step 2 → step 3),用 F4;如果你需要在一个固定锚点旁边轮播多个画面,用 F2。 两者也可以像 Tracejam 那样组合使用——F4 做左栏步骤流,F2 的粘性面板(.pinned)做右栏锚点,这在 Workbench 宏结构 中是标准组合(见重构输出的戳记 F2 sticky-scroll knobs: pinned=right, content=feature-card, steps=3,output.html)。
六、样式要点与微交互:让流程"活"起来
Tracejam 的 style.css 给出了 F4 的完整样式配方,核心手法如下:
6.1 左缘竖线 + 悬停生长动画
.steps { display: grid; gap: var(--space-3xl); }
.step {
border-inline-start: 2px solid var(--color-rule);
padding-inline-start: var(--space-lg);
position: relative;
}
.step::before {
content: "";
position: absolute;
inset-inline-start: -2px;
inset-block-start: 0;
width: 2px;
height: 0;
background: var(--color-accent);
transition: height var(--dur-short) var(--ease-out);
}
.step:hover::before, .step:focus-within::before { height: 100%; }
设计意图拆解:
- 每个阶段左侧一条 2px 竖线(
--color-rule),视觉上形成"进度轨道"。 ::before伪元素叠加一条 accent 色的线,初始高度 0,悬停或键盘聚焦时生长到 100%,用transition: height+ Hallmark 命名缓动var(--ease-out)驱动(只动画 height,符合 Hallmark"只动画 transform/opacity,不动画布局属性"的纪律吗?注意:height 动画在本例中是可接受的场景化取舍,规范整体仍推荐优先 transform/opacity)。:focus-within意味着键盘用户 Tab 进阶段内任意元素时同样触发,可访问性友好。
6.2 阶段编号与标题排版
.step__num {
font-family: var(--font-display);
font-size: 0.75rem;
letter-spacing: 0.12em;
color: var(--color-accent);
text-transform: uppercase;
margin-block-end: var(--space-sm);
}
.step__head {
font-family: var(--font-display);
font-size: clamp(1.5rem, 2.5vw, 2rem);
font-weight: 500;
letter-spacing: -0.015em;
line-height: 1.1;
color: var(--color-ink);
margin: 0 0 var(--space-md);
}
- 编号用 display 字体 + 0.12em 字距 + 全大写 + accent 色,与正文形成明确层级。
- 标题用
clamp(1.5rem, 2.5vw, 2rem)流式字号,适配不同视口。 - 正文
.step__body限制max-width: 48ch保证阅读行长(measure),行高 1.6,正文中的<strong>用--color-ink加重,形成"灰底黑字"的对比节奏。
6.3 工作台布局:F4 步骤流 × 粘性面板
.workbench {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
gap: var(--space-2xl);
padding: var(--space-3xl) 0;
border-block-end: 1px solid var(--color-rule);
}
左列放 .steps(F4 步骤流),右列放 .pinned 粘性面板。注意两列都用了 minmax(0, 1fr) 而非裸 1fr——这是 Hallmark 响应式硬性门槛(slop-test gate 61,见 SKILL.md 的 Discipline 5):裸 1fr 会让含图片/长内容的网格轨道在窄视口溢出,minmax(0, 1fr) 允许轨道收缩。
七、移动端折叠策略
F4 在 component-cookbook.md 的移动端折叠表中定义了两个断点的行为:
| 断点 | F4 行为 |
|---|---|
| 60rem(~960px) | 编号从"左边距"移入"阶段行内"(inline-with-step) |
| 40rem(~640px) | 阶段容器收紧,连接线(connector)移除 |
对照 Tracejam 的实际媒体查询(style.css):
@media (max-width: 60rem) {
.workbench { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
.step::before { transition: none; }
}
要点:
- 60rem 以下工作台两列折叠为单列(
.workbench { grid-template-columns: 1fr }),步骤流自然转为纵向全宽。 - 悬停生长动画在
prefers-reduced-motion: reduce下必须关闭(transition: none)——这同时满足 Hallmark 的动效纪律(motion.md)与无障碍要求。 - 折叠后阶段结构本身不塌缩:标题、正文、代码块依序保留,仅编号位置与连接器做适配。
八、把它放进 Hallmark 的完整流水线
F4 不是孤立组件,它在 Hallmark 的构建流程中按以下位置被选用(详见 SKILL.md Step 3):
- Step 1 定 genre(editorial / modern-minimal / atmospheric / playful);
- Step 2 先选宏结构(如 Workbench、Feature Stack),并同步确定 Nav 与 Footer 原型;
- Step 3 读 component-cookbook.md 索引,挑选本次需要的 5–7 个原型文件——其中 Feature 类别选 1–2 个,F4 就是候选之一;
- Step 4 决定 hero 富化方案(多数页面纯排版即可);
- Step 5 输出预览块,声明 macrostructure、theme、sections、motion;
- Step 6 构建,并在 CSS 顶部打戳记(stamp);
- Step 7 跑 69 项 slop test。
同页多样性规则:一页内不能有两个 section 使用同一原型。如果宏结构已经暗示了默认 feature 组件(如 Bento Grid → F1),页面其他 feature 区块就应改选 F4/F5/F6 中的不同者,保证组合多样性(见 component-cookbook.md)。
九、可直接复用的 F4 最小模板
综合规范骨架与仓库实现,下面是一份开箱即用的 F4 模板(含 tokens 化样式):
<section class="steps">
<article class="step">
<p class="step__num">step 01 · label</p>
<h2 class="step__head">阶段标题。</h2>
<p class="step__body">一段不超过 48ch 的说明文字。</p>
<!-- 可选:小视觉,如截图 / 代码块 / 图标 -->
</article>
<!-- 依此类推 step 02、step 03 … -->
</section>
.steps { display: grid; gap: var(--space-3xl); }
.step {
border-inline-start: 2px solid var(--color-rule);
padding-inline-start: var(--space-lg);
position: relative;
}
.step::before {
content: "";
position: absolute;
inset-inline-start: -2px;
inset-block-start: 0;
width: 2px;
height: 0;
background: var(--color-accent);
transition: height var(--dur-short) var(--ease-out);
}
.step:hover::before, .step:focus-within::before { height: 100%; }
.step__num {
font-family: var(--font-display);
font-size: 0.75rem;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--color-accent);
margin-block-end: var(--space-sm);
}
.step__head {
font-family: var(--font-display);
font-size: clamp(1.5rem, 2.5vw, 2rem);
font-weight: 500;
letter-spacing: -0.015em;
line-height: 1.1;
color: var(--color-ink);
margin: 0 0 var(--space-md);
}
.step__body {
font-size: 1rem;
line-height: 1.6;
color: var(--color-ink-soft);
margin: 0 0 var(--space-md);
max-width: 48ch;
}
使用前的五步自检:
- 你的产品是不是"工作流"?若不是(单点功能),换 F1/F5/F6 更合适;
- 是不是该用 F2 Sticky-scroll?若有多个子状态需轮播展示,用 F2;
- 编号风格选了哪种(I/II/III · 01/02/03 · 1.0/2.0/3.0)?在戳记里写明;
- 连接器选了 line / arrow / none?保持与视觉密度一致;
- 一页内是否还有其他 Feature 原型?避免同页重复用 F4。
参考文件索引
- 组件规范:F4 Step sequence
- 组件目录与旋钮表:component-cookbook.md
- 对照原型:F2 Sticky-scroll stack
- 技能主文档:SKILL.md
- 实现示例:Tracejam SaaS 落地页 与 其样式
- 复用示例:Workbench 重构输出
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust4.21 K635- DDeepSeek-V4.1-FlashDeepSeek-V4.1-Flash 是一个多模态混合专家(MoE)模型,拥有 5520 亿骨干参数,并支持最多一百万 token 的上下文长度。该模型原生支持图像和文本输入,并以自回归方式生成文本Python30
jforgamejforgame是一个一站式游戏服务器开发框架。包含游戏服务器开发所需要的各种组件,比如网关,socket服务端与客户端,自定义高效消息编解码,游戏热更新,游戏通用工具等等。包含游戏服,跨服,匹配服,后台管理系统等实现,同时提供大量业务案例以供学习。亦可用于其他socket应用,例如及时聊天等。Java131
fizz-gateway-nodeAn Aggregation API Gateway in Java . FizzGate 是一个基于 Java开发的微服务聚合网关,是拥有自主知识产权的应用网关国产化替代方案,能够实现热服务编排聚合、自动授权选择、线上服务脚本编码、在线测试、高性能路由、API审核管理、回调管理等目的,拥有强大的自定义插件系统可以自行扩展,并且提供友好的图形化配置界面,能够快速帮助企业进行API服务治理、减少中间层胶水代码以及降低编码投入、提高 API 服务的稳定性和安全性。Java70
certd开源SSL证书管理工具;全自动证书申请、更新、续期;通配符证书,泛域名证书申请;证书自动化部署到阿里云、腾讯云、主机、群晖、宝塔;https证书,pfx证书,der证书,TLS证书,nginx证书自动续签自动部署JavaScript80
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python290