# Zine Maker — Agent Authoring Guide

You are an AI agent helping a user make a printable paper zine with
**Zine Maker** (https://zine-maker.com/). Your job: turn the user's notes into
one **v2 zine-project JSON document**. The user will paste it into the app
(**Load → paste JSON → Import**), where it is validated, previewed page by
page, and printed.

No tools, accounts, or setup are required. Produce **one JSON code block** as
your final output and tell the user to paste it into the Load dialog at
https://zine-maker.com/.

## Workflow

1. **Plan an 8-page arc** from the user's notes: cover hook → context → main
   points (one idea per page) → closing thought / call-to-action on the back
   cover.
2. **Pick a format**: `mini-8` (pocket-fold zine from one printed sheet; small
   pages, ~40–80 words per page max) or `saddle-8` (stapled booklet; same
   canvas but prints at 2× size, tolerates denser text). Default to `mini-8`.
3. **Write the JSON** following the rules below. Self-check every rule — the
   app runs this exact validation on import and will reject the document with
   the same error messages.
4. **Deliver**: one fenced JSON code block, plus one line of instructions:
   _"Open https://zine-maker.com/ → Load → paste this JSON → Import."_
5. If the user reports validation errors or says a page looks wrong, fix the
   document and re-emit the full JSON block.

## Document shape

```json
{
  "version": 2,
  "title": "Zine Title",
  "format": "mini-8",
  "pages": [
    { "elements": [
      { "id": "p0-title", "type": "text", "x": 5, "y": 30, "w": 90, "h": 22,
        "preset": "title", "align": "center", "autoFit": true, "html": "BIG<br>TITLE" }
    ]},
    { "elements": [] }
  ]
}
```

## Validation rules (the app enforces every one)

- `version` must be exactly `2`; `title` must be a string.
- `format` must be `"mini-8"` or `"saddle-8"`.
- `pages` must contain **exactly 8** page objects, each `{ "elements": [...] }`.
  Page 0 is the front cover, page 7 the back cover. An empty page is
  `{ "elements": [] }`.
- Every element needs a unique `id` across the **whole document** — use
  `p<page>-<role>` (e.g. `"p3-body"`).
- `type` is `"text"` or `"image"`.
- Positions are % of a 330×510 portrait canvas: `x`,`y` numbers in [-50, 150];
  `w` in [1, 200]. Z-order = array order (backgrounds first).
- Text elements additionally require:
  - `h`: number in [1, 200]
  - `preset`: `"title"` (34px bold) / `"heading"` (22px bold) / `"body"` (16px)
    / `"caption"` (12px)
  - `align`: `"left"`, `"center"`, or `"right"` — **required, no default**
  - `html`: string. Stick to plain text with `<br>`, `<b>`, `<i>` (the app
    strips everything outside its whitelist).
  - `autoFit`: optional boolean. Use `true`; it shrinks text that overflows.
- Image elements require a non-empty `src` and take an optional `h`.

## Text budgets (fit without shrinking)

`autoFit` rescues overflow by shrinking, but shrunk text reads as a mistake.
Write to these budgets:

| box | rough capacity |
|-----|----------------|
| title box, w:90 h:20 | 2 short lines (≤ ~14 chars/line) |
| heading box, w:90 h:8 | one line, ~22 chars |
| body box, w:90 h:30 | ~55 words |
| full-page body, w:90 h:80 | ~150 words — a WALL; prefer 80–100 |
| caption, w:60 h:6 | ~10 words |

Fewer, punchier words beat autofit. Bold key phrases. One idea per page.

## Layout patterns

- **Cover**: title centered around y:30, subtitle below, tagline near y:86.
- **Interior**: heading at top (`y:4–5, h:8–9`), body starting `y:16–18`. Keep
  4–6% side margins (`x:5, w:90`).
- **Two text blocks on one page**: don't leave a half-page void between them —
  either keep them close (second block starting ~10% below where the first
  ends) or make the gap read as deliberate (e.g. a centered pull-quote in the
  bottom third).
- **Back cover**: sparse — closing thought centered mid-page, credits in a
  caption box near y:88.
- Vary layouts; six identical heading+paragraph pages read as template output.

## Images

For this paste-into-the-website flow, **prefer text-only documents** and tell
the user to add photos afterward in the editor (Add Image button) — the app
stores them automatically. Only inline an image yourself if you can genuinely
produce a working `data:` URI; `src` must be a data URI or a URL the browser
can reach. Never fabricate base64. Text elements overlapping an image must
come after it in the `elements` array.

## Optional: the full toolchain

If you are a coding agent with a shell (Claude Code, Codex, etc.), you can
clone https://github.com/pmelman/zine-maker and get a stronger loop — CLI
validation, image packing, and rendered PNG previews you can visually check:

```
git clone https://github.com/pmelman/zine-maker
cd zine-maker && npm install
node cli/zine-cli.js validate my-zine.json
node cli/zine-cli.js render my-zine.json --out previews/
```

See `AGENTS.md` in the repo. Claude Code also auto-discovers the bundled
`make-zine` skill when run inside the repo.

## Printing (tell the user)

- `mini-8`: print single-sided, landscape. Fold in half twice, cut along the
  center line, fold into a booklet. The app's Print button and fold-guides
  toggle handle the imposition.
- `saddle-8`: print double-sided landscape (flip on short edge), fold the
  stack, staple on the fold.
