Skip to content
Back of house Not in the nav · noindex · not a secret

How to publish here

What to type, where it goes, and the handful of things that make a page come out wrong without telling you. The build-side documentation lives in the theme repo; this is the writing side.

Updated 25 Aug 2026 · Reconciled with the built theme

Ghost will happily publish something half-tagged. The theme is what notices. Almost everything below is a consequence of that one fact.

The eight things you publish

What
Made in
Comes out as
Newsletter issue
Roundup Builder → paste
Post page + email
Job listing
BJB Job Tool → draft
Board row + listing page
Resource
Ghost editor
Card + entry page
Portfolio piece
Ghost editor
Row + entry page
Footnotes entry
Footnotes admin
A row on /footnotes/
Changelog note
Ghost editor
"What's new" on /resources/
Podcast episode
Ghost editor + audio card
Post with a player
Standing page
Ghost editor
page.hbs

Everything except Footnotes is a Ghost post or page. Footnotes never touches Ghost — entries appear the moment you save them in the admin tool, with no publish step. And there are no custom theme settings anywhere in Ghost admin: the whole authoring surface is the body, the tags, the excerpt, the feature image and the post's meta fields.

What each type needs

Newsletter issue3 required
SeriesExactly one of roundup, bad-job-bingo, deep-dives — bare slugs, settled. The series tint on the issue-number cell comes from this.
NumberInternal tag #issue-NNN, zero-padded, next in the house sequence — one sequence for the whole newsletter regardless of series. Set the tag's description to the digits (059 on #issue-059): the numeral cell reads the description, and a tag without one renders the cell blank. A deleted issue leaves a gap forever; never renumber.
ExcerptWritten, not auto-generated. It is the dek in the feed.
ImageOptional. Without one the card collapses and centers, which is the designed state and not a fallback.
OrderInternal tags never sit first — Ghost's primary tag is "first public tag" with no fall-through, so an internal tag at position one silently blanks the series wherever it's read that way.
Job listingthe tool sets these
TagsOne rating (bjb-*), discipline, level, type, arrangement, salary band, location, company, status — all on namespaced slugs (job-discipline-*, job-status-open…). Salary is one rung of the seven-band ladder (job-salary-0-50kjob-salary-300k-plus) or a no-comp tag; exact ranges go in the body as text. IT IS A MYSTERY is a location tag — the posting never said where the job is.
RatingEvery listing gets rated. There is no unrated state and no paid listing — the theme has nothing to render instead.
ImageThe feature image is the company logo — that is what the slot means here. No logo → a stable tinted monogram; never a placeholder.
LocationCountry, plus state or province only where the posting restricts it. City goes in the body as plain text, never as a tag.
OpinionYours goes under the Steph's Notes heading — inside it, a blockquote is the company's words and a paragraph is yours. Closing a job is adding job-status-closed; the theme hides the Apply button and greys the strip.
Resource1 required, rest optional
KindThe internal #resource tag. Without it the entry never appears in the library at all, and nothing warns you.
DirectoryExactly one res-directory-* of the ten: Podcasts, Blogs, Newsletters, Learning, Communities, Events, Books, Job Boards, Tooling, Gear.
FactsThe body opens with the fact run — one paragraph per fact, typed as Label: value. The theme lifts it into the bordered fact table; the Website: fact powers the rail's "Open it ↗". Recognized labels: Title, Website, Publisher, Type, Venue, Hosted by / Organizer, Platform, Format, Location, Access, Model / Version, Price / Subscription / Cost, Submitted by, Where to get it, Reviewed. Never Cadence — a schedule claim rots and nothing detects it.
VendorMark Vendor published only if it is. Nothing marks independent entries.
EventsThe tag is res-directory-events, and the date lives in the body as <time datetime> — see Setting the body. An undated event sits in the upcoming list forever.
ReviewsTooling and Gear only, under Steph's Notes, with a Reviewed: row in the fact run. The other eight describe and stop.
Podcast episodea format, not a series
AudioGhost's native audio card at the top of the body — the card in the body is the storage; the theme lifts it into the Listen band, and /podcast/ plays it in place from the same card. Use Captivate's direct media URL (podcasts.captivate.fm/media/…), never the feed's analytics-wrapped one.
Tag#has-audio, so the archive shows the chip — added last, never first.
SeriesStill needed — an episode can be a Deep Dive or a Roundup. Podcast is how it is delivered, not what it is.
SummaryThe custom excerpt is the episode's summary line on /podcast/. Write it.

Whose words are whose

Their words in Instrument Serif italic. Your words in the body sans. It holds on job posts, quoted passages and Footnotes, and it is the whole reason a reader can tell a company's language from yours without you having to say so.

Theirs
“We’re looking for a rockstar who thrives in ambiguity.”
Yours
Ambiguity here means nobody has decided what this job is, and you will find that out in month two.
The one exception
Resource descriptions are not italicized, even though most of them are the source's own words. They run long — event details and podcast blurbs especially — and italics at that length is a punishing read. /faqs/ states the provenance instead: assume a description came from the resource unless a note says otherwise.

Setting the body

An issue runs on three columns: a sticky contents rail on the left, the body in the middle at 562px, and a notes margin on the right. Below the breakpoint the rail collapses and the notes move to the end. Everything here was settled against a real issue, so the answer to "how do I mark this up" already exists — you are choosing from a set, not inventing.

Most of this is plain Ghost. The chip on each device says how it's authored: a green chip means you use the editor's own feature — or type the thing — and the theme styles it; a grey chip means an HTML card, and every one of those is saved as a Ghost snippet so it's a pick, not a paste.

HeadingsGhost editorstructure the theme reads
H2 is a department (Roundup) or a verdict (Bad Job Bingo); H3 is a story subhead; H4 is a job title inside a Bingo verdict — and the verdict's listing count is derived from those H4s, so they are load-bearing. Department numerals and tints are generated by the theme; add, remove or reorder departments and nothing renumbers by hand. A Bingo verdict H2 must be the exact verdict name — Green Means Go · Eh, It's Probably Fine · Tread Carefully · BINGO · Seriously, Maybe Don't — because the icon, tint, rule and count all hang off matching the text.
Things That Happened
Salesforce tries to acquire everyone
Margin notesHTML cardthe digression that isn't worth a paragraph
A superscript number in the body, purple, with the note itself in the right-hand margin beside the line that raised it. The contents rail counts them. Below the breakpoint they collapse into the NOTES block at the end, each anchored so the number still jumps, and they are always printed at the foot as well for email, RSS and print. Numbering restarts each issue. A note longer than about forty words is a paragraph pretending to be a note.

…signed agreements to acquire Contentful, m3ter,1 and the big one, Fin.

1Which I had genuinely never heard of before this.
You typeTwo pieces, and the numbers pair them. A marker inline where the note occurs, and one NOTES list at the end of the body in a single HTML card — the foot list is the source of truth, and everything else (the margin copies, the pairing highlight, the mobile behavior) is generated from it. Save both as snippets; bump N per note.
…acquire Contentful, m3ter,<sup><a href="#note-1" data-note-ref="1">1</a></sup> and the big one, Fin.

<!-- one HTML card at the end of the body -->
<ol class="sh-notes">
  <li id="note-1">Which I had genuinely never heard of before this.</li>
  <li id="note-2">The second note.</li>
</ol>
Block quoteGhost editorsomeone else's words
Instrument Serif italic behind a 2px blue bar, indented from the measure. It mirrors the Footnotes treatment exactly, so quoted material looks the same everywhere on the site. Attribution goes underneath in mono, not inside the quote. A plain Ghost blockquote — no class, no card.

As I discussed in last week’s premium newsletter, the AI Tokenomics of it all are deeply unfavourable.

Ed Zitron · Where’s Your Ed At
Pull quoteHTML cardyour own line, emphasized
Sans bold, no bar, no quote marks, a ✦ opening and closing the line. Not a quote at all — it is your voice turned up, so it must not borrow the block-quote furniture. One per section at most; if two lines both want it, one of them is a heading.

I just want it on the record that that’s what they’re calling it.

You typeA blockquote carrying the class, in an HTML card. The class is what tells the theme — and the reader quote cards — that this blockquote is your voice, not a quotation. The ✦ marks are generated.
<blockquote class="sh-pull"><p>The line, in my own voice, turned up.</p></blockquote>
The ✦ aside, and the marker highlightType it / HTML cardeveryday, and once an issue
The aside is a line opened and closed by typed marks, sitting inline in the body flow — the workhorse for a parenthetical that would clutter the sentence it belongs to. No markup, just the glyphs. The highlight is translucent coral swiped over the words like a marker, and it is the loudest thing in the body — at most once per issue, counting both forms below.

Yes, they really did rename the company mid-acquisition.

Which means the number they reported last quarter was never the number at all.

You typeFor a phrase in body copy, <mark> around the words and stop — the theme paints one pass of coral and overrides the browser's yellow. For the display-size line-to-screenshot, the marked pull quote below — the theme injects the paint, runs two passes, and lands the swipe as the reader reaches it. Coral is the ink in an issue; the blue marker on /bad-job-bingo/ belongs to that section and is not a per-page choice. With JavaScript off a display-size mark reads as a plain pull quote — deliberate, not something to work around.
…the number they reported <mark>was never the number at all</mark>.

<blockquote class="sh-pull sh-pull--marked"><p>The line to screenshot.</p></blockquote>
Job quote pairsGhost editorBad Job Bingo
The bar marks their words only. Your reply sits outside it as ordinary body copy — one bar around both made your response read as part of the job ad. No glyph between them.

Great people deserve great benefits

I mean, shitty people deserve great benefits too, Supabase.

The standing noteType itthe policy line at the top of a Bingo
Hairlines above and below, the label in the left gutter in mono. It reads as a fixture rather than as this issue's opening — which is the point, because a returning reader recognizes and skips it. Same wording every issue; rewriting it is a decision about policy, not about copy. The theme wraps it automatically when the issue opens on the standard "I play Bad Job Bingo…" paragraphs — keep that opening line intact and there is nothing to mark up.
Standing
note

I play Bad Job Bingo with real Customer Experience job listings, and rate them using my five-point scale. A job appearing in a positive category isn’t an endorsement of any role or company, and a job appearing in a negative category doesn’t mean I think you shouldn’t apply. You’re an adult and you get to decide.

TablesMarkdown cardrarely, and it should stay that way
Hairline rows, no verticals, no fill — it reads as part of the article rather than a pasted spreadsheet. The constraint is width: the body column is 562px, so three columns is the ceiling. Below the rail breakpoint a table keeps its columns and scrolls sideways rather than reflowing, and four columns will not survive that.
ListsGhost editortwo styles, chosen by length
Five items or more: ruled rows, a hairline above each. The shoutout list runs twenty-plus names and people scan it looking for themselves — a wall of bullets defeats that. Fewer than five: hanging markers, which sit closer to a paragraph. Markers are a coral in Instrument Serif in both styles; numerals are zero-padded. The fundraiser ledger uses the same ruled rows.
You typeRuled rows are the default — a plain list needs nothing. A short list opts out with a class on the list element, via the HTML card, because CSS can't count items.
<ul class="sh-list-short"> … </ul>
Images and captionsGhost editorchosen by the image's job, not by taste
Four treatments. Anything with text in it — a listing screenshot, a tweet, a LinkedIn post — is the default: full 562px measure, because text needs width. A reaction GIF runs at its natural width, never upscaled. Wide — Ghost's Wide option, spanning the notes margin — is for an image that is the point rather than the evidence, an exception to reach for deliberately. The closing meme is a position, not a treatment — the theme finds the last image before the notes and gives it its air. Full is never used on a post.
Captions are optional everywhere. The preferred credit is linking the image itself to its source. Add a visible caption only when the attribution should be readable without hovering, or the source is offline — and it gives the source, not a description: @CNN, quote-tweeted by @EldritchGirl. On desktop the theme moves a Regular image's caption into the notes margin. The description lives in alt, which is the one thing that is never optional.
Cited videoPaste URL / HTML cardalways someone else's, always temporary
YouTube and Vimeo: paste the URL on its own line and stop. The theme decorates the card, holds the 16:9 frame, and rewrites the request to youtube-nocookie.com / Vimeo's dnt=1 before it leaves the page. Vertical video — TikTok, Reels — sits at 300px with your reaction alongside. Nothing ever autoplays, and TikTok and Instagram do not load at all until a reader presses play: their embed is a hand-authored click-to-load facade, never a pasted URL, because their script tracks whoever opens the post otherwise.
Every cited video needs one sentence of yours saying what happens in it — the survival line, bolded at its start in the next paragraph. A clip of someone being awful gets deleted, often by them; without that sentence the paragraph reacts to nothing months later.
TikTok@corporatehellscape
Play video Playing loads TikTok’s player, which sets their cookies. Nothing loads until you do.
You typeThe facade, in an HTML card — save it as a snippet. data-platform is tiktok or instagram. If you paste the URL by mistake the theme aborts their script and rebuilds a facade from the wreckage, but the rescue has no handle and no survival line — second best, not the contract.
<div class="sh-video__facade" role="button" tabindex="0"
     data-platform="tiktok" data-url="https://www.tiktok.com/@handle/video/…">
  <div class="sh-video__facade-head"><span>TikTok</span><span>@handle</span></div>
  <div class="sh-video__facade-body">
    <span class="sh-video__facade-play" aria-hidden="true"></span>
    <span class="sh-video__facade-cta">Play video</span>
    <span class="sh-video__facade-note">Playing loads TikTok's player, which sets
      their cookies. Nothing loads until you do.</span>
  </div>
</div>
When a cited video is taken down, replace the embed with the removed-video card — grey tint, VIDEO REMOVED chip, your survival line promoted to serif. Nothing detects a dead embed; the swap is yours. Do not delete the paragraph around it.
<div class="sh-video-removed">
  <span class="sh-video-removed__chip">Video removed</span>
  <p class="sh-video-removed__line">At eleven seconds he says the policy is
     unlimited, and that every request last quarter was denied.</p>
  <p class="sh-video-removed__meta">@handle · TikTok · taken down since publication</p>
</div>
Cited audiosomeone else's episode — never your own
Not built yet
The designed click-to-load audio facade has no theme counterpart. Until it lands, do not paste a Spotify or SoundCloud URL — Ghost embeds their player and their iframe loads with the page, and nothing intercepts it. Cite the episode as a link-preview card plus one line of your prose saying what's in it. Your own episodes are unaffected — they use Ghost's native audio card.
Link previewsPaste the URLpaste a URL on its own line
Ghost's bookmark card, restyled: the thumbnail and favicon are dropped, their title comes out in Instrument Serif italic because it is their words, the description goes small and grey, the domain in mono, hairlines above and below. Don't fight it with a screenshot of the same page — the card is the citation. For a run of five links or more, use the ruled-row list instead.
Support was never a cost centre, and finance knew it The line item was invented by people who had never answered a ticket, and it has been quietly wrong for thirty years. everythingisbroken.com · 8 min read
DividerGhost editorpunctuation, not decoration
Ghost's divider card comes out as one centered asterisk in Instrument Serif, in ink, with generous air. Ink rather than coral for a reason: it is punctuation, so it never counts against the twinkle budget. It needs nothing from you but the card.
Upcoming EventsHTML cardthe events block inside a Roundup
Not the same thing as an event post in the library — this is the display block in an issue body. One HTML card, saved as the Upcoming Events snippet (the paste-ready copy is docs/snippets/upcoming-events.html in the repo). Five fields per row in fixed order: date, place-or-time, title, host, link. A row with no second line drops the <br><span>. Skipping the snippet degrades to plain prose rows — the failure mode, not a second style.
<div class="sh-events">
  <div class="sh-event">
    <p class="sh-event__when">JUL 13–14<br><span>NYC, NY</span></p>
    <div class="sh-event__main">
      <p class="sh-event__title">Event title</p>
      <p class="sh-event__host">Hosted by <a href="…">Host</a>. <a href="…">Register →</a></p>
    </div>
  </div>
</div>
Event datesHTML cardon an event post in the library
The only date mechanism the events page reads: <time datetime="YYYY-MM-DD"> elements in the post body. Earliest is the start, latest is the end, one element is a one-day event; the theme adds a noon time internally so timezones can't shift the day. From the end date the row moves under ALREADY HAPPENED on its own — and the entry page flips itself to its expired state: grey band, THIS EVENT HAS ENDED, "Coming up instead". Never type the past state by hand. The line's visible text is the entry page's headline dateline (the big peach band under the title), so phrase it the way it should read at display size. The excerpt is the human dateline — 30 Sep – 2 Oct 2026 · Austin, TX · In person — and drives display only. Body order after the date line: facts (Type · Venue · Price · Website, never dates or location — the band owns those), then one paragraph of links (Tickets · Schedule · Refund policy · Code of conduct — the Tickets link powers the rail's black CTA, which reads Register ↗ when the link is registration-shaped and Get tickets ↗ otherwise), then the neutral description, ending with a short Hosted by {organizer}. line, organizer linked — the theme lifts it into the fact table as a HOSTED BY row and the expired page's ORGANIZER row reads the same line. Never put a TikTok or Instagram embed in an event body: the events index renders every body to read the dates, so their script would run for every reader of the index.
<time datetime="2026-09-30">30 September</time> – <time datetime="2026-10-02">2 October 2026</time>
Cards to skipthe editor offers them; the theme won't dress them
Social post embedsTwitter, Bluesky, Mastodon. Screenshot plus a source caption, always — it survives deletion and matches the image treatments.
Callout cardThe ✦ aside owns that job, and it sits in the body flow rather than in a box.
Gallery cardThe four image treatments own this. A gallery picks the layout for you and picks wrong.
Toggle cardThe contents rail owns collapsible structure. Nothing in an issue should have to be opened.
Product cardNo affiliate links, ever. That is policy, not pricing.
Signup cardThe designed support blocks own the ask, and they close on the settled line.
Video card (native)The four cited-video treatments own this — and Loom is not supported at all.
The end of an issuesign-off, then the ask
The sign-off and the submission ask do different jobs and were settled as one sequence, not two competing boxes. Keep the order. The support block, if there is one, comes after both — never between them. And the sign-off is not exempt from the cadence rule: "That's it for this one", never "that's it for this week".
The two rationing rules
The marker highlight at most once an issue, and six twinkles a page maximum — six is a ceiling, not a target, and the divider's asterisk doesn't count against it. Both stop working the moment they are ordinary, and both are the kind of thing that creeps up an issue at a time.

Unique to each type

Everything above still applies; these pull out the elements that belong to one post type only, because that is exactly what gets buried. If a page comes out wrong, check its sheet first.

Roundup issueroundup
StructureH2 = a department, H3 = a story inside it. The 01/02/03 numerals and their tints are generated — reorder freely, nothing renumbers by hand.
EventsThe Upcoming Events block is a Roundup section — the Upcoming Events snippet, one row per event.
ShoutoutsThe shoutout list is the ruled-row list — no class needed at five-plus items.
EndingSign-off then submission ask, in that order. "That's it for this one", never "this week". The closing meme is the last image before the NOTES list.
Bad Job Bingo issuebad-job-bingo
OpeningThe standing note paragraphs, wording unchanged — the theme wraps them by recognizing the "I play Bad Job Bingo…" opener.
VerdictsH2 = a verdict, and the text must be the exact name: Green Means Go · Eh, It's Probably Fine · Tread Carefully · BINGO · Seriously, Maybe Don't. The icon, tint, rule and count all key off the match.
ListingsH4 = each job title under a verdict, and it is load-bearing: the verdict's listing count is derived from the H4s. A listing that isn't an H4 isn't counted; zero renders NONE.
QuotesJob quote pairs: the blockquote bar is the posting's words only; your reply is plain body copy outside it, no glyph between.
WordingVerdict prose stays loose — never sync an issue's wording to the Career Suite tool's thresholds.
Deep Dive issuedeep-dives
StructureThe plain form: no departments, no verdicts. H2s are ordinary subheads in the label voice; the rail lists them unnumbered. Everything else in Setting the body applies as-is.
AudioAn episode is usually a Deep Dive or a Roundup — if this one is an episode, the audio card sits at the top of the body and #has-audio goes last.
Jobs postthe job board
BodyThe BJB Job Tool owns the body order: Steph's Notes → From the Reviews → editor's Note → "Read this issue →" → original JD → "Apply for this job →". Don't rearrange.
VoicesInside Steph's Notes: a blockquote is the company's words, a paragraph is yours.
TagsThe full namespaced set, landed by the tool since the 21 Aug 2026 rewire — no hand-check needed.
ImageThe feature image is the company logo. City is body text, never a tag. Reader-sourced listings carry #reader-submitted.
ClosingAdd job-status-closed — the theme greys the strip and hides the Apply button (the last button card in the body).
Resource postthe library
TagsInternal #resource + exactly one res-directory-* + any Collections. Without #resource the entry never reaches the library.
FactsThe body opens with the fact run — Label: value paragraphs. Website: powers "Open it ↗". Never Cadence.
VoiceDescriptions are neutral and never italic — the one voice carve-out. A quoted description is a blockquote followed by — their description, unedited.
ReviewsTooling and Gear only: a Steph's Notes H2 plus a Reviewed: fact row. The other eight Directories describe and stop. Vendor published only when true.
EventsAn event is a resource on res-directory-events with <time datetime> in the body, the dateline excerpt, and never a TikTok/Instagram embed card. Body order: date line · facts (Type / Venue / Price / Website) · links paragraph (Tickets / Schedule / Refund policy / Code of conduct) · description. Never dates as fact lines, never a typed past state.

Never write

A cadence claim.
Issues go out whenever they're ready. Never weekly, never every Thursday, never every couple of weeks — a published schedule turns a quiet month into a failure. "Latest issue", not "this week's".
A tag count in prose.
They change constantly and the sentence rots. Counts belong where the theme generates them.
Member counts, subscriber goals, scarcity or urgency.
All four are pressure, and the ask is never pressured.
Anything about sponsors, ads, paid placements, affiliate links or paid recommendations.
They don't exist and never will. That is policy, not pricing — /who-pays-for-this/ is the page that explains it.
Support Human defined by what other publications do badly.
Say what this is. The comparison ages badly and reads as insecurity.
Anything implying something was withheld for the reader's own good.
Support Human does not filter. Nothing is hidden, everything is rated, the reader decides.
Us, we, or the company line.
You speak only for yourself here, never for UserScape.

The support ask

All of it is free. None of it is free to make.

Reader's benefit first, ask second. A fact rather than a plea, and it never implies anything is being withheld. Reword it if a particular page needs it — don't reinvent the shape.

Asks in order: Subscribe (if you want to), then Become a Support(ing) Human — the tier's name, never "become a member" — then Buy me a coffee. A fundraiser is a line of text, never a button. Every support block closes on this, or something with the same shape:

Support if you can, don’t worry about it if you can’t. Support Human is for you either way.

It removes the obligation instead of softening it. Do not replace it with anything that ranks the options, says what a tier unlocks, or thanks the reader in advance. Nothing is locked, so nothing can be unlocked — including by a fundraiser. One exemption: the sign-off sentence in the email is your own line and runs coffee before Support(ing) Human. That order is settled there and nowhere else. Fundraisers run two weeks with a stated end date, show a ledger and never a thermometer, and say plainly that falling short is fine.

When something is missing

The theme handles it — do nothing
No feature image — the card collapses and centers. Don't add a stock photo to fill it.
A marked phrase — write <mark> and stop; the theme picks two passes or one by size.
No company logo — becomes a tinted monogram, the same one every time for that company.
A count of zero — the whole container is suppressed. A zero never prints as a failure.
A long title — headers and social cards step the type down rather than truncating.
Search catching up — the index rebuilds hourly, so a new post is searchable within the hour. Not a bug, nothing to do.
Publishes wrong — and nothing warns you
A missing #issue-NNN — or one whose description isn't the digits — leaves the numeral cell blank.
A job listing with no rating has no fallback state to render.
An event with no <time datetime> never expires out of the upcoming list.
A post without its kind tag (#job / #resource / #portfolio) falls through to the newsletter feed.
An internal tag in first position blanks the series or company wherever Ghost's primary tag is read.
An empty tag publishes a stranded archive page with nothing on it.
A pasted Spotify URL ships their player with the page — nothing intercepts it.

If you are hand-writing HTML inside a post, two house rules follow you in: text at or below 13px is never lighter than #6b6b6b on paper, #3a3a3a on a section tint or #b8b6b4 on the near-black ground, and never smaller than 10px; and accent color is not for body text. Decorative marks are exempt — twinkles, oversized numerals, the Footnotes dagger †.

The four tools

Roundup Buildercollects all week, emits the issue
Sections are News from Around Supportlandia, Good News, Read / Watch / Listen, Upcoming Events. It assembles the issue as markdown you paste into the Ghost editor, plus a separate labeled block for the Upcoming Events HTML card — and its event drafts arrive with <time datetime> in the body, the dateline excerpt, and the right tags, at the real publish date.
The queue syncs through the tool's own database, so any browser works. Paste the events block into one HTML card under the Upcoming Events heading — as markdown it degrades to plain paragraphs.
Resources toolscans, queues, drafts events
Reads the event source list weekly (plus on demand), queues candidates, and drafts event posts in Ghost with the <time datetime> line, the dateline excerpt, real publish dates, and slug-checked tags. It also hands the Roundup's events block over for copying. Since the 25 Aug 2026 rewire, drafts arrive in the full entry-page body order — date line, facts (extractor-prefilled where the source page offers them), links row, description, Hosted by — plus optional collection tags and the vendor flag.
Tags are looked up by slug and never minted — an unknown collection slug is skipped with a warning, not created. The tool warns on a date-looking title and refuses a start/end mix-up. No hand-steps remain on an event draft.
Footnotes adminits own database, no Ghost
Entries appear on /footnotes/ as soon as you save, and reach site search on the next hourly index build. Freeform lowercase tags. No entry pages, no comments — the # button copies an on-page anchor, and a shared anchor opens on the right page of the paginated wall.
Entry numbers are permanent and never reused. Gaps are honest and shouldn't be tidied up. Until the tool assigns numbers automatically, set one — an unnumbered entry logs a console warning.
BJB Job Toolposting in, rated draft out
Turns a posting into a Ghost draft with the taxonomy already set: one rating, one each of discipline / level / type / arrangement, location, one canonical salary band, company as primary tag, job-status-open, #job last. The rewire landed and passed acceptance 21 Aug 2026 — tags are matched by slug, missing ones are minted with their pretty names, and no hand-correcting is needed.

Before you hit publish

Right type, right tags — the required ones above, kind tag included, internal tags never first.
Excerpt written by you. Meta description too.
Issue number set — with the digits in the tag's description — if it's a newsletter issue.
No cadence claim anywhere in the copy, sign-off included.
Their words italic, your words sans — and .sh-pull on the one blockquote that's yours.
If there's a support block, it closes on the approved line.
A real feature image or none at all — never a filler one.
Newsletter issues previewed as email as well as page.
Eight boxes. If one of them is going to be wrong, it is the excerpt.
Podcast episodes: audio card at the top, #has-audio last, and a series tag as well.

Settled by the build

The seven questions this page carried while the theme was being built, each answered from the templates that actually run — kept here so the answer is findable where the question used to be.

SettledTag slugs. Deep Dives is bare deep-dives (renamed from feature, redirects live). The Events directory is res-directory-events. Everything namespaced per the table above.
SettledEvent dates. <time datetime="YYYY-MM-DD"> in the body is the only mechanism; the excerpt is display only.
SettledPodcast. More than #has-audio: the audio card at the top of the body is the storage, the media URL is Captivate's direct one, the excerpt is the summary line, and the tag goes last.
SettledSearch. The index rebuilds on deploy and hourly at :17 — a new post is searchable within the hour, everything else is instant.
SettledCustom settings. There are none. Nothing in Ghost admin changes what you fill in.
SettledRoundup Builder. The rewire landed 21 Aug 2026: backdate instruction deleted, <time datetime> and the events card are emitted by the tool, drafts tagged res-directory-events + #resource. No hand-steps.
SettledBJB Job Tool. The slug and salary rewire landed 21 Aug 2026 and passed acceptance on the live install: namespaced slugs on every axis, one canonical salary band by midpoint, IT IS A MYSTERY filed under location, internal tags last. No hand-steps.