design-reference
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePlan mode: If you are planning work, this entire skill is ONE plan step: "Invoke /vibes:design-reference". Do not decompose the steps below into separate plan tasks.
Display this ASCII art immediately when starting:
░▒▓███████▓▒░░▒▓████████▓▒░░▒▓███████▓▒░▒▓█▓▒░░▒▓██████▓▒░░▒▓███████▓▒░
░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░░▒▓█▓▒░▒▓██████▓▒░ ░▒▓██████▓▒░░▒▓█▓▒░▒▓█▓▒▒▓███▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓███████▓▒░░▒▓████████▓▒░▒▓███████▓▒░░▒▓█▓▒░░▒▓██████▓▒░░▒▓█▓▒░░▒▓█▓▒░计划模式:如果你正在规划工作,整个技能仅作为一个计划步骤:"调用 /vibes:design-reference"。不要将以下步骤拆分为单独的计划任务。
开始时立即显示此ASCII图案:
░▒▓███████▓▒░░▒▓████████▓▒░░▒▓███████▓▒░▒▓█▓▒░░▒▓██████▓▒░░▒▓███████▓▒░
░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░░▒▓█▓▒░▒▓██████▓▒░ ░▒▓██████▓▒░░▒▓█▓▒░▒▓█▓▒▒▓███▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓███████▓▒░░▒▓████████▓▒░▒▓███████▓▒░░▒▓█▓▒░░▒▓██████▓▒░░▒▓█▓▒░░▒▓█▓▒░Design Reference Transformer
设计参考转换工具
Transform a complete design reference HTML file into a working Vibes app with Fireproof data persistence.
将完整的设计参考HTML文件转换为带有Fireproof数据持久化功能的可运行Vibes应用。
Core Principle
核心原则
Preserve and adapt, don't interpret and recreate.
The design reference is source code to transform, not inspiration to interpret. When given a complete HTML file with styles, your job is to make minimal surgical changes to connect it to React/Fireproof—not to recreate it from your understanding of its aesthetic.
保留并适配,而非解读与重造。
设计参考是待转换的源代码,而非用于解读的灵感来源。当收到包含样式的完整HTML文件时,你的工作是进行最小化的精准修改以将其连接到React/Fireproof——而非根据你对其美学的理解重造它。
When to Use This Skill
何时使用此技能
Use this skill when:
- User provides a , mockup, or static prototype file
design.html - User says "match this design exactly" or "use this as a reference"
- User wants their existing HTML converted to a Vibes app
- A previous implementation didn't match the design reference
在以下场景使用此技能:
- 用户提供、模型或静态原型文件
design.html - 用户表示“完全匹配此设计”或“以此为参考”
- 用户希望将现有HTML转换为Vibes应用
- 之前的实现未匹配设计参考
The Transformation is Mechanical
转换过程是机械性的
The conversion from design HTML to React/Fireproof is deterministic, not creative:
| Transformation | Rule | Example |
|---|---|---|
| Attributes | | |
| Attributes | | |
| Attributes | kebab-case → camelCase | |
| Self-closing | Add explicit close | |
| Comments | HTML → JSX | |
| Inline styles | String → Object | |
| Event handlers | Lowercase → camelCase | |
CSS requires NO changes. Copy the entire block verbatim.
<style>从设计HTML到React/Fireproof的转换是确定性的,而非创造性的:
| 转换操作 | 规则 | 示例 |
|---|---|---|
| 属性 | | |
| 属性 | | |
| 属性 | 短横线命名 → 驼峰命名 | |
| 自闭合标签 | 添加显式闭合 | |
| 注释 | HTML → JSX | |
| 内联样式 | 字符串 → 对象 | |
| 事件处理器 | 小写 → 驼峰命名 | |
CSS无需修改。 完整复制块内容。
<style>Workflow
工作流程
Step 1: Read the Design Reference
步骤1:读取设计参考
bash
undefinedbash
undefinedRead the design file completely
完整读取设计文件
Read design.html
Note the structure:
- `<style>` block (copy verbatim)
- HTML structure (preserve exactly)
- Any vanilla JavaScript (will be replaced with React)Read design.html
注意以下结构:
- `<style>`块(原样复制)
- HTML结构(完全保留)
- 任何原生JavaScript(将被React替代)Step 2: Identify Dynamic Content
步骤2:识别动态内容
Ask: "What content comes from the database?"
Typical dynamic elements:
- List items that repeat ()
.map() - Text that users enter (controlled inputs)
- Counts, totals, timestamps
- User-specific content
Everything else stays static.
思考:“哪些内容来自数据库?”
典型的动态元素:
- 重复的列表项(使用)
.map() - 用户输入的文本(受控输入框)
- 计数、总计、时间戳
- 用户专属内容
其他所有内容保持静态。
Step 3: Create the React Component
步骤3:创建React组件
jsx
import React from "react";
import { useFireproofClerk } from "use-fireproof";
export default function App() {
const { database, useLiveQuery, useDocument } = useFireproofClerk("app-db");
// Hooks for dynamic data
const { doc, merge, submit } = useDocument({ /* initial shape */ });
const { docs } = useLiveQuery("type", { key: "item" });
return (
<>
{/* CSS copied VERBATIM from design.html */}
<style>{`
/* Paste entire <style> block here unchanged */
`}</style>
{/* HTML structure preserved, only syntax converted */}
{/* Dynamic content replaced with {expressions} */}
</>
);
}jsx
import React from "react";
import { useFireproofClerk } from "use-fireproof";
export default function App() {
const { database, useLiveQuery, useDocument } = useFireproofClerk("app-db");
// 动态数据钩子
const { doc, merge, submit } = useDocument({ /* 初始结构 */ });
const { docs } = useLiveQuery("type", { key: "item" });
return (
<>
{/* 从design.html原样复制的CSS */}
<style>{`
{/* 在此处粘贴完整的<style>块内容,不做修改 */}
`}</style>
{/* HTML结构保留,仅转换语法 */}
{/* 动态内容替换为{表达式} */}
</>
);
}Step 4: Handle Dark Mode Override (If Needed)
步骤4:处理深色模式覆盖(如需)
The Vibes template has dark mode support. If your design is light-only, add this CSS override:
css
/* Force light theme regardless of system preference */
html, body, #container, #container > div {
background-color: var(--your-bg-color) !important;
}Note: Avoid targeting as this will style the VibesSwitch toggle button.
[style*="position: fixed"]Vibes模板支持深色模式。若你的设计仅支持浅色模式,添加以下CSS覆盖:
css
/* 强制使用浅色主题,不受系统偏好设置影响 */
html, body, #container, #container > div {
background-color: var(--your-bg-color) !important;
}注意: 避免定位,这会影响VibesSwitch切换按钮的样式。
[style*="position: fixed"]Step 4b: Scope CSS to Avoid VibesSwitch/VibesPanel Conflicts
步骤4b:限定CSS作用域以避免与VibesSwitch/VibesPanel冲突
The template includes a VibesSwitch toggle button and VibesPanel admin menu that sit outside your app container. Broad CSS selectors can accidentally style these components.
Watch for these problematic patterns:
| Problematic | Why | Safe Alternative |
|---|---|---|
| Styles VibesSwitch toggle | |
| Cascades everywhere | Scope to specific containers |
| Targets VibesSwitch | Target by class/ID instead |
| May match menu wrapper | Use |
If your design has global button/element styles:
- Wrap your app content in a container with a class:
<div className="app">...</div> - Scope broad rules: →
button { }.app button { } - Or use which is the template's app root
#container
The template already protects components with:
css
button[aria-controls="hidden-menu"] { background: transparent !important; }
#hidden-menu { /* menu-specific variable resets */ }But defense-in-depth is better—scope your CSS to avoid conflicts.
模板包含VibesSwitch切换按钮和VibesPanel管理菜单,它们位于应用容器外部。宽泛的CSS选择器可能会意外影响这些组件的样式。
注意以下有问题的模式:
| 有问题的写法 | 原因 | 安全替代方案 |
|---|---|---|
| 会样式化VibesSwitch切换按钮 | |
| 会全局级联 | 限定到特定容器 |
| 会定位VibesSwitch | 改用类名/ID定位 |
| 可能匹配菜单容器 | 使用 |
若你的设计包含全局按钮/元素样式:
- 将应用内容包裹在带类名的容器中:
<div className="app">...</div> - 限定宽泛规则的作用域:→
button { }.app button { } - 或使用模板的应用根容器
#container
模板已通过以下方式保护组件:
css
button[aria-controls="hidden-menu"] { background: transparent !important; }
#hidden-menu { /* 菜单专属变量重置 */ }但多层防御更稳妥——限定你的CSS作用域以避免冲突。
Step 5: Assemble and Test
步骤5:组装与测试
bash
node "/path/to/vibes-skill/scripts/assemble.js" app.jsx index.htmlOpen in browser and visually diff against the design reference. They should be pixel-identical except for dynamic content.
bash
node "/path/to/vibes-skill/scripts/assemble.js" app.jsx index.html在浏览器中打开并与设计参考进行视觉对比。除动态内容外,两者应像素级一致。
Anti-Patterns (DO NOT DO THESE)
反模式(切勿执行)
| Anti-Pattern | Why It's Wrong | Correct Approach |
|---|---|---|
| Translate colors to OKLCH | Changes the design | Use exact hex values from reference |
| Restructure HTML "for React" | Breaks layout | Preserve structure, only change syntax |
| "Improve" the CSS | Not your job | Copy verbatim |
| Add your own classes | Introduces drift | Use exact classes from reference |
| Interpret the "vibe" | Creates divergence | Be literal, not interpretive |
| Skip vanilla JS analysis | Miss functionality | Understand what it does, then React-ify |
| 反模式 | 错误原因 | 正确做法 |
|---|---|---|
| 将颜色转换为OKLCH | 会改变设计 | 使用参考文件中的精确十六进制值 |
| 为适配React重构HTML | 会破坏布局 | 保留结构,仅修改语法 |
| “优化”CSS | 这不是你的工作 | 原样复制 |
| 添加自定义类名 | 会导致设计偏差 | 使用参考文件中的精确类名 |
| 解读设计的“风格” | 会产生差异 | 严格按字面转换,不做解读 |
| 跳过原生JavaScript分析 | 会遗漏功能 | 先理解其功能,再转换为React实现 |
Transformation Checklist
转换检查清单
Before writing code, verify:
- Read the entire design.html file
- Identified all blocks (will copy verbatim)
<style> - Identified dynamic content (lists, inputs, user data)
- Identified vanilla JS functionality (will convert to React)
- Noted any custom fonts (add to imports if needed)
- Checked for dark/light theme assumptions
During transformation:
- CSS pasted unchanged (no "improvements")
- HTML structure preserved exactly
- Only syntax converted (class→className, etc.)
- Dynamic content uses and
{expressions}.map() - Vanilla JS replaced with React hooks and handlers
- Dark mode override added if design is light-only
After assembly:
- Visual comparison with design reference
- All interactive elements work
- Data persists on refresh
- No console errors
- VibesSwitch toggle (bottom-right) displays correctly with no background box
- VibesPanel menu opens when toggle is clicked
- Menu buttons are correctly styled (not inheriting app button styles)
编写代码前,确认:
- 已完整阅读design.html文件
- 已识别所有块(将原样复制)
<style> - 已识别动态内容(列表、输入框、用户数据)
- 已识别原生JavaScript功能(将转换为React实现)
- 已记录任何自定义字体(如需添加至导入)
- 已检查深色/浅色主题预设
转换过程中:
- CSS已原样粘贴(无“优化”)
- HTML结构已完全保留
- 仅转换语法(class→className等)
- 动态内容使用和
{表达式}.map() - 原生JavaScript已替换为React钩子和处理函数
- 若设计仅支持浅色模式,已添加深色模式覆盖
组装完成后:
- 与设计参考进行视觉对比
- 所有交互元素可正常工作
- 刷新后数据可持久化
- 控制台无错误
- VibesSwitch切换按钮(右下角)显示正常,无背景框
- 点击切换按钮可打开VibesPanel管理菜单
- 菜单按钮样式正确(未继承应用按钮样式)
Example: Static List → Dynamic List
示例:静态列表 → 动态列表
Design HTML:
html
<ul class="item-list">
<li class="item">First item</li>
<li class="item">Second item</li>
</ul>React with Fireproof:
jsx
const { docs } = useLiveQuery("type", { key: "item" });
<ul className="item-list">
{docs.map(item => (
<li key={item._id} className="item">{item.text}</li>
))}
</ul>Note: Only the content changed. The classes, structure, and styling are identical.
设计HTML:
html
<ul class="item-list">
<li class="item">First item</li>
<li class="item">Second item</li>
</ul>搭配Fireproof的React实现:
jsx
const { docs } = useLiveQuery("type", { key: "item" });
<ul className="item-list">
{docs.map(item => (
<li key={item._id} className="item">{item.text}</li>
))}
</ul>注意:仅内容发生变化。类名、结构和样式完全一致。
Example: Static Form → Controlled Form
示例:静态表单 → 受控表单
Design HTML:
html
<form>
<input type="text" class="input" placeholder="Enter text...">
<button class="btn">Submit</button>
</form>React with Fireproof:
jsx
const { doc, merge, submit } = useDocument({ text: "", type: "item" });
<form onSubmit={submit}>
<input
type="text"
className="input"
placeholder="Enter text..."
value={doc.text}
onChange={(e) => merge({ text: e.target.value })}
/>
<button type="submit" className="btn">Submit</button>
</form>Note: Same structure, same classes, same placeholder. Only added React bindings.
设计HTML:
html
<form>
<input type="text" class="input" placeholder="Enter text...">
<button class="btn">Submit</button>
</form>搭配Fireproof的React实现:
jsx
const { doc, merge, submit } = useDocument({ text: "", type: "item" });
<form onSubmit={submit}>
<input
type="text"
className="input"
placeholder="Enter text..."
value={doc.text}
onChange={(e) => merge({ text: e.target.value })}
/>
<button type="submit" className="btn">Submit</button>
</form>注意:结构、类名、占位文本均相同。仅添加了React绑定。
Integration with Vibes Assembly
与Vibes组装工具的集成
This skill produces an that works with the standard Vibes assembly:
app.jsxbash
undefined此技能生成的可与标准Vibes组装工具配合使用:
app.jsxbash
undefinedIn the working directory
在工作目录中执行
node "/path/to/vibes-skill/scripts/assemble.js" app.jsx index.html
The assembly script:
- Inserts your JSX into the Vibes template
- Handles Clerk authentication wrapper
- Sets up import maps for React and Fireproof
- Configures Connect if `.env` is present
---node "/path/to/vibes-skill/scripts/assemble.js" app.jsx index.html
组装脚本会:
- 将你的JSX插入Vibes模板
- 处理Clerk认证包装
- 为React和Fireproof设置导入映射
- 若存在`.env`文件则配置Connect
---What's Next?
下一步操作?
After transforming a design reference, present these options using AskUserQuestion:
Question: "Design reference transformed! What's next?"
Header: "Next"
Options:
- Label: "Test locally"
Description: "Open index.html in browser to verify it matches the design exactly"
- Label: "Deploy to exe.dev (/exe)"
Description: "Push the app live at yourapp.exe.xyz"
- Label: "Make adjustments"
Description: "Fine-tune specific elements while preserving the design"
- Label: "I'm done"
Description: "Wrap up - files are saved locally"完成设计参考转换后,使用AskUserQuestion呈现以下选项:
Question: "Design reference transformed! What's next?"
Header: "Next"
Options:
- Label: "Test locally"
Description: "Open index.html in browser to verify it matches the design exactly"
- Label: "Deploy to exe.dev (/exe)"
Description: "Push the app live at yourapp.exe.xyz"
- Label: "Make adjustments"
Description: "Fine-tune specific elements while preserving the design"
- Label: "I'm done"
Description: "Wrap up - files are saved locally"