---
name: make-brochure
description: Meta-skill that runs the full brand-design → property-extract → property-brochure pipeline end-to-end, skipping any step whose output already exists on disk. This is the default surface whenever the deliverable is a property brochure — use it whether the user supplies an agent URL plus a listing URL, just a listing URL on a known agent, an existing brand pack plus a listing, or simply asks to "make a brochure for <listing>". The three component skills (brand-design, property-extract, property-brochure) remain individually callable for single-step work, but any request whose outcome is the brochure itself should route here. Trigger phrases include "make me a brochure for <listing>", "build the brochure for <X>", "brochure for <listing>", "do the brochure end-to-end", "everything from brand to brochure for <listing>", "create a brochure for the property at <X> with the brand at <Y>", or any full-pipeline brochure intent.
allowed-tools:
  - Bash
  - Read
  - Write
  - Edit
  - Glob
  - Grep
  - WebFetch
---

# make-brochure

Single-entry orchestrator for the `brand-design` → `property-extract` → `property-brochure` pipeline. Routes inputs to the right skill in the right order, **skipping any upstream step whose output already exists on disk for the requested source URL**.

This skill is a playbook, not a programmatic dispatcher. It tells you (the agent) the routing rules; you execute each step using the underlying skills' own contracts.

## Outcome contract

The deliverable is identical to `property-brochure`'s outcome — written into `<property-dir>/output/`:

- `brochure.html` plus per-page 300 dpi PNG print snapshots (canonical, archival)
- Two image-only PDFs: `<slug>-brochure-print.pdf` (300 dpi print master) and `<slug>-brochure-web.pdf` (192 dpi web/digital). Both built from per-page Playwright snapshots via img2pdf and linearized via qpdf — no Ghostscript anywhere in the chain. See `property-brochure → PDF deliverable` and `a4-print-documents → PDF deliverables`.
- A self-contained **web bundle** at `output/web/` plus `output/<slug>-web.zip` — the smaller, ready-to-host version for property micro-sites; includes both the brochure and a companion **landing page** at `index.html` that presents the property as a continuous scrollable web page. See `property-brochure → Web bundle` and `property-brochure → Page`

The orchestrator's value is in what it does **not** redo:

- If the brand pack for the agent already exists and matches the requested agent URL, `brand-design` is **skipped**.
- If the property assets for the listing already exist and match the requested listing URL, `property-extract` is **skipped**.
- `property-brochure` always runs (the brochure itself is the deliverable; re-running it is the point).

A run that re-tokenises a brand pack already on disk for the same URL is a **defect**, not an extra-careful pass. Re-tokenisation burns tokens, can mutate logo PNGs that downstream brochures already reference, and risks divergence between the brand pack and the brochures that consumed it earlier.

## Inputs

Required, in either form for each:

| Input | URL form | Path form |
|---|---|---|
| **brand source** | `https://<agent>.co.uk` | `<dir-with-DESIGN.md>` |
| **property source** | `https://<agent>.co.uk/property/<slug>/<id>/` | `<dir-with-property.json>` |
| **orientation** | `portrait` or `landscape` (A4) — see **Orientation routing** below |
| **seller brief** | a path to `seller-brief.md` (per the template at `make-brochure/references/seller-brief-template.md`), **or** answers to all 20 brief questions in any format | — |

Optional:

- `force` — one of `brand`, `property`, `all`, or absent. When set, the named upstream step runs even if its output already exists.
- `output_root` — defaults to the **caller's current working directory** (`./`). The orchestrator creates `<output_root>/<brand_slug>/` for the brand pack and nests properties at `<brand_slug>/properties/<property_slug>-<id>/`. To place the workspace elsewhere — e.g. alongside an existing brand pack from a prior run — pass `output_root` explicitly (absolute path, or relative to CWD). The orchestrator never infers location from an existing brand pack; if you already have one and want this run to reuse it, point `brand_source` at its directory path (see Routing rule 1) AND pass `output_root` to its parent so the new property nests under the same workspace.
- `register` — one of `premium`, `branded`, or absent. **Premium** keeps the template's super-premium tokens verbatim (only the agent's logo and contact details change); the brand pack's DESIGN.md palette/type are deliberately *not* applied. **Branded** re-skins the template with the brand's tokens. **Absent → branded.** Resolve the register only AFTER brand-design has run, so DESIGN.md presence is a guaranteed state (brand-design is step 1 of this same pipeline; gating "branded" on a pre-existing DESIGN.md made the branch structurally unreachable on first runs and silently fell through to premium). Premium is **opt-in only** — the operator must say "premium" or "super-premium" in the request, otherwise branded. The orchestrator passes the resolved register through to `property-brochure`. See `property-brochure → Default visual scheme — and when to override it` for the full contract.

If only one input is supplied, **decline and ask for the other** — the orchestrator's reason for being is having both. Route a single-input request to the appropriate sub-skill directly.

### Why the seller brief is required, not optional

Brochure copy without a seller's brief is generic copy. The agent has the listing description, the photos, and the floor plan; it does not have *the seller's reason for buying, the room they will miss most, the feeling they want a buyer to have on entry, the three words they would use to describe the home*. Those answers are what separate "luxury 5-bedroom country home, well-presented" from a folio that reads as a specific, personal place.

The brief is **not** quoted verbatim in the brochure (unless an answer is explicitly marked `[VERBATIM]` by the seller). It is read by the brochure agent before any copy is written and informs:

- The cover sub-line and back-page tagline (Q19, Q20)
- The opening chapter deck (Q5)
- The body paragraphs of every chapter (Q1–4, Q7, Q11–14)
- The particulars list emphasis (Q9, Q10, Q18)
- The Material Information context line (Q17)
- Which photographic slot gets hero treatment (Q6 — the seller's favourite room)

See `property-brochure → Seller brief` for the per-question mapping.

### Brief routing

Apply this rule before running `property-brochure`:

| Brief state | Action |
|---|---|
| `<property_dir>/seller-brief.md` exists, every question has a non-empty answer | **Use it.** Pass the path through to `property-brochure`. |
| `<property_dir>/seller-brief.md` exists but ≥ 1 answer is empty / placeholder text | **Stop and ask the operator** to provide the missing answers. List the question numbers that are unanswered. |
| `<property_dir>/seller-brief.md` does not exist, but the user pasted answers in this conversation | Write the answers to `<property_dir>/seller-brief.md` per the template structure, then proceed. If any of the 20 questions is missing, ask for the missing ones first. |
| Nothing — no file, no inline answers | **Stop and ask.** Send the operator the 20 questions (verbatim from `references/seller-brief-template.md`), wait for answers, write the file, then proceed. Do not synthesise answers from the listing description. |

The brief lives at `<property_dir>/seller-brief.md` so it persists across re-renders. Re-running `property-brochure` does not invalidate the brief; only the seller invalidates the brief by editing it.

### What an "answer" must contain

A non-empty answer is at least one full sentence per question, in the seller's voice. Single-word answers are accepted only for Q19 ("three words to describe the home") — every other question expects two to four sentences. If the operator provides a single-word answer to anything other than Q19, ask a clarifying follow-up before proceeding.

If a section is genuinely not applicable (e.g. the seller has not done any improvements, so Q8/9 are "none"), record that explicitly: `Q8: No renovations since moving in. The home was substantially complete on purchase and we changed nothing.` That is a valid answer. A blank, "n/a", or "—" is not.

## Orientation routing

The brochure ships in either portrait (210×297mm) or landscape (297×210mm) A4. The two are not visually interchangeable — page geometry, render-slot dimensions, print-snapshot pixel sizes, and the PDF call all change with the choice. See `property-brochure`'s **Orientation** section for the full dimensional contract.

Apply this rule **before** running any of the upstream steps:

| Did the user state orientation? | Action |
|---|---|
| Yes — explicit `portrait` / `landscape`, or named A4 dimensions in one of the two orders | Use the stated value. Pass it through to `property-brochure`. |
| No — but a prior brochure exists at `<property_dir>/output/brochure.html` | Read the existing `@page { size: A4 portrait \| landscape }` rule and confirm with the user in one line ("Keeping existing landscape — OK?"). Default to the inherited value if they don't object. |
| No — and there's no prior brochure | **Stop and ask.** One-line prompt: "Portrait or landscape A4?" Do not silently default to portrait. |

The reason orientation is hoisted to the orchestrator (not deferred to `property-brochure`) is the same as for missing brand/property sources: the question costs one round-trip; rebuilding a wrong-orientation brochure costs a full pipeline run plus user re-review. Always pay the cheap cost.

When the user answers, pass the orientation through to `property-brochure` as an explicit parameter. Do not re-ask in the downstream skill — the contract is "asked once at the orchestrator level".

## Routing rules

The skill performs four checks in order. Each rule fully specifies its *condition* and its *action*; do not improvise extra branches.

### 1. Resolve the brand identity

If `brand_source` is a URL: derive `brand_slug` as the lowercase domain root with no TLD (e.g. `https://<agent>.co.uk` → `<agent>`, `https://example-agent.co.uk` → `example-agent`).

If `brand_source` is a path: `brand_slug` = the directory's basename.

Resolve `brand_dir` as:
- `<output_root>/<brand_slug>/` when `brand_source` was a URL. Recall: `<output_root>` defaults to the **caller's CWD** (`./`) — never inferred from an existing brand pack. Pass `output_root` explicitly to override.
- the supplied path when `brand_source` was a path.

### 2. Decide whether to run `brand-design`

Read `<brand_dir>/DESIGN.md` if it exists. The first paragraph should record the source URL (per the `brand-design` artefact contract).

| `<brand_dir>/DESIGN.md` exists? | Recorded source URL matches request? | `force` value | Action |
|---|---|---|---|
| No | — | any | Run `brand-design` against the URL |
| Yes | Yes | absent | **Skip**. Reuse the existing brand pack. |
| Yes | Yes | `brand` or `all` | Run `brand-design` (overwrites existing pack) |
| Yes | No | absent | **Stop and ask the user** — the directory belongs to a different brand. Do not silently overwrite. |
| Yes | No | `brand` or `all` | Run `brand-design` (overwrites — user opted in) |

If `brand_source` was a path and `DESIGN.md` is missing, treat that as an authoring error — the user pointed at a directory that isn't a brand pack. Stop and ask for the actual brand-pack directory or a URL.

### 3. Resolve the property identity

If `property_source` is a URL: derive `property_slug` from whichever path component the source exposes (e.g. `/property/<slug>/<id>/` on Loop-CRM tenants; portals expose different shapes). The folder name is `<property_slug>-<id>` (e.g. `<street-locality-postcode>-<listing-id>`).

If `property_source` is a path: the folder name is the directory's basename.

Resolve `property_dir` as:
- `<brand_dir>/properties/<property_slug>-<id>/` when `property_source` was a URL. The property directory always lives **inside** the brand workspace, never as a sibling of it. This is non-negotiable — `property-extract`, `property-brochure`, and the brand pack all assume this nesting.
- the supplied path when `property_source` was a path. If the supplied path is not under `<brand_dir>/properties/`, stop and ask — silently re-rooting the property would orphan it from its brand pack.

### 4. Decide whether to run `property-extract`

Read `<property_dir>/property.json` if it exists.

| `<property_dir>/property.json` exists? | `source.url` matches request? | `force` value | Action |
|---|---|---|---|
| No | — | any | Run `property-extract` against the URL |
| Yes | Yes | absent | **Skip**. Reuse the existing property assets. |
| Yes | Yes | `property` or `all` | Run `property-extract` (overwrites existing) |
| Yes | No | absent | **Stop and ask the user** — the directory holds a different listing. |
| Yes | No | `property` or `all` | Run `property-extract` (overwrites — user opted in) |

### 5. Verify the seller brief is complete

Before invoking `property-brochure`, confirm `<property_dir>/seller-brief.md` exists with non-empty answers to all 20 questions. Apply the **Brief routing** table from the *Inputs* section. If any answers are missing, the orchestrator stops and asks the operator — the brochure is not generated until the brief is complete.

The brief is the single most cost-effective input to the editorial quality of the brochure. Skipping it produces generic copy that the operator will then ask to be rewritten. Asking once at the orchestrator level costs one round-trip; collecting it after the brochure is built costs a full re-render.

### 6. Always run `property-brochure`

Once steps 2, 4, and 5 have either completed or been skipped (skip applies only to 2 and 4 — the brief check is mandatory), invoke `property-brochure` with both directories AND the seller brief as inputs. The brochure HTML and print PNGs land in `<property_dir>/output/` — that exact path, with the exact filenames listed in the Reference standard. No alternate names, no nested `brochure/` wrapper directory.

If `<property_dir>/output/brochure.html` already exists from a prior run and the user has **not** asked to re-render, ask before overwriting. Re-rendering the brochure is cheap, but it invalidates whatever review state the user had on the previous version.

## Image preview safety

**Hard rule: never `Read` an image file whose longest edge exceeds 2000px.** The harness loads images into context as multimodal inputs and large ones break the session — the encoding budget overruns, the conversation can drop, and recovery is expensive.

Property photographs almost always exceed this threshold. Concrete examples in the validated reference directory:

| Filename pattern | Typical longest-edge |
|---|---|
| `DSC*` (DSLR) | 6000–8000px |
| `IMG*` (iPhone wide) | 4000–5000px |
| `DJI_*` (drone) | 4000–8000px |
| `ChatGPT-Image-*` (AI render) | 1024 or 2048px (borderline — measure) |
| `Screenshot-*` (desktop capture) | 1200–2880px (borderline — measure) |

Filename prefixes vary by source — Loop-CRM tenants commonly ship the shapes above; other portals re-serve under their own filename conventions. The 2000 px rule is what binds, not the prefix.

### Safe inspection workflow

Before any `Read` against an image:

1. **Measure first.** On macOS: `sips -g pixelWidth -g pixelHeight <file>`. With ImageMagick: `identify -format "%wx%h\n" <file>`. Both are fast and require no decode.
2. **If the longest edge ≤ 2000px**, reading the original is safe.
3. **If the longest edge > 2000px**, generate a downscaled preview into `/tmp/`, read the preview, then delete it:
   ```bash
   sips -Z 2000 "<src>" --out "/tmp/preview-$(basename "<src>")"
   # ...Read the preview...
   rm "/tmp/preview-$(basename "<src>")"
   ```
   Or with ImageMagick: `magick "<src>" -resize '2000x2000>' "/tmp/preview-..."`.
4. **Often you don't need the pixels at all** — filename, byte-size, dimensions, and EXIF tags answer most QA questions ("is this the kitchen wide shot?", "is this in landscape?") without a multimodal read.

The constraint applies to **every** image-reading touchpoint in the pipeline: shortlisting cover candidates, picking the kitchen hero, sanity-checking floorplans, verifying a downloaded asset, eyeballing AI-render quality. Treat the rule as non-negotiable; the failure mode is loss of the entire session, not a graceful error.

Generated brochure print snapshots (`cover-print.png`, `pageN-print.png`) are produced at A4 @ 96dpi which is **794×1123px** — those are safe to read directly.

## Process — high level

1. **Parse and validate inputs.** Confirm all three sources are present (brand, property, **seller brief**); pick form (URL/path/inline answers) per source; bail early with a clear question if any is missing or ambiguous. Apply the **Orientation routing** table — if orientation is not stated and not inheritable, stop and ask before doing any other work.
2. **Apply the Brief routing table.** If `<property_dir>/seller-brief.md` is missing or any of the 20 answers is empty, **stop and ask the operator** — paste the questions from `references/seller-brief-template.md`, wait for answers, write the file, then proceed. Do not synthesise answers from the listing description.
3. **Apply Routing rules 1–4** for the upstream skills. For each, determine `run` / `skip` / `ask` based on the table; record the decision in a one-line log so the user can see what was reused.
4. **Run the upstream skills in sequence**, brand first then property. Each runs under its own SKILL.md contract — do not adapt or shortcut their completion criteria. If either reports `DONE_WITH_CONCERNS` or `STATUS: BLOCKED`, surface that to the user and stop before invoking `property-brochure`.
5. **Verify the curator-friendly image rename happened.** `property-extract` is responsible for producing `<Property Name> N.jpg` (1-indexed) alongside the original CDN-named files — see *property-extract → Curator-friendly rename*. Before invoking `property-brochure`, check `<property_dir>/images/` for files matching `<Property Name> *.jpg` (or `<address line 1> *.jpg` if the property has no distinct name). If the rename is missing on a freshly-extracted property, run it now — the brochure step's slot map relies on `<property-slug>-NN.webp` aligning 1:1 with the curator's intuitive numbering, and that alignment is what lets a human reviewer tell "this photo is in slot 22" by looking at filenames alone.
6. **Run `property-brochure`** pointing at the brand directory, property directory, **and the seller brief**. Confirm the canonical archive landed in `<property_dir>/output/` with `brochure.html`, the two PDFs (print master + digital), and the per-page print PNGs.
7. **Confirm the web bundle was produced.** `property-brochure` also emits `output/web/` (with web-tier images, JPEG snapshots, and the digital PDF) and `output/<slug>-web.zip` — see *property-brochure → Web bundle*. If the web bundle is missing on an otherwise-successful brochure run (e.g. `property-brochure` reported `DONE` but only the print archive is present), invoke its web-bundle step explicitly before reporting `DONE` here.
8. **Report.** Tell the user, in order: which steps ran fresh, which were reused, the path to the canonical print archive, the path to the web zip, and any `DONE_WITH_CONCERNS` items from the upstream steps. Note explicitly that the seller brief was used to source the editorial copy, and (if any answers were marked `[VERBATIM]`) which phrases were preserved word-for-word.

The orchestrator does not bundle the upstream skills' outputs — each leaves its artefacts where its own SKILL.md says to. The two end-user-facing deliverables are the canonical print archive (`output/brochure.html` + PDFs + PNG snapshots) and the web zip (`output/<slug>-web.zip`).

## Slot-assignment hand-off — verify image content visually, not by filename

A repeated failure mode in this pipeline is mis-mapping a slot from filename alone — the brochure step references `images/<property-slug>-22.webp` because slot 22 should be the inglenook, but the actual photograph at index 22 is a downstairs WC. Filename tells you order; pixels tell you content.

The orchestrator's role is to **enforce the visual-verification step** before `property-brochure` writes the HTML:

- The agent must read either a labelled contact-sheet montage of all 49 images (sized ≤ 2000px per the safety rule) or each candidate slot directly, and match content to slot before referencing the filename in the HTML.
- If a slot's intended content (cover hero, principal bedroom, family bathroom, inglenook) does not match the photograph at the chosen index, change the index — don't ship the wrong photo. The render-slot index table in `property-brochure` is canonical for *role*, but the curator's `N` numbering is canonical for *which photo is N*.

See `property-brochure → Image content verification` for the contact-sheet recipe and the common-mistake pairs.

## Page-count — 16 canonical, 12 only when content is thin

The canonical brochure ships **16 pages** (cover + 8 chapters with intermissions, gallery, and site-plan inserts + back). The 16-page folio is the structure encoded in `property-brochure/references/template.html`, with these inserts already in place:

| Insert | Position | Content |
|---|---|---|
| Full-bleed interior intermission | After "A home at ease" and after "Hall, hearth & sun" | One strong room shot full-bleed with a dark caption pill, no chapter title — `.page.intermission` |
| Image-led gallery | After "Bedrooms & baths" | 4–5 cell grid of additional internal shots, each with a one-word italic caption in a translucent panel — `.page.gallery-page` |
| Full-bleed outdoor intermission | After "Pool, outdoor kitchen & summerhouse" | The single strongest exterior moment, full-bleed |
| Site plan dedicated page | After "Garden & ground" | The plot drawing (trees + boundary + paddocks) on one side, plot/grounds copy panel on the other — `.page.siteplan-page` |

When the property genuinely lacks the photography or features to fill 16 pages (e.g. an apartment without grounds, or fewer than ~25 strong photos), drop down to **12 pages** by removing the three intermissions and the site-plan page. Both 12 and 16 are even, so both saddle-stitch cleanly (12 = 3 folded sheets, 16 = 4). Avoid 14 — it's an awkward 3.5-sheet count. The chapter-page numbers in the TOC and folio update accordingly: 16-page chapter starts at 03, 04, 06, 08, 10, 12, 14, 15; 12-page chapter starts at 03, 04, 05, 06, 07, 08, 10, 11.

Intermission pages are unnumbered chapters — they wear a small "Continued, Chapter II" eyebrow on their caption pill, never a Roman numeral.

## Reference standard

After a complete run, the on-disk layout is **exactly** this — no deeper nesting, no extra wrappers, no sibling `properties/`:

```
<output_root>/
  <brand_slug>/                           # = brand workspace = <brand_dir>
    DESIGN.md                             # produced by brand-design
    description.md                        # produced by brand-design
    <brand_slug>-logo-light.png           # produced by brand-design — light-coloured art (white/cream pixels, for dark surfaces)
    <brand_slug>-logo-dark.png            # produced by brand-design — dark-coloured art (black/navy pixels, for light surfaces)
    properties/                           # nested INSIDE the brand workspace
      <property_slug>-<id>/               # = <property_dir>
        property.json                     # produced by property-extract
        description.md                    # produced by property-extract
        seller-brief.md                   # operator-supplied via the make-brochure orchestrator (20 Q&As)
        images/                           # produced by property-extract — original photo filenames preserved
        floorplans/                       # produced by property-extract
        epc/                              # produced by property-extract (may be empty)
        output/                           # canonical print archive — owned by property-brochure
          brochure.html
          <property_slug>-brochure-print.pdf   # print master (300 dpi, ~65–100 MB) — canonical archive
          <property_slug>-brochure-web.pdf     # web/digital deliverable (192 dpi, ~25–45 MB) — emailed/attached
          cover-print.png                      # canonical 300 dpi snapshots (used for print PDF + .print-img swap)
          page2-print.png … page15-print.png
          backpage-print.png
          .snapshots-web/                      # intermediate 192 dpi PNGs for web-PDF build (deletable after)
            cover-print.png … backpage-print.png
          images/                         # renamed + per-slot-optimised brochure photos: <property_slug>-NN.webp
            <property_slug>-NN.webp
            <brand_slug>-logo-light.png   # light-coloured logo art — used on the back-page dark masthead
            <brand_slug>-logo-dark.png    # dark-coloured logo art — used on the TOC credit and other paper-surface placements
            qr-video.png, qr-listing.png
          web/                            # self-contained web bundle, generated alongside print archive
            brochure.html                 # same HTML; print-img refs point at .jpg snapshots; QR codes are clickable <a>
            index.html                     # companion property landing page (Modern House-style scroll)
            <property_slug>-brochure.pdf  # digital PDF, copied for the in-page Download button
            cover-print.jpg
            page2-print.jpg … page15-print.jpg
            backpage-print.jpg
            images/                       # web-tier per-slot encodings: hero 1300/q82, story 1100/q80, thumb 800/q76
              <property_slug>-NN.webp
              <property_slug>-hero-1-main.webp     # index.html hero rotator — source-res @ q88
              <property_slug>-hero-2-<role>.webp   # index.html hero rotator — interior moment
              <property_slug>-hero-3-<role>.webp   # index.html hero rotator — garden / outdoor
              <property_slug>-floorplan.png        # line-art PNG, copied unchanged from canonical
              <brand_slug>-logo-light.png # light-coloured logo art — for dark surfaces (e.g. dark index.html sections)
              <brand_slug>-logo-dark.png  # dark-coloured logo art — for light surfaces (e.g. index.html nav, brochure cover when paper)
              qr-video.png, qr-listing.png
          <property_slug>-web.zip         # zipped form of web/, ready to upload to a static-site host
```

The `output/` folder is a portable deliverable: every image referenced by `brochure.html` resolves to a file under `output/images/`. References that escape `output/` (`../images/`, `../../floorplans/`, `../../epc/`) are a defect — the brochure must not depend on the sibling property-extract folders staying in place.

The brand-workspace set is whatever directories exist under the caller's `<output_root>/` — enumerate them with `ls <output_root>` at runtime rather than assuming a fixed set. Each brand directory is its own workspace and matches the `<brand_slug>/` layout above.

A fresh run with no `output_root` and no existing brand pack lands the workspace in the caller's CWD as `./<brand_slug>/`, not under any other path.

Determinism rules — a run that violates any of these is wrong, even if the brochure renders:
- `properties/` is **inside** `<brand_dir>/`, never a sibling.
- `output/` is the property's deliverable directory, sitting at the root of `<property_dir>/`. No `<name>-brochure-brand.html`, no nested `brochure/` wrapper between `<property_dir>/` and `output/`.
- The brochure's HTML lives at `<property_dir>/output/brochure.html`. The filename is literal `brochure.html` — not `<property_slug>-brochure.html`.
- Print snapshots are named `cover-print.png`, `page2-print.png` … `page15-print.png`, `backpage-print.png` (16 files for the 16-page folio; 12 if the property warranted the reduced-page variant — see **Page-count**) — never `cover-print-brand.png` or other variants.
- Both PDFs are present: `<property_slug>-brochure-print.pdf` (300 dpi print master) **and** `<property_slug>-brochure-web.pdf` (192 dpi web/digital). Shipping only one is wrong — the print master is the canonical archive artefact, the web PDF is what gets emailed and lives inside the web bundle.
- The brochure has an **even page count** (the canonical folio is 16; alternative even counts — typically 12 — only with explicit user consent). See `a4-print-documents` → Even-page count for duplex printing.
- Anything that would otherwise pollute `output/` (legacy versions, scratch HTML, branding experiments) is moved out of `output/` entirely. `_archive/` at the property root is acceptable; extra files inside `output/` are not.
- The **web bundle** is a derived artefact, not a separate canonical archive. `output/web/` contains only files derivable from `output/`. The zipped `<slug>-web.zip` lives alongside `output/web/` (at `output/<slug>-web.zip`), not inside `web/`. Regenerating the web bundle never modifies `output/brochure.html` or any canonical asset.

## Common mistakes

| Mistake | Why it's wrong |
|---|---|
| Running `brand-design` when `DESIGN.md` already exists for the same URL | Wastes tokens and risks regenerating logo PNGs that earlier brochures point at. |
| Treating "directory exists" as enough for skip-check | The directory may exist with a different brand's content. The check is **content match** (recorded source URL), not filesystem presence. |
| Silently overwriting a brand pack whose recorded URL differs from the request | The user almost certainly meant a sibling directory or a typo. Asking takes one turn; an overwrite costs them work. |
| Reading a 6000px DSLR photo with `Read` to "have a look" | Breaks the session. Always measure first; downscale if needed. |
| Skipping `property-brochure` because the brochure already exists from a prior run | The user asked for the end-to-end deliverable. If they want to keep the existing brochure, they will say so — confirm before overwriting, but don't unilaterally skip. |
| Bundling `brand-design`'s outputs into the property directory | The artefacts are separable on purpose. The brand pack is reused across listings; collapsing it into a single property's folder defeats reuse. |
| Inferring `force` from the user's tone ("redo it properly") | `force` is an explicit lever. If the user's intent is unclear, ask — don't assume `force=all`. |
| Silently defaulting to portrait when the user did not specify orientation | The brochure's geometry, render slots, and PDF call all change with orientation. A wrong choice means a full rebuild. One-line ask is cheaper than a wasted run. |
| Asking for orientation again in `property-brochure` after the orchestrator already collected it | The contract is "asked once". Re-asking annoys the user and risks a divergent answer mid-pipeline. Pass the value through. |
| Assigning brochure slots from filename alone (e.g. "slot 22 should be the inglenook → use `<slug>-22.webp`") | Filenames carry order, not content. Verify the actual photo at index 22 before referencing it; a downstairs WC at index 22 will silently ship as the chapter's hero. See `property-brochure → Image content verification`. |
| Calling the outdoor kitchen "the cedar pavilion" or "the summerhouse" interchangeably | They are three distinct features. The outdoor kitchen is cedar-clad with a grill and bench seating; the summerhouse is glass-walled and houses the gym; the orangery is inside the home's footprint. Conflating them in copy or in image alt text is a silent editorial failure. |
| Em-dashes used as connector between phrases ("a home of beam, hearth — and quiet flow") | Hallmark of AI-generated copy. Replace with comma, full stop, or restructure. See `property-brochure → Editorial copy register`. |
| "House" instead of "home" at super-premium register | Wrong word for the buyer. "Home" is warmer, more aspirational, and matches the register. Replace globally. |
| Text overlaid on photographs relying on a gradient + text-shadow for legibility | Insufficient against busy backgrounds (stone tile, golden-hour skies). Use a translucent dark panel directly behind the text. See `property-brochure → Text on images`. |
| Including a detached gymnasium-summerhouse footprint in the principal home's first-floor sq ft | Misrepresents £/sq ft. List ancillary footprints separately. See `property-brochure → Floor area`. |
| Shipping a web bundle without `index.html` | The web bundle is the property's hosted experience. The brochure is a downloadable folio; the landing page is the scrollable "for sale" page that links to it. Both are mandatory in the zip. See `property-brochure → Page`. |
| Putting QR codes on the back page without a visible URL or a clickable wrapper | A QR is unscannable from the digital screen showing the brochure. The clickable URL beneath each QR is mandatory; it makes the digital reader experience equivalent to the print reader experience. See `property-brochure → Back-page QR codes`. |
| Using the same logo variant for the back-page masthead (dark surface) and the landing-page nav (light surface) | The two surfaces need opposite logo variants — white-on-transparent for the back page, dark/coloured for the landing nav. Both must be present in `output/web/images/`. |

## Completion criteria

Report `DONE` only after:

- All three upstream artefact contracts are satisfied at their expected paths (`<brand_dir>/DESIGN.md`, `<property_dir>/property.json`, **`<property_dir>/seller-brief.md` with non-empty answers to all 20 questions**).
- Orientation was explicit before any layout work began — either stated by the user, inherited from a prior brochure with confirmation, or asked-and-answered.
- The brochure HTML exists at `<property_dir>/output/brochure.html` and its `@page { size: A4 portrait | landscape }` matches the chosen orientation.
- Both PDF deliverables exist alongside `brochure.html`: the print master (`<property_slug>-brochure-print.pdf`, ~50–80 MB at 300 dpi) and the web/digital (`<property_slug>-brochure-web.pdf`, ~20–35 MB at 192 dpi). Both are image-only, built from per-page Playwright snapshots via img2pdf and linearized via qpdf; both pass `qpdf --check`, both report `Optimized: yes`, and both have zero embedded fonts (`pdffonts | wc -l` returns 2). See `a4-print-documents → Verification`.
- All per-page print snapshots referenced by the HTML's print CSS exist at expected names — `cover-print.png`, `page2-print.png` through `page15-print.png`, and `backpage-print.png` (16 files for the 16-page folio) — at the orientation-correct 300 dpi pixel dimensions (3509×2481 landscape / 2481×3509 portrait).
- The brochure has an **even page count** (canonical 16; multiples of 2 required, ideally multiples of 4 for booklet binding) — see `a4-print-documents` → Even-page count for duplex printing.
- The **web bundle** exists at `output/web/` and as a zipped `output/<slug>-web.zip` — see `property-brochure → Web bundle` for what it contains. The bundle includes both `brochure.html` and the companion `index.html` (see `property-brochure → Page`), plus a copy of the web PDF named simply `<property_slug>-brochure.pdf` to match the in-page Download links. Smoke-test was performed: an isolated HTTP server returned 200 for every referenced asset (HTML, web-tier images, jpg snapshots, the bundled PDF), and **both** `brochure.html` and `index.html` rendered correctly. Typical zip is 30–50 MB for a 16-page folio.
- **Back-page QR codes are clickable.** Each QR is wrapped in an `<a target="_blank">` tag and accompanied by a visible underlined URL beneath the label, so a digital reader can click instead of scan. See `property-brochure → Back-page QR codes`.
- The user-facing report names which steps ran and which were reused, **and the chosen orientation**, **and the path to both the canonical print archive and the web zip**.
- The web PDF and the web zip are already written under `output/` — state their exact paths (`output/<slug>-brochure-web.pdf` and `output/<slug>-web.zip`) so the operator can retrieve them from the Artefacts panel or file share.
- No image was read in violation of the 2000px rule (verifiable: every image read should have been preceded by a `sips`/`identify` measurement, and any over-threshold image was previewed via `/tmp/`).

If any condition is unmet, report `DONE_WITH_CONCERNS` and list the gap.

## When NOT to use this skill

- The user supplies only a brand URL (no property) → route directly to `brand-design`.
- The user supplies only a property URL (no brand context) → ask which agent's brand to use; if they say "use the existing one in `<dir>`", route to `property-extract` and then `property-brochure` with that brand directory.
- The user supplies pre-staged photos and asks for the brochure → route directly to `property-brochure`. There's nothing to orchestrate.
- The user wants to refresh a single piece (e.g. just regenerate the dark logo, just re-download images) → call the underlying skill directly with whatever scope they specified. The orchestrator is for end-to-end runs, not à la carte fixes.
