# Articles — SE Studio

## Routing

Public URLs use the **article type** as the first path segment (not a generic `/articles` prefix). Primary tag is **not** in the path.

| Type | Public URL pattern | Example |
|------|--------------------|---------|
| Case study (`work`) | `/work/{client}/{title-slug}/` | `https://www.se.studio/work/arcticdb/an-identity-with-scale/` |
| Blog (`blog`) | `/blog/{slug}/` | `https://www.se.studio/blog/ask-your-website-anything/` |
| Video (`video`) | `/video/{slug}/` | — |

**CMS slug** (Contentful) is without the type prefix:

- Case study: `{client}/{title-slug}` e.g. `arcticdb/an-identity-with-scale`
- Blog: single segment e.g. `ask-your-website-anything`

Read `cms-edit://customer/routing` and `production-site` before guessing markdown/preview URLs. Tag indexes and people indexes are **disabled**.

### Lab / test ports

When porting or experimenting with multi-block composition, create a **new** draft — never edit the live published entry:

| Field | Lab value |
|-------|-----------|
| `slug` | `lab/{original-slug}` e.g. `lab/arcticdb/an-identity-with-scale` |
| `hidden` | `true` |
| `indexed` | `false` |
| `cmsLabel` | prefix `LAB \| …` |

Do not publish lab articles.

## Article types (required)

Every article must link to an **articleType**. List types before creating:

```bash
cms-edit list --type articleType
```

| Type | Slug | Use for |
|------|------|---------|
| **Case study** | `work` | Client project stories — primary content type |
| **Blog** | `blog` | Studio thought leadership, product posts |
| **Video** | `video` | Video-led pieces |

Prefer `--article-type-slug work` (or `blog`, `video`) — marketers should not need Contentful entry IDs.

```bash
cms-edit list --type article --article-type-slug work
cms-edit list --type article --article-type-slug blog
```

## Template

Articles use **Article Template** (`18bSfHlEeNVisz9PWtOso0`). It provides **Article hero** (and related shell) in `preContent` and **Related articles** in `postContent` — do **not** duplicate hero or related collections in article `content`.

```bash
cms-edit peek --template-label "Article Template"
```

## Discoverability (SEO) — mandatory

Agents **must not** save a new or ported article without a strong meta description. Discoverability is a first-class requirement, not an afterthought.

| Field | Rule |
|-------|------|
| `title` | Full human headline for the piece (H1 in hero). **Not** the client name alone (bad: `OM1`). Include searchable terms (brand, website, campaign, industry). |
| `subtitle` | Case study: client or series name (hero client line). |
| `description` | **Required.** **120–160 characters.** Must include: **who** (client or topic) + **what SE delivered** + **outcome or differentiator**. No empty string, no “Learn more…”, no single clause under 100 chars. Draft from **existing source copy only** — do not invent claims. |
| `summary` | Rich-text hero summary when the template expects it — distinct from meta `description`. |
| `slug` | Stable kebab path; lab uses `lab/…`. |

### Good vs bad meta descriptions

**Good (case study, ~158 chars):**

> Brand identity for ArcticDB — built to signal technical credibility and bold innovation in fintech. Bold logomark, data-science typography, designed to scale.

**Good (blog, ~150 chars):**

> What if your marketing team could ask their website anything — and act on the answer instantly? SE Studio's AI content integration makes it a reality.

**Bad — refuse save until fixed:**

- `OM1 case study` (too short, no delivery detail)
- `Learn more about our work with healthcare brands.` (generic, no who/what)
- Missing `description` entirely

**Gate:** Before `create from-json` real run or final `save`, count `description` length. If &lt; 100 or &gt; 165, revise. Prefer 120–160.

Also see `task-seo-descriptions` and `task-create-article`.

## Source packages (Drive, Figma, docs)

Before building from an external package:

1. Run **`task-source-readiness-review`** (inventory → beat sheet → GO / GO-WITH-GAPS / NO-GO).
2. Post a **soft-proof** (numbered `content` order + gaps).
3. Get a light human **yes** / **go** / **proceed**.
4. **Do not rewrite source copy** — structure and place only.
5. Full package workflow + worked example: **`cms-edit://customer/case-study-from-package`**.

### Source hierarchy (when sources disagree)

1. **Sequence & layout** — Figma / approved comps  
2. **Art files** — Drive / export  
3. **Words** — approved copy (as written)  
4. **CMS patterns** — production / this playbook (how to map, not what to invent)

## Reference articles

| CMS slug | Type | Notes |
|----------|------|-------|
| `arcticdb/an-identity-with-scale` | Case study | Client in `subtitle`; production body is single ART + embeds |
| `microsoft/meet-the-makers` | Case study | Simpler image set — good multi-block lab source |
| `ask-your-website-anything` | Blog | Blog RTF layout; public path `/blog/…` |

```bash
cms-edit peek --article-slug /arcticdb/an-identity-with-scale
```

Production markdown (structure reference): append `.md` to the **public** path from `production-site` (e.g. `https://www.se.studio/work/arcticdb/an-identity-with-scale.md`).

## Article fields

| Field | Guidance |
|-------|----------|
| `title` | Full headline — discoverable (see SEO above) |
| `subtitle` | Client or series — hero client line |
| `description` | SEO meta — **required**, 120–160 chars (see SEO above) |
| `slug` | No leading slash; case study `client/title-slug`; lab `lab/…` |
| `date` | Publication date (ISO) |
| `articleType` | Required |
| `featuredImage` | OG/social — **landscape** preferred |
| `visuals` | Article-level hero/listing media only — **not** body image dumps |
| `summary` | Hero summary RTF |
| `tags` | Optional; public tag pages disabled |
| `hidden` / `indexed` | Lab: `hidden true`, `indexed false`. Production: `hidden false`, `indexed true` unless unlisted |

## Composition patterns

### Body component types (choose by article type)

| `componentType` | Use for |
|-----------------|---------|
| **Case study rich text** | **Preferred** for new / lab **work** multi-block bodies |
| **Blog rich text** | **Preferred** for new / lab **blog** multi-block bodies |
| **Article rich text** | **Legacy only** — existing production entries (layout still branches blog vs work by page type) |

Do not create new multi-block work articles with Article rich text when Case study rich text is available.

### A — Legacy production (live entries)

Most published case studies and blogs still use:

- **One** `Article rich text` in `content`
- Images/videos as **RTF embeds** inside that body: Media, **Separated visuals**, **Visuals**
- Article `featuredImage` (+ optional `visuals`) for hero/OG

Do not break live entries unless explicitly migrating.

### B — Multi-block (preferred for new agent-built / lab work)

**Faithful sequence first.** Multiple siblings in article `content`, ordered like the design/source — not “CMS convenience.”

```
[template] Article hero …
Case study rich text  (work)  OR  Blog rich text (blog)
  — optional section `heading`; optional single `visual`; body RTF
  — only use Separated visuals when the source is a true side-by-side pair
Case study rich text / Blog rich text  (next beat)
Visuals      — optional 3+ image grid when design is a grid
…
Centered quote — optional sibling when source has a pull quote
[template] Related articles …
```

**Mapping decision table:**

| Source signal | CMS mapping |
|---------------|-------------|
| Continuous prose (no art between) | **One** CSRT/BRT body — **merge** paragraphs; do not split body-only blocks |
| Single feature image + prose | CSRT/BRT with field `visual` (+ Media width % if needed) |
| True side-by-side pair in design | **Separated visuals** between body blocks |
| 3+ grid | **Visuals** collection |
| Quote pull | Centered / wide / right quote as appropriate |
| Decorative loop demo | Media; **autoplay + loop** when decorative |
| Missing frame (GO-WITH-GAPS) | Keep the slot; **labeled placeholder** — do not renumber |

**Rules:**

1. Page title stays on the article entry / hero — block `heading` is a **section title** (section typography, not display 96–200px). Omit when the design has no section title.
2. Section titles may use **CMS `heading`** and/or **headings inside body RTF** (`##` / `###`) only when the **source** has them — do not invent.
3. **Separated visuals only for true pairs** — not the default for “two images nearby.” Stacked editorial images → sequential CSRT field visuals (or single-item stacks), not invented side-by-side.
4. **Grids (3+)** → top-level **Visuals** collection when the design is a grid.
5. **Single** image for a section → block field `visual`. Case study field media defaults to ~**67%** width when unset (ContainedVisual); set Media width for full-bleed or explicit comps.
6. **Media-before-copy:** Blocks render `heading` → `visual` → `body`. For “media then prose”, use a media-only block (or visual on its own CSRT), then a **body only** block.
7. Do **not** put the whole body image set only on article `visuals`.
8. Prefer incremental `open` → `add` / `set` / `rtf` over one giant `from-json`.
9. Labels: rename default cmsLabels; lab uses `LAB | …`.
10. **Spacing caveat:** Adjacent body-only CSRTs each get full section shell spacing + article paragraph rhythm — they look **gappy**. Prefer merging continuous prose into one block. Do not invent empty paragraphs to “fix” spacing.

Read: `components/case-study-rich-text`, `components/blog-rich-text`, `components/article-rich-text` (legacy), `collections/separated-visuals`, `collections/visuals`, `case-study-from-package`.

## Featured images

Read `cms-edit://customer/defaults`.

1. **Custom** — set `featuredImage` / `featuredImageAssetFilename` when provided  
2. **Article type default** — inherit if omitted  
3. **Site default** — asset `5OU6quGThpQuSJFSbxHsHZ`

Landscape for OG. Distinct hero vs OG: set both `featuredImage` and article `visuals` explicitly when needed.

## Creating articles

1. Read this playbook + `components-index` + `defaults` + `routing`
2. External package → **`task-source-readiness-review`** + soft-proof + light human yes
3. `index sync` if catalog may be stale
4. Resolve article type
5. **Write SEO fields** (`title`, `description` 120–160 from source claims only, `subtitle`) — refuse thin descriptions
6. Soft-proof multi-block structure (or single-ART only if user insists on legacy)
7. Lab ports: `lab/…` + `hidden` + unindexed
8. `create from-json --dry-run --strict` or incremental create — **copy unchanged**
9. `diff` → `save`
10. `preview urls` + **`task-preview-verify`** multi-block checklist

### Case study from a package (preferred path)

1. `task-source-readiness-review` → see also **`case-study-from-package`**
2. Doc/Figma title → full `title`; client → `subtitle`; slug → `{client}/{kebab-title}` (or `lab/…`)
3. Soft-proof → multi-block **Case study rich text** in **source order**; Separated **only** for true pairs
4. Draft SEO description from the brief (120–160 chars) **before** create — no invented claims
5. `articleTypeSlug`: `work`

### Blog from a document

Same readiness + SEO gates; `articleTypeSlug`: `blog`; single-segment slug (or `lab/{slug}`); body blocks use **Blog rich text**.

## After save — preview

```
cms-edit preview urls <cms-slug>
```

Map CMS slug to public path: case study → `/work/{cms-slug}/`, blog → `/blog/{cms-slug}/`.

## Publish handoff

`save` creates **drafts only**. Publish in Contentful UI when ready. **Never publish lab articles** without explicit human request.
