Deckle
Deckle is a site for independent magazines and journals (print quarterlies with a website, literary and food journals, studio publications, newsletters that come out in issues, long-form blogs that want to feel like print), set like a printed magazine you could pick up: uncoated paper with grain, photos with torn deckled edges, letterpressed serif headlines and covers that catch a raking light. It has your stories (each with its own page), your issues with their covers, contents and editor’s letters, subscriptions and single issues, and an about page for pitches and advertisers.
Deckle comes in two variants, chosen when you create the site: files/Sanity (static pages, any
host) and EmDash (--cms emdash, rendered on request on Cloudflare). The
pages are the same in both.
Pages and their content
Section titled “Pages and their content”| Page | Edit it in |
|---|---|
| Home | Pages → Home page (a list of sections) |
| Stories, issues, subscribe, about, 404 | Pages → the page’s own entry |
| Stories | Content → Stories |
| Issues (covers, contents, editor’s letters) | Content → Issues |
| Magazine name, tagline, email, where it’s made, navigation, header button, profiles, colophon | Pages → Site settings |
| Buttons, labels, chat, search, emails, game texts | Content → Interface texts |
| Privacy, terms | Pages → Legal |
In headlines, words wrapped in *stars* are set in italic in the accent, as in “Brine,
*slowly*”.
Issues and stories
Section titled “Issues and stories”Each issue has a number, a theme (“Salt”), a season, a 4:5 cover photo, up to four cover lines, the cover stock (the second or third color as paper, the accent as book cloth), its pages and price, and the editor’s letter as its text. An issue can be sold out: its page then says so instead of offering it.
Each story has a standfirst, a department (the stories page filters by it, so keep them
short and consistent: “Essays”, “Food”, “Places”), the author and an optional photo credit, a 3:2
lead photo with its caption, a color for its swatch, and the issue it was printed in (the
issue’s address, e.g. salt) with its page in print: together they build the issue’s
contents page. A story without an issue is web-only. Reading time is counted from the text.
Stories are written in Markdown: > makes a pull quote, --- a section break (* * *), ## a
small-capitals subhead, and footnotes ([^1]) are listed at the end. The first paragraph gets a
drop cap and the last an end mark.
Covers, plates and the bookmark ribbon
Section titled “Covers, plates and the bookmark ribbon”Covers are drawn by the site from the issue’s fields: the masthead (your magazine’s name) is letterpressed across the stock, the photo is set in as a plate with a deckled edge, the cover lines are printed under it. On the home page and the issue page, the cover catches a soft light once as the page opens. Back issues stand on a shelf; hovering one draws it out.
On a story, a silk ribbon in the accent hangs from the top of the page on wide screens and lengthens as you read. Visitors who prefer reduced motion see the light at rest and the ribbon simply hanging.
Subscriptions and single issues
Section titled “Subscriptions and single issues”Pages → Subscribe page → Plans holds up to four plans, each a yearly subscription or a one payment (a gift), with what’s included and a Stripe Price id. The plan marked Featured is bound in cloth. Issues have their own one-time Stripe Price id: the issue page then shows a buy button. Without Price ids the buttons say how to set them up. The subscribe page also lists your stockists and questions.
Integrations
Section titled “Integrations”Everything works without keys; each feature switches on with its variables in .env.example.
| Feature | Where | Service |
|---|---|---|
| Subscriptions, gifts, single issues | Subscribe page, home page, issue pages | Stripe |
| Pitch form | About page; pitches go to the email in Site settings | Resend |
| Book a call (advertising, stockists) | About page, loads on click | Cal.com |
| The Sunday Letter (newsletter) | Home and stories pages, under every story, with a welcome email | Supabase |
| Ask the archive | Chat on every page, answers from your stories, issues, plans and questions | Claude |
| Search | ⌘K or the search button: stories, issues, subscribe, about | built in, or Algolia |
| Analytics | Every page; Google Analytics only after consent | Plausible, Umami, Google Analytics |
After a payment, the Stripe webhook (/api/stripe/webhook) emails the reader; add your own
steps there, such as adding a subscriber to the mailing list for the print run.
Sections
Section titled “Sections”The home page is built from these sections, in any order: Cover (the current issue, or one you pick, with its first stories), Lead story (a spread), In this issue (the contents page), Latest stories, Pull quote, Back issues (the shelf), Subscribe (the plans) and Newsletter sign-up. Sections that show an issue or a story take its address; leave it empty for the newest issue and the newest featured story.
Colors and brand
Section titled “Colors and brand”src/content/singletons/brand.json (Pages → Brand in Keystatic) holds three colors: the
accent is the ink (buttons, italics in headlines, rules, the bookmark ribbon, book cloth),
the second and third are paper stocks (covers, the newsletter, selected states). Buttons
and cloth are darkened until their paper-white text is readable, the stocks lightened until ink
on them is; a color that can’t get there stops the build with a message. The paper, links and
the night theme (black card stock under a lamp) are derived from them. Brand also sets the fonts
(a serif display face for headlines, a serif for reading, and the labels in the text font or a grotesk) and the corners
(square, or softly rounded).
Languages
Section titled “Languages”Deckle is ready for more languages: see Languages.
The 404 page
Section titled “The 404 page”A small game, Stop the press: the proofs are back, one line at a time, and every line hides one
misprint. Tap the wrong word (or move along the words with the arrow keys and press Enter)
before the press runs in 60 seconds; a word that was right costs three seconds. The lines are
content (Interface texts → 404 game), with each misprint written {right|wrong}. The best score
is kept in the visitor’s browser.
Printing
Section titled “Printing”Stories print as plain text: no navigation, forms or chat, ink on white, with link addresses written out.
AI assistants and search engines
Section titled “AI assistants and search engines”AGENTS.mddescribes the project for coding assistants (Claude Code reads it throughCLAUDE.md, Cursor through.cursor/rules/), including what makes the look./llms.txtlists your pages, stories and issues for AI assistants, in every language.- Pages carry JSON-LD: the magazine as a periodical, each issue, each story as an article, the plans and the questions.
Commands
Section titled “Commands”pnpm dev # local site, editor at /keystaticpnpm build # production buildpnpm cms sanity schema|seed # move content to Sanity (see Content → Sanity)In the EmDash variant: npm run dev, npm run deploy (Cloudflare) and npm run emdash:schema
(after changing the content model).