# task-2389 — IDS Phase 1 카드뉴스 고급화 (Benzaiten)

- **Date**: 2026-05-03
- **Owner**: 디자인팀 벤자이텐 (model: sonnet)
- **Scope**: Fix 1 (12 satori 매거진 템플릿) + Fix 2 (`design_md_loader.py`) + Fix 5 (`sizes.py`) + SKILL.md append

## 결과 요약
- **상태**: PASS
- **신규 파일**: 38건
  - templates/ 36건 (12 × HTML/CSS/JSON)
  - design_md_loader.py 1건
  - sizes.py 1건
- **기존 파일 수정**: SKILL.md (append만, 본문 변경 없음)
- **금지 경로 변경**: 0건 (`resources/design-md/**`, dispatch.py 등 모두 무손)
- **외부 API 호출**: 0건 (정규식 + 키워드 매칭만)

## Fix 1 — 12 매거진 템플릿
위치: `/home/jay/workspace/skills/satori-cardnews/templates/`

| ID | HTML | CSS | JSON |
|----|------|-----|------|
| magazine | magazine.html | magazine.css | magazine.json |
| grid-4 | grid-4.html | grid-4.css | grid-4.json |
| grid-6 | grid-6.html | grid-6.css | grid-6.json |
| asymmetric | asymmetric.html | asymmetric.css | asymmetric.json |
| typography-focus | typography-focus.html | typography-focus.css | typography-focus.json |
| infographic | infographic.html | infographic.css | infographic.json |
| storytelling | storytelling.html | storytelling.css | storytelling.json |
| minimal | minimal.html | minimal.css | minimal.json |
| monochrome | monochrome.html | monochrome.css | monochrome.json |
| colorful | colorful.html | colorful.css | colorful.json |
| corporate | corporate.html | corporate.css | corporate.json |
| cover | cover.html | cover.css | cover.json |

전 템플릿 공통:
- Flexbox 전용 (grid 미사용)
- inline-style 우선 (Satori 호환)
- `font-family: '{{font_display}}', Pretendard, 'Noto Sans KR'` 명시
- `<div style=` 시작 + `</div>` 종료 검증 통과
- JSON `id/name/description/required_vars/optional_vars/default_size/supports_sizes` 필드 모두 보유

## Fix 2 — design_md_loader.py
위치: `/home/jay/workspace/skills/satori-cardnews/design_md_loader.py`

- 외부 API 호출 0건 — 정규식 (`_HEX_PATTERN`, `_RGBA_PATTERN`) + 키워드 라인 매칭으로만 추출
- `load_design_md(brand)` → `DesignTokens` TypedDict (primary/secondary/accent/background/text_primary/text_secondary/font_display/font_body/spacing/border_radius/shadow)
- `list_brands()` → 60종 (검증: 59 출력, INDEX.md 제외)
- `fallback_tokens()` → 안전한 기본값 dict
- 한글 폰트: Pretendard 1순위 강제

`load_design_md('supabase')` 출력 샘플:
```
primary=#0f0f0f  secondary=#171717  accent=#0f0f0f
background=#0f0f0f  text_primary=#4d4d4d  text_secondary=#898989
font_display=Circular  font_body=Source Code Pro
spacing={'sm':8,'md':16,'lg':32,'xl':64}  border_radius=6px  shadow=[]
```

## Fix 5 — sizes.py
위치: `/home/jay/workspace/skills/satori-cardnews/sizes.py`

```
SIZES = {
  'instagram': (1080, 1080),
  'facebook':  (1200, 630),
  'twitter':   (1200, 675),
  'threads':   (1080, 1350),
  'naver':     (800, 800),
}
```

- `get_size(platform)` → fallback `(1080, 1080)`
- `list_platforms()` → 5종 리스트

## SKILL.md 업데이트
위치: `/home/jay/workspace/skills/satori-cardnews/SKILL.md`

추가 섹션:
- `## 12 매거진 템플릿 (Phase 1)` — 12 ID 표 + 사용법 코드 스니펫
- `## design-md 자동 매칭` — load_design_md 사용 예시
- `## 5 사이즈 자동` — get_size 사용 예시

기존 본문(스펙/Double-Bezel/Eyebrow/Grain Texture/품질 체크리스트 등) 무수정. append-only.

## 검증 결과 (모두 PASS)
- `python3 -m py_compile sizes.py` → OK
- `python3 -m py_compile design_md_loader.py` → OK
- `from design_md_loader import list_brands, load_design_md; brands=59; load_design_md('supabase')` → 정상
- 12 HTML 모두 `<div style=` + `</div>` 포함
- 12 JSON 모두 valid JSON + 필수 키 7개 보유

## 720+ 조합
60 brand × 12 template = **720 조합**. 5 사이즈까지 곱하면 3,600 조합 자동 생성 가능.

## 금지 경로 무손 확인
변경 0건: `resources/design-md/**`, `dispatch.py`, `scripts/auto_merge.py`, `scripts/done-watcher.py`, `scripts/finish-task.sh`, `scripts/whisper-compile.py`, `teams/shared/**`, `CLAUDE.md`.
