# Magazine 템플릿 가이드 ## 1. 소개 잡지 지면처럼 사진과 세리프 타이포를 쓰는 에디토리얼형. 브랜드에 격을 더하고 싶은 인터뷰·에세이·큐레이션에 맞는다. ## 2. 톤 가이드 잡지 지면의 문장을 쓴다 — 평서문, 단정, 형용사 절제. 느낌표와 이모지를 쓰지 않는다. 한 장에 한 생각만 담는다. 문장을 이어 붙여 채우지 말고, 생각이 바뀌면 장을 넘긴다. `pullquote` 는 본문에서 **가장 강한 한 문장**만 뽑는다. 두 문장을 넣으면 힘이 반으로 준다. ## 3. 슬라이드 흐름 권장 `cover → article → colophon` 이 뼈대다. `pullquote` 와 `photo` 는 사이사이에 **호흡으로** 끼워 넣는다. 권장 배열: `cover → article ×2 → pullquote → article ×2 → photo → colophon` - 사진은 1080×1350 이상을 **공개 HTTPS URL** 로 넣는다. 지면의 절반을 차지하므로 화질이 그대로 드러난다. - 전체 8~11장이 읽기 좋다. ## 4. 슬롯별 작성 요령 아래 슬롯 한계는 등록 시 manifest에서 자동 생성했다. design_max는 디자인 권장 상한이며 초과해도 렌더는 성공하지만 `design_max_exceeded` 경고가 발생한다. max_chars는 실측 하드 상한이며 초과하면 422 `max_chars_exceeded`가 발생한다. 다만 max_chars는 레이아웃 안전을 보장하는 값이 아니라, 같은 글자 수라도 글자 폭이나 줄바꿈에 따라 max_chars 이내에서 렌더 영역을 넘을 수 있다. 이 경우 렌더는 성공하고 결과 이미지와 함께 `text_overflow` 등의 warning을 반환하므로, 경고가 발생한 슬롯의 문구를 더 줄여 다시 렌더한다. 이 수치는 손으로 쓴 것이 아니라 manifest가 원본이다 — 본 가이드와 manifest는 영구히 일치한다. - 요청 크기: `POST /v1/renders`의 전체 JSON 요청 본문 상한은 1,048,576바이트(1MB)다. 초과하면 HTTP 413 `payload_too_large`가 발생한다. - 글쓰기 원칙: 한 슬라이드에 한 주장. 좋은 예: `API 문서를 자동으로 검증하는 법`. 나쁜 예: `정말 놀랍고 엄청난 API 문서 자동화에 관하여 알아볼까요?`. - 브랜딩: `brand_logo_url`은 프로젝트 브랜드 자산(`logo_horizontal`)으로 렌더 시 자동 공급된다. 슬롯 값으로 데이터 URI를 직접 넣지 않는다. - 색상: `accent_color`는 manifest 테마 또는 `brand.colors.accent`의 `#RRGGBB`로 자동 공급된다. - 이미지: `image` 타입 슬롯은 공개 HTTPS URL과 `data:image/;base64,...` 데이터 URI를 모두 허용한다. 실사진은 본문 상한을 피하도록 원격 HTTPS URL을 사용하고, 데이터 URI는 로고·아이콘 같은 작은 자산에만 사용한다. 슬라이드 타입별로 아래 소절을 확인한다. 슬롯 이름·필수 여부·한계값은 manifest에서 생성되며, 타입별 작성 요령은 manifest의 `slide_types[].guidance`가 원본이다. ### `cover` (min 1, max 1) 표지는 사진이 절반을 차지한다. kicker 는 분류(예: INTERVIEW), headline 은 지면 제목처럼. | 슬롯 | 필수 | 형식·한계 | | --- | --- | --- | | `photo_url` | 예 | 이미지(공개 HTTPS URL 또는 data URI) | | `kicker` | 아니오 | 텍스트 | | `headline` | 예 | 텍스트 | | `standfirst` | 아니오 | 텍스트 | | `accent_color` | 아니오 | 색상(#RRGGBB, 자동 공급) | | `brand_logo_url` | 아니오 | 브랜드 자산(logo_horizontal) | | `account_name` | 아니오 | 텍스트 | ### `article` (min 1, max 8) 본문 지면. subhead 는 소제목, body 는 두세 문장. 읽는 호흡을 위해 한 장에 한 생각만 담는다. | 슬롯 | 필수 | 형식·한계 | | --- | --- | --- | | `subhead` | 예 | 텍스트 | | `body` | 예 | 텍스트 | | `accent_color` | 아니오 | 색상(#RRGGBB, 자동 공급) | | `brand_logo_url` | 아니오 | 브랜드 자산(logo_horizontal) | | `account_name` | 아니오 | 텍스트 | ### `pullquote` (min 0, max 3) 지면의 쉼표. 본문에서 가장 강한 한 문장만 뽑는다. 두 문장 이상 넣지 않는다. | 슬롯 | 필수 | 형식·한계 | | --- | --- | --- | | `quote` | 예 | 텍스트 | | `attribution` | 아니오 | 텍스트 | | `accent_color` | 아니오 | 색상(#RRGGBB, 자동 공급) | | `brand_logo_url` | 아니오 | 브랜드 자산(logo_horizontal) | | `account_name` | 아니오 | 텍스트 | ### `photo` (min 0, max 5) 사진이 말하게 두는 장. caption 은 짧게, 사진 설명이 아니라 맥락을 준다. | 슬롯 | 필수 | 형식·한계 | | --- | --- | --- | | `photo_url` | 예 | 이미지(공개 HTTPS URL 또는 data URI) | | `caption` | 아니오 | 텍스트 | | `accent_color` | 아니오 | 색상(#RRGGBB, 자동 공급) | | `brand_logo_url` | 아니오 | 브랜드 자산(logo_horizontal) | | `account_name` | 아니오 | 텍스트 | ### `colophon` (min 1, max 1) 마지막 장. 잡지 판권면처럼 조용하게 마무리한다. | 슬롯 | 필수 | 형식·한계 | | --- | --- | --- | | `headline` | 예 | 텍스트 | | `body` | 아니오 | 텍스트 | | `accent_color` | 아니오 | 색상(#RRGGBB, 자동 공급) | | `brand_logo_url` | 아니오 | 브랜드 자산(logo_horizontal) | | `account_name` | 아니오 | 텍스트 | ## 5. 완성된 slides.json 예시 이미지 슬롯은 **공개 HTTPS URL 과 data URI 를 모두** 받는다. 실사진은 URL 을 쓴다 — 전체 JSON 요청 본문 상한이 1,048,576바이트(1MB)라 실사진을 base64 로 넣으면 두 장에서 넘어간다 (초과 시 HTTP 413 `payload_too_large`). ```json { "template": "magazine", "format": "instagram", "slides": [ { "type": "cover", "slots": { "photo_url": "https://images.unsplash.com/photo-1503023345310-bd7c1de61c7d?w=1080", "kicker": "INTERVIEW", "headline": "멀리 가는 사람은 서두르지 않는다", "standfirst": "10년째 같은 자리에서 같은 일을 하는 사람에게, 지치지 않는 법을 물었다.", "account_name": "@lightsoft_studio" } }, { "type": "article", "slots": { "subhead": "속도를 줄이면 보이는 것", "body": "그는 처음 3년을 가장 느리게 보냈다고 했다. 남들이 결과를 낼 때 자신은 방법을 익혔고, 그 차이가 7년째부터 벌어지기 시작했다.", "account_name": "@lightsoft_studio" } }, { "type": "pullquote", "slots": { "quote": "빨리 가는 법은 금방 배웠고, 오래 가는 법은 아직도 배우는 중이다.", "attribution": "— 인터뷰이", "account_name": "@lightsoft_studio" } }, { "type": "photo", "slots": { "photo_url": "https://images.unsplash.com/photo-1503023345310-bd7c1de61c7d?w=1080", "caption": "작업실은 10년 동안 세 번 옮겼지만 책상은 그대로다.", "account_name": "@lightsoft_studio" } }, { "type": "colophon", "slots": { "headline": "오래 하는 사람들의 이야기", "body": "매달 한 사람을 만나 기록합니다.", "account_name": "@lightsoft_studio" } } ] } ``` ## 6. curl 호출 예시 ```bash curl -X POST 'https://api.cardnews.example/v1/renders' \ -H 'Authorization: Bearer $CARDNEWS_API_KEY' \ -H 'Content-Type: application/json' \ --data-binary @slides.json ``` ## 7. 검증·경고 대응 가이드 - `max_chars_exceeded`: 해당 슬롯의 글자수를 줄인다. `max_chars` 는 넘기면 확실히 거부되는 상한이지 안전 보장이 아니다 — 글자가 넓으면(전각·이모지) 상한 안에서도 넘칠 수 있다. - `text_overflow` / `out_of_bounds`: 렌더는 성공하고 이미지와 함께 경고가 온다. 글자를 줄이고 다시 렌더한다. - `low_resolution`: 더 큰 원본 이미지를 쓴다. - `unknown_slot` / `missing_required_slot`: 4절의 슬롯 목록과 대조한다.