instagram-carousel

Creates high-quality Instagram carousels as swipeable HTML previews with export-ready slides (1080×1350px PNG). Handles the full workflow: brand setup, slide copy, visual design system (colors, fonts, components), HTML generation, and Playwright-based export. Use this skill whenever the user asks to

By marcolang · 699 installs

npx skills add marcolang/marketing-skills --skill instagram-carousel

Source repository · Upstream listing

Instagram Carousel Generator Generates fully self contained, swipeable HTML carousels where every slide is designed to be exported as an individual 1080×1350px PNG for Instagram. Step 1: Collect Brand Details Before generating, ask the user for the following (if not already provided): 1. Brand name — displayed on first and last slides 2. Instagram handle — shown in the IG frame header 3. Primary brand color — hex code, or describe and Claude picks one 4. Logo — SVG path, brand initial, or skip 5. Font preference — see typography table below, or specific Google Fonts 6. Tone — professional, casual, playful, bold, minimal, etc. 7. Images — profile photo, screenshots, product images, etc. 8. Idioma dos slides — default: Português (BR) unless specified otherwise 9. Carousel format — standard (7 slides) or alternate sequence (see sequences section) If the user provides a website URL or brand assets, derive colors and style from those. If the user says "make me a carousel about X" without brand details, ask before generating. Don't assume defaults. Handling User Provided Images This section applies from the very first HTML generation — not only during export. When the user provides an image file path (e.g., /home/user/gestante.png , /mnt/user data/uploads/foto.jpg ): ⚠️ Critical Rules 1. NEVER use relative paths ( gestante.png ) — they break in every browser context except the exact folder the HTML lives in. 2. NEVER use background: url(filepath) — leads to 1.5MB+ base64 inline strings that crash the browser parser. 3. ALWAYS embed as base64 data: URI — works in preview, export, and any environment. 4. ALWAYS generate the HTML via Python ( Path.write text() ) — shell heredocs interpolate $ and backticks, corrupting base64 strings. Step by step: embed an image Image as slide background (most common use) For dark slides, use rgba(0,0,0,0.45) as the overlay instead. Common image mistakes to avoid Mistake What goes wrong Fix <img src="gestante.png" Broken image — relative path only works if HTML and image share the same folder Always use base64 data: URI background: url('data:...') inline with 1.5MB base64 Browser parser crash, 1.3M token context Use <img tag with object fit:cover Generating HTML via shell echo or heredoc $ and backtick characters in base64 get interpolated and corrupt the string Always use Python Path.write text() Assuming .png extension = PNG format File may actually be JPEG; wrong MIME type breaks rendering Run file command to detect actual format Step 2: Derive the Full Color System From the user's single primary brand color , generate the full 6 token palette: Rules for deriving colors: LIGHT BG: tinted off white complementing the primary (warm → warm cream, cool → cool gray white) DARK BG: near black with subtle brand tint (warm → 1A1918, cool → 0F172A) LIGHT BORDER: always ~1 shade darker than LIGHT BG Brand gradient: linear gradient(165deg, BRAND DARK 0%, BRAND PRIMARY 50%, BRAND LIGHT 100%) Step 3: Set Up Typography Based on the user's font preference, pick a heading font and body font from Google Fonts. Style Heading Font Body Font Editorial / premium Playfair Display DM Sans Modern / clean Plus Jakarta Sans (700) Plus Jakarta Sans (400) Warm / approachable Lora Nunito Sans Technical / sharp Space Grotesk Space Grotesk Bold / expressive Fraunces Outfit Classic / trustworthy Libre Baskerville Work Sans Rounded / friendly Bricolage Grotesque Bricolage Grotesque Font size scale (fixed across all brands): Headings: 28–34px, weight 600, letter spacing 0.3 to 0.5px, line height 1.1–1.15 Body: 14px, weight 400, line height 1.5–1.55 Tags/labels: 10px, weight 600, letter spacing 2px, uppercase Step numbers: heading font, 26px, weight 300 Small text: 11–12px Apply via CSS classes .serif (heading font) and .sans (body font) throughout all slides. Slide 1 — Hook Rules The first slide must stop the scroll in under 1 second. Prioritize these formats: Hook format Example Afirmação polêmica "Você está usando IA errado" Número + benefício "7 ferramentas que substituem seu designer" Pergunta que dói "Por que seus carrosséis têm 0 salvamentos?" Resultado concreto "Esse post gerou 4.200 seguidores em 3 dias" Inversão de expectativa "Mais esforço no design = menos alcance" Rules: Never start with the brand name as headline Visual proof on Slide 1 whenever possible (screenshot, result, real number) Hook must promise value that the following slides deliver Slide Sequences Standard (7 slides — default) Type Background Purpose 1 Hero LIGHT BG Hook — bold statement, logo lockup, optional watermark 2 Problem DARK BG Pain point — what's broken, frustrating, or outdated 3 Solution Brand gradient The answer — what solves it, optional quote/prompt box 4 Features LIGHT BG What you get — feature list with icons 5 Details DARK BG Depth — customization, specs, differentiators 6 How to LIGHT BG Steps — numbered workflow or process 7 CTA Brand gradient Call to action — logo, tagline, CTA button. No arrow. Full progress bar. Listicle (5–10 slides) Type Background 1 Hero LIGHT BG 2–N Item N Alternating LIGHT/DARK Last CTA Brand gradient Use for: "X ferramentas", "X erros", "X dicas" Tutorial (7 slides) Type Background 1 Hero LIGHT BG 2 Contexto / Por quê DARK BG 3–5 Passo 1, 2, 3 Alternating 6 Resultado esperado DARK BG 7 CTA Brand gradient Comparação (5 slides) Type Background 1 Hero (o que será comparado) LIGHT BG 2 Opção A LIGHT BG 3 Opção B DARK BG 4 Veredicto Brand gradient 5 CTA DARK BG General rules for all sequences: Start with a hook — first slide must stop the scroll End CTA on brand gradient — no swipe arrow, progress bar at 100% Alternate light and dark backgrounds for visual rhythm Adapt sequence to topic — not every carousel needs all slides Slide Architecture Format Aspect ratio: 4:5 (Instagram carousel standard) Each slide is self contained — all UI elements baked into the image Alternate LIGHT BG and DARK BG backgrounds for visual rhythm Required Elements on Every Slide 1. Progress Bar (bottom of every slide) Shows position in the carousel. Fills as user swipes. Position: absolute bottom, full width, 28px horizontal padding, 20px bottom padding Track: 3px height, rounded corners Fill width: ((slideIndex + 1) / totalSlides) 100% Light slides: rgba(0,0,0,0.08) track, BRAND PRIMARY fill, rgba(0,0,0,0.3) counter Dark slides: rgba(255,255,255,0.12) track, fff fill, rgba(255,255,255,0.4) counter Counter label beside the bar: "1/7" format, 11px, weight 500 ⚠️ Important: Always replace BRAND PRIMARY with the actual hex value before rendering. Never leave it as a variable name in the HTML output. 2. Swipe Arrow (right edge — every slide EXCEPT the last) Subtle chevron guiding the user to keep swiping. Removed on the last slide. Position: absolute right, full height, 48px wide Background: gradient fade transparent → subtle tint Chevron: 24×24 SVG, rounded strokes Light slides: rgba(0,0,0,0.06) bg, rgba(0,0,0,0.25) stroke Dark slides: rgba(255,255,255,0.08) bg, rgba(255,255,255,0.35) stroke Reusable Components Strikethrough pills Tag pills Prompt / quote box Feature list Numbered steps Color swatches CTA button (final slide only) Tag / Category Label Light slides: BRAND PRIMARY Dark slides: BRAND LIGHT Brand gradient slides: rgba(255,255,255,0.6) Logo Lockup (first and last slides) If logo icon: 40px circle (BRAND PRIMARY bg) + icon centered + brand name beside If initials: 40px circle with first letter in white Brand name: 13px, weight 600, letter spacing 0.5px Layout Rules Content padding: 0 36px standard Bottom aligned slides with progress bar: 0 36px 52px to clear the bar Hero/CTA slides: justify content: center Content heavy slides: justify content: flex end Content must never overlap the progress bar — use padding bottom: 52px Instagram Frame (Preview Wrapper) When displaying in chat, wrap in an Instagram style frame: Header: Avatar (BRAND PRIMARY circle + logo) + handle + subtitle Viewport: 4:5 aspect ratio, swipeable/draggable track with all slides Dots: Small dot indicators below the viewport Actions: Heart, comment, share, bookmark SVG icons Caption: Handle + short description + "2 HOURS AGO" timestamp Include pointer based swipe/drag interaction for preview. Slides are still standalone export ready images. Important: .ig frame must be exactly 420px wide . The carousel viewport is 420×525px. Do NOT change this width — export depends on it. Review Flow Always follow this flow. Never skip to export without approval. 1. Generate the HTML preview first — never jump directly to export 2. Show the preview and ask: "Quais slides precisam de ajuste antes de exportar?" 3. Fix only the mentioned slides — never regenerate the entire carousel unless the direction fundamentally changes 4. Only proceed to export when the user explicitly confirms approval (e.g., "pode exportar", "aprovado", "ok") Exporting Slides as Instagram Ready PNGs After the user approves the carousel preview, export each slide as an individual 1080×1350px PNG . Critical Export Rules 1. Use Python for HTML generation — never use shell scripts with variable interpolation. Always use Path.write text() or open().write() . 2. Embed images as base64 — all user uploaded images must be base64 encoded as data:image/jpeg;base64,... URIs. Check actual file format with the file command — a .png extension may contain a JPEG. 3. Keep the 420px layout width — use Playwright's device scale factor to scale up to 1080px output WITHOUT changing the layout viewport. Install Playwright (only if needed) Before running the export script, check and install only if missing: Export Script Why This Works device scale factor=2.5714 renders at high DPI — a 420px element becomes 1080px in the output. Layout stays at 420px. clip captures only the carousel viewport, not browser chrome. wait for timeout(3000) gives Google Fonts time to load. track.style.transition = 'none' disables swipe animation so slides snap instantly. Common Export Mistakes to Avoid Mistake What goes wrong Fix Setting viewport to 1080×1350 Layout reflows — fonts tiny, spacing breaks Keep viewport at 420×525, use device scale factor Using shell scripts to generate HTML $ signs and backticks get interpolated Always use Python for HTML generation Not waiting for fonts Headings render in fallback system fonts wait for timeout(3000) after page load Not hiding IG frame chrome Export includes header, dots, caption Hide .ig header,.ig dots,.ig actions,.ig caption Changing .ig frame width Entire layout shifts Always keep at exactly 420px Leaving BRAND PRIMARY as variable name in CSS Color renders as invalid / invisible Always interpolate actual hex values into HTML Design Principles 1. Every slide is export ready — arrow and progress bar are part of the slide image 2. Light/dark alternation — creates visual rhythm across swipes 3. Heading + body font pairing — display font for impact, body for readability 4. Brand derived palette — all colors stem from one primary, keeping everything cohesive 5. Progressive disclosure — progress ba