# 카드뉴스 비율 변환 하네스 — 요구사항 정리 (초안 v1, 2026-10-27)

정방형 카드뉴스(1080×1080) 한 쪽을 다른 비율(먼저 인스타 세로 1080×1350, 다음 1080×1920)로 바꿀 때
**원본의 의도를 지키며 자연스럽게** 펴는 하네스의 요구사항. 실험 r2~r5 에서 사용자가 눈으로 판정하며 확정된
것만 적는다. "프롬프트" 라 부르지만 실제로는 **① 코드가 하는 결정적 규칙 ② LLM 이 하는 판단 ③ 검수 잣대** 세 층이다.

---

## 0. 한 문장 목표

> 같은 디자인을 다른 캔버스에 **다시 그린** 것처럼 보여야 한다. 요소를 늘어놓은 것이 아니라.

---

## 1. 지켜야 하는 것 (불변 — 바꾸면 실패)

| 항목 | 규칙 |
|---|---|
| 글자 내용·개행·색·굵기·서체·자간 | 그대로 |
| 색·colorMap·그라데이션·투명도·외곽선·둥근 모서리 | 그대로 |
| 반전·회전 | 그대로 (회전한 요소는 중심만 옮긴다) |
| 요소 개수·쌓임 순서(z) | 그대로 — 지우거나 추가하지 않는다 |
| 글자 크기·폭 | **덩어리째 확대할 때만** 같은 배율로 — 글자만 따로 줄이지 않는다 |

기계 검사: `diff_check.py` — 위치·크기·crop·scale·표 행 높이·(덩어리 배율만큼의) fontSize 밖의 변경이 있으면 실패.

---

## 2. 원본의 의도를 읽는 법 (역할)

쪽의 루트 요소를 아래 역할로 읽는다. 이 어휘가 규칙과 판정의 공통 언어다.

| 역할 | 뜻 | 판정 |
|---|---|---|
| **cover** | 배경 그림·텍스처·공책 판 | 캔버스 95% 이상 덮음, 그림이면 50% 이상 |
| **edge-top / edge-bottom** | 변에 붙은 것 | 변에 닿거나(≤6px) 넘침. 높이 20% 이상이면 **판/인물**, 미만이면 **띠/장식** |
| **panel** | 여백 둔 큰 판 (흰 카드) | 변에 안 닿고 가로·세로 70% 이상 |
| **content** | 글·사진 틀·아이콘·선·표 | 나머지 |
| **free** | 글자 없는 큰 그림·좌우로 넘친 장식 | 높이 20% 이상 또는 변 밖. 글자를 받치면 free 아님 |
| **rider** | edge 요소 위에 올라탄 것 | 겹침 50% 이상 (글·도형은 묶음 과반일 때만) |
| **덩어리(block)** | 같이 움직여야 하는 것들 | 2.5% H 안에 있거나 품은 것. 세로로 겹치면 한 줄 |

---

## 3. 코드가 하는 규칙 (결정적) — r5

k = 새 높이 / 원래 높이 (1350 이면 1.25), Δ = 늘어난 픽셀.

| 대상 | 하는 일 | 왜 |
|---|---|---|
| cover 그림 | 가로 중심 유지 k 배 균일 확대 | 넘침 비율 유지 |
| cover 벡터 판(공책·종이) | 세로만 k 배, 안의 것은 판 기준으로 재배치(컨테이너) | 판이 옆으로 넘치면 안 된다 |
| edge 판(높이 20%↑ 사진·도형) | 위/아래 고정하고 h·k | 상하 2:1 분할은 2:1 로 남는다 |
| edge 인물 그림(높이 20%↑) | k 배 키워 발을 바닥에. **글자를 새로 가리면 배율을 줄인다** | 세로 화면에서 작아 보이지 않게, 글자는 안 가리게 |
| edge 띠·장식(높이 20% 미만) | 위는 그대로, 아래는 Δ 내림 | 두께는 디자인 |
| 바닥 띠 위에 앉은 것(책·연필꽂이) | 띠와 같이 Δ 내림 | 바닥에서 뜨면 안 된다 |
| panel | y·k, h·k + 컨테이너 | |
| **덩어리** | 강체(간격 그대로). 글자·받침 도형의 폭 여유만큼 덩어리째 s 배(≤ k, 옆 여백 절반 유지), **글자 크기도 s 배** | 같은 덩어리는 같이, 크기 줄이지 말고 여유 있으면 키운다 |
| 덩어리 안 장식(동전·화살표) | 따라 커지되 캔버스 밖으로 더 나가면 안으로 당긴다 | 꾸밈이 잘리지 않게 |
| 사진·표만의 덩어리 | h·k 로 채운다 (crop 창을 더 열고, 표는 행 높이) | 빈 공간은 사진이 받는다 |
| 덩어리 사이 | 남는 세로를 원래 여백·간격에 **비례** 배분, 간격은 최대 1.6배, 남으면 위·아래 여백에 | 가운데 있던 덩어리는 가운데에 |
| rider | 올라탄 요소를 따라간다 | |

### 지나오며 버린 규칙 (다시 시도하지 말 것)

1. 띠 사이 빈 공간에 Δ 배분 → 빈 공간이 0 이면 전체가 통째로 내려간다.
2. 위는 고정, 아래로만 → 바닥에 270px 이 빈다.
3. 세로축 전체 비례(요소마다 y·k) → 제목·부제·리본이 벌어지고 원 안 아이콘이 어긋난다.
4. 글자는 그대로 두고 그림만 키움 → 그림↔글자 비율이 깨지고 글자가 작아 보인다.
5. 올라탄 요소를 낱개 판정 → 목록 다섯 줄 중 한 줄만 떨어진다.

---

## 4. LLM 이 하는 판단 (2단계, 아직 미구현)

코드 규칙이 못 하는 것만 LLM 에 넘긴다. 입력은 **역할표 + 덩어리표 + 원본 썸네일 + 변환 근사 렌더**,
출력은 **plan.json(이동·크기·개행 연산 목록)** 이고 적용은 코드가 한다. LLM 이 좌표·색을 직접 쓰지 않는다.

| 판단 | 예 |
|---|---|
| 긴 제목을 두 줄로 개행 | "텍스트만 교체하면 되는" 리본이 폭에 꽉 차면 → 어디서 끊을지 |
| 덩어리 묶음이 틀렸을 때 다시 묶기 | 부제가 제목이 아니라 그림에 묶였다 |
| 장식을 어디로 옮길지 | 동전이 인물에 가려진다 → 비어 있는 모서리로 |
| 1080×1920 처럼 많이 길어질 때 무엇을 키우고 무엇을 채울지 | 사진을 더 열까, 제목을 키울까, 여백으로 둘까 |
| 합격/불합격 사전 판정 | 아래 5 의 눈 판정 항목을 LLM 에게 먼저 묻는다 |

프롬프트 뼈대(초안):

```
너는 미리캔버스 카드뉴스를 다른 비율로 옮기는 레이아웃 편집자다.
원본(1080×1080)과 규칙 변환본(1080×1350)의 역할표·덩어리표·그림을 준다.
원칙: 같은 덩어리는 같이 움직인다. 가운데 있던 것은 가운데에. 크기를 줄이지 않는다.
      여백이 있으면 페이지 비율에 맞게 키운다. 꾸밈 요소는 가려지거나 잘리지 않게 자리를 옮긴다.
      글자 내용·색·서체·반전·회전·요소 개수는 바꾸지 않는다.
할 수 있는 연산: move(id, dx, dy) · scale_block(ids, s) · wrap_text(id, 줄 수) · regroup(ids)
변환본에서 원칙에 어긋나는 곳만 골라 연산 목록(JSON)으로 답하라. 어긋난 곳이 없으면 빈 목록.
```

---

## 5. 검수 잣대 (합격 기준)

**기계(거부권, 한 건이라도 늘면 그 쪽은 진다)**: 겹침(글자 줄끼리) · 쪽밖(내용 요소) · 어절 개행 · 대비.
원본에도 있던 건은 세지 않는다 — **원본 대비 증가분**만 본다.

**눈 판정 체크리스트** (사용자 지적 12건에서 추린 것 — 쪽마다 ○/×):

1. 한 덩어리(제목+부제+리본, 원+아이콘+라벨)가 벌어지지 않았다
2. 글자가 원본보다 작아 보이지 않는다 (같은 폭으로 놓고 본다)
3. 가운데 있던 덩어리가 가운데에 있다
4. 꾸밈 요소(동전·캐릭터)가 가려지거나 잘리지 않았다
5. 인물·배경이 원본과 같은 느낌의 자리에 있다 (바닥에 선 것은 바닥에)
6. 제목·알약 안 글자의 정렬이 원본과 같다
7. 상하 분할 비율(2:1 등)이 원본의 느낌대로다
8. 투명도·외곽선·둥근 모서리·색·반전·회전이 그대로다
9. 원본에 없던 빈 공간이 어색하게 생기지 않았다 (원본 밀도)
10. 표·목록 같은 반복 구조의 간격이 고르다

**합격선(제안)**: 10항목 중 9 이상이면 합격, 덩어리(1)·가림(4)·불변(8) 중 하나라도 × 면 불합격.

---

## 6. 입력·출력·도구 (지금 있는 것)

```
pick_samples.py   표본 고르기 — 기계번역판은 translation_status='TRANSLATED' 로 뺀다
roles.py          역할 읽기
resize.py         규칙 변환 (r5) → {idx}-p{N}.1350.json + report.json(적용 규칙 로그)
diff_check.py     불변 검사
render.py         근사 렌더 + 거부권 + 갤러리(정답 썸네일 · 원본 근사 · 변환 근사, 같은 폭)
playground/       에디터 실렌더 확인용 PageData
```

근사 렌더의 남은 한계: 비공개 자산은 썸네일, 곡선 글자·게이지·차트는 자리표, 403 SVG 는 점선.
**합격 판정은 에디터 실렌더로 한다.** 근사 렌더는 걸러내는 용도.

---

## 7. 열린 질문

- 1080×1920 은 k=1.78 이라 "비례 배분" 만으로는 빈다 — 사진을 얼마나 더 열지, 제목을 얼마나 키울지 LLM 판단이 필요.
- 구형 XML 시트(카드뉴스의 91%)는 대상 밖. 같은 규칙을 XML 에 적용하려면 추출기부터.
- 글자 크기를 덩어리 배율로 키운 것이 에디터에서 상자 밖으로 넘치지 않는지(autoHeight 글상자) 실렌더 확인 필요.
