| name | instagram-writer |
| description | Create high-engagement Instagram carousels. Rich layout with mono rails, display headlines, sticky notes, icon rows, tables, terminal proof cards and gradient panels, or the original plain layout. Palette comes from social-studio themes (electric by default). Optimized for saves and comment-gated CTAs. Triggers on: instagram carousel, instagram writer, write carousel, ig carousel, create instagram carousel, make a carousel, carousel for instagram. |
Instagram Carousel Writer
Creates 6-slide Instagram carousels in the @aiwithanushka style that drives saves, shares, and comment-bait CTA engagement.
Design system (hardcoded in renderer)
- Background: warm cream
#F5F0E8 (default) or a custom image passed as 3rd arg to the renderer
- Primary text: near-black
#1C1C1C, bold
- Accent: terra cotta
#C4713A on key words
- Font: Arial Bold, clean and large
- Slide counter: top-left (1/6, 2/6...)
- Dotted grid: top-right decorative element
- Brand:
AI (terra cotta) bottom-left, @handle (gray) bottom-right
- Dimensions: 1080x1350 (4:5 ratio)
Slide structure
| # | Type | Purpose |
|---|
| 1 | cover | Big hook headline - stops the scroll |
| 2 | pain | Relatable problem (question format) + bullets |
| 3 | solution | The answer - key noun in accent color |
| 4 | how | Framework / steps with bullets |
| 5 | results | Proof / outcomes with bullets |
| 6 | cta | Summary lines + giant "Comment [WORD]" |
Step 1: Gather inputs
Ask the user for:
-
Topic - what the carousel teaches (e.g. "Claude Code skills", "AI content automation")
-
CTA word - one ALL-CAPS word for the comment CTA (e.g. SKILLS, GUIDE, SYSTEM, LIST, TOOLKIT)
-
Handle - their Instagram handle (default: @tylerai_dev)
-
Renderer - which rendering framework to use:
Which renderer do you want?
1. PIL (default) - fast, free, pixel-perfect typography. Best for text-heavy carousels.
2. Kie.ai - AI-generated visuals for every slide. Richer look, ~$0.54/carousel, slower.
3. Hybrid (recommended) - PIL for text slides, Kie.ai asset for cover logo/visuals. Best of both.
If the user provides a topic in their command, infer CTA word from the topic (e.g. "skills" topic → "SKILLS").
Renderer notes:
- PIL → use
instagram_writer.py
- Kie.ai → use
instagram_kie.py
- Hybrid → use
instagram_writer.py (it auto-loads logo assets from assets/logo-{name}.png when "logo" is set in the cover slide)
Two layouts
This skill renders two ways, chosen by the data rather than by type:
- Rich - the full treatment: mono rails, display headline, sticky notes,
icon rows with inline emphasis, tables, terminal proof cards, quad cards.
Triggered by any of
lines, table, quad, proof, note, closer,
pill, rows, hero_path. Format: SLIDES.md.
- Plain - the original headline-and-bullets slide, below. Still the default
for anything not carrying those keys, so old carousels are untouched.
Colours come from ~/social-studio/themes/<id>.json (THEME=electric by
default). The styles these layouts copy, and why, are in
~/content/BRAIN/instagram/carousel-styles.md.
Step 2: Generate slide content JSON
Create the JSON following this exact structure. Headlines must be SHORT lines (3-5 words max each) so the text is BIG and bold.
{
"topic": "<topic>",
"handle": "@tylerai_dev",
"brand_text": "AI",
"slides": [
{
"type": "cover",
"headline_lines": ["<2-3 words>", "<KEY WORD here>", "<2-3 words>"],
"accent_words": ["<KEY WORD>"],
"subtitle": "<One punchy line that hooks them into sliding>"
},
{
"type": "pain",
"headline_lines": ["Still doing this", "<PAIN WORD>?"],
"accent_words": ["<PAIN WORD>"],
"bullets": [
"<Pain point 1 - short phrase>",
"<Pain point 2 - short phrase>",
"<Pain point 3 - short phrase>",
"<Pain point 4 - short phrase>"
]
},
{
"type": "solution",
"headline_lines": ["The fix:", "<SOLUTION>", "is simpler"],
"accent_words": ["<SOLUTION>"],
"subtitle": "<Supporting line>",
"bullets": []
},
{
"type": "how",
"headline_lines": ["The", "<FRAMEWORK>"],
"accent_words": ["<FRAMEWORK>"],
"bullets": [
"<Step 1 - 4-7 words>",
"<Step 2 - 4-7 words>",
"<Step 3 - 4-7 words>",
"<Step 4 - 4-7 words>"
]
},
{
"type": "results",
"headline_lines": ["Real", "<RESULTS>"],
"accent_words": ["<RESULTS>"],
"bullets": [
"<Specific result 1>",
"<Specific result 2>",
"<Specific result 3>",
"<Specific result 4>"
]
},
{
"type": "cta",
"summary_lines": [
"<1-line takeaway from the carousel>",
"<2nd supporting line>"
],
"cta_action": "Comment",
"cta_word": "<CTA_WORD>",
"cta_subtext": "and I'll send you the full guide"
}
]
}
Content rules
- Headlines: 2-3 SHORT lines (3-5 words each) - the text must fill the slide vertically
- Accent words: 1-2 per slide, the most important noun or concept
- Bullets: max 4 per slide, short phrases (4-8 words)
- Pain slide: question format creates scroll-stopping relatability
- CTA word: single ALL-CAPS word, creates urgency to comment
- No em dashes - use commas or plain hyphens with spaces ( - )
- Write for saves first - the information must be worth saving
Step 3: Save JSON and render
-
Create a 2-3 word kebab-case slug from the topic.
-
Set OUTPUT_DIR=~/content/platform/instagram/<slug>/
-
Save the JSON:
mkdir -p ~/content/platform/instagram/<slug>/
Write the JSON to ~/content/platform/instagram/<slug>/slides.json
-
Run the renderer:
python3 ~/.claude/skills/instagram-writer/instagram_writer.py \
~/content/platform/instagram/<slug>/slides.json \
~/content/platform/instagram/<slug>/
To use a custom background image (e.g. a watercolor texture from Kie.ai):
python3 ~/.claude/skills/instagram-writer/instagram_writer.py \
~/content/platform/instagram/<slug>/slides.json \
~/content/platform/instagram/<slug>/ \
~/path/to/background.png
The image is cover-cropped to 1080x1350 with a subtle white overlay for text readability.
Output:
slide_01.png through slide_06.png - individual slides
carousel.pdf - combined PDF for Blotato upload
Step 4: Write the caption
Short. Forty words is the ceiling, and fewer is usually better.
<One line that matches slide 1 and promises the payoff>
Comment <CTA_WORD> and I'll send it.
#claudecode #aiagents #ai #<topic> #carousel
Why short
The carousel is the content. The caption's only job is to get the comment,
because a comment-gated payoff is what produces the comment count. Everything
you would have explained in paragraph three is already on slide four, and
nobody reads past "... more" to find it.
Measured on the two carousels in the swipe file, both of which out-saved
anything of ours:
| Caption | Comments | Saves |
|---|
| @ibraviz.ai | "Comment JARVIS for the setup!" - 6 words | 4,026 | 10.4K |
| @albert.olgaard | "Comment 'Famous' for the skills" - 5 words | - | 219 |
Ours have been running 180 to 197 words. Reach explains a lot of that gap and
caption length is not the only variable, so treat this as a strong prior rather
than a proven cause - but the direction is one-way, and a short caption costs
nothing to test.
Rules
- First line is the hook, visible before "... more". Promise the payoff.
- One comment CTA, naming the keyword. That is the whole point of it.
- Under 40 words before the hashtags. If it needs a second paragraph, that
paragraph belongs on a slide.
- Five hashtags, the set above.
- No em dashes.
Hashtags
Five, in slots. Three fixed, two that change per post:
#claudecode #aiagents #ai #<topic> #carousel
| Slot | Value | Why |
|---|
| Tool | #claudecode | fixed |
| Category | #aiagents | fixed |
| Broad | #ai | fixed |
| Topic | #mcp, #arcade, #jarvis, #obsidian | changes every post |
| Format | #carousel | fixed |
The topic slot is the part copied from @ibraviz.ai, the only reference whose
tags were visible: #claude #claudecode #ai #jarvis #reel. Four of their five
describe the tool or the category; the fifth names what the post is about.
That is the one doing work a tool tag cannot - it reaches people searching the
subject rather than the software.
They tagged a carousel #reel, which we are not copying. Tag the format you
actually posted.
Honest note on #aiagents: it did not appear on any captured screenshot. It is
in the set because it is the category we want to be found in, not because it
was observed. Treat it as a deliberate bet, and if a post is not about agents,
swap it for something truer rather than leaving it in out of habit.
Save the caption to ~/content/platform/instagram/<slug>/caption.md
Step 5: Update status.md
After rendering (and again after scheduling), update ~/content/platform/instagram/status.md:
| Slug | Topic | Created | Scheduled | Posted |
|---|
| claude-code-skills | Claude Code skills | 2026-04-09 | Apr 10 12pm | - |
Step 6: Present results
Show the user:
- A summary of each slide's content (1 line each)
- The full caption
- File paths:
- Slides:
~/content/platform/instagram/<slug>/slide_01.png through slide_06.png
- PDF:
~/content/platform/instagram/<slug>/carousel.pdf
- Caption:
~/content/platform/instagram/<slug>/caption.md
- Ask if they want to schedule via Blotato or adjust any slides
Step 7: Save to carousel app Library
After generating carousel content, also save a JSON to the carousel maker app so it appears in the Library drawer:
~/carousel-maker/carousels/carousel_<timestamp>.json
JSON format:
{
"id": "carousel_<timestamp>",
"title": "Carousel Title",
"platform": "instagram",
"slides": [
{
"id": "slide_0_<timestamp>",
"type": "cover|content|cta",
"slideNumber": 1,
"headline": "Main Headline",
"emphasisLine": "Accent line",
"bodyText": "Body text.",
"bgColor": "#F5F0EB",
"textColor": "#1B1B1B",
"accentColor": "#E07355"
}
]
}
Slide types: cover (slide 1), content (slides 2-5, include stepNumber), cta (slide 6).
This keeps the carousel app Library and ~/content/platform/carousels/<slug>/ in sync. Always write to both locations.