Self-contained design transformer — invoke directly, do not decompose. Transforms a design reference HTML file into a Vibes app. Use when user provides a design.html, mockup, or static prototype to match exactly.
npx skills add https://github.com/popmechanic/VibesOS --skill design
> Plan mode: If you are planning work, this entire skill is ONE plan step: "Invoke /vibes:design". Do not decompose the steps below into separate plan tasks.
Display this ASCII art immediately when starting:
░▒▓███████▓▒░░▒▓████████▓▒░░▒▓███████▓▒░▒▓█▓▒░░▒▓██████▓▒░░▒▓███████▓▒░
░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░░▒▓█▓▒░▒▓██████▓▒░ ░▒▓██████▓▒░░▒▓█▓▒░▒▓█▓▒▒▓███▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓███████▓▒░░▒▓████████▓▒░▒▓███████▓▒░░▒▓█▓▒░░▒▓██████▓▒░░▒▓█▓▒░░▒▓█▓▒░
Transform a complete design reference HTML file into a working Vibes app with TinyBase reactive data.
> 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/TinyBase—not to recreate it from your understanding of its aesthetic.
Use this skill when:
design.html, mockup, or static prototype fileThe conversion from design HTML to React/TinyBase is deterministic, not creative:
| Transformation | Rule | Example |
|----------------|------|---------|
| Attributes | class → className | class="btn" → className="btn" |
| Attributes | for → htmlFor | for="email" → htmlFor="email" |
| Attributes | kebab-case → camelCase | stroke-width → strokeWidth |
| Self-closing | Add explicit close | <input> → <input /> |
| Comments | HTML → JSX | <!-- x --> → {/* x */} |
| Inline styles | String → Object | style="color: red" → style={{ color: 'red' }} |
| Event handlers | Lowercase → camelCase | onclick → onClick |
CSS requires NO changes. Copy the entire <style> block verbatim.
# Read the design file completely
Read design.html
Note the structure:
<style> block (copy verbatim)Ask: "What content comes from the database?"
Typical dynamic elements:
.map())Everything else stays static.
function App() {
// TinyBase hooks are globals — no imports, no initialization call needed
const rowIds = useRowIds('items');
const handleAdd = useAddRowCallback('items', (e) => ({
text: '', type: 'item', created: Date.now()
}));
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} */}
</>
);
}
The Vibes template has dark mode support. If your design is light-only, add this CSS override:
/* Force light theme regardless of system preference */
html, body, #container, #container > div {
background-color: var(--your-bg-color) !important;
}
Note: Avoid targeting [style*="position: fixed"] as this will style the VibesSwitch toggle button.
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 |
|-------------|-----|------------------|
| button { ... } | Styles VibesSwitch toggle | .app button { ... } or #container button { ... } |
| * { ... } (with colors/backgrounds) | Cascades everywhere | Scope to specific containers |
| [style*="position: fixed"] | Targets VibesSwitch | Target by class/ID instead |
| body > div | May match menu wrapper | Use #container > div |
If your design has global button/element styles:
<div className="app">...</div>button { } → .app button { }#container which is the template's app rootThe template already protects components with:
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.
VIBES_ROOT="${CLAUDE_PLUGIN_ROOT:-$(dirname "$(dirname "${CLAUDE_SKILL_DIR}")")}"
bun "$VIBES_ROOT/scripts/assemble.js" app.jsx index.html
Open in browser and visually diff against the design reference. They should be pixel-identical except for dynamic content.
| 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 |
Before writing code, verify:
<style> blocks (will copy verbatim)During transformation:
{expressions} and .map()After assembly:
Design HTML:
<ul class="item-list">
<li class="item">First item</li>
<li class="item">Second item</li>
</ul>
React with TinyBase:
const rowIds = useRowIds('items');
<ul className="item-list">
{rowIds.map(id => (
<ItemRow key={id} id={id} />
))}
</ul>
// Child component uses useCell for reactive per-row data
function ItemRow({ id }) {
const text = useCell('items', id, 'text');
return <li className="item">{text}</li>;
}
Note: Only the content changed. The classes, structure, and styling are identical.
Design HTML:
<form>
<input type="text" class="input" placeholder="Enter text...">
<button class="btn">Submit</button>
</form>
React with TinyBase:
const [text, setText] = useState('');
const handleAdd = useAddRowCallback('items', () => ({
text, type: 'item', created: Date.now()
}));
<form onSubmit={(e) => { e.preventDefault(); handleAdd(); setText(''); }}>
<input
type="text"
className="input"
placeholder="Enter text..."
value={text}
onChange={(e) => setText(e.target.value)}
/>
<button type="submit" className="btn">Submit</button>
</form>
Note: Same structure, same classes, same placeholder. Only added React bindings.
This skill produces an app.jsx that works with the standard Vibes assembly:
# In the working directory
VIBES_ROOT="${CLAUDE_PLUGIN_ROOT:-$(dirname "$(dirname "${CLAUDE_SKILL_DIR}")")}"
bun "$VIBES_ROOT/scripts/assemble.js" app.jsx index.html
The assembly script:
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 Cloudflare (/cloudflare)"
Description: "Push the app live to Cloudflare Workers"
- Label: "Make adjustments"
Description: "Fine-tune specific elements while preserving the design"
- Label: "I'm done"
Description: "Wrap up - files are saved locally"
Integration with protocols.io API for managing scientific protocols. This skill should be used when working with protocols.io to search, create, update, or publish protocols; manage protocol steps and materials; handle discussions and comments; organize workspaces; upload and manage files; or integrate protocols.io functionality into workflows. Applicable for protocol discovery, collaborative protocol development, experiment tracking, lab protocol management, and scientific documentation.
Analyzes job descriptions and generates tailored resumes that highlight relevant experience, skills, and achievements to maximize interview chances
Generate Excalidraw diagrams from natural language descriptions. Use when asked to "create a diagram", "make a flowchart", "visualize a process", "draw a system architecture", "create a mind map", or "generate an Excalidraw file". Supports flowcharts, relationship diagrams, mind maps, and system architecture diagrams. Outputs .excalidraw JSON files that can be opened directly in Excalidraw.
Build and distribute Expo development clients locally or via TestFlight
Use when you have a written implementation plan to execute in a separate session with review checkpoints
Data structure for annotated matrices in single-cell analysis. Use when working with .h5ad files or integrating with the scverse ecosystem. This is the data format skill—for analysis workflows use scanpy; for probabilistic models use scvi-tools; for population-scale queries use cellxgene-census.
Benchling R&D platform integration. Access registry (DNA, proteins), inventory, ELN entries, workflows via API, build Benchling Apps, query Data Warehouse, for lab data management automation.
Comprehensive molecular biology toolkit. Use for sequence manipulation, file parsing (FASTA/GenBank/PDB), phylogenetics, and programmatic NCBI/PubMed access (Bio.Entrez). Best for batch processing, custom bioinformatics pipelines, BLAST automation. For quick lookups use gget; for multi-service integration use bioservices.
Take popmechanic/design from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.