# task-305.1: 렌더러 피드백 v5 — 제이회장님 실전 리뷰 반영

## 개요
task-304.1 결과물에 대한 제이회장님의 상세 피드백을 반영.
**풀미팅 진행 후 구현.** 특히 FB-1(줄바꿈)은 로직 자체를 근본적으로 재설계해야 함.

## 참고 이미지
최신 테스트 결과:
- BlackRed: `/home/jay/projects/ThreadAuto/output/cardnews_20260306_125822_*.png`
- PurplePink: `/home/jay/projects/ThreadAuto/output/cardnews_20260306_125821_*.png`
- NavyGold: `/home/jay/projects/ThreadAuto/output/cardnews_20260306_125910_*.png`

## 피드백 항목 (8건)

### FB-1-v2. 줄바꿈 로직 근본 재설계 (가장 중요!)
- **현재 문제**: 단어 단위 줄바꿈은 됐지만, 오른쪽에 큰 여백을 남기고 불필요하게 많은 줄(4줄)로 만듦
- **제이회장님 지적**: "로직을 일단 써놓고 줄바꿈을 추가하는게 아니라, 단어 표현할 때 체크해서 줄바꿈 해놓고 이어서 작성하게 해야함"
- **핵심 원리**:
  - 단어를 하나씩 추가하면서, 현재 줄에 들어가는지 체크
  - 들어가면 현재 줄에 이어붙이고, 안 들어가면 줄바꿈 후 새 줄에서 시작
  - 이렇게 하면 각 줄이 max_width를 최대한 채우게 됨 (greedy line-filling)
  - 오른쪽 여백이 최소화되고, 줄 수도 최소화됨
- **구현**: `engine.py` `wrap_text()` 전면 재작성
  ```
  words = text.split()  # 공백 기준 분리
  current_line = ""
  lines = []
  for word in words:
      test = current_line + (" " if current_line else "") + word
      if font.getbbox(test)[2] <= max_width:
          current_line = test
      else:
          if current_line:
              lines.append(current_line)
          # 단어 자체가 max_width 초과면 글자 단위 분리
          if font.getbbox(word)[2] > max_width:
              # 글자 단위 폴백
          else:
              current_line = word
  if current_line:
      lines.append(current_line)
  ```
- **검증**: "설계사 커리어, 장기적으로 어떻게 그려야 할까요?" → 2~3줄로 빈틈없이 채워져야 함

### FB-3-v2. ㄴ 장식 완전 삭제
- **제이회장님 지시**: "아직 겹쳐보임. 그냥 ㄴ장식 삭제"
- **구현**: `_draw_corner_decoration()` 함수 호출부 전체 제거 또는 함수를 no-op으로 변경
- 모든 슬라이드에서 코너 ㄴ/ㄱ 장식 제거

### FB-4-v2. 동그라미 숫자 첫줄 align 재구현
- **제이회장님 지적**: "구현 제대로 안됨"
- **문제**: badge_cy가 여전히 제목 첫줄 세로 중앙에 정렬되지 않음
- **구현 방향**:
  - 블록 제목 렌더링 시, 첫 줄의 y좌표와 line_height를 정확히 계산
  - `badge_cy = first_line_y + first_line_height // 2`
  - card_list, detail, summary_cta 모든 슬라이드에서 동일 적용
  - **반드시** 실제 렌더링된 이미지로 시각적 확인 후 커밋

### FB-6-v2. detail 슬라이드(04번) description 들여쓰기
- **현재 문제**: card_list(03번)은 30px 들여쓰기가 적용됐는데, detail 슬라이드(04번)는 전체가 왼쪽으로 붙어있음
- **원인**: `_draw_info_box()` 또는 `render_detail()` 내부에서 description indent가 누락되었을 가능성
- **구현**: detail 슬라이드의 인포박스 내부에서도 description에 동일한 30px 들여쓰기 적용
  - label(제목) 위치: 기존 유지
  - value(설명) 위치: label_x + 30px

### FB-7-v2. 오버플로우 고도화
- **제이회장님 지적**: "더 고도화 필요"
- **강화 포인트**:
  - 전체 슬라이드에서 렌더링 전 총 필요 높이 사전 계산
  - 초과 시: 아이템 수 줄이기 → 설명 축약 → 최후 폰트 축소 순서로 대응
  - detail: 인포박스 수 동적 조절 (3개→2개) + TIP 조건부 표시
  - card_list: 아이템 설명이 길면 2줄 제한 + "..." 처리

### FB-8. CTA 슬라이드(05번) 종합 개선
- **문제 1**: 글박스 내부 동그라미 숫자가 첫 줄 글자와 세로 중간정렬 안됨
  - → FB-4-v2와 동일: CTA 슬라이드에서도 badge_cy를 첫줄 기준으로 정렬
- **문제 2**: 큰제목 2째줄 단어가 너무 적음
  - 현재: "절차가 두려워서 망설이고 / 계신다면 / 먼저 편하게 여쭤봐 주세요"
  - 제이회장님 예시: "(절차가 두려워서) / (망설이고 계신다면) / (먼저...주세요)"
  - → FB-1-v2의 greedy line-filling이 적용되면 자연스럽게 해결될 것. 확인 필요.
- **문제 3**: URL 변경
  - 현재: `snu-insurance-mentor.tistory.com`
  - 변경: `incar-top1.tistory.com`
  - **구현 위치**: `renderer/themes.py` 또는 `renderer/cardnews.py`의 CTA URL 상수
  - 또는 `content/prompts_v2.py`의 CTA 프롬프트에서 URL 참조가 있는지 확인
  - **두 곳 모두** 변경해야 할 수 있음 (콘텐츠 생성 시 + 렌더링 시)

### FB-유지. 변경 불필요 항목
- FB-2 (TIP 블록 로직): 괜찮음 → 유지
- FB-5 (subtitle 들여쓰기): OK → 유지

## 파일 범위
- `renderer/engine.py` — wrap_text() 전면 재작성 (FB-1-v2)
- `renderer/cardnews.py` — FB-3,4,6,7,8 전체
- `renderer/themes.py` — URL 상수 변경 가능
- `content/prompts_v2.py` — CTA URL 확인/변경

## 진행 방법
1. **풀미팅** (불칸/이리스/아테나/아르고스)
   - FB-1-v2 줄바꿈 greedy 알고리즘 설계 토론
   - FB-4-v2 정확한 badge_cy 수식 합의
   - 미팅 기록: `memory/meetings/2026-03-06-renderer-feedback-v5.md`
2. **구현**: 미팅 합의대로 코딩
3. **테스트**:
   - `/tmp/test_pipeline_v4.json` 콘텐츠로 5개 테마 렌더링
   - 줄바꿈 엣지: 긴 제목, 짧은 제목, 영문 포함 제목
   - 오버플로우 엣지: 인포박스 3개 + 긴 설명
   - CTA 슬라이드: badge align + URL 확인
4. **샘플 이미지**: `output/feedback_v5/` 하위 저장
5. **보고서**: `memory/reports/task-305.1.md`

## 완료 기준
- [ ] 줄바꿈이 각 줄을 최대한 채움 (오른쪽 큰 여백 없음)
- [ ] ㄴ/ㄱ 코너 장식 완전 제거
- [ ] 동그라미 숫자가 모든 슬라이드에서 첫줄 세로 중앙 정렬
- [ ] detail 슬라이드 description 30px 들여쓰기 적용
- [ ] CTA 내부 badge도 첫줄 정렬
- [ ] CTA URL: incar-top1.tistory.com
- [ ] 오버플로우 대응 강화 (사전 높이 계산)
- [ ] 5개 테마 정상 렌더링
- [ ] 기존 테스트 PASS

## task-timer
- task_id: task-305.1
- 완료 시: `python3 /home/jay/workspace/memory/task-timer.py end task-305.1`
