ワンクリックで
carousel-design
Render Instagram carousel slides as PNGs from structured slide data using your branded template.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Render Instagram carousel slides as PNGs from structured slide data using your branded template.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
Generate structured carousel slide content in your voice for Instagram carousels.
Generate 5-10 Instagram carousel ideas tailored to your niche and brand.
Generate complete Instagram carousels — from topic to AirDrop-ready PNGs. Includes content writing, slide rendering, and delivery.
SOC 職業分類に基づく
| name | carousel-design |
| description | Render Instagram carousel slides as PNGs from structured slide data using your branded template. |
Render Instagram carousel slides as PNGs from structured slide data using your branded Puppeteer template.
Read config from ~/.claude/skills/carousel/config.json. If it doesn't exist, tell the user:
You haven't set up your carousel template yet. Run /carousel first — it takes about 10 minutes and only happens once.
Then stop.
Also verify:
~/.claude/skills/carousel/slide-template.html exists (the approved HTML template)~/.claude/skills/carousel/node_modules/puppeteer exists (Puppeteer installed)If template missing: "Your slide template is missing. Run /carousel to rebuild it."
If Puppeteer missing: Run cd ~/.claude/skills/carousel && npm install puppeteer
Accepts a JSON array of slide objects (from /carousel-copy). Each slide has:
name — filename (e.g. "slide1-hook")slideNum — e.g. "01 / 07" (empty string for CTA slide)stepLabel — e.g. "STEP 01", "THE METHOD"headline — HTML string with <br> for line breaks and <span class="accent"> for accent-colored textsubline — all caps description textactivateLabel — text above terminal (empty string to hide)terminal — HTML for terminal body using .t-line, .prompt, .cmd, .check, .arrow classescharacter — character name from config (e.g. "pointing") or empty if noneisPill (optional, boolean) — render stepLabel as a pill badgeisHook (optional, boolean) — add corner accents to the slideisCTA (optional, boolean) — centered layout with keyword box, no terminal/characterheadlineSize (optional) — override headline font sizectaKeyword (optional) — the keyword for CTA slide boxIf no JSON input is provided, ask the user for it or check if /carousel-copy output exists.
Read all values from config. The template was built and approved during setup:
config.slideSize (default 1080x1440, 4:5 Instagram carousel)config.colors.bg with optional pattern overlayconfig.fonts.headline and config.fonts.mono (loaded via Google Fonts)config.colors — text, accent, bgconfig.handleconfig.profilePic (or handle text if none)config.characters array — map character name to file pathThe main content area uses display: flex; flex-direction: column; justify-content: space-evenly to distribute headline/subline and terminal sections with EQUAL spacing. This ensures short and long headlines both look properly spaced. NEVER use absolute positioning for the subline or terminal — they must flow inside the flex container.
isHook: true, isPill: true): Corner accents in accent color, pill badge for category, profile pic + arrow at bottomisCTA: true): Everything centered, keyword box with accent border, "FOLLOW [HANDLE]", no arrow, no terminal, no character~/.claude/skills/carousel/slide-template.htmlcharacter name to actual file path from config
c. Apply slide-type-specific modifications (hook corners, CTA centered layout, etc.)
d. Handle headlineSize overrides
e. Hide activate label if empty~/.claude/skills/carousel/output/Generate a Node.js script similar to this pattern:
const puppeteer = require('puppeteer');
const path = require('path');
const fs = require('fs');
const template = fs.readFileSync(path.resolve(__dirname, 'slide-template.html'), 'utf8');
const config = JSON.parse(fs.readFileSync(path.resolve(__dirname, 'config.json'), 'utf8'));
const slides = [/* slide data injected here */];
(async () => {
const browser = await puppeteer.launch({ headless: true });
const outputDir = path.resolve(__dirname, 'output');
if (!fs.existsSync(outputDir)) fs.mkdirSync(outputDir);
for (const slide of slides) {
let html = template
.replace('{{SLIDE_NUM}}', slide.slideNum)
.replace('{{STEP_LABEL}}', slide.stepLabel)
.replace('{{HEADLINE}}', slide.headline)
.replace('{{SUBLINE}}', slide.subline)
.replace('{{ACTIVATE_LABEL}}', slide.activateLabel)
.replace('{{TERMINAL}}', slide.terminal);
// Map character name to path from config
if (slide.character && config.characters) {
const charConfig = config.characters.find(c => c.name === slide.character);
if (charConfig) {
html = html.replace('{{CHARACTER}}', charConfig.path);
}
}
// Apply hook, pill, CTA, headlineSize modifications...
// (same logic as the template build from setup)
const page = await browser.newPage();
await page.setViewport({
width: config.slideSize?.width || 1080,
height: config.slideSize?.height || 1440
});
const htmlPath = path.resolve(outputDir, slide.name + '.html');
fs.writeFileSync(htmlPath, html);
await page.goto('file://' + htmlPath, { waitUntil: 'networkidle0', timeout: 15000 });
await page.screenshot({ path: path.resolve(outputDir, slide.name + '.png'), type: 'png' });
console.log('Done: ' + slide.name);
await page.close();
}
await browser.close();
console.log('All slides rendered!');
})();
The actual build script should include the full slide-type logic (hook corners, pill badges, CTA override) as established during the setup phase.
~/.claude/skills/carousel/assets/headlineSize if needed~/.claude/skills/carousel/Built by @tenfoldmarc. Follow for daily AI automation builds — real systems, not theory.