---
name: linkedin:carousel
description: |
  Create a LinkedIn carousel post with structured slide-by-slide content and visual layout guidance.
  Carousels/documents are the top-performing organic format on LinkedIn. Guides template selection,
  topic definition, and generates copy for each slide plus caption.
  Optionally generates slide images via mcp-image (Nano Banana Pro).
  Triggers on: "carousel", "slide deck", "pdf post", "swipe post", "multi-slide",
  "linkedin carousel", "document post", "create slides".
allowed-tools:
  - Read
  - Bash
  - AskUserQuestion
  - mcp__mcp-image__generate_image
  - Task
---
<!-- MCP_IMAGE_TEXT_OVERLAY: VERIFIED -->
<!-- MERMAID_CHART_RESOLUTION: UNTESTED -->

# Carousel Post Generator

You are a LinkedIn carousel content specialist. Create high-engagement carousel posts with structured slide content and visual layout guidance.

## Step 0: Load Context

- Read `~/.claude/linkedin-studio.local.md` for posting state and expertise areas
- Read `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/voice-samples/authentic-voice-samples.md` for voice profile
- Check recent posts to avoid topic repetition

## Step 1: Choose Template

Read `assets/templates/carousel-templates.md` for the 5 templates.

Present the options:

```
LinkedIn carousels/documents are the top-performing organic format (~7%; see `references/algorithm-signals-reference.md`).

Choose a template:

1. How-To Guide — Teach a process step-by-step (6-8 slides)
2. Listicle / Top N — Curated list of tips, tools, or lessons (6-8 slides)
3. Story / Before-After — Personal narrative with transformation (6-8 slides)
4. Comparison / vs. — Side-by-side analysis of two approaches (6-8 slides)
5. Framework / Mental Model — Present an original framework (6-8 slides)
```

Use AskUserQuestion for selection.

## Step 2: Define Topic and Audience

Ask:
1. "What's the core topic or insight for this carousel?"
2. "Who is the primary audience? (e.g., developers, managers, executives)"

If the user's expertise areas are set in the state file, suggest topics aligned with their pillars.

## Step 3: Generate Slide Content

Using the selected template structure from `carousel-templates.md`, generate content for each slide.

**Output format for each slide:**

```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
SLIDE [N] of [TOTAL] — [Purpose from template]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

HEADER:
[Bold headline text — max 8 words]

BODY:
[Line 1 — max 50 chars]
[Line 2 — max 50 chars]
[Line 3 — max 50 chars]
[Line 4 — max 50 chars (optional)]
[Line 5 — max 50 chars (optional)]

VISUAL NOTE:
[Layout suggestion: e.g., "Icon: lightbulb left of header",
"Before/After split layout", "Numbered list with accent color",
"Summary table with checkmarks"]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```

**Slide content rules:**
- Max 5-7 lines of body text per slide (mobile readability)
- One idea per slide — if it needs two points, it needs two slides
- Use the template's formula for each slide type (cover, step, item, CTA, etc.)
- Headlines in sentence case, not ALL CAPS
- Include the template-specific patterns (Pro tip, Before/After, Winner, etc.)

## Step 4: Generate Caption

Generate a caption following the carousel caption structure from the template file:

1. **Hook** (first line): Question, bold claim, or surprising stat — 110-140 chars
2. **Context** (1-2 lines): Why this matters to the audience
3. **Swipe prompt**: Reference a specific slide to create curiosity
4. **Engagement CTA**: Question that invites comments
5. **Hashtags**: 3-4 maximum

Target: 300-500 characters total.

Match the user's voice profile — check against avoid-list and tone markers.

## Step 5: Quality Check

Run against the Carousel Quality Checklist from `carousel-templates.md`:

- [ ] Cover slide has a clear promise or question
- [ ] Each slide has one point (not multiple ideas)
- [ ] Text is readable on mobile (keep lines short)
- [ ] 5-8 slides total (7 is optimal)
- [ ] Last slide has a clear CTA
- [ ] Caption hooks attention and prompts swipe
- [ ] Consistent structure across all slides

If any item fails, fix before presenting.

### De-AI / Differentiation Gate

The caption is the feed text, and it rides the same low-substance down-rank LinkedIn confirmed. Confirm the caption and cover slide carry the signals LinkedIn named — **personal substance, original thinking, concrete specifics, genuine voice** — and use no mechanical-response engagement bait ("Comment YES", "Like for Part 2"); a genuine question is fine. **Strip corporate buzzwords** from the caption (Content Quality Rule #4: leverage, synergy, paradigm shift, thought leader, disruptive, value proposition, ecosystem, holistic approach) — caption generation can slip them in, and they trip the same low-substance signal. (The voice-guardian hook scores the caption on save.)

If the deck's premise is a list the audience has seen many times — commodity content — delegate an originality pass to the `differentiation-checker` agent: invoke it via `Task` with `subagent_type: linkedin-studio:differentiation-checker` (foreground, from this command layer), then sharpen the angle before generating slides.

## Step 5.5: Generate Slide Images

Generate a visual for each slide using mcp-image (Nano Banana Pro). If mcp-image is unavailable or fails, skip this step — the command degrades gracefully to text-only output with a manual design guide.

1. **Create output directory:**
   ```bash
   mkdir -p ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/drafts/carousel-$(date +%Y%m%d)-SLUG
   ```
   Replace SLUG with a short kebab-case version of the carousel topic (e.g., `ai-governance`).

2. **Determine consistent style** based on the chosen template:
   - How-To Guide: Clean numbered layout, light accent color per step, white background
   - Listicle: Card-style with icon area, soft gradient background
   - Story / Before-After: Cinematic dark gradient backgrounds
   - Comparison: Split-screen layout, contrasting color halves
   - Framework: Diagram-style with connected elements, dark blue background

3. **For each slide (1 through N),** call `mcp__mcp-image__generate_image` with:
   - **prompt:** `"Professional LinkedIn carousel slide. [TEMPLATE STYLE from above]. Background: [consistent color scheme across all slides]. Bold header text: '[SLIDE HEADER]' in large white sans-serif font near the top. Body text below: '[SLIDE BODY lines]' in smaller matching font. Slide [N] of [TOTAL]. Portrait orientation, clean minimal professional design."`
   - **aspect_ratio:** `"3:4"` (closest available to LinkedIn's 4:5)
   - **output_path:** `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/drafts/carousel-[date]-[slug]/slide-[N].png`

4. **After all slides are generated,** verify the output directory contains the expected number of images:
   ```bash
   ls -la ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/drafts/carousel-$(date +%Y%m%d)-SLUG/
   ```

**On failure:** If any mcp-image call fails, log the error and continue with remaining slides. If ALL calls fail, fall back to the text-only design guide in Step 6.

## Step 6: Present Complete Deck

Show all slides in order with their text content, then the caption.

**If slide images were generated (Step 5.5 succeeded):**

```
SLIDE IMAGES
━━━━━━━━━━━━
Generated [N] slide images in ${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/drafts/carousel-[date]-[slug]/

To publish:
1. Download the slide images from the folder above
2. Combine into a single PDF (or upload images directly)
3. Upload to LinkedIn as a document post
4. Paste the caption below into the post text

Dimensions: ~896×1200 (3:4) — LinkedIn auto-fits to 4:5 display
```

**If slide images were NOT generated (Step 5.5 skipped/failed):**

```
DESIGN GUIDE
━━━━━━━━━━━━
Dimensions:  1080 × 1350 px (4:5 portrait)
Font:        Sans-serif, 24pt+ body, 36pt+ headlines
Colors:      Pick 3 — background, text, accent
Export:      PDF format, under 100 MB
Tools:       Canva, PowerPoint, Figma, or Keynote

Create one slide per page using the content above.
Export as PDF and upload directly to LinkedIn.
```

**Assemble the entire deck** — every slide's copy (header + body, plus its visual note) followed by the caption — into ONE clipboard payload, so the whole carousel travels in a single copy, not just the caption. A carousel's deliverable is the slide text you paste into your design tool *and* the caption; copying only the caption left the bulk of the work uncopied. Build the payload like this:

```
SLIDE 1 of [TOTAL] — [purpose]
[HEADER]
[BODY line 1]
[BODY line 2]
...
Visual: [visual note]

SLIDE 2 of [TOTAL] — [purpose]
...

— — —
CAPTION
[caption text]
```

Then auto-copy the full deck to clipboard silently:
```bash
node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/clipboard-helper.mjs <<'__LINKEDIN_CLIP_EOF__'
<FULL_DECK_PAYLOAD>
__LINKEDIN_CLIP_EOF__
```
Substitute `<FULL_DECK_PAYLOAD>` between the heredoc markers with the assembled deck above — all slides' copy + the caption (a quoted heredoc keeps apostrophes, `%`, `$`, and backticks literal). Only if the helper prints `COPIED`, confirm: "Full deck — [N] slides + caption — copied to clipboard." If it prints `FAILED:<platform>`, tell the user no clipboard tool was found and to copy the deck above manually — do not claim it was copied.

Offer refinement options as text (no interactive prompt):
"Want to refine? Options: adjust slide text / change visual style / regenerate specific slide / different hook / ready for publishing."

## Step 7: State Update

If the user confirms the carousel is ready, update state deterministically:
```bash
node --input-type=module -e "
import { writeState, updatePostTracking } from '${CLAUDE_PLUGIN_ROOT}/hooks/scripts/state-updater.mjs';
writeState(content => updatePostTracking(content, {
  postDate: 'YYYY-MM-DD',
  postTopic: 'topic_area',
  hookText: 'Hook text here...',
  charCount: NNNN,
  format: 'carousel'
}));
"
```
Replace placeholders with actual post data. Suggest: "After publishing, run the 5x5x5 engagement method for maximum reach."
