Skip to content
Development
Skill

/design

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.

From plugin
vibes
13311 skills2 hooks
Install
$ npx -y skills add popmechanic/VibesOS --skill design --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/design

Context preview

The summary Claude sees to decide when to auto-load this skill.

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.

SKILL.md

design.SKILL.md
name: design
argument-hint: "<design.html>"
description: 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.
license: MIT
allowed-tools: Read, Write, Bash, AskUserQuestion
metadata:
  author: "Marcus Estes"

> **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:**

░▒▓███████▓▒░░▒▓████████▓▒░░▒▓███████▓▒░▒▓█▓▒░░▒▓██████▓▒░░▒▓███████▓▒░
░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░      ░▒▓█▓▒░      ░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░      ░▒▓█▓▒░      ░▒▓█▓▒░▒▓█▓▒░      ░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░░▒▓█▓▒░▒▓██████▓▒░  ░▒▓██████▓▒░░▒▓█▓▒░▒▓█▓▒▒▓███▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░             ░▒▓█▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░             ░▒▓█▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓███████▓▒░░▒▓████████▓▒░▒▓███████▓▒░░▒▓█▓▒░░▒▓██████▓▒░░▒▓█▓▒░░▒▓█▓▒░

Design Reference Transformer

Transform a complete design reference HTML file into a working Vibes app with TinyBase reactive data.

---

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/TinyBase—not to recreate it from your understanding of its aesthetic.

---

When to Use This Skill

Use this skill when:

  • User provides a `design.html`, mockup, or static prototype file
  • 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

---

The Transformation is Mechanical

The 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.

---

Workflow

Step 1: Read the Design Reference

# Read 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)

Step 2: Identify Dynamic Content

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.**

Step 3: Create the React Component

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} */}
    </>
  );
}

Step 4: Handle Dark Mode Override (If Needed)

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.

Step 4b: Scope CSS to Avoid VibesSwitch/VibesPanel Conflicts

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:**

1. Wrap your app content in a container with a class: `<div className="app">...</div>` 2. Scope broad rules: `button { }` → `.app button { }` 3. Or use `#container` which is the template's app root

**The 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.

Step 5: Assemble and Test

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-Patterns (DO NOT DO THESE)

| Anti-Pattern | Why It's Wrong | Correct Approach | |--------------|----------------|------------------| | Translate colors to OKLCH | Changes the design | Use exact hex values fro

Read more
Ships withvibes

Instantly make your own small multi-user apps, without a backend. For apps made with Vibes, the front-end is the app.

Get the whole plugin
Stats
133
Stars
5
Forks
Maintained
Maintenance
HTML
Language
MIT
License
1mo ago
Last commit
8mo ago
Created

Repo: popmechanic/VibesOS

Other skills on vibes.