Install
$ agentstack add skill-timurgaleev-vibestack-design-html ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
When to invoke
Use when: "finalize this design", "turn this into HTML", "build me a page", "implement this design", or after any planning skill.
Proactively suggest when user has approved a design or has a plan ready.
Voice triggers (speech-to-text aliases): "build the design", "code the mockup", "make it real".
Preamble
eval "$(~/.vibestack/bin/vibe-slug 2>/dev/null)" 2>/dev/null || SLUG="unknown"
_LEARN_FILE="${VIBESTACK_HOME:-$HOME/.vibestack}/projects/${SLUG:-unknown}/learnings.jsonl"
if [ -f "$_LEARN_FILE" ]; then
_LEARN_COUNT=$(wc -l /dev/null | tr -d ' ')
echo "LEARNINGS: $_LEARN_COUNT entries loaded"
if [ "$_LEARN_COUNT" -gt 5 ] 2>/dev/null; then
~/.vibestack/bin/vibe-learnings-search --limit 5 2>/dev/null || true
fi
else
echo "LEARNINGS: none yet"
fi
{{include lib/snippets/session-host.md}}
{{include lib/snippets/decision-brief.md}}
{{include lib/snippets/working-protocols.md}}
{{include lib/snippets/state-protocols.md}}
DESIGN SETUP
# Bind $D to vibe-design (OpenAI image backend) when a key is configured.
D=~/.vibestack/bin/vibe-design
if [ -x "$D" ] && [ "$("$D" status 2>/dev/null)" = "DESIGN_AVAILABLE" ]; then
echo "DESIGN_AVAILABLE via $D"
else
echo "DESIGN_NOT_AVAILABLE"
fi
If DESIGN_NOT_AVAILABLE: skip visual mockup generation and fall back to text-based design review.
UX Principles: How Users Actually Behave
These principles govern how real humans interact with interfaces. They are observed behavior, not preferences. Apply them before, during, and after every design decision.
The Three Laws of Usability
- Don't make me think. Every page should be self-evident. If a user stops
to think "What do I click?" or "What does this mean?", the design has failed. Self-evident > self-explanatory > requires explanation.
- Clicks don't matter, thinking does. Three mindless, unambiguous clicks
beat one click that requires thought. Each step should feel like an obvious choice (animal, vegetable, or mineral), not a puzzle.
- Omit, then omit again. Get rid of half the words on each page, then get
rid of half of what's left. Happy talk (self-congratulatory text) must die. Instructions must die. If they need reading, the design has failed.
How Users Actually Behave
- Users scan, they don't read. Design for scanning: visual hierarchy
(prominence = importance), clearly defined areas, headings and bullet lists, highlighted key terms. We're designing billboards going by at 60 mph, not product brochures people will study.
- Users satisfice. They pick the first reasonable option, not the best.
Make the right choice the most visible choice.
- Users muddle through. They don't figure out how things work. They wing
it. If they accomplish their goal by accident, they won't seek the "right" way. Once they find something that works, no matter how badly, they stick to it.
- Users don't read instructions. They dive in. Guidance must be brief,
timely, and unavoidable, or it won't be seen.
Billboard Design for Interfaces
- Use conventions. Logo top-left, nav top/left, search = magnifying glass.
Don't innovate on navigation to be clever. Innovate when you KNOW you have a better idea, otherwise use conventions. Even across languages and cultures, web conventions let people identify the logo, nav, search, and main content.
- Visual hierarchy is everything. Related things are visually grouped. Nested
things are visually contained. More important = more prominent. If everything shouts, nothing is heard. Start with the assumption everything is visual noise, guilty until proven innocent.
- Make clickable things obviously clickable. No relying on hover states for
discoverability, especially on mobile where hover doesn't exist. Shape, location, and formatting (color, underlining) must signal clickability without interaction.
- Eliminate noise. Three sources: too many things shouting for attention
(shouting), things not organized logically (disorganization), and too much stuff (clutter). Fix noise by removal, not addition.
- Clarity trumps consistency. If making something significantly clearer
requires making it slightly inconsistent, choose clarity every time.
Navigation as Wayfinding
Users on the web have no sense of scale, direction, or location. Navigation must always answer: What site is this? What page am I on? What are the major sections? What are my options at this level? Where am I? How can I search?
Persistent navigation on every page. Breadcrumbs for deep hierarchies. Current section visually indicated. The "trunk test": cover everything except the navigation. You should still know what site this is, what page you're on, and what the major sections are. If not, the navigation has failed.
The Goodwill Reservoir
Users start with a reservoir of goodwill. Every friction point depletes it.
Deplete faster: Hiding info users want (pricing, contact, shipping). Punishing users for not doing things your way (formatting requirements on phone numbers). Asking for unnecessary information. Putting sizzle in their way (splash screens, forced tours, interstitials). Unprofessional or sloppy appearance.
Replenish: Know what users want to do and make it obvious. Tell them what they want to know upfront. Save them steps wherever possible. Make it easy to recover from errors. When in doubt, apologize.
Mobile: Same Rules, Higher Stakes
All the above applies on mobile, just more so. Real estate is scarce, but never sacrifice usability for space savings. Affordances must be VISIBLE: no cursor means no hover-to-discover. Touch targets must be big enough (44px minimum). Flat design can strip away useful visual information that signals interactivity. Prioritize ruthlessly: things needed in a hurry go close at hand, everything else a few taps away with an obvious path to get there.
SETUP
# vibestack does not include a browse daemon.
echo "BROWSE_NOT_AVAILABLE"
If BROWSE_NOT_AVAILABLE: skip all $B commands and use text-only fallbacks (curl, open, direct HTTP checks).
Step 0: Input Detection
eval "$(~/.vibestack/bin/vibe-slug 2>/dev/null)"
Detect what design context exists for this project. Run all four checks:
setopt +o nomatch 2>/dev/null || true
_CEO=$(ls -t ~/.vibestack/projects/$SLUG/ceo-plans/*.md 2>/dev/null | head -1)
[ -n "$_CEO" ] && echo "CEO_PLAN: $_CEO" || echo "NO_CEO_PLAN"
setopt +o nomatch 2>/dev/null || true
_APPROVED=$(ls -t ~/.vibestack/projects/$SLUG/designs/*/approved.json 2>/dev/null | head -1)
[ -n "$_APPROVED" ] && echo "APPROVED: $_APPROVED" || echo "NO_APPROVED"
setopt +o nomatch 2>/dev/null || true
_VARIANTS=$(ls -t ~/.vibestack/projects/$SLUG/designs/*/variant-*.png 2>/dev/null | head -1)
[ -n "$_VARIANTS" ] && echo "VARIANTS: $_VARIANTS" || echo "NO_VARIANTS"
setopt +o nomatch 2>/dev/null || true
_FINALIZED=$(ls -t ~/.vibestack/projects/$SLUG/designs/*/finalized.html 2>/dev/null | head -1)
[ -n "$_FINALIZED" ] && echo "FINALIZED: $_FINALIZED" || echo "NO_FINALIZED"
[ -f DESIGN.md ] && echo "DESIGN_MD: exists" || echo "NO_DESIGN_MD"
Now route based on what was found. Check these cases in order:
Case A: approved.json exists (design-shotgun ran)
If APPROVED was found, read it. Extract: approved variant PNG path, user feedback, screen name. Also read the CEO plan if one exists (it adds strategic context).
Read DESIGN.md if it exists in the repo root. These tokens take priority for system-level values (fonts, brand colors, spacing scale).
Then check for prior finalized.html. If FINALIZED was also found, use AskUserQuestion: > Found a prior finalized HTML from a previous session. Want to evolve it > (apply new changes on top, preserving your custom edits) or start fresh? > A) Evolve — iterate on the existing HTML > B) Start fresh — regenerate from the approved mockup
If evolve: read the existing HTML. Apply changes on top during Step 3. If fresh or no finalized.html: proceed to Step 1 with the approved PNG as the visual reference.
Case B: CEO plan and/or design variants exist, but no approved.json
If CEO_PLAN or VARIANTS was found but no APPROVED:
Read whichever context exists:
- If CEO plan found: read it and summarize the product vision and design requirements.
- If variant PNGs found: show them inline using the Read tool.
- If DESIGN.md found: read it for design tokens and constraints.
Use AskUserQuestion: > Found [CEO plan from /plan-ceo-review | design review variants from /plan-design-review | both] > but no approved design mockup. > A) Run /design-shotgun — explore design variants based on the existing plan context > B) Skip mockups — I'll design the HTML directly from the plan context > C) I have a PNG — let me provide the path
If A: tell the user to run /design-shotgun, then come back to /design-html. If B: proceed to Step 1 in "plan-driven mode." There is no approved PNG, the plan is the source of truth. Ask the user for a screen name to use for the output directory (e.g., "landing-page", "dashboard", "pricing"). If C: accept a PNG file path from the user and proceed with that as the reference.
Case C: Nothing found (clean slate)
If none of the above produced any context:
Use AskUserQuestion: > No design context found for this project. How do you want to start? > A) Run /plan-ceo-review first — think through the product strategy before designing > B) Run /plan-design-review first — design review with visual mockups > C) Run /design-shotgun — jump straight to visual design exploration > D) Just describe it — tell me what you want and I'll design the HTML live
If A, B, or C: tell the user to run that skill, then come back to /design-html. If D: proceed to Step 1 in "freeform mode." Ask the user for a screen name.
Context summary
After routing, output a brief context summary:
- Mode: approved-mockup | plan-driven | freeform | evolve
- Visual reference: path to approved PNG, or "none (plan-driven)" or "none (freeform)"
- CEO plan: path or "none"
- Design tokens: "DESIGN.md" or "none"
- Screen name: from approved.json, user-provided, or inferred from CEO plan
Step 1: Design Analysis
- If
$Dis available (DESIGN_READY), extract a structured implementation spec:
$D prompt --image --output json
This returns colors, typography, layout structure, and component inventory via GPT-4o vision.
- If
$Dis not available, read the approved PNG inline using the Read tool.
Describe the visual layout, colors, typography, and component structure yourself.
- If in plan-driven or freeform mode (no approved PNG), design from context:
- Plan-driven: read the CEO plan and/or design review notes. Extract the described
UI requirements, user flows, target audience, visual feel (dark/light, dense/spacious), content structure (hero, features, pricing, etc.), and design constraints. Build an implementation spec from the plan's prose rather than a visual reference.
- Freeform: use AskUserQuestion to gather what the user wants to build. Ask about:
purpose/audience, visual feel (dark/light, playful/serious, dense/spacious), content structure (hero, features, pricing, etc.), and any reference sites they like. In both cases, describe the intended visual layout, colors, typography, and component structure as your implementation spec. Generate realistic content based on the plan or user description (never lorem ipsum).
- Read
DESIGN.mdtokens. These override any extracted values for system-level
properties (brand colors, font family, spacing scale).
- Output an "Implementation spec" summary: colors (hex), fonts (family + weights),
spacing scale, component list, layout type.
Step 2: Smart Pretext API Routing
Analyze the approved design and classify it into a Pretext tier. Each tier uses different Pretext APIs for optimal results:
| Design type | Pretext APIs | Use case | |-------------|-------------|----------| | Simple layout (landing, marketing) | prepare() + layout() | Resize-aware heights | | Card/grid (dashboard, listing) | prepare() + layout() | Self-sizing cards | | Chat/messaging UI | prepareWithSegments() + walkLineRanges() | Tight-fit bubbles, min-width | | Content-heavy (editorial, blog) | prepareWithSegments() + layoutNextLine() | Text around obstacles | | Complex editorial | Full engine + layoutWithLines() | Manual line rendering |
State the chosen tier and why. Reference the specific Pretext APIs that will be used.
Step 2.5: Framework Detection
Check if the user's project uses a frontend framework:
[ -f package.json ] && cat package.json | grep -o '"react"\|"svelte"\|"vue"\|"@angular/core"\|"solid-js"\|"preact"' | head -1 || echo "NONE"
If a framework is detected, use AskUserQuestion: > Detected [React/Svelte/Vue] in your project. What format should the output be? > A) Vanilla HTML — self-contained preview file (recommended for first pass) > B) [React/Svelte/Vue] component — framework-native with Pretext hooks
If the user chooses framework output, ask one follow-up: > A) TypeScript > B) JavaScript
For vanilla HTML: proceed to Step 3 with vanilla output. For framework output: proceed to Step 3 with framework-specific patterns. If no framework detected: default to vanilla HTML, no question needed.
Step 3: Generate Pretext-Native HTML
Pretext Source Embedding
For vanilla HTML output, check for the vendored Pretext bundle:
_PRETEXT_VENDOR=""
_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
[ -n "$_ROOT" ] && [ -f "$_ROOT/.claude/skills/design-html/vendor/pretext.js" ] && _PRETEXT_VENDOR="$_ROOT/.claude/skills/design-html/vendor/pretext.js"
[ -z "$_PRETEXT_VENDOR" ] && [ -f ~/.claude/skills/design-html/vendor/pretext.js ] && _PRETEXT_VENDOR=~/.claude/skills/design-html/vendor/pretext.js
[ -n "$_PRETEXT_VENDOR" ] && echo "VENDOR: $_PRETEXT_VENDOR" || echo "VENDOR_MISSING"
- If
VENDORfound: read the file and inline it in a `` tag. The HTML file
is fully self-contained with zero network dependencies.
- If
VENDOR_MISSING: use CDN import as fallback:
import { prepare, layout, prepareWithSegments, walkLineRanges, layoutNextLine, layoutWithLines } from 'https://esm.sh/@chenglou/pretext' Add a comment: ``
For framework output, add to the project's dependencies instead:
# Detect package manager
[ -f bun.lockb ] && echo "bun add @chenglou/pretext" || \
[ -f pnpm-lock.yaml ] && echo "pnpm add @chenglou/pretext" || \
[ -f yarn.lock ] && echo "yarn add @chenglou/pretext" || \
echo "npm install @chenglou/pretext"
Run the detected install command. Then use standard imports in the component.
HTML Generation
Write a single file using the Write tool. Save to: ~/.vibestack/projects/$SLUG/designs/-YYYYMMDD/finalized.html
For framework output, save to: ~/.vibestack/projects/$SLUG/designs/-YYYYMMDD/finalized.[tsx|svelte|vue]
Always include in vanilla HTML:
- Pretext source (inlined or CDN, see above)
- CSS custom properties for design tokens from DESIGN.md / Step 1 extraction
- Google Fonts via `
tags +document.fonts.readygate before firstprepare()` - Semantic HTML5 (`
,,,,`) - Responsive behavior via Pretext relayout (not just media queries)
- Breakpoint-specific adjustments at 375px, 768px, 1024px, 1440px
- ARIA attributes, heading hierarchy, focus-visible states
contenteditableon text elements + MutationObserver to re-prepare + re-layout on edit- ResizeObserver on containers to re-layout on resize
prefers-color-schememedia query for dark modeprefers-reduced-motionfor animation respect- Real content extracted from the mockup (never lorem ipsum)
Never include (AI slop blacklist):
- Purple/blue gradients as default
- G
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: timurgaleev
- Source: timurgaleev/vibestack
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.