# SOP — ShareCraft Flyer Visual Iteration

**Established:** 2026-05-02 (S83-H156)
**Owner:** CC + Brady
**Applies to:** ShareCraft series (May 2, May 30, June 28, future). Pattern is generalizable to other event types when their builders are extended.

## Why this SOP exists

Pre-H156, regenerating a ShareCraft flyer required remembering:
1. The right CLI invocation (`build_rc_sharecraft_flyer.py` with the right flags)
2. The R2 upload path (`rosecourt-assets/rosecourt/events/flyers/<slug>.pdf`)
3. The wrangler syntax for binary uploads (`--content-type=application/pdf --remote`)

H156 ships a per-event metadata dict + dashboard buttons that copy the full pipeline to clipboard. This SOP captures the 3-step iteration loop so future Brady can ship a new flyer in under 5 minutes.

## The 3-step loop

### Step 1 — Edit copy

Open `~/builders/build_rc_sharecraft_flyer.py`, find the `SHARECRAFT_EVENTS` dict (top of file), and edit the entry for the slug you want to change. Editable fields per slug:

| Field | What it controls |
|---|---|
| `date` | Header date line (e.g. "Saturday, May 30, 2026") |
| `time` | Header time line (e.g. "10:00 AM &ndash; 11:30 AM") |
| `continues_note` | Italic line under the time (e.g. "Drop in any time") |
| `next_label` | Footer "Next:" callout |
| `format_banner` | Burgundy-on-gold banner (FREE ENTRY / OPEN MIC + SHOW-AND-TELL / etc) |
| `description` | The paragraph between the banner and the hero band |
| `cross_promo` | The dark gradient card near the bottom (kicker / title / subtitle / qr_url) |

Brand-static fields (logo, four-zone block, How-It-Works) live higher in the file. They rarely need editing — when they do, edit the `ZONES` list or the inline HTML directly.

### Step 2 — Regen + upload

Two paths:

**A. Dashboard button (preferred)**
1. Open `https://roseinthegrove.com/admin/brady/`
2. Find the event in **🌱 RSVP by Event** section
3. Click **🎨 Regen flyer** — copies the full pipeline command to clipboard
4. Paste into terminal, hit Return
5. Wait ~10–15s for build + upload to complete

**B. Manual CLI (if dashboard is offline)**
```bash
cd ~/builders && python3 build_rc_sharecraft_flyer.py --slug sharecraft-may-30 && \
  cd /tmp/rc-flyers && \
  npx wrangler r2 object put rosecourt-assets/rosecourt/events/flyers/sharecraft-may-30.pdf \
    --file=sharecraft-may-30.pdf --content-type=application/pdf --remote
```

The build emits both `<slug>.html` (browser-printable) and `<slug>.pdf` (WeasyPrint). The `--remote` flag uploads to production R2 (NOT the local emulator).

### Step 3 — Verify

```bash
curl -I https://pub-ffdd6924be764a8c86899a937394fd1b.r2.dev/rosecourt/events/flyers/sharecraft-may-30.pdf
# Expect: HTTP/2 200
```

Or visit `https://rosecourt.co/sharecraft/may-30/` and click the **📥 Flyer (PDF)** button on the event page.

If the cached version is still showing, force-reload (`⌘+Shift+R`). R2 itself doesn't cache; the browser does.

## Adding a new ShareCraft date

1. Add a row to Airtable `2026 Events` (RC base, table `tblxZcxySqGLgvHcI`) with `Status=Building`, `Brand=RoseCourt`, `Canonical Path=/sharecraft/<slug>/`
2. Add an entry to `SIMPLE_EVENT_META` in `~/builders/build_rc_sharecraft.py` (date, slug, etc — copy May 30 as template)
3. Add an entry to `SHARECRAFT_EVENTS` in `~/builders/build_rc_sharecraft_flyer.py` (mirrors the per-event flyer copy)
4. Run page builder + flyer builder, deploy + upload:
   ```bash
   cd ~/builders && python3 build_rc_sharecraft.py --output /tmp/rc-build && \
     cd /tmp/rc-build && npx wrangler pages deploy . --project-name=rosecourt --branch=main
   cd ~/builders && python3 build_rc_sharecraft_flyer.py --slug sharecraft-<slug> && \
     cd /tmp/rc-flyers && \
     npx wrangler r2 object put rosecourt-assets/rosecourt/events/flyers/sharecraft-<slug>.pdf \
       --file=sharecraft-<slug>.pdf --content-type=application/pdf --remote
   ```

## Replacing a hero image

The flyer hero is currently shared across all dates (`{R2_BASE}/rosecourt/events/sharecraft-workshop.webp`). To swap it per event:

1. Generate or pick a 4:3 image (1200×900 minimum)
2. Use the **MJ 4-variant flow** on `/admin/brady/` (Render 4 → pick → Promote MJ Variant)
3. Promote to a per-event hero path: `rosecourt/sharecraft/<slug>-hero.webp` (already in `HERO_PATHS` dict in `~/builders/bin/refresh_event_assets.py`)
4. Edit `SHARECRAFT_EVENTS[<slug>]` — add a `hero_r2_path` field (TODO: builder doesn't read this yet — current heroes are shared. When per-event heroes are wanted, extend `build_flyer(meta)` to read `meta.get("hero_r2_path", DEFAULT_HERO)`)

This step is **deferred** until Brady has a clear per-event hero direction. The shared brand photo works fine for now.

## Reference files

- Builder: `~/builders/build_rc_sharecraft_flyer.py`
- Page builder: `~/builders/build_rc_sharecraft.py` (renders the dedicated event pages that link to the flyer)
- Asset orchestrator: `~/builders/bin/refresh_event_assets.py` (HERO_PATHS dict drives `--hero` swaps)
- Dashboard: `~/builders/build_rig_admin_brady.py` (Refresh Assets + Regen Flyer buttons live in the Event/RSVP loop)
- Auto-rebuild: dashboard rebuilds every 30 min via LaunchAgent `com.grove.admin-brady-rebuild`

## Common gotchas

- **WeasyPrint warnings about unsupported CSS** are noise. The flyer renders fine.
- **R2 cache** — there is none on the public bucket. If the URL still 404s after upload, check the wrangler output for an actual upload-failed error.
- **PDF is 3.9MB** — that's the embedded webp hero + Cinzel/Raleway fonts. Acceptable for download but don't email-attach.
- **The `--content-type=application/pdf` flag is required** — without it, browsers download the file as `.bin` instead of opening inline.
- **Don't `wrangler pages deploy` from `/tmp/rc-flyers/`** — that's R2-only content. Pages deploys from `/tmp/rc-build/`.

## Audit trail

Every flyer regen leaves a 200 OK on the canonical R2 path. To verify recent changes are live, `curl -I` the URL and check the `last-modified` header. There's no separate revision log (PDFs overwrite in place).

---

_Filed S83-H156 G3 (2026-05-02 by CC). Iteration tested with May 30 + June 28 first ships._
