SKILL.md
LinkedIn Carousel Generator
One self-contained HTML file: LinkedIn-style preview frame, swipeable 540x540 slides, dot navigation, and a download panel that exports each slide as a 1080x1080 PNG via html2canvas. Copy first, design second, export always.
Gate: ask before building
Never generate a carousel without asking the onboarding questions first, even if the topic is fully specified. Post them as plain numbered text in one message and wait:
- Who is this for? (name or brand on cover and CTA slide)
- LinkedIn handle? (creator badge)
- Topic, angle, or argument?
- Target audience? (calibrates tone)
- Primary brand color? (hex, or describe it)
- Slide count: punchy 6-8, standard 9-12, deep-dive 13-16? Default 10.
- Tone: analytical / tactical / bold / conversational / storytelling?
- Font vibe: editorial / sharp / warm / bold / clean modern?
- Logo, initials, or photo for the cover?
- CTA: follow / save / DM / comment / visit link?
Proceed once you have topic, brand color, name, and handle. State your choice explicitly for anything left blank. If the user has a saved brand kit file, load it and skip the questions it answers; ask the rest.
Red flags (excuses to build without asking)
- "The topic is detailed enough to infer the rest."
- "I'll use tasteful defaults and they can correct me."
- "Asking ten questions feels like friction."
- "They said ASAP."
All of these produce off-brand output that gets rebuilt from scratch. Any workaround that ends with HTML generated before the user answered is a violation of this gate.
Workflow
- Gather inputs (gate above).
- Build the 7-token color system from the primary color: CORE, CORE_SOFT (12% opacity), CORE_LIGHT (+28%), CORE_DEEP (-35%), CANVAS (tinted off-white, never pure #fff), CANVAS_RULE, INK. Full derivation rules: read references/content-patterns.md section 5.
- Set typography from the font vibe. Pairing matrix: references/content-patterns.md section 4. Type scale is fixed, do not deviate: cover 36-42px/700-800, headings 26-30px/700, body 14px/400, eyebrows 9px/700 uppercase, counters 11px/300.
- Write ALL slide copy before any design. Pick a content pattern (How-To, Myth vs Reality, Before/After, Data Story, Framework, List) from references/content-patterns.md section 2. One idea per slide. Max 50 words per slide, target 30. Cover earns the swipe, summary earns the save, CTA earns the follow.
- Generate the HTML. Read references/components.md for the component library. Background rhythm: cover gradient, alternate CANVAS and INK, CTA gradient. Every slide gets a decorative element, a zero-padded counter bottom-left, and a swipe arrow (except the last slide).
- Wrap in the LinkedIn preview frame (header, viewport, dots, page label, action bar, caption preview): references/content-patterns.md section 6.
- Add the download panel (per-slide buttons plus Download All): references/content-patterns.md section 7. For lossless output, offer the Playwright export recipe in section 8.
- Run the quality checklist in references/content-patterns.md section 9 before presenting.
- After approval, offer the post caption: hook line visible before "...see more", 3-5 context lines, swipe prompt, closing question, 3-5 hashtags.
Layout rules
- Reserve the bottom 44px; nothing overlaps the counter.
- No flat backgrounds, ever. Decorative element per slide.
- Real numbers over adjectives.
- Dots and download panel are non-negotiable.
Verification
Open the finished HTML in a browser (or headless screenshot). Expect: all slides swipe, dots track, and one PNG download produces a 1080x1080 file with correct fonts. If the PNG shows fallback fonts, fonts did not finish loading before capture: add a 3500ms wait before html2canvas runs and re-test.
Completion checklist
- [ ] Questions asked and answered before any HTML
- [ ] All copy written before design, one idea per slide, under 50 words each
- [ ] 7 color tokens derived, type scale respected
- [ ] Counter, swipe arrow, decorative element on every slide per rules
- [ ] Preview frame, dots, and download panel present
- [ ] PNG export verified at 1080x1080 with correct fonts
- [ ] Caption offered
Any box unchecked: not done. Fix or say so.
Good vs bad
- Bad cover: "10 Tips For Better Outreach" (generic, nothing to disagree with).
- Good cover: "Your first cold email line is why 92% never reply" (specific, debatable, earns the swipe).
Footguns
- Setting the viewport to 1080px reflows the layout and shrinks fonts. Keep 540x540 and export at scale 2.
- External image URLs vanish in export. Base64-encode every image inline.
- Frame chrome captured in the PNG: hide the frame's UI classes before capture.
- Filenames not zero-padded break sort order when slides get assembled into a PDF. Use 01, 02, ...
- Writing the HTML through shell heredocs corrupts
$sequences. Write the file with a proper file-write tool or PythonPath.write_text().