Built for SaaS · social template S3

BFS post system.
Every post, every rule, every number.

The approved Instagram and LinkedIn post set (1080×1350) with the design language behind it: frame, tokens, components, rules and a spec any AI model can follow to make new posts that match.

Frame

One frame, never changed per post.

All coordinates are in post pixels on the 1080×1350 canvas. Inside posts use this frame; covers add a left rail (see Covers in the library).

builtforsaas.com @builtforsaas Pillar · label Remote design team for SaaSSave ▢ 1 2 3 4 5 6
1

Chrome bar · 0–72White, dashed bottom rule. Three grey dots #DCDDDF (r6, x 34/55/76). URL pill 360×38 centred, lock icon in blue, 17px. Handle @builtforsaas 16px #8A9097, right 28.

2

Header · x 104Pillar pill: 32px white tile r8 with a 16px blue line icon, then "Pillar · label" 18px/600. Headline 66px, weight 680, line-height 1.02, tracking −0.045em, #141618. Optional grey second line #9AA0A7.

3

Subtext25px, line-height 1.45, #5C6169, 22px under the headline, max about 800px wide (1–2 lines). Says the point or the source. On every inside post.

4

Visual area · x 64–1016, ends at y 1270Dashed 1.5px (5/6) rect, fill #EFEFED + fine grain, 9px white corner handles. Top depends on the header: 300 (1 line), 360 (headline + 1-line subtext), 420 (3 lines), 470 (headline + grey line + 2-line subtext). Must start ≥24px under the header.

5

Main objectOne hero object, 40–56px from the area edges (windows usually at x 120, width 840). Radius 16 on all four corners, layered navy shadow.

6

Footer · centre y 1307"Remote design team for SaaS" 19px #5C6169 at x 144; "Save" + blue bookmark on the right. Carousels: 5-segment progress (active blue), "01 / 09", "Swipe →"; last slide "Link in bio ↗".

Formats

One master, every channel.

Design the 1080×1350 post once; it ships unchanged to Instagram, LinkedIn, X and Threads. Stories, link cards and blog images get their own frames, built from the same parts. Blue dashed area = safe zone for text and the main object.

ChannelUseExport sizeRatioFileNotes
InstagramFeed post, carousel slide1080×13504:5PNGThe master size. The profile grid shows a centred 3:4 crop, which trims about 34px from each side: keep everything inside the dashed guides (x 64–1016), as the frame already does. Every carousel slide the same size, max 20 slides.
Story, Reel cover1080×19209:16PNGKeep text out of the top ~250px and bottom ~340px (app UI sits there). The grid shows the Reel cover as a centred 3:4 crop.
LinkedInImage post1080×13504:5PNGSame file as Instagram. Taller than 4:5 gets cropped.
Carousel (document post)1080×1350 per page4:5PDFOne PDF, every page identical in size (the first page sets the size for all). Under 100 MB, 8–12 pages. Cover first, CTA last.
Link preview1200×6301.91:1PNG/JPGComes from the page's og:image, so the blog OG image covers it.
XSingle image1080×13504:5PNG ≤ 5 MBShows uncropped as a single image. Posts with 2–4 images get cropped tiles, so use one image per post.
Landscape / link card1200×67516:9PNG/JPGFor a wide visual or the summary_large_image card (set twitter:card).
ThreadsImage post, carousel1080×13504:5PNGSame file as Instagram.
BlogCard thumbnail1600×100016:10WebP/AVIFMatches the 16:10 thumbs in the BFS blog. Shown small: one headline, one visual, no body text.
Article hero2400×135016:9WebP/AVIF2× of a 1200px column. Also the BlogPosting image (Google wants ≥ 1200px wide; 16:9, 4:3 or 1:1).
In-article figure1600×1000 or 1600×90016:10 / 16:9WebP/AVIFOne real screenshot or diagram per figure, with a caption below in HTML (not in the image).
OG / share image1200×6301.91:1PNGGenerated per post at build time. Absolute https URL in og:image; add twitter:card = summary_large_image.
VideoYouTube / video thumbnail1280×72016:9JPG/PNG ≤ 2 MBBottom-right corner is covered by the duration badge.

Rules for every format

  • Make the 4:5 master first; adapt it, don't redesign it.
  • Keep text and the main object inside the safe zone; only background and window edges may reach the crop line.
  • Phones show a 1080px post about 390px wide (×0.36). For new posts: notes and labels ≥ 22px, callout titles ≥ 28px, headline ≥ 56px.
  • Export at 2× (2160×2700) by default, 3× (3240×4050) for posts with fine UI detail, then compress (see Export below). Check the file once on a phone.
  • LinkedIn carousels: same slides, exported as one PDF. Instagram, X and Threads carousels: same slides as PNGs.
  • Blog and link images: WebP or AVIF on the site, PNG/JPG for og:image. Always set width, height and alt.

Adapting the frame

  • Landscape (16:9, 16:10, 1.91:1): chrome bar 48px with the URL pill and handle; text column on the left (≈40%, pillar pill, headline 56–64px, one subtext line); visual on the right (≈60%) in the dashed area; 48px outer margin; no footer.
  • Blog thumbnail: headline only (≤ 6 words, 72px+ at 1600 wide) plus one real visual. No pins, legends or footnotes; it is read at 300–400px.
  • Story (9:16): chrome at the top, header below the top safe zone, one visual centred, CTA above the bottom safe zone.
  • OG image: the blog title, the BFS mark and the pillar; it must read at 600×315.

Export: sharp, true colour, small

StepSettingWhy
Rendernode export.mjs S3-<name> 2 → 2160×2700 PNG (use 3 → 3240×4050 for fine UI detail)Platforms downscale a larger source more cleanly than they upscale; text and 1.5px lines stay crisp.
Compresspython compress.py png@2x upload@2xWrites upload-ready files next to the masters.
FormatJPEG quality 90, progressiveMeasured on W1: 2× PNG 1.6 MB → JPEG 0.49 MB, PSNR 46.7 dB against the PNG, so no visible difference. 3× ≈ 0.93 MB.
Colour4:4:4 chroma (no subsampling) + embedded sRGB profileDefault 4:2:0 smears blue pins, red/green tags and coloured text edges; the profile keeps colours identical on every phone.
LinkedIn carouselPDF from the 2× JPEGs, one page eachSame pages, small file (8–12 pages ≈ 4–6 MB).
BlogWebP/AVIF quality ~80 at 2× of display size, PNG for og:imageSmallest files for the site; og:image stays PNG for previews.
NeverUpscale a 1× export, use 4:2:0 JPEG, strip the colour profile, or save below quality 85Each one blurs text or shifts BFS blue.
Tokens

Colour, type, spacing, depth.

Blue is the only brand accent. State colours appear only when they carry meaning (before/after, myth/fact, live, waiting).

Neutrals

Ink#141618 · headlines, body
Mute#5C6169 · subtext, notes
Faint#8A9097 · handle, meta
Grey line#9AA0A7 · 2nd headline line
Page#F7F7F5 · post background
Area#EFEFED + grain · visual area
Window bar#F4F4F2 · browser top bar

Brand + states

BFS blue#0058F6 · bg #EAF1FF
Greentext #0B7A55 · bg #E5F6EE · dot #12B76A
Redtext #B42318 · bg #FDECEB · dot #F04438
Orangetext #B54708 · bg #FEF0E4 · dot #F97316
Yellowtext #8A6100 · bg #FEF6DA · dot #EAB308
BrandFact · liveMyth · beforeLazy · laterYour review

Depth + radius

d10 0 0 1px rgba(20,22,24,.08), 0 1px 1px rgba(16,40,96,.04), 0 2px 4px rgba(16,40,96,.05)
d30 0 0 1px rgba(20,22,24,.08), 0 2px 3px rgba(16,40,96,.06), 0 12px 24px -8px rgba(16,40,96,.18), 0 40px 80px -24px rgba(16,40,96,.28)
Radius16 windows, cards, panels, phones (screen r = width × .118) · 12 buttons · 10 pins, highlight rings · 8 tags
LightOne light from above. Navy-tinted shadows, never pure black.
Type roleSize / lineWeight · trackingColourWhere
Inside headline66 / 1.02680 · −0.045em#141618Every inside post
Cover headline56 / 1.04680 · −0.04em#141618 + grey lineFirst slide
No-visual headline80 / 1.0700 · −0.045em#141618 + #9AA0A7D1, H2
Subtext25 / 1.45400#5C6169Under every headline
Pillar label18560–600#141618 / blue on coversHeader pill
Callout title23–26650 · −0.02em#141618Pins, legends
Callout text18–20 / 1.4400#5C6169Pins, legends, captions
Mono labels14–17 Geist Mono500#8A9097 / bluePins, code, axis, meta
Footer19400 / 600#5C6169 / #141618Every post
Minimum16px––Anything outside a real screenshot (QA fails below 16)
SpacingValue
Grid8pt (4 for small details). Text x 104 inside, 144 on covers.
Content to visual-area edge40–56px (never touching, nothing cut by accident)
Header end → visual area≥ 24px (QA gate), usually 40–56
Title → its text4–8px; groups 20–40px; ruled rows 24–32px padding
Window chromeTop bar 40px, dots 11px #DCDDDF gap 8, URL pill 24px r7 13px
Legend / rule lines1.5px dashed rgba(20,22,24,.16)
Components

The annotation and showcase kit.

Real UI is the subject; blue is the spec layer drawn on top of it.

sydecar.io
Close SPVs without surprises.

Browser window. 16px radius, d3 shadow, 40px #F4F4F2 bar, grey dots, centred URL pill. Holds a real screenshot from the case, full section, never cut mid-row.

1
Headline56px bold, −4%

Pin + leader + callout. Pin 30px r10 blue, Geist Mono 16 white. Leader 1.5px dashed rgba(0,88,246,.6) 4/4. Dot 10px blue with 3px white ring. Callout title 23–26/650, text 18–20 #5C6169.

Your remote design team.33

Part tag (anatomy v2). The part stays bright while the rest of the screen dims softly (rgba(12,18,34,.10), brightness .93). A 20px blue tag with a 2px white ring sits on the part's right edge, and the dashed leader runs from it to the same number on the note.

Invest in marketing
1

Spotlight. Dims only the UI surface: rgba(12,18,34,.30) + brightness .76 + saturate .25, no blur. Holes get a 1.5px white ring and a 20px pin on the corner. 1 hole, 2 at most.

7:04▮▮ ◠ ▭
Real builtforsaas.com mobile capture

Mobile screen. Real capture (iPhone 13, 390×797), screen only: no bezel, notch or home bar. Hairline + soft shadow, status bar at iOS proportions reading 7:04.

Sam M
Sam MFounder, Built for SaaS
Rishi M
Rishi MCo-Founder, Built for SaaS

Author byline · 3 options. byline("sam" | "rishi" | "bfs"). Sam is the default (opinion, process, sales). Rishi covers build, performance, CMS and engineering. BFS team, shown with the metal mark, covers news and case studies. Photo 56–60px, r14, 3px white ring.

4 choices1 choiceLive on launch dayYou reviewLoads later

State tags. 30px tall, r8, 7px dot, text + tint from one state. Only when the state is the point.

Rules

What makes a post look like BFS.

Every line here came from a round of feedback on the set.

Do

  • One main object per post, large and on purpose.
  • Show real UI: case screenshots, real mobile captures, real chat screenshots.
  • Show a whole section of a screenshot, top to bottom.
  • Give every inside post a headline and a one or two line subtext.
  • Use 16px radius on all four corners of every window, card and panel.
  • Keep 40–56px between content and the visual-area edge.
  • Mark 1–2 things with a spotlight; 3+ parts with numbered pins.
  • Start a leader at the thing it explains (outline it, then draw the line).
  • Lay text-led posts straight on the area, divided by dashed rules.
  • Take facts, numbers, quotes and names only from builtforsaas.com or Sam.
  • Light the post's pillar in the cover rail; light two for a two-pillar post.

Don't

  • Describe UI in a text box instead of showing it.
  • Crop a screenshot mid-row or stretch its ratio.
  • Stack cards on cards or float a small window in empty space.
  • Blur in the spotlight, or dim the whole textured area.
  • Use zoom lenses or magnified duplicates.
  • Put a blue word inside a headline or use colour as decoration.
  • Use gradients outside real screenshots; no dark theme posts.
  • Use tilted or 3D-rotated mockups, glass only as a UI bezel.
  • Use text under 16px outside real screenshots.
  • Show a phone with a home bar or a 9:41 clock.
  • Invent numbers, clients or quotes. Draft opinion copy goes to Sam first.
Post library

All 45 approved posts and formats.

Each card says what the post is, what it is built from and when to reuse it. Click a post for full size.

Workflow

Making a new post.

Source lives in agency\clients\built-for-saas\social-posts; templates in designs-v16.js (set S3) and covers in set S3C.

  1. Pick the pillar and the closest templateWork, Design, Dev, Conversion, Process, Wins, Learn, or a text post. Reuse a template; add a new one only when none fits.

  2. Write the copy from real sourcesHeadline (one idea, ≤ 7 words), subtext (the point or the source, 1–2 lines). Facts only from builtforsaas.com or Sam.

  3. Collect real visualsDesktop: BFS case shots (assets/work). Mobile: Playwright iPhone 13 capture, cookie banners rejected or hidden, never accepted. Chats: Sam's screenshot.

  4. Buildpost(T(pillar, label, headline, "", subtext), inner, areaTop); annotate with spot(), pins or outlines.

  5. Export and QAnode export.mjs S3-<name>, then node qa.mjs S3- must print "QA passed" (text ≥ 16px, nothing clipped, nothing outside the area, header ≥ 24px above it, no placeholder copy).

  6. Look at it at full sizeZoom into small parts: pins, tags, status bar, highlight edges. Fix, re-export, then share one change at a time.

LLM spec

Give this to any AI model.

Also at /skill/references/full-spec.md for tools that read a URL. A self-contained brief: paste it into Claude, ChatGPT or any model, add the topic, and attach 1–3 of the post images above as reference.

bfs-post-system.md