# /pb-post

> Create a Vacca/ColdIQ-grade LinkedIn post for Faris's personal brand (faris-bio) — a dark, information-rich infographic (static PNG + animated GIF) plus brand-voice copy and a pinned comment with a proof image.


# /pb-post — faris-bio LinkedIn post engine

Produces a complete, post-ready LinkedIn asset in the ColdIQ / Alex Vacca visual language, but in Faris's brand and voice. The differentiator vs. AI image tools: **the graphic is hand-coded HTML/CSS rendered to PNG/GIF by Chromium**, so every label is pixel-sharp and every number is real. Krea is only ever used for a text-free atmospheric backdrop (the `hero` style), never for text.

## When to trigger
"make me a LinkedIn post", "pb-post", "post about X", "turn this into a LinkedIn graphic/carousel", "a Vacca-style post about Y". English only.

## Output — ALWAYS a proposed/ folder
Everything for one post goes in **one self-contained folder** so it can be ACME Agencywed/handed off:

```
faris-bio/channels/linkedin/proposed/<YYYY-MM-DD-slug>/
  post.md                 # the body copy
  pinned-comment.md       # pinned comment text (+ which image to attach)
  checklist.md            # the little-elements check, all ticked
  visual.gif              # the post asset (animated — POST THIS)
  visual.png              # static fallback
  pinned-comment-image.png# proof shot / secondary image for the comment
```

Never scatter a post across `posts/` + `assets/` again — one proposed folder per post.

## Styles (pick or let the user choose)
- **grid** (default) — dense 2-column category grid, real tool logos + numbered badges, center Claude-orange hub, animated dots. Best all-rounder. Engine: `faris-bio/scripts/<id>.mjs`.
- **hero** — AI (Krea) text-free glowing orb backdrop + code cards/text on top + glowing curved connectors. Most cinematic. Engine: `<id>.mjs` (+ `<id>.mjs --backdrop` for the orb).
- **radial** — central hub + nodes on connector lines. Engine: `render_claude_stack.mjs --layout radial`.
- **terminal-proof** — a real `ls`-style terminal (proof shot). Engine: `<id>.mjs`. Also the default pinned-comment image.
- **funnel** — top-to-bottom stacked stages that narrow (funnel silhouette), heat rising, animated flow chevrons. For anything sequential/staged (e.g. a full-funnel system). Engine: `render_pb_funnel.mjs`.

New styles are welcome — add a render script and document it here.

**Color rule:** Claude brand orange (#D97757) is reserved for posts *about Claude Code* (the title highlight + center logo). For any other topic, use faris-bio blue (#5BA3F5) for the highlight. Category/stage colors are free.

## Pipeline
1. **Get the topic + the real facts.** Never invent numbers. Confirm team size, client count, metrics with Faris. Pull skill/agent counts live from `.claude/skills` + `.claude/agents` (the terminal-proof script does this).
2. **Write the copy** in Faris's voice — delegate to the `copywriter` agent with `faris-bio/brand/voice.md` as reference. Structure: number/claim hook → reframe → numbered list mirroring the visual's sections → one napkin-math moment → one honest-about-fails line → one "don't do X" line → single ask ending in a question. Then a pinned comment (full detail + a link/proof).

   **LinkedIn packaging (readability — always apply):** the copy must be *scannable*, like Charlie Hills / Jasmin Alić posts.
   - **One idea per line.** Never a dense multi-sentence paragraph. Max 1-2 lines per block.
   - **Blank line between every block** (LinkedIn eats single newlines; double them).
   - **Hook = the first 2 short lines** — they must land before LinkedIn's "…more" cutoff. No throat-clearing.
   - **Numbered list** that mirrors the visual's stages/cards: each item is a short label line, then ONE supporting line under it.
   - **No markdown bold** (`**`) — LinkedIn renders it literally. Use a bare label line or CAPS for emphasis.
   - **Emoji:** at most one, functional (e.g. a 👇 on the comments line). Usually none. Never decorative.
   - **Length:** aim ~120-180 words. Shorter is better. Cut every line that does not teach.
   - **End with:** one CTA question, then an optional short **P.S.** (great home for the "don't do X" / credibility line).
   - **Pinned comment:** same short-line treatment — numbered, label + one line, the exact commands/tools, one rule, and the YouTube handle.
3. **Render the visual** with the chosen style's script → PNG + GIF.
4. **Render/choose the pinned-comment image** (default: terminal-proof).
5. **Assemble** the `proposed/<slug>/` folder (copy assets in, write post.md + pinned-comment.md + checklist.md).
6. **Verify** against the checklist below before declaring done. Regenerate anything that fails.

## The little elements — verify EVERY post (verify-by-default)
Copy of this lives in each post's `checklist.md`.

**Voice** (brand/voice.md): number/claim hook · single-sentence paragraphs · one checkable napkin-math moment · one honest-about-fails line · one "don't do X" line · named tools · exactly one ask, ends on a question · NO em-dashes · no banned phrases (unlock, game-changer, in this video, let's dive in…) · no two-word fragments.

**Facts:** real and checkable · identical across copy + visual + proof image · skill/agent counts match `ls .claude/skills`.

**Identity:** name = "Faris Biogradlić" (never "faris-bio") · tagline set, no "@faris-bio" handle in the body · real headshot in avatar (`brand/visual-identity/headshot.png`).

**Visual:** Claude orange for the "CLAUDE CODE" highlight + center logo, faris-bio blue (#5BA3F5) for personal-brand chrome · real tool logos (favicons via `fetch_brand_icons.mjs`) on 3rd-party items, terminal glyph on own /skills · pixel-sharp code-rendered text (never an AI image for text) · **motion actually works** (GIF frames differ — animated GIF is ~1MB, a static one is ~330KB; if it's tiny, the animation didn't render) · seamless loop.

**Comment:** pinned comment written · proof/secondary image attached.

## Assets & helpers
- Brand voice: `faris-bio/brand/voice.md` · tokens: `brand/visual-identity/tokens.json`
- Headshot: `brand/visual-identity/headshot.png` (auto-used when present, else "FB" monogram)
- Tool logos: `brand/visual-identity/icons/*.png` (refresh with `scripts/fetch_brand_icons.mjs`)
- Render scripts: `faris-bio/scripts/render_claude_stack_*.mjs`, `<id>.mjs`

## Gotcha (learned)
The GIF animation must be gated on an `animated` flag passed to the HTML builder, and set TRUE for the frame-capture loop (not on a `--video` CLI flag the GIF path never sets) — otherwise every GIF frame is identical and the post is silently static. Confirm motion by checking the GIF file size (~1MB) or diffing two frames.
