光圈拓扑故事
一个产品页面,其行为如同一份安静的工程文档,但蕴含一次电影般的移动:读者滚动进入网络的一个节点,深色页面像相机光圈一样打开,进入一个明亮的纸色工作空间,在其中通过卡片展示产品的真实工作流程。它适用于其价值在于可展示的管道(输入→来源/对等节点→结果→输出)的工具:推理网格、OSINT和研究工具、数据管道、CI、同步引擎、包注册表。它不适用于生活方式或时尚品牌。
参考构建是 example/index.html:OSINT-Book(Android和Windows上的被动、来源优先的OSINT笔记本)的真实网站,英文/土耳其文,使用应用自身的颜色。详细代码在 references/components.md 中;screenshots/ 展示了每个部分、每个故事阶段、土耳其文、减少动画和移动端。
如果用户指定了参考网站,仅采纳其风格。切勿复制其渲染、产品名称、文案、标志或数据。
1. 设计之前
- 首先阅读产品的来源:README、用户指南、隐私/威胁模型、API或来源注册表、发布说明、CHANGELOG。页面上的每个声明都与其中之一对应。精确复制数字(版本、文件名、大小、SHA-256、端口)。如果两个来源冲突(例如“22个模块”与一个20行的表格),展示表格所证明的内容。
- 从产品本身获取颜色:启动图标、Android
colors.xml/ ComposelightColorScheme和darkColorScheme、Web CSS自定义属性。将应用的深色方案映射到深色背景,将其浅色方案映射到光圈工作空间——页面然后从应用的一个主题字面切换到另一个。 - 找到故事:将产品的工作流程写成四个动词(OSINT-Book:目标→发现→分析→报告;推理网格:模型→切片→放置→服务)。每个阶段一个动词。每个阶段需要一个不超过6个词的标题。
- 故事中的样本数据必须明显是样本:
example.org、文档IP(192.0.2.x、203.0.113.x)、每张卡片上的“样本数据”芯片。切勿发明统计数据、用户数、基准或推荐语。 - 在架构部分使用真实的应用截图(WebP格式,约800px宽)。
2. 视觉DNA
| 元素 | 规则 |
|---|---|
| 深色背景 | 近黑色,略微混入品牌色:--bg-2(页面)/ --bg / --surface / --surface-2 / --surface-3。在整个主体上覆盖36px网格的1px线条,亮度约为浅色墨水的7%。在英雄区和舞台后方有径向光晕(品牌色约13%,第二个信号色约6%)。 |
| 浅色工作空间 | 应用的浅色背景(--paper),带有34px网格,墨水约5.5%和中间的品牌容器色的柔和径向渐变。仅限光圈内部。 |
| 墨水颜色 | 深色:--fg / --fg-2 / --muted(muted对比度在背景上≥4.5:1)。浅色:--ink / --ink-2 / --ink-muted。 |
| 品牌色 | 用于目标节点、光圈原点、“样本数据”芯片、注意状态、活动导航项、悬停边框的产品颜色。在深色上使用较浅色调(--brand-2),在纸色上使用较深色调(--brand-ink)。 |
| 信号色 | 另外两种色调,各有含义:青色=免费/正常/发现已返回;金色=需要密钥/可选/缺失。出站数据包使用品牌色,返回数据包使用青色。严重性始终是颜色+图标+文字。 |
| 展示字体 | Rajdhani 700,行高.84–.98,字间距0,句首大写。英雄区2.6–5.2rem,带四层发光:0 0 2px #fff·86%, 0 0 18px brand-2·36%, 0 0 48px teal·14%, 0 18px 52px #000·60%。在纸色上使用相同的字体,带 0 1px #fff, 0 14px 34px ink·12%。 |
| 正文/UI | Geist 400–700,14–17px。 |
| 标签 | Geist Mono 10–13px:节点标签、子标签、芯片、表格配额、终端、导航栏、标题(01 / ai 分析,仅此处使用大写 + .14em字间距)。 |
| 卡片 | 深色面板:16px圆角,1px --line-2,垂直渐变表面。纸色卡片:白色,14px圆角,1px暖色线条,0 14px 34px -14px阴影。芯片为药丸形(20px高)。结果行左侧有一个6×18px的渐变手柄。 |
| 按钮 | 主要按钮 = 近白色填充带深色墨水(8px圆角,40px高)。幽灵按钮 = 1px线条,悬停时变为brand-2。导航中的药丸按钮带有等宽后缀(· web-v0.2.2)。 |
| 图标 | 24网格单笔1.7px线条图标,放在内联<symbol>精灵中;同一个精灵在SVG图形内通过<use>使用。 |
3. 部分模式
- 固定导航(64px高,半透明深色+16px模糊,底部发丝线)– 图标+双色文字标志、小链接、带版本的GitHub药丸、EN/TR切换、主要按钮。
- 英雄区 – 全宽SVG拓扑图(viewBox 1200×520;中间的目标节点带光晕+光环;5-7个源节点在弯曲虚线上,每个带等宽标签和等宽子标签说明访问方式:
key-free、your key)。展示标题位于图的左下方。标题下方:一句引导语和一个三列行 – “运行它”(一个带复制的命令芯片+主要/幽灵下载按钮+“关注...”链接)、“它是什么”(粗体首句+带彩色点的事实行)和一个小的品牌徽章。如果产品有一个拓扑图未展示的头版功能(OSINT-Book:可选的AI分析),在引导语中命名它,并在其下添加一个药丸:填充的品牌标签(AI 分析)+一行+箭头,链接到该部分,该部分随后在故事之后首先出现。 - 光圈故事(固定,约640vh)– 见§4。
- 集成条 – 左侧等宽大写标签,右侧换行点状名称列表,上方和下方有发丝线。
- 架构切换器 – 部分标题(左侧大展示标题,右侧段落),然后一个深色面板:一个标签列表(填充药丸=选中)、一个文本列(标题、一个段落、✓列表)和一个HTML节点图,覆盖在SVG动画虚线连接器上(品牌色=出发,青色=返回,金色=可选),然后一个水平截图条带,带等宽说明,最后是一个图例页脚。
- 模块块 – 顶部边缘有两个小“拼图标签”的块:输入行→一个侧/中/侧行(中间块更大,品牌色调,展示字体)→一个6个输出的行;其下一条等宽注释。
- 目录表 – 搜索字段+等宽标签选择器、一个带名称+等宽id的表格、类型药丸、带彩色点的访问列、等宽配额列、备注;页脚带“显示x–y,共n个·源文件”和分页器。其下有一个
<details>“有遗漏,故意为之”列表。 - 范围划分 – 两个深色面板,“它能做什么”(青色方块)/“它从不做什么”(红色方块),每个项目一个粗体开头加一句解释,左侧发丝线。
- 安装 – 两个下载卡片(图标瓷砖、名称、等宽文件名·大小),然后一个终端窗口(信号灯、等宽标签、只复制命令的
COPY按钮、彩色提示符/命令/标志/注释/输出)带状态页脚(发光实时点),然后一个诚实的金色“早期版本”注释。 - 页脚 – 关于文本+语言药丸、两个链接卡片列表(带箭头的行;↗外部链接,→文档链接)、底部行带文字标志、版本芯片和归属行。
4. 标志性交互:光圈故事
一个 section.story(高度约640vh)包含一个 position:sticky; top:0; height:100svh 的舞台,有两层:
- 深色层 – 同样的拓扑图、一个等宽提示(
滚动 · 关注一个目标)和结束语。 - 浅色层 –
clip-path: circle(R at X Y)其中X/Y是目标节点的屏幕位置(通过getBoundingClientRect测量)。内部:四个堆叠标题(只有一个.on)、一个逻辑板(宽1120×560,窄屏360×640)缩放以适应、和一个等宽阶段导航栏。
单个进度值 p = -rect.top / (story.offsetHeight - innerHeight) 驱动一切;每个元素都有关键帧 [p, {x, y, s, o}] 使用缓入缓出立方插值,并作为 translate() scale() + opacity 应用。向后滚动则完全倒放。
| p | 阶段 | 移动内容 |
|---|---|---|
| .015 → .10 | 光圈打开 | R从0增长到最远角落;提示淡出。然后 clip-path:none。 |
| .00 → .33 | 1 · 输入 | 输入卡片升起;其检查列表行逐个勾选(p > .13 + i·.026);密钥受限行保持未勾选。 |
| .31 → .56 | 2 · 结果 | 输入卡片淡出;“笔记本”卡片取代其位置;六个来源卡片出现在其周围;每个来源的一个芯片从其卡片飞入笔记本的一个插槽(st = .37 + i·.024,在 st + .04 着陆)。间隙芯片为虚线。 |
| .56 → .79 | 3 · 解释 | 来源卡片缩小为点;笔记本向左滑动(芯片跟随其变换);三个观察卡片从右侧滑入;从引用的芯片到每个卡片绘制虚线连接器;出现一个“无裁决”药丸。 |
| .79 → .92 | 4 · 输出 | 所有内容折叠成一张报告卡片;其下一个提交卡片升起,其六个路由点亮起。 |
| .915 → .975 | 光圈关闭 | R缩小到0回到节点;深色层上发光结束语淡入。 |
- 滚动时仅
transform、opacity、clip-path和SVG属性发生变化(一个 rAF 节流的处理程序)。 - 图形数据包仅在图形在屏幕上时在 rAF 循环中运行,在减少动画模式或隐藏标签页下永不运行。
- 窄屏幕(< 760px): 第二种板布局(来源作为顶部3×2药丸网格,阶段3中笔记本缩放至0.6,观察卡片堆叠,隐藏连接器)。相同时间线。
- 减少动画(或用于审查的
?motion=reduce):无固定、无光圈;故事渲染为四个静态纸色帧(p = .30、.55、.78、1处的板)及其标题。 - 板是
aria-hidden的;一个sr-only的有序列表讲述相同的四个步骤。
5. 构建规则
- 一个独立的
index.html:doctype、charset、viewport、color-scheme: dark、theme-color;内联CSS和JS;仅Google字体(Rajdhani、Geist、Geist Mono);图片作为WebP放在页面旁边;图标作为内联SVG精灵。 - 标志符放在
:root上;页面的每种颜色都来自它们(§2)。按角色命名它们,保留产品的十六进制值。 - 国际化:英语位于HTML中(
data-i18n键作为英语源读取一次);其他语言在JS字典中;JS构建的字符串使用T({en, tr})。在try/catch中将选择持久化到localStorage。也翻译标题(大写 + 土耳其语环境将“install”转换为“İNSTALL”)。 - 可访问性:两种背景上AA对比度、可见焦点环(brand-2)、跳过链接、带有
role=tab、aria-selected、焦点切换tabindex和箭头键的选项卡、真正的<table>和<details>、带标签的复制按钮。 - 响应式:≥1060px完整布局;<1060px隐藏英雄区侧面徽章,AI网格堆叠,版本堆叠;<760px单列,图形viewBox裁剪(
150 40 900 480)带更大标签和没有子标签,窄故事板,图节点没有子行。在360px处无水平滚动;检查grid子项有min-width:0。 - 在使用
innerHTML渲染的任何数据字符串中转义<和>(http://<server-ip>)。
6. 撰写文案
- 标题是陈述属性而非承诺的两行短句:“每个发现都保留其来源。”“两个版本。一种文件格式。”“AI阅读发现。绝不重写它们。”
- 段落:一或两句简单的句子,包含具体名词(端口、格式、算法、文件名)。
- 限制与特性获得同等重视(“它从不做什么”、“早期版本”、“有遗漏,故意为之”)。
- 等宽标签为小写且简洁(
key-free、your key、target · sample、sha-256 3f9a…)。
7. 完成清单
- 每个声明、数字、文件名和哈希值与产品自身的文件和当前版本匹配。
- 颜色标记来自产品(图标+亮/暗方案);严重性绝不单靠颜色。
- 故事双向同步,光圈从节点打开并关闭回节点,在p = .27/.5/.75/.9处无重叠。
- 窄布局和减少动画帧均正确读取;数据包在屏幕外停止。
- 选项卡、分页器、搜索、过滤器和复制按钮可通过键盘操作;焦点可见。
- EN/TR切换重新渲染板、图表、表格、终端和标题。
- 在360/390px处无水平滚动;无控制台错误。
- 截图在1440×900和390×844:
node scripts/screenshots.mjs example/index.html screenshots。