Generates LinkedIn post copies and images to position a technical brand (X - Scriptor) around web development, accessibility, usability, programming, TypeScript, JavaScript, VS Code, extensions, dev ecosystem, Linux distros, and career. Use when the user asks for LinkedIn posts, copies, hooks, hashtags, publishing calendar, personal-brand positioning, or 1080x1350 post images; also to continue or regenerate a numbered content series.
LinkedIn Content (X - Scriptor)
Complete LinkedIn content system: publication-ready copies plus 1080x1350 images
on OLED black with the tiny X - Scriptor signature.
Everything is deterministic and numbered: the .md NNN always matches the image NNN.
When to use this skill
- Create or extend a series of LinkedIn posts.
- Generate the image for a copy (1080x1350, 4:5).
- Plan cadence, publishing windows, and topic blocks.
- Review or rewrite hooks, hashtags, and post structure.
Quick start
# 200 full posts (copies + images + index) into ./contenido
python3 scripts/generar.py --out contenido --count 200
# single topic, 20 posts
python3 scripts/generar.py --topic typescript --count 20 --out out-ts
# continue an existing series from 201
python3 scripts/generar.py --out contenido --count 50 --start 201
# copies only (fast drafts, no rsvg)
python3 scripts/generar.py --out drafts --count 30 --text-only
Output:
<out>/
├── indice.md # table: Nº | topic | hook | image
├── posts/NNN-slug.md
└── img/NNN-slug.png
Each .md contains: topic, image path, ALT text, suggested publishing
window, hashtags, and the copy ready to paste (no markdown, line breaks included).
Workflow
- Run the generator with the desired
--countand--out. - Review 2-3 random
.mdfiles and one full-size image (not only thumbnails). - Tune content in
scripts/temas.py(ideas per topic) andscripts/ganchos.py(new hooks); run again. - When publishing: copy the text, upload the image with the same number, and paste the ALT text into LinkedIn.
Quality rules (non-negotiable)
- The hook fits in the first 2 lines (≈140-210 characters).
- Copy is at least 800 characters; paragraphs of 1-3 lines; arrows
→or lists. - Maximum 3 niche hashtags; never 6+.
- No external links in the body (nor in the first comment).
- The image carries ALT text and its number matches the
.mdnumber. - The image signature is only
X - Scriptor, small and barely visible. Never mention any internal brand name in the content or the images.
Customization
| I want to | Where |
|---|---|
| Add/change topics, hashtags, subtitles | scripts/temas.py (TOPICS) |
| Add new hooks | scripts/ganchos.py (HOOKS) |
| Change CTAs, intros, windows | scripts/temas.py (CLOSERS, OPENERS, WINDOWS) |
| Change colors, fonts, layout | constants and build_svg() in scripts/generar.py |
| Change the signature brand | BRAND constant in scripts/generar.py |
References
references/linkedin-strategy.md— what the algorithm rewards (with numbers) and mistakes to avoid.references/copy-structure.md— hooks, the 4 post structures, hashtags, CTAs.references/visual-system.md— tokens, grid, motifs, and signatures for the images.references/publishing.md— cadence, windows, golden hour, topic blocks, and metrics.
Requirements
- Python 3 (standard library only).
rsvg-convert(librsvg2-binpackage) to rasterize the images.- Installed fonts: Space Grotesk, Space Mono, and Doto. If missing,
rsvg falls back to generic fonts and the design loses character (see
references/visual-system.md).
References (4)
copy-structure
Copy Structure
The generator builds every post as: hook + intro + 4 ideas + closing, rotating one of four shapes so no two publications look the same.
Hook rules
- Two lines maximum (≈140-210 characters). It must fit "above the fold".
- Formulas that work: a short debatable claim, a concrete data point, a common mistake, a promise of usefulness, a question with tension.
- No empty clickbait: if the hook promises and the body does not deliver, dwell time drops.
- Write the hook last, once you know what the post actually says.
Examples from the pack:
- "any is not a type: it is turning the compiler off with style."
- "Users do not wait 3 s: they leave before your spinner loads."
- "If the save button needs explaining, the design fails."
The 4 structures
| Mode | Shape | Best for |
|---|---|---|
| 0 | hook → intro → 4 "→" bullets → question | tip lists |
| 1 | hook → intro → 4 numbered points → question | steps or levels |
| 2 | hook → 4 short paragraphs → question | developing one idea |
| 3 | hook → intro → 4 "•" bullets → question | mistakes and nuances |
Body
- 4 concrete ideas, each 1-2 sentences with at least one data point, API name, or verifiable consequence.
- No markdown (LinkedIn does not render it): backticks are stripped at generation time. Arrows and numbers are the format.
- Neutral Spanish, "tú/ustedes"; concrete verbs; short sentences.
Closing and hashtags
- Closing = open question, specific and answerable in one comment. Avoid generic "what do you think?".
- Hashtags: exactly 3, niche and related to the post topic. Never 6+; the net impact of more hashtags is negative.
- The closing question is also an honest invitation: replying to every comment is part of the strategy (golden hour).
Content bank
scripts/temas.py→TOPICS: each topic has 16 concrete ideas, an image label, hashtags, and 3 subtitles.scripts/ganchos.py→HOOKS: 200 unique hooks grouped by topic.- The generator interleaves topics round-robin (never two consecutive posts on the same topic) and picks 4 ideas with a different rotation per post, so combinations do not repeat across the series.
linkedin-strategy
LinkedIn Strategy (2025-2026)
Operational summary of what rewards and sinks posts, with the numbers that matter when planning.
What the algorithm rewards
- Dwell time (reading time) is the core metric. LinkedIn penalizes predicted
"short dwell": if the reader leaves after 3 seconds, the post sinks.
- Document carousel: ~55 s of reading time vs. ~15 s for a text post.
- 61 s or more: 15.6% engagement; under 3 s: 1.2%.
- Interaction hierarchy: a save ≈ 5x a like and ~2x a comment; a comment ≈ 2x a like; comment threads up to 2.4x reach; a plain repost only 0.29x.
- The first 2-3 lines (~140 characters on mobile, ~210 on desktop) decide whether "see more" is tapped. Misleading hooks that cause quick exits penalize.
- Consistent interest (Interest/Knowledge Graph): 70-80% of content should fall within 2-3 areas of expertise. Going off-niche reduces reach.
- Early comments: replying to every comment within the first 30-90 min reactivates scoring (+30% typical engagement).
What gets penalized
- External links in the body: ~-60% reach. "Link in first comment" is also penalized. Publish natively; keep the link in the profile or add it later by editing the post.
- Bait: "comment YES", "like if…" is suppressed by NLP. Engagement pods are prohibited (detection ~97%).
- Generic AI content without a personal perspective: ~-30% reach and -55% engagement.
- Posting more than once a day; more than 8 posts/week drops ER to 1.79%.
- Too many hashtags (6+ sinks; 3-5 slightly reduces; the optimum is 3 or fewer).
Format that performs
- 800-1,000+ characters per post (1,000+ = 1.18x reach; under 300 = 0.88x).
- 16-20 sentences, 1-3 line paragraphs, easy reading (~4th grade level).
- Bullets, arrows (→), unicode bold, 0-2 emojis, no markdown.
- An open, specific closing question to drive comments.
Image
- 1080x1350 px (4:5) performs best for a single image (2.83% ER vs. 2.54% square and 2.14% horizontal). LinkedIn crops above 1350 px in height.
- Text inside the image: no formal penalty, but screen readers cannot read it → always ALT and keep the key message in the copy too.
- PDF carousel (6-10 slides, 1080x1350): 1.39x reach and 1.30x engagement; worth it above ~20K followers rather than a single image.
Profile and consistency
- A profile aligned with the topic (headline, featured) multiplies each post's reach.
- Avoid editing the post after publishing (it resets initial distribution).
- 3-5 posts/week: 4-5 per week yields ~2.60% ER and ~870 impressions.
publishing
Publishing: Cadence, Windows, and Metrics
Cadence
- 4 posts/week is the sweet spot (range 3-5).
- Never more than 1 per day; 8+ per week drops ER to ~1.79%.
- 200 posts ≈ 1 year at 4 per week.
- Round-robin interleaving (the generator does it) avoids saturating one niche, but dedicating weekly blocks to your 2-3 strong topics is better.
Recommended windows
- Main: Wednesday 15:00-16:00 and Friday 15:00-16:00.
- Alternative: Tuesday to Thursday, 7:00-9:00 and 12:00-14:00.
- Each
.mdcarries a rotated suggested window; validate with your own stats after 4-8 weeks and adjust.
Golden hour (first 30-90 min)
- Before publishing, spend 10-15 min commenting on accounts in your niche.
- Publish inside the chosen window.
- Reply to every comment within 60-90 min; each reply reactivates scoring.
- Do not edit the post afterwards: it resets the initial distribution.
Suggested topic blocks
The pack has 12 topics. For the Interest Graph, publish in blocks:
- Month 1: TypeScript + web development + xscriptor (your strong topics).
- Month 2: accessibility + usability + programming.
- Month 3: JavaScript + VS Code + extensions.
- Month 4: ecosystem + distros + career.
- Repeat the cycle with the remaining hooks.
Keep 70-80% of content in 2-3 areas of expertise; rotate the rest.
Metrics to track (weekly)
- Dwell time and reach per post (what the algorithm looks at first).
- Saves: the strongest signal; no saves means the post teaches little.
- Comments (and replies inside the thread).
- Followers gained per post, not just impressions.
- Profile click rate.
Pre-publish checklist
- [ ] The hook fits in 2 lines and is not misleading.
- [ ] The post exceeds 800 characters and has 4 concrete ideas.
- [ ] Exactly 3 niche hashtags.
- [ ] No external links in the body.
- [ ] 1080x1350 image with the right number and ALT pasted into LinkedIn.
- [ ] Valid time window and 30-60 free minutes afterwards for comments.
visual-system
Visual System
Single image, 1080x1350 (4:5). OLED black, dot grid, hairline strokes, technical
typography, and a single red accent. The only visible brand is a tiny
X - Scriptor at the bottom right.
Tokens
| Element | Value |
|---|---|
| Background | #000000 |
| Dot grid | #171717 (0.9 px dots every 16 px) |
| Hairline motif lines | #151515 |
| Corner ticks | #3A3A3A |
| Ink (headline) | #F2F2F2 |
| Top label | #6E6E6E (Space Mono, uppercase, 0.18em tracking) |
| Subtitle | #7A7A7A (Space Mono, uppercase, 0.16em tracking) |
| Doto number | #383838 |
| Signature | #3E3E3E (Space Mono 19 px) |
| Accent (single) | #D71921 (160x1.6 px rule + 3 px dot) |
Typography and hierarchy
- Headline: Space Grotesk Medium, auto-fitted between 96 and 54 px, up to 5 lines, -0.02em tracking. It is the synthesis of the copy (the hook).
- Label: post topic, top left.
- Number: Doto 46 px, top right; matches the
.mdnumber. - Subtitle: one short line from the topic, under the headline.
- Signature:
X - Scriptorat 19 px, barely visible.
Layout
- Margins: 96 px on the sides.
- Headline vertically centered around y=700, left-aligned.
- Accent rule right above the headline; accent dot at the end of the rule.
- Corner ticks (18 px).
- Rotating background motif by
n % 4: concentric circles, diagonal lines, horizontal lines, or dashed circles. Motif center alternates between (860, 300), (220, 1080), and (880, 1120) to vary the framing.
Hard rules
- Never put any brand name other than
X - Scriptor; no internal system names. - The signature never competes with the content: small size and dark gray.
- One color accent per image; everything else is monochrome.
- No solid fills behind text: the background breathes.
- The key message also lives in the copy; not every device can read text in images.
How to change it
Everything lives in scripts/generar.py: color and font constants at the top,
motif() for background structures, and build_svg() for the composition.
To change the signature, edit the BRAND constant.
Fonts
Space Grotesk, Space Mono, and Doto must be installed (rsvg resolves them through fontconfig). If missing, rendering does not fail but falls back to generic alternatives: install them to preserve the system's character.