Content format
One post per Markdown file anywhere under posts/. Files and folders starting with
_ or . are ignored, so posts/_ideas/ is a safe place for scraps.
---
id: launch-week-1 # optional; defaults to the file name
at: 2026-10-27 09:00 # local time in the configured timezone
status: ready # ready (default) or draft
channels: [linkedin] # defaults to every configured channel
topic: launch # used by the repeat-topic check and the brief
image: ../assets/photo.jpg # PNG or JPEG inside the project root
alt: Team photo at the offsite
card: { ... } # see below
variants:
bluesky: Shorter text for Bluesky.
---
The post body, exactly as it should appear.
Body
Plain text. Line breaks are kept. Hashtags written as #Word become proper hashtags
on LinkedIn and Bluesky. Links can be full URLs or bare domains with a path
(acme.com/blog/post); a bare domain with no path is left as text.
id values are also used for safe output filenames. They must begin with a letter
or number and may contain only letters, numbers, dots, underscores and hyphens.
Unknown status values are errors and are treated as drafts, never as ready posts.
Rules such as hashtag and hook limits apply to the final per-channel variant.
Cards
card:
layout: rows # rows | grid | statement | any custom layout
size: landscape # optional, overrides card.size in config
eyebrow: Case study # small uppercase line in the accent colour
headline: # 1 or 2 lines; line 2+ is in the accent colour
- Cutting CI from 22 minutes
- to 6 without new hardware.
subline: Optional sentence under the headline (statement layout).
items: # 2 to 4 reads best
- title: Remote cache
note: 71% of steps skipped
label: Biggest win # grid: small label above; rows: replaces the number
chip: passing # coloured pill, tone from brand.chips
footer: One line at the bottom left.
- rows: numbered rows, each with an optional chip. Good for steps, lists, before/after.
- grid: up to four panels. Good for stats and case studies, especially in landscape.
- statement: headline and an optional subline. Good for questions and quotes.
Text in cards is escaped, so <, & and quotes are safe.
Custom layouts and card data
With design.templates configured, layout can name any of your own templates
(postline layouts lists them). Custom layouts don't require a headline and can
read extra values from card.data:
card:
layout: quote
headline: [Reputation compounds, faster than revenue.]
data:
author: Isaac Emmanuel
role: Founder, Nsisong Labs
tags: [business, lessons]
card.data accepts text, numbers, true/false, lists and nested mappings. See
design-systems.md for the template syntax.
Status
Drafts are ignored by publish and most lint rules. postline plan creates drafts.
A post without at can sit in the repo as an idea; it is never sent.