← All playbooks · Raw API
case-study-from-package
# Case study from a package — SE Studio
Build a **work** multi-block case study from Drive / Figma / copy **without inventing layout or rewriting prose**.
## When to use
- New or lab case studies from a multi-file package
- Ports of editorial Figma frames into text blocks plus Visuals collections
- Intent: “build this case study from the assets”, “multi-ART port”, “lab case study from Drive”
## Pipeline
```text
task-source-readiness-review
→ soft-proof + light human yes
→ task-media-pipeline-prepare (Drive folder of masters → ready URLs → CMS assets)
→ task-create-article / incremental CMS build (lab by default for experiments)
→ task-preview-verify (multi-block checklist)
```
Read `cms-edit://customer/articles` for routing, SEO, lab flags, and composition rules.
### SE Studio media pipeline (via cms-edit)
| Setting | Value |
|---------|--------|
| Agent API | MCP tool **`cms_edit_media`** (`prepare` → `wait` → `catalog` → `import`) |
| Tenant | Set on host as `MEDIA_PIPELINE_TENANT=se` (not projectKey) |
| Profile | `case-study-v1` |
| Auth | **Contentful OAuth only** for agents; pipeline service key lives on the cms-edit host |
| Share folders with | `media-pipeline-reader@se-media-pipeline.iam.gserviceaccount.com` (**Viewer**) |
Full steps: `cms-edit://customer/task-media-pipeline-prepare`. **Never ask for `MEDIA_PIPELINE_API_KEY`.**
**Order matters:** process the Drive pack **before** building the body. Prefer `asset upload --url` from catalog `readyUrl` over mid-build staged upload of 4MB+ masters. If the folder is not shared as Viewer with `media-pipeline-reader@se-media-pipeline.iam.gserviceaccount.com`, that is a **NO-GO**. Tell the editor that address. Do not ask them to grant their own Google login.
## Non-negotiables
| Rule | Detail |
|------|--------|
| **No copy rewrite** | Structure and place source text only |
| **Sequence from design** | Figma / ordered list wins over CMS convenience |
| **Separated demoted** | Only for **true** side-by-side pairs |
| **Placeholders beat reordering** | GO-WITH-GAPS: keep the slot, label the gap |
| **Merge continuous prose** | Adjacent body-only CSRTs look gappy — prefer one body block |
| **Media pack first** | Oversized Drive assets go through media pipeline |
| **Light yes** | Human confirms the asset map with yes/go/proceed. "Build this case study" starts the review; it is not the yes |
| **Text and pictures split** | Case study rich text is copy only. Pictures go in Visuals or Separated visuals |
| **Figma file must be this project** | Leftover layers, notes, or copy from another case study are a NO-GO |
## Condensed example — GO-WITH-GAPS (OM1-shaped)
Synthetic package; teaches structure, not client confidentiality.
**Sources:** Figma ordered frame + Drive folder (~15 files) + narrative doc.
**Inventory (excerpt):**
| # | Role | Status | Mapping |
|---|------|--------|---------|
| 1 | Hero | ready (after pack) | `article.visuals` file ending `-hero` |
| 2 | Website UI | ready | Visuals, width from the frame |
| 3 | Pair L / R | L **missing**, R ready | Separated + **placeholder** left |
| 4 | Origin copy | ready | Case study rich text body (merge paras) |
| 5 | Hands photo | ready | Visuals, width 99 |
| 6 | Pair L / R | L ready, R **missing** | Separated + **placeholder** right |
| 7 | Challenge copy | ready | Case study rich text body |
| 8 | Landscape demo video | ready (pipeline H.264) | Visuals; autoplay+loop |
**Verdict:** GO-WITH-GAPS (2 missing visual slots ≤3; sequence clear; copy usable as written).
**Soft-proof sketch:**
```text
1. [template] hero — `-hero` on article.visuals
2. Visuals — website
3. Separated — placeholder | blue model
4. Case study rich text — origin (merged)
5. Visuals — hands
6. Separated — man/patterns | placeholder
7. Case study rich text — challenge
8. Visuals — demo video autoplay+loop
… (continue in source order)
Lab: lab/…, hidden, unindexed
```
**Do not:** invent Separated for stacked singles; rewrite narrative; drop placeholders; put body images on article `visuals` (that field is `-hero` / `-home` only); compress videos in chat.
## Composition
| Beat | CMS |
|------|-----|
| Copy | **Case study rich text**. Leave `visual` empty. Merge adjacent prose when no image sits between. Sibling gaps (image/text 48px, image/quote 96px, image/image 16px, text/quote 128px below 1024px and 96px from 1024px) only apply between these blocks |
| One image, or three or more in one row | One **Visuals** entry. Set each Media `width` (1–99) and `horizontalPosition` from this frame |
| Exactly two images in one row | **Separated visuals**. Widths sum to less than 100 when the design has a gap |
| Page hero | File ending `-hero` on `article.visuals` |
| Work grid | File ending `-home` on `article.visuals` |
| Share image | File ending `-og` on `featuredImage` |
Do not put the hero or work-grid asset in `content` as well. Empty width on a Visuals image is full column. Measure this frame: `widthPct = round(nodeWidth / contentWidth * 100)`, cap at 99. **Left** when `x ≈ 0` and the node is narrower than the column; **Right** when it is pinned right; **Middle** only when the design is centred. Do not reuse widths or asset choices from another case study.
An annotation counts only when it names a file that is in this Drive folder. A note that says "replace image", or that names another client, is a leftover.
### Alpha images
Prefer pipeline **WebP** for transparent masters (clinical UI, cutouts). Do not leave large transparent PNGs if the pack produced WebP.
## Figma NO-GO
These override a generic **GO** from `task-source-readiness-review`. Any one of them stops the build. List what you found. Do not guess a Drive file for a layer.
The soft-proof is one row per visible image: Figma node, layer name, Drive filename, width, position. The human yes is approval of that table.
- Layer names, annotations, or text frames from another client or an old template (another client's prefix, or placeholder lines that are not this project's copy).
- An annotation that does not name a file in this Drive folder.
- A visible image whose layer name is not the Drive filename, extension included, and nobody has confirmed that row.
- Two rectangles stacked on the same spot, or a zero-height row that still holds an image or text.
- Placeholder copy still in a text frame.
- Drive folder not shared as Viewer with `media-pipeline-reader@se-media-pipeline.iam.gserviceaccount.com`.
## Anti-patterns
- Putting a picture on Case study rich text `visual` for new work
- A media-only Case study rich text block
- Leaving Media `width` empty when the frame is not full column
- Separated pairs at implicit 50/50 with no gap when Figma shows a gutter
- Treating a leftover annotation as an asset choice
- Copying another case study's widths
- Default “multi-ART + Separated between every pair”
- One Case study rich text per paragraph with no art between
- Inventing section titles / H1s on body blocks
- Editing the live production entry instead of a lab draft
- “Improving” client copy in cms-edit
- Staged-uploading 4MB+ masters without **media pipeline**
## Related
- `cms-edit://customer/articles`
- `cms-edit://customer/task-source-readiness-review`
- `cms-edit://customer/task-media-pipeline-prepare`
- `cms-edit://customer/task-media-reuse-and-upload`
- `cms-edit://customer/task-create-article`
- `cms-edit://customer/task-create-from-document`
- `cms-edit://customer/task-preview-verify`
- Components: `case-study-rich-text`, collections: `separated-visuals`, `visuals`