// ============================================ // DEMO RENDERER - Generic rendering for command and skill demos // ============================================ import { getCommandDemo } from './demos/commands/index.js'; import { getSkillDemo } from './demos/skills/index.js'; /** * Initialize a command demo's JS after its HTML has been inserted into the DOM. * Call this after innerHTML is set and split compare is initialized. */ export function initCommandDemo(commandId, container) { const demo = getCommandDemo(commandId); if (demo && typeof demo.init === 'function') { const demoArea = container.querySelector('.split-after .split-content') || container; console.log('[initCommandDemo]', commandId, 'demoArea:', demoArea); demo.init(demoArea); } } /** * Render a command demo with split-screen comparison */ export function renderCommandDemo(commandId) { const demo = getCommandDemo(commandId); if (!demo) { // impeccable has multiple modes — show a usage guide if (commandId === 'impeccable') { return `
Three ways to use /impeccable
/impeccable freeform
Use on any task. Loads full design intelligence, anti-patterns, and reference knowledge into the current context.
/impeccable teach one-time setup
Scans your codebase, interviews you about brand and audience, then saves a Design Context that all other commands use automatically.
/impeccable craft build a feature
Runs /shape to plan UX first, loads the right references, then builds and iterates visually until the result delights.
Start with /impeccable teach once per project. Then use the other modes as needed.
`; } // craft is the full end-to-end flow, show the four stages if (commandId === 'craft') { return `
Shape, reference, build, iterate
1. Shape
Runs /impeccable shape internally to build a design brief from discovery questions. No code yet.
2. Reference
Loads the right reference files for the feature (spatial design, typography, motion, color) based on what the brief calls for.
3. Build
Implements structure, spacing, type, color, states, motion, responsive. Every decision traces back to the brief.
4. Visual iteration
Opens the result in a browser, checks against the brief and anti-pattern list, refines until the polish bar is high.
The full shape-then-build flow in one command. Best for brand-new features.
`; } // teach sets up the project's design context, show the flow if (commandId === 'teach') { return `
One-time project setup
1. Explore
Scans the codebase for brand assets, existing design tokens, typography, components, and documentation.
2. Interview
Asks about audience, brand personality, aesthetic direction, and accessibility needs. Skips anything it can infer from the code.
3. Save
Writes a PRODUCT.md file with users, brand, aesthetic direction, and design principles. Every future command reads it automatically.
Run once per project. Then forget it exists.
`; } // shape is a planning skill — show the process if (commandId === 'shape') { return `
Design before you build
1. Discovery
Interviews you about purpose, audience, content, constraints, and anti-goals. Adapts questions based on your answers.
2. Design Brief
Synthesizes a 9-section brief: feature summary, primary action, design direction, layout strategy, key states, interaction model, content needs, recommended references, and open questions.
3. Handoff
The confirmed brief guides /impeccable craft or any other implementation approach. No code written, just the thinking that makes code good.
Use standalone or as the first step of /impeccable craft.
`; } return `
Visual demo for /${commandId} coming soon
`; } // Use split-screen comparison return `
${demo.before}
${demo.after || demo.before}
${demo.caption}
`; } /** * Render a skill demo (with tabs if multiple demos) */ export function renderSkillDemo(skillId) { const skill = getSkillDemo(skillId); if (!skill || !skill.tabs || skill.tabs.length === 0) { return `

Demo for ${skillId.replace(/-/g, ' ')} coming soon

`; } const showTabs = skill.tabs.length > 1; const tabs = showTabs ? skill.tabs.map((tab, i) => ` `).join('') : ''; const panels = skill.tabs.map((tab, i) => `
${renderSkillTabDemo(skillId, tab)}
`).join(''); return `
${showTabs ? `
${tabs}
` : ''}
${panels}
`; } /** * Render a single skill tab demo */ function renderSkillTabDemo(skillId, tab) { const hasToggle = tab.hasToggle !== false; const demoId = `${skillId}-${tab.id}`; return `
${hasToggle ? `
Before After
` : ''}
${tab.before}
${tab.caption}
`; } /** * Setup demo tab switching */ export function setupDemoTabs() { document.querySelectorAll('.demo-tab').forEach(tab => { tab.addEventListener('click', () => { const tabId = tab.dataset.demoTab; const container = tab.closest('.demo-tabbed-container'); container.querySelectorAll('.demo-tab').forEach(t => t.classList.remove('active')); tab.classList.add('active'); container.querySelectorAll('.demo-panel').forEach(p => p.classList.remove('active')); container.querySelector(`[data-demo-panel="${tabId}"]`)?.classList.add('active'); }); }); }