The /playground skill
/playground builds self-contained single-file HTML explorers. Three zones: a
controls panel (left), a live preview (right), and a
natural-language prompt output (bottom) with a copy button. User tweaks controls,
preview updates instantly, prompt updates live, user copies it back into Claude. No server, no CDN,
zero dependencies. Six templates cover design, data, learning, document review, code diffs, and
architecture diagrams.
The loop
The playground exists to bridge the gap between visual exploration and Claude instructions. The loop is:
The key insight: the hardest part of complex requests is articulating what you want. The playground handles that articulation for you — you explore visually and it writes the prompt.
The 6 templates
Playground picks the closest template automatically based on your request. Each template defines the layout, control types, preview rendering approach, and prompt output format.
▸ design-playground visual design
For visual design decisions: components, layouts, spacing, color, typography, animation, responsive behavior. Controls map directly to CSS properties; the prompt describes the result as a direction to a developer.
Control types
| Decision | Control | Example |
|---|---|---|
| Sizes, spacing, radius | Slider | border-radius 0–24px |
| On/off features | Toggle | show border, hover effect |
| Choosing from a set | Dropdown | font-family, easing curve |
| Colors | H+S+L sliders | shadow color, accent hue |
| Layout structure | Clickable cards | sidebar-left / top-nav / no-nav |
| Responsive behavior | Viewport-width slider | watch grid reflow at breakpoints |
Example prompt output
Written as a direction to a developer, not a spec sheet:
Use cases
▸ data-explorer data & queries
For data queries, APIs, pipelines, and structured config: SQL builders, API designers, regex builders, pipeline visuals, cron schedules. Preview renders syntax-highlighted output or a visual flow diagram.
Control types
| Decision | Control | Example |
|---|---|---|
| Select from available items | Clickable cards / chips | table names, columns, HTTP methods |
| Add filter / condition rows | Add button → row of dropdowns + input | WHERE column op value |
| Join type or aggregation | Dropdown per row | INNER/LEFT/RIGHT, COUNT/SUM/AVG |
| Limit / offset | Slider | result count 1–500 |
| Ordering | Dropdown + ASC/DESC toggle | order by column |
| On/off features | Toggle | include header, show descriptions |
Preview rendering
Syntax-highlighted output using <span> tags with color classes for keywords, table names, strings. Or a horizontal/vertical flow diagram with arrow connectors for pipeline-style playgrounds.
Example prompt output
orders to users on user_id, filters for orders after 2024-01-01 with total > $50, groups by user, and returns the top 10 users by order count."Use cases
▸ concept-map learning & exploration
Canvas-based learning and knowledge maps. The visual IS the control — users drag nodes, draw connections, mark knowledge levels. Different from other templates: there's no separate controls panel, the canvas is the interaction.
Interaction model
| Decision | Control | Example |
|---|---|---|
| Knowledge level per node | Click-to-cycle in sidebar | Know → Fuzzy → Unknown |
| Connection type | Selector before drawing edge | calls, depends on, contains, reads from |
| Node arrangement | Drag on canvas | spatial layout reflects mental model |
| Which nodes to include | Toggle per node | hide/show concepts |
| Auto-layout | Button | Force-directed spring simulation |
Example prompt output
Use cases
▸ document-critique doc review
Review and critique documents with an approve/reject/comment workflow. Left panel shows the document with line-level highlights; right panel shows filterable suggestions. Only approved items make it into the prompt.
Color coding
| State | Left border color | Background |
|---|---|---|
| Pending | Amber #bf8700 | rgba(191,135,0,0.08) |
| Approved | Green #1a7f37 | rgba(26,127,55,0.08) |
| Rejected | Red #cf222e | rgba(207,34,46,0.08) + opacity 0.6 |
Pre-populating for a specific doc
When building a critique playground for your document: read the doc → analyze and generate suggestions with specific line references + category tags (clarity, completeness, performance, accessibility, ux) → embed both the doc content and suggestions array in the HTML.
Use cases
▸ diff-review git diffs
Review git diffs with interactive line-level commenting. Click any diff line to open a textarea, save a comment, and see a 💬 badge appear. The prompt output formats all comments as structured code review feedback with file:line references.
Line type styling
| Type | Background | Prefix |
|---|---|---|
| context | transparent | (space) |
| addition | #dafbe1 (light) / rgba(46,160,67,0.15) (dark) | + |
| deletion | #ffebe9 (light) / rgba(248,81,73,0.15) (dark) | - |
| hunk header | #ddf4ff (light) | @@ |
Pre-populating with a real commit
Run git show <commit> --format="%H%n%s%n%an%n%ad" -p and paste the output when requesting the playground. Claude parses it into the diffData structure automatically.
Use cases
▸ code-map architecture
SVG architecture diagrams with click-to-comment on any node. Supports layer visibility filtering, connection type filtering, view presets, and zoom controls. Comments accumulate in the sidebar and build a targeted prompt about specific components.
Connection types
| Type | Color | Style | Use for |
|---|---|---|---|
| data-flow | Blue #3b82f6 | Solid | Request/response, data passing |
| tool-call | Green #10b981 | Dashed (6,3) | Function calls, API invocations |
| event | Red #ef4444 | Short dash (4,4) | Async events, pub/sub |
| skill-invoke | Orange #f97316 | Long dash (8,4) | Plugin / skill activation |
| dependency | Gray #6b7280 | Dotted | Import / require relationships |
Layer color palette
| Layer | Node fill |
|---|---|
| Client / UI | #dbeafe (blue-100) |
| Server / API | #fef3c7 (amber-100) |
| SDK / Core | #f3e8ff (purple-100) |
| Agent / Logic | #dcfce7 (green-100) |
| Data | #fce7f3 (pink-100) |
Use cases
Core requirements
Every playground produced by this skill satisfies all of these, regardless of template:
- Single HTML file. Inline all CSS and JS. No external CDN dependencies. If the CDN goes down, your playground should still work.
- Live preview. Updates instantly on every control change — keypress, slider drag, toggle flip. No "Apply" button. The gap between action and feedback must be zero.
- Natural-language prompt output. Not a JSON value dump. Only mentions choices that differ from defaults. Uses qualitative language alongside numbers. Includes enough context to act on without seeing the playground.
- Copy button with "Copied!" feedback. One click to clipboard. Brief flash confirmation so the user knows it worked.
- Sensible defaults + 3–5 named presets. Looks good on first load. Presets snap all controls to a cohesive combination (e.g., "Minimal", "Elevated", "Compact").
- Dark theme, system fonts. System font for UI chrome, monospace for code and values. Minimal chrome that doesn't compete with the preview.
The prompt output pattern
This is the most important part to get right. The prompt output is not a value dump. It's a natural instruction a developer could act on.
Reads like a direction from a designer to a developer:
translateY(-1px) and deepen the shadow slightly. Use the Inter font family."Notice: uses qualitative framing ("soft and elevated"), quantitative specifics only where precise, omits default values (border-color was already correct), includes context to act on alone.
This is what not to produce:
{ borderRadius: 12, padding: 24, shadow: true,
shadowY: 4, shadowBlur: 12, shadowOpacity: 0.1,
font: "Inter", hover: true, hoverTranslate: -1,
color: "#141413", bg: "#ffffff" }
Unusable without the playground. Includes defaults. No qualitative context. Can't be acted on as a Claude prompt.
// Keep a DEFAULTS object — only emit lines that differ const DEFAULTS = { borderRadius: 4, padding: 16, shadowBlur: 0, font: 'system-ui' }; function updatePrompt() { const parts = []; // Only mention non-default values if (state.borderRadius !== DEFAULTS.borderRadius) parts.push(`${state.borderRadius}px border-radius`); // Use qualitative language alongside numbers if (state.shadowBlur > 16) parts.push('a pronounced shadow'); else if (state.shadowBlur > 0) parts.push('a subtle shadow'); if (state.font !== DEFAULTS.font) parts.push(`the ${state.font} font family`); // Write as direction, not spec sheet prompt.textContent = parts.length ? `Update the card to use ${parts.join(', ')}.` : '(using all defaults — adjust controls to build a prompt)'; }
State management pattern
Every playground uses a single state object. Every control writes to it. Every render reads from it. No scattered variables.
// Single source of truth const state = { borderRadius: 4, padding: 16, shadowBlur: 0, font: 'system-ui', preset: 'default' }; // One function that does both — called after every control change function updateAll() { renderPreview(); // update the visual updatePrompt(); // rebuild the prompt text } // Every control calls updateAll() on change slider.addEventListener('input', () => { state.borderRadius = +slider.value; updateAll(); }); // Presets snap all controls at once const PRESETS = { minimal: { borderRadius: 2, padding: 12, shadowBlur: 0 }, elevated: { borderRadius: 12, padding: 24, shadowBlur: 12 }, compact: { borderRadius: 4, padding: 8, shadowBlur: 4 }, }; function applyPreset(name) { Object.assign(state, PRESETS[name]); syncControlsToState(); // update slider/toggle DOM to match updateAll(); }
updateAll() on initial load with defaults — never start with a blank or broken preview. The user should see a polished result before touching anything.How to trigger /playground
Just describe what you want to explore. Claude picks the template, builds all controls, wires up live preview and prompt output, then opens the file in your browser.
Common mistakes to avoid
| Mistake | Problem | Fix |
|---|---|---|
| Prompt is a value dump | JSON object of all current state values | Write as natural instruction. Only non-defaults. Qualitative framing. |
| Too many controls at once | Overwhelming; user doesn't know where to start | Group by concern (spacing / color / typography). Hide advanced options in a collapsible section. |
| Preview doesn't update instantly | Added an "Apply" button or debounce delay | Every control change/input event must call updateAll() immediately. |
| No defaults or presets | Starts blank or broken on load | Set sensible defaults in state. Call updateAll() on page load. Add 3–5 presets. |
| External dependencies | CDN request, npm package, iframe to external URL | Inline everything. If CDN goes down, playground must still work. |
| Prompt lacks context | Output only makes sense while looking at the playground | Include entity names, schema context, or qualitative framing so prompt is actionable standalone. |
updatePrompt().