agentleFS
moiharsmoihars/carousel-skill/SKILL.md

carousel

Skill0 starsChanged 2 months agoMITView on GitHub

Use this skill to turn a blog post, or any source article, into a finished social carousel for LinkedIn and Instagram. Trigger whenever someone asks to make a carousel, a slide post, a document post, a swipe post, or to "turn this blog into social", or asks to repurpose, atomize, or break a post into slides. Also use when asked to restyle or re-cut an existing carousel, change its angle, or regenerate it at a different length. Produces 1080x1350 PNGs, a LinkedIn PDF, captions, alt text, and a shareable HTML review page. Do not use for single-image graphics, video scripts, or plain social captions with no slides.

  • Installs packages

9 other projects use a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

3 rules. 0 are common, 2 are distinctive, and 1 is very specific to this project.

  • 0

    Common

    Most of the 6 edited versions we read keep these.

  • 2

    Distinctive

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Every word on a slide is customer-facing copy.

    line 19
  2. Distinctive:

    Read the post. Pull out what actually carries a slide: statistics with named sources, case studies, customer quotes, and list structures.

    line 37
  3. Very specific:

    Every deck opens on a cover and closes on a cta.

    line 64

“Common” is measured: kept by at least 6 in 10 of the 6 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Carousel

Turns a blog post into a posting-ready carousel: images for Instagram, a PDF document post for LinkedIn, captions, alt text, and an HTML review page for sign-off.

Setup: everything brand-specific lives in brand.json at the skill root. Palette, logo, type, character budgets, and voice rules are all read from there. Fill it in once. Do not edit the scripts to change brand values. See the README for the full field reference.

Load the voice skill first, if you have one

Every word on a slide is customer-facing copy. If your brand has a voice skill, load it before writing any headline, body line, or caption. This skill governs structure and layout; the voice skill governs language. Where they seem to conflict, the voice skill wins on wording.

The voice_rules block in brand.json is the machine-enforceable subset of that: the rules worth failing a build over. It pairs with a written voice guide rather than replacing one.

The pipeline

Blog → angle briefing (stop here) → card script → preflight → render → review page.

The card script is the pivot. Everything downstream reads from it, so all editing happens there, never in the rendered output.

Step 1. Read the source and brief the angles. Then stop.

Read the post. Pull out what actually carries a slide: statistics with named sources, case studies, customer quotes, and list structures.

Most posts support several carousels. Propose two or three angles and stop for a decision. Do not pick one silently. For each angle give:

  • the hook it opens on
  • why it earns attention, in one line
  • its weakness, honestly stated

See references/angles.md for how to construct these and a worked example.

Step 2. Write the card script

Once an angle is chosen, write card_script.json. Full schema, the seven card types, and the per-slot character budgets are in references/card-types.md.

Length is 6 to 8 slides, chosen by topic complexity, not by how much material exists. A simple topic is 6. A data-heavy one with a case study is 8. Going longer costs completion rate. The exact range is configurable in brand.json under deck.

Cutting is normal and expected. Material that does not fit moves into the caption, where the "read the full post" work belongs anyway. Record what was cut and why in meta.cut_for_length, so the tradeoff stays visible instead of looking like an oversight.

Every deck opens on a cover and closes on a cta. Slide 1 is the feed thumbnail before it is anything else, so the hook has to survive at thumbnail size.

Step 3. Preflight

python3 scripts/preflight.py card_script.json

This must exit clean before rendering. It enforces the per-slot character budgets and the voice rules from brand.json, and it catches things the eye misses: banned constructions, em dashes outside attribution lines, deck length, undefined or repeated themes, alt-text count, and captions over the platform limits.

Fix the copy. Never widen a budget to make an error disappear. The budgets are derived from the template, so a bust means the slide would have shrunk its own type to stay inside the box.

Step 4. Render

python3 scripts/render_carousel.py card_script.json out/

Produces the 1080×1350 PNGs and the LinkedIn PDF. Watch stdout for autofit warnings: any slide reporting a scale below 1.00 had copy too long for its slot, and the fix is shorter copy, not smaller type.

Step 5. Build the review page

python3 scripts/build_review.py card_script.json out/ out/carousel-review.html "headlines: DM Sans 800"

One self-contained file with images and fonts embedded, so it works offline and can be sent to a reviewer as a single attachment. It shows the swipeable deck, every caption with a live character count, and the per-slide alt text. Share this for approval rather than a folder of PNGs.

Posting

  • LinkedIn — upload the PDF as a document post. Use the LinkedIn caption.
  • Instagram — upload the PNGs in filename order. Use the Instagram caption.
  • Alt text — one entry per slide, in card_script.json. Not optional. Preflight fails if the count does not match the deck.

Design system

Set in brand.json. Do not restyle per deck; consistency across the feed is the point.

Palette. Themes are named background/foreground/accent sets. Alternate slide themes so the swipe has rhythm; preflight warns on two identical backgrounds in a row.

Type. One family throughout by default. headline_family and headline_scale exist for brands whose display face sets optically larger or smaller than the body face at the same px value.

Logo. Placed automatically on every slide, including the cover. The variant is computed from background luminance and the contrast of the coloured mark against that background, so full colour is used wherever it is legible and mono is used where it is not. On a slide whose background is the brand accent, the mark would score near 1.0 contrast and disappear, so that slide correctly falls back to mono. Because it is computed rather than a lookup table, adding a new background colour needs no logo work.

Environment

Needs playwright with chromium, img2pdf, and Pillow. Fonts and logos ship in assets/, so there is no network dependency at render time.

pip install playwright img2pdf Pillow && python3 -m playwright install chromium

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.