diff --git a/.mcp.json b/.mcp.json new file mode 100644 index 0000000..feef2d2 --- /dev/null +++ b/.mcp.json @@ -0,0 +1,15 @@ +{ + "mcpServers": { + "Framelink Figma MCP": { + "command": "cmd", + "args": [ + "/c", + "npx", + "-y", + "figma-developer-mcp", + "--figma-api-key=figd_R6ASvFG2IHcHs35_XFPJh0sTkvp4RxWyEhMhT9vv", + "--stdio" + ] + } + } +} diff --git a/CLAUDE.md b/CLAUDE.md index f2f0197..5ec4821 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,70 +2,175 @@ ## 프로젝트 목적 -텍스트 콘텐츠를 **1페이지 가로 슬라이드**로 시각 구조화하는 독립 에이전트. +텍스트/MDX 콘텐츠를 **가로 슬라이드(1페이지 또는 다중 페이지)**로 시각 구조화하는 독립 에이전트. 콘텐츠의 의미를 분석하여 적합한 레이아웃 블록을 선택하고, 핵심만 추출하여 깔끔한 HTML/CSS로 렌더링한다. -**핵심 원칙:** 전체 페이지를 하나의 고정 템플릿으로 찍어내는 것이 아니라, 콘텐츠를 분석 → 각 덩어리별로 적합한 레이아웃 블록 선택 → 조합하여 배치. +**핵심 원칙:** +- 전체 페이지를 하나의 고정 템플릿으로 찍어내는 것이 아니라, 콘텐츠를 분석 → 각 덩어리별로 적합한 레이아웃 블록 선택 → 조합하여 배치 +- 기획자(편집자)가 정리한 텍스트가 기준. **디자인이 텍스트에 맞춘다** (텍스트가 디자인에 맞추는 것이 아님) +- **모든 판단은 실장/팀장/편집자의 사고. 하드코딩 없음** --- -## 아키텍처 +## 아키텍처 (5단계 파이프라인) ``` -Kei (실장) — Kei Persona API 호출 - "이 콘텐츠는 비교+정의+관계도 구조다. 이렇게 배치해라." +[1단계] Kei 실장 (Sonnet) — AI 사고 + 꼭지 추출 → 레이어 수준 → 강조 판단 → 배치 방향 ↓ -디자인 팀장 (Sonnet) - "비교는 2단, 정의는 카드 3열, 관계도는 벤. 핵심만 남기고 나머지 버려." +[2단계] 디자인 팀장 (Sonnet) — AI 사고 + 블록 매핑 + 공간 배분 + 글자 수 가이드 → 편집자에게 전달 ↓ -실행자 (CSS Grid 렌더러) - "팀장이 정한 대로 CSS Grid로 조립." +[3단계] Kei 텍스트 편집자 (Sonnet) — AI 사고 + 글자 수 가이드 참고하되 내용 의미 우선. 도메인 용어 보존하며 편집 + ↓ +[4단계] 디자인 실무자 (Sonnet + Jinja2 + CSS) — AI + 코드 + 편집자가 정리한 텍스트에 맞게 디자인 조정 + HTML 조립 + ↓ +[5단계] 디자인 팀장 (Sonnet) — AI 사고 + 전체 균형 재검토 → 공간 재배분 → 2차 조정 지시 ``` ### 역할 분리 -| 역할 | 담당 | 하는 일 | 하지 않는 일 | -|------|------|---------|------------| -| Kei (실장) | Opus via Kei API | 콘텐츠 의미 분석, 유형 분류, 배치 방향 결정 | 디자인, CSS 작성 | -| 디자인 팀장 | Sonnet | 블록 타입 선택, 콘텐츠 선별(70% 버림), 슬롯 채우기, 세부 기준 수립 | 콘텐츠 의미 판단 | -| 실행자 | CSS Grid 렌더러 | 확정적 HTML/CSS 생성, 디자인 토큰 적용 | 판단, 선택 | +| 역할 | 담당 | 방식 | 하는 일 | 하지 않는 일 | +|------|------|------|---------|------------| +| Kei 실장 | Sonnet | AI | 꼭지 추출, 레이어 판단, 강조 판단, 배치 방향, 이미지/표/상세 판단 | 디자인, 텍스트 편집 | +| 디자인 팀장 | Sonnet | AI | catalog에서 블록 선택, 공간 배분, 겹침 방지, 글자 수 가이드, 전체 재검토 | 텍스트 정리, 콘텐츠 의미 판단 | +| 텍스트 편집자 | Sonnet | AI | 도메인 용어 보존하며 편집, 출처 보존, 표 내용 편집 | 레이아웃 결정, 디자인 판단 | +| 디자인 실무자 | Sonnet + 코드 | AI + 코드 | 텍스트에 맞게 디자인 조정, HTML/CSS 조립, 이미지 크기 조정, 표 스케일링 | 콘텐츠 의미 판단 | --- ## 핵심 프로세스 ``` -사용자 콘텐츠 입력 (텍스트 붙여넣기 또는 파일 업로드) +사용자 콘텐츠 입력 (텍스트/MDX 붙여넣기 또는 파일 업로드) ↓ -[1단계] Kei 실장(Opus) — 콘텐츠 유형 분류 - → "이건 비교(A vs B) + 정의(3개 용어) + 관계도(상위/하위)" - → 적합한 블록 조합 결정 +[1단계] Kei 실장 — 꼭지 추출 + 분석 + + 꼭지 추출: + - 본문에서 핵심 꼭지 추출 (2~5개) + - 1페이지 적정 꼭지 수: 5개 + + 페이지 분리 판단: + - 중요도가 5개를 넘고 레이어도 동등하면 → 2페이지로 분리 + - 내용과 의미 기반으로 자연스러운 분할 (2/3, 3/4, 4/3, 5/2 등) + - 5개인데 내용이 많으면 → 꼭지 레이어를 보고 세부 내용은 자세히보기로 + + 각 꼭지 분석: + - 레이어 수준 (도입/핵심/보조/결론) + - 강조 판단 (어떤 꼭지를 눈에 띄게 할 것인가) + - 배치 방향 (세로로 긴 꼭지, 가로 나열 꼭지) + + 이미지 판단: + - 몇 개인지, 어떤 꼭지에 속하는지 + - 핵심인지(도표/차트) 보조인지(참고 문서 표지) + - 텍스트가 포함된 이미지인지 (너무 축소하면 안 됨) + + 표 판단: + - 행/열 규모 + - 전체 표시 가능한지, 요약 필요한지 + + 상세 콘텐츠 판단: + - 너무 구체적/세부적인 내용은 "자세히보기" 대상 ↓ -[2단계] 디자인 팀장(Sonnet) — 레이아웃 컨셉만 - → "이 파트는 카드로, 이건 비교로, 2페이지 필요" - → 블록 배치 + 페이지 수 + 슬롯 목록 (텍스트는 채우지 않음) +[2단계] 디자인 팀장 — 레이아웃 설계 + + 블록 매핑: + - catalog 메뉴판에서 각 꼭지에 적합한 블록 선택 + - 꼭지의 성격을 보고 판단 (출처 있으면 example-card, 정의면 card-grid 등) + + 이미지 배치: + - 원본 이미지 크기 확인 (Pillow Image.open().size) + - 가로/세로 비율에 따라 영역 결정 + (가로형이면 전체 너비, 세로형이면 텍스트 옆) + - 텍스트 포함 도표는 너무 작게 하면 안 됨 + - 이미지는 원본 그대로 사용, 크기만 조절 + + 표 배치: + - 행×열 규모 보고 공간 안에 들어가는지 판단 + - 안 들어가면 실장에게 요약 요청 또는 2페이지 분리 + + 자세히보기 설계: + - 상세 콘텐츠는
/ 영역으로 설계 + + 공간 배분: + - 전체 공간에서 영역별 비율 결정 + - 꼭지끼리 겹치지 않도록 grid-template 설계 + - 각 블록의 대략적 글자 수 가이드 + + 페이지 판단: + - 안 들어가면 2페이지로 분리 ↓ -[3단계] 텍스트 편집자(Sonnet, Kei 역할) — 슬롯 텍스트 정리 - → 도메인 전문가로서 원본 핵심을 유지하며 각 슬롯 분량에 맞게 편집 - → 과도한 요약 금지, 출처 보존, 개조식 작성 +[3단계] Kei 텍스트 편집자 — 텍스트 정리 + + - 팀장의 글자 수 가이드 참고하되, 내용 의미가 우선 + - 전체 컨텍스트와 핵심 용어 유지 + - 도메인 전문가로서 세련된 표현으로 편집 + - 출처 보존, 개조식 작성, 날조 금지 + - 결과 글자 수가 가이드와 다를 수 있음 (의미 > 글자 수) + - 표 내용도 편집 (핵심 행/열 선택, 요약 등) + - 자세히보기 대상은 요약 버전 + 상세 버전 둘 다 작성 ↓ -[4단계] 실행자(CSS Grid) — 확정적 HTML 생성 - → 블록 타입에 맞는 CSS 템플릿 적용 - → 디자인 토큰 (색상, 여백, 폰트 크기) 적용 - → 다중 페이지 시 page-break 처리 +[4단계] 디자인 실무자 — 디자인 조정 + HTML 조립 + + 텍스트 맞춤: + - 편집자가 정리한 텍스트 양에 맞게 디자인 조정 + - 텍스트가 가이드보다 길면 → 폰트/여백/박스를 조정 (텍스트를 자르지 않음) + - 빈 공간 방치 안 함 (박스 줄이거나 공간 활용) + + 이미지 처리: + - object-fit: contain (비율 유지, 잘리지 않게) + - 팀장이 정한 영역 크기에 맞춤 + + 표 처리: + - table-layout: fixed + container query 폰트 스케일링 + - 행/열 수에 따라 셀 크기 자동 조정 + + 자세히보기: + -
/로 접기/펼치기 + - 인쇄 시 자동 펼침 (JavaScript) + + HTML 조립: + - Jinja2 템플릿 렌더링 + - 다중 페이지 시 page-break 처리 ↓ -미리보기 → 사용자 확인 → HTML 다운로드 +[5단계] 디자인 팀장 — 전체 재검토 + + 균형 점검: + - 1차 조립 결과의 전체 균형 확인 + - 블록별 채움 비율 (텍스트 양 vs 공간) + - 블록 간 균형 (한쪽만 빽빽하고 다른 쪽 비어있지 않은지) + + 이미지/표 점검: + - 이미지 크기가 적절한지 (너무 작아서 안 보이지 않는지) + - 표가 읽을 수 있는 크기인지 + + 조정: + - 필요 시 공간 재배분 → 실무자에게 2차 조정 지시 + - 좌우 불균형, 어색한 빈 공간 해소 + - 최종 HTML 출력 + ↓ +미리보기 → HTML 다운로드 ``` -**핵심 원칙:** 디자인 팀장은 레이아웃만 결정하고 콘텐츠를 건드리지 않는다. 텍스트 정리는 도메인 지식이 있는 Kei 역할(텍스트 편집자)이 한다. -``` +**핵심 원칙:** +- 디자인 팀장은 레이아웃 + 공간 배분. 텍스트를 건드리지 않는다. +- 텍스트 편집자가 정리한 텍스트가 기준. 디자인이 텍스트에 맞춘다. +- 실무자는 텍스트를 자르지 않고, 디자인을 조정한다. +- 이미지는 원본 그대로 사용, 크기만 조절. +- 표는 표로 유지, 공간 안 되면 요약하거나 페이지 분리. +- 상세 내용은 `
`로 접기/펼치기. +- 1차 조립 후 팀장이 전체 균형을 재검토하여 2차 조정. +- **모든 기준은 하드코딩 없이 실장/팀장/편집자의 사고로 판단.** --- ## 콘텐츠 유형 분류 기준 -Opus가 콘텐츠를 분석하여 아래 유형으로 분류한다. -**이 분류는 하드코딩이 아니라, Opus가 매번 사고하여 판단한다.** +실장이 콘텐츠를 분석하여 아래 유형으로 분류한다. +**이 분류는 하드코딩이 아니라, 실장이 매번 사고하여 판단한다.** | 텍스트 패턴 | 유형 | 적합한 블록 | |------------|------|-----------| @@ -78,6 +183,9 @@ Opus가 콘텐츠를 분석하여 아래 유형으로 분류한다. | 연도별 사건, 로드맵 | 시간 순서 | 타임라인 (가로/세로) | | 핵심 메시지, 결론 | 강조 | 결론 바 / 인용 블록 | | 문제 상황, 경고 | 문제 제기 | 경고 박스 / 강조 인용 | +| 이미지 + 텍스트 | 이미지 참조 | 전체너비 / 사이드 / 썸네일 | +| 다항목 데이터 | 표 | 비교 테이블 | +| 세부/구체적 내용 | 자세히보기 | `
/` | --- @@ -130,10 +238,39 @@ Opus가 콘텐츠를 분석하여 아래 유형으로 분류한다. - 슬롯: 행/열 헤더, 셀 내용 - 용도: 다차원 비교, 기능 매트릭스 -### 10. 이미지 참조 (image-ref) -- 이미지 썸네일 + 캡션 -- 슬롯: 이미지 경로, 캡션 텍스트 -- 용도: 근거 자료, 문서 참조, 사진 +### 10. 이미지 블록 (image-block) +- 이미지 + 캡션 +- 3가지 변형: 전체너비(image-full), 텍스트옆(image-side), 썸네일(image-thumb) +- 슬롯: 이미지 경로, 캡션 텍스트, 이미지 크기 정보 +- 용도: 도표, 다이어그램, 근거 자료, 문서 참조 +- CSS: object-fit: contain (비율 유지, 잘리지 않음) + +--- + +## 이미지 처리 원칙 + +- 원본 이미지를 **그대로 사용** (crop/재구성은 극히 예외) +- 팀장이 슬라이드 구조에 맞게 **크기만 조절** (가로/세로 비율 유지) +- 이미지 크기 읽기: Pillow `Image.open().size` (헤더만 읽음, 전체 로드 안 함) +- 가로형(ratio > 1.2) → 전체 너비 배치 +- 세로형(ratio < 0.8) → 텍스트 옆 배치 +- 텍스트 포함 도표 → 너무 작게 축소하면 안 됨 +- CSS: `object-fit: contain` (전체 보이게, 비율 유지) + +## 표 처리 원칙 + +- 표는 **표로 유지** (다른 형태로 전환하지 않음) +- 공간에 안 들어가면: 요약하거나 페이지 분리 +- CSS: `table-layout: fixed` + container query 폰트 스케일링 +- 표 내용 편집은 Kei 텍스트 편집자가 담당 + +## 자세히보기 (상세 콘텐츠) 원칙 + +- HTML 네이티브 `
/` 사용 (JavaScript 불필요) +- 슬라이드 표면: 요약/핵심만 표시 +- 펼치면: 전체 상세 내용 표시 +- 인쇄 시: JavaScript 6줄로 자동 펼침 +- 정보 밀도는 실장/팀장이 사고로 판단 (하드코딩 기준 없음) --- @@ -141,19 +278,25 @@ Opus가 콘텐츠를 분석하여 아래 유형으로 분류한다. ### 레이아웃 배치 규칙 - CSS Grid 기반 (`grid-template-areas`) -- 가로 슬라이드 비율: 16:9 (1280×720 또는 1920×1080) -- 최대 블록 수: 1페이지에 4~6개 +- 가로 슬라이드 비율: 16:9 (1280×720) +- 1페이지 적정 꼭지 수: 5개 - 정보 계층: 위 → 아래 (문제 제기 → 분석 → 결론) - 여백: 블록 간 최소 20px, 페이지 패딩 40px +### 페이지 분리 기준 +- 꼭지 5개 이하 + 내용 적절 → 1페이지 +- 꼭지 5개 + 내용 많음 → 1페이지 + 일부 자세히보기 +- 꼭지 5개 초과 + 레이어 동등 → 2페이지 (의미 기반 분할) +- 분할 비율: 2/3, 3/4, 4/3, 5/2 등 내용에 따라 + ### 블록 조합 예시 ``` ┌─────────────────────────────────────────────┐ │ [강조 인용] 문제 제기 │ ├──────────────────┬──────────────────────────┤ -│ [비교] │ [카드 그리드] │ -│ 2단 비교 │ 정의 3열 │ +│ [사례 카드 2열] │ [카드 그리드 3열] │ +│ 정책 사례 │ 용어 정의 │ ├──────────────────┴──────────────────────────┤ │ [관계도] 벤 다이어그램 │ ├─────────────────────────────────────────────┤ @@ -163,6 +306,29 @@ Opus가 콘텐츠를 분석하여 아래 유형으로 분류한다. --- +## 글자 수 추정 (타이포그래피 기반) + +한글은 글자 너비가 거의 일정하므로, 블록 크기에서 글자 수를 계산할 수 있다. +**이 계산은 팀장의 글자 수 가이드를 보조하는 참고 도구이지, 하드코딩 기준이 아니다.** + +``` +계산식: + 한 줄 글자 수 = 블록 너비(px) ÷ (폰트 크기(px) × 0.97) + 줄 수 = 블록 높이(px) ÷ (폰트 크기(px) × 줄간격) + 총 글자 수 = 한 줄 글자 수 × 줄 수 × 안전 계수(0.85) +``` + +Pretendard 폰트 크기별 참고값 (1회 측정, 상수 저장): + +| 폰트 크기 | 한글 글자 너비 | 줄간격 1.6 기준 줄 높이 | +|----------|-------------|---------------------| +| 12px | ~11.6px | 19.2px | +| 16px | ~15.5px | 25.6px | +| 20px | ~19.4px | 32.0px | +| 24px | ~23.3px | 38.4px | + +--- + ## 디자인 원칙 (절대 규칙) ### DO (해야 하는 것) @@ -171,16 +337,15 @@ Opus가 콘텐츠를 분석하여 아래 유형으로 분류한다. - 폰트 크기 체계를 일관되게 유지 (제목/소제목/본문/캡션 4단계) - 흑백 기조 + 포인트 컬러 최소 사용 - 정보 계층을 시각적으로 명확히 표현 -- 한 슬라이드에 메시지는 1개 ### DON'T (하지 않는 것) - 그라데이션 배경 금지 - CSS 애니메이션/트랜지션 금지 - 호버 효과 금지 - 그림자(box-shadow) 최소화 (1개 레벨만) -- 원본 콘텐츠를 전부 넣으려 하지 않는다 (70% 버려라) - 다크 테마 금지 (요청하지 않는 한) - 둥근 모서리 과다 사용 금지 (border-radius 최대 8px) +- 텍스트를 자르지 않는다 (디자인이 텍스트에 맞춘다) --- @@ -189,98 +354,84 @@ Opus가 콘텐츠를 분석하여 아래 유형으로 분류한다. ```css :root { /* 색상 */ - --color-primary: #1e293b; /* 메인 (짙은 남색) */ - --color-accent: #2563eb; /* 포인트 (파랑) */ - --color-neutral: #64748b; /* 중성 (회색) */ - --color-bg: #ffffff; /* 배경 */ - --color-bg-subtle: #f8fafc; /* 보조 배경 */ - --color-border: #e2e8f0; /* 테두리 */ - --color-danger: #dc2626; /* 경고/문제 */ + --color-primary: #1e293b; + --color-accent: #2563eb; + --color-neutral: #64748b; + --color-bg: #ffffff; + --color-bg-subtle: #f8fafc; + --color-border: #e2e8f0; + --color-danger: #dc2626; /* 폰트 크기 */ - --font-title: 2rem; /* 슬라이드 제목 */ - --font-subtitle: 1.25rem; /* 섹션 제목 */ - --font-body: 0.95rem; /* 본문 */ - --font-caption: 0.8rem; /* 캡션/출처 */ + --font-title: 2rem; + --font-subtitle: 1.25rem; + --font-body: 0.95rem; + --font-caption: 0.8rem; /* 여백 */ - --spacing-page: 40px; /* 페이지 패딩 */ - --spacing-block: 20px; /* 블록 간 간격 */ - --spacing-inner: 16px; /* 블록 내부 패딩 */ + --spacing-page: 40px; + --spacing-block: 20px; + --spacing-inner: 16px; /* 기타 */ - --radius: 6px; /* 둥근 모서리 */ - --border-width: 1px; /* 테두리 두께 */ - --accent-border: 3px; /* 강조 테두리 */ + --radius: 6px; + --border-width: 1px; + --accent-border: 3px; } ``` --- -## 교본 (레퍼런스) 관리 - -### 저장 위치 -``` -D:\ad-hoc\kei\design_agent\ -├── CLAUDE.md ← 이 파일 -├── templates/ ← 블록별 HTML/CSS 교본 -│ ├── comparison.html ← 비교 블록 교본 -│ ├── card-grid.html ← 카드 그리드 교본 -│ ├── relationship.html ← 관계도 교본 -│ ├── process.html ← 프로세스 교본 -│ ├── timeline.html ← 타임라인 교본 -│ ├── big-number.html ← 핵심 지표 교본 -│ ├── quote-block.html ← 강조 인용 교본 -│ ├── conclusion-bar.html ← 결론 바 교본 -│ ├── comparison-table.html ← 비교 테이블 교본 -│ └── image-ref.html ← 이미지 참조 교본 -├── samples/ ← 완성 슬라이드 샘플 (레퍼런스 이미지 + HTML) -├── design-tokens.css ← 공통 디자인 토큰 -└── docs/ ← 조사 자료, 기술 문서 -``` - -### 교본 추가 방법 -1. 좋은 디자인 샘플을 찾는다 (CodePen, 직접 제작 등) -2. HTML/CSS 코드를 `templates/` 폴더에 저장한다 -3. 슬롯 위치를 `{{SLOT_NAME}}` 형식으로 표시한다 -4. CLAUDE.md의 블록 타입 정의에 참조를 추가한다 - -### 교본 품질 기준 -- 디자인 원칙(DO/DON'T)을 준수하는가 -- 슬롯이 명확하게 분리되어 있는가 -- 디자인 토큰을 사용하는가 (하드코딩 색상 아닌 CSS 변수) -- 1페이지 안에 들어가는 크기인가 - ---- - ## Kei API 연동 -### 연동 방식 -- Design Agent는 Kei Persona 서버(`localhost:8000`)의 API를 호출하여 콘텐츠 분석을 요청한다 -- Kei 서버가 떠있어야 Design Agent가 동작한다 -- 향후 글벗에 붙일 때도 같은 API 호출 방식 - ### 호출 포인트 | 단계 | API | 용도 | |------|-----|------| -| 1단계 콘텐츠 분류 | Kei API (Opus) | 콘텐츠 유형 판단 + 배치 방향 | -| 2단계 콘텐츠 선별 | Kei API (Sonnet) | 핵심 추출 + 슬롯 채우기 | -| 3단계 렌더링 | 로컬 (CSS Grid) | HTML 생성 (API 불필요) | +| 1단계 꼭지 추출 | Anthropic API (Sonnet) | 꼭지 추출 + 레이어 + 강조 + 배치 + 이미지/표/상세 판단 | +| 2단계 레이아웃 설계 | Anthropic API (Sonnet) | 블록 매핑 + 공간 배분 + 글자 수 가이드 | +| 3단계 텍스트 정리 | Anthropic API (Sonnet) | 의미 보존 편집 + 표 편집 + 자세히보기 작성 | +| 4단계 디자인 조정 + 조립 | Anthropic API (Sonnet) + Jinja2/CSS | 텍스트에 맞게 디자인 조정 + HTML 생성 | +| 5단계 재검토 | Anthropic API (Sonnet) | 균형 점검 + 2차 조정 | ### 독립 실행 가능 -- Kei API 없이도 2-3단계만으로 동작 가능 (사용자가 직접 유형 선택) -- Kei API 연결 시 1단계 자동화 +- Kei API 없이 Anthropic API 직접 호출로 동작 +- Kei API 연결 시 1단계에서 Kei RAG 지식 활용 가능 --- -## 기술 스택 (예정) +## 교본 (레퍼런스) 관리 + +### catalog.yaml +- 디자인 팀장의 "메뉴판" +- 각 블록의 id, 시각 설명, 언제 쓰는지(when), 슬롯 목록 +- Figma에서 디자인 추출 → 템플릿 변환 → catalog에 등록 +- **Figma 작업 완료 후 연동 예정** + +### 저장 위치 +``` +design_agent/ +├── templates/ +│ ├── catalog.yaml ← AI용 블록 메뉴판 (Figma 작업 후) +│ ├── slide-base.html ← 슬라이드 베이스 +│ └── blocks/ ← 블록 템플릿 +├── samples/ ← 완성 슬라이드 샘플 +└── docs/ ← 조사 자료 +``` + +--- + +## 기술 스택 | 역할 | 도구 | 비고 | |------|------|------| -| 프론트엔드 | React + Vite | Kei와 동일 스택 | -| 렌더링 | CSS Grid + 디자인 토큰 | 순수 CSS, 프레임워크 없음 | -| AI 콘텐츠 분석 | Kei API (Opus + Sonnet) | localhost:8000 | -| 출력 | HTML 다운로드 | PDF 불필요 | +| 서버 | FastAPI + uvicorn | 포트 8001 | +| 템플릿 | Jinja2 | 블록 조합 | +| 렌더링 | CSS Grid + 디자인 토큰 | 16:9 고정 | +| 폰트 | Pretendard Variable | word-break: keep-all | +| AI | Anthropic API (Sonnet) | 5단계 모두 | +| 이미지 크기 | Pillow Image.open().size | 헤더만 읽음 | +| 자세히보기 | `
/` | HTML 내장 | +| 출력 | HTML 다운로드 | | --- @@ -295,27 +446,13 @@ D:\ad-hoc\kei\design_agent\ C) 둘 다 ``` -독립적으로 만들어두면 어디에 붙이든 API 호출만 하면 된다. - ---- - -## 업계 근거 - -- **SlideSpeak**: 16개 레이아웃 타입 + 슬롯 기반 매핑 (가장 실용적 아키텍처) -- **Beautiful.ai**: 300개 템플릿 + 규칙 기반 자동 레이아웃 조정 -- **Napkin AI**: NLP로 텍스트 패턴 → 시각화 유형 자동 매핑 -- **PPTAgent (EMNLP 2025)**: 레퍼런스 슬라이드 클러스터링 → 유형별 패턴 추출 → 편집 방식 생성 -- **InfoDesignLM (ICDAR 2025)**: 텍스트만으로 인포그래픽 레이아웃 생성, GPT-4o 능가 -- **Microsoft LIDA**: 4단계 파이프라인 (요약 → 목표 → 시각화 → 스타일링) -- **Dr. Andrew Abela Chart Chooser**: 콘텐츠 유형 → 시각화 유형 결정 트리 - --- ## 금지 사항 1. Kei Persona Agent 코드를 수정하지 않는다 -2. 디자인 판단을 하드코딩하지 않는다 (Opus/Sonnet이 사고한다) +2. 디자인 판단을 하드코딩하지 않는다 (AI가 사고한다) 3. 전체 페이지를 하나의 고정 템플릿으로 만들지 않는다 (블록 조합 방식) -4. 콘텐츠를 전부 넣으려 하지 않는다 (핵심만 추출) -5. 그라데이션, 애니메이션, 다크 테마를 기본으로 사용하지 않는다 -6. 교본 없이 자유 디자인을 하지 않는다 (교본 참조 필수) +4. 텍스트를 자르지 않는다 (디자인이 텍스트에 맞춘다) +5. 이미지를 crop하지 않는다 (크기만 조절) +6. 그라데이션, 애니메이션, 다크 테마를 기본으로 사용하지 않는다 diff --git a/PLAN.md b/PLAN.md index 71814e3..0988222 100644 --- a/PLAN.md +++ b/PLAN.md @@ -77,35 +77,57 @@ ## Phase 3: AI 파이프라인 연결 -### DA-12: Kei API 연동 — 콘텐츠 분류 (Opus) +### DA-12: 1단계 — Kei 실장 (꼭지 추출 + 분석) - **파일:** src/kei_client.py -- **내용:** Kei API (`localhost:8000/api/message`)에 콘텐츠 전송 → Opus 분류 결과 수신. Kei API 미연결 시 수동 분류 fallback +- **내용:** 본문에서 핵심 꼭지 추출 + 다단계 분석 + - 꼭지 추출: 본문에서 2~5개 핵심 파트 식별 (1페이지 적정: 5개) + - 페이지 분리: 5개 초과 + 레이어 동등 → 2페이지 (의미 기반 분할 2/3, 3/4 등) + - 5개 + 내용 많음 → 세부 내용은 자세히보기 대상 + - 레이어 수준: 각 꼭지가 도입/핵심/보조/결론 중 어디인지 + - 강조 판단: 어떤 꼭지를 시각적으로 눈에 띄게 할 것인가 + - 배치 방향: 세로로 긴 꼭지, 가로로 나열할 꼭지 판단 + - 이미지 판단: 몇 개, 어떤 꼭지 소속, 핵심/보조, 텍스트 포함 여부 + - 표 판단: 행/열 규모, 전체 표시 가능 여부 + - 상세 콘텐츠 판단: 자세히보기 대상 식별 +- **기술:** Anthropic API (Sonnet) - **의존성:** DA-2 -- **완료 기준:** 테스트 콘텐츠 전송 → 유형 분류 JSON 반환 +- **완료 기준:** 꼭지 목록 + 레이어 + 강조 + 배치 + 이미지/표/상세 판단 JSON -### DA-13: 디자인 팀장 — 레이아웃 컨셉 (Sonnet) +### DA-13: 2단계 — 디자인 팀장 (레이아웃 설계) - **파일:** src/design_director.py -- **내용:** Anthropic API 직접 호출. Opus 분류 결과 + 원본 콘텐츠 → 레이아웃 컨셉만 결정. 텍스트 정리 안 함. -- **출력:** 블록 배치 + 페이지 수 + 슬롯 목록 (텍스트 없이 구조만) -- **기술:** Anthropic API (Sonnet), JSON 반환 +- **내용:** 블록 매핑 + 공간 배분 + 글자 수 가이드 + - 블록 매핑: catalog 메뉴판에서 각 꼭지 성격에 맞는 블록 선택 + - 이미지 배치: Pillow로 원본 크기 확인 → 가로/세로에 따라 영역 결정 (크기만 조절, crop 안 함) + - 표 배치: 행×열 규모 보고 공간 판단 (안 되면 요약 요청 또는 페이지 분리) + - 자세히보기: 상세 콘텐츠는 `
` 영역으로 설계 + - 공간 배분: 영역별 비율, 겹침 방지 + - 글자 수 가이드: 각 블록 공간에 맞는 대략적 글자 수 (하드코딩 아닌 판단) + - 페이지 판단: 안 들어가면 2페이지 분리 +- **기술:** Anthropic API (Sonnet) + Pillow (이미지 크기) - **의존성:** DA-12 -- **완료 기준:** "이 파트는 카드로, 이건 비교로, 2페이지 필요" 수준의 컨셉 JSON 반환 +- **완료 기준:** 블록 배치 + 이미지/표 배치 + 글자 수 가이드 JSON -### DA-13b: 텍스트 편집자 — 슬롯 텍스트 정리 (Kei 역할) -- **파일:** src/content_editor.py (신규) -- **내용:** Anthropic API 직접 호출. 디자인 팀장의 레이아웃 컨셉 + 원본 콘텐츠 → 각 슬롯에 맞는 텍스트 편집. 도메인 지식 보존, 핵심 유지. -- **역할:** 도메인 전문가로서 콘텐츠를 정리하는 편집자 (Kei persona 규칙 일부 적용) -- **규칙:** 핵심 내용 유지, 개조식, 출처 보존, 슬롯 분량 준수, 내용 날조 금지 -- **기술:** Anthropic API (Sonnet), JSON 반환 +### DA-13b: 3단계 — Kei 텍스트 편집자 (텍스트 정리) +- **파일:** src/content_editor.py +- **내용:** 팀장의 글자 수 가이드 참고하되 내용 의미 우선 + - 전체 컨텍스트와 핵심 용어 유지 + - 세련된 표현으로 편집 (의미 > 글자 수) + - 출처 보존, 개조식, 날조 금지 + - 표 내용 편집 (핵심 행/열 선택, 요약) + - 자세히보기 대상: 요약 버전 + 상세 버전 둘 다 작성 +- **기술:** Anthropic API (Sonnet) - **의존성:** DA-13 -- **완료 기준:** 슬롯별 텍스트가 채워진 JSON 반환. 원본 핵심 내용 보존 확인. +- **완료 기준:** 슬롯별 텍스트 JSON. 핵심 용어 보존. 자세히보기 포함. -### DA-14: 전체 파이프라인 연결 (3단계) -- **파일:** src/pipeline.py -- **내용:** 콘텐츠 입력 → Opus 분류 → 디자인 팀장 컨셉 → 텍스트 편집자 정리 → 렌더러 조립 → HTML 출력 -- **기술:** 순차 호출, 다중 페이지 지원 +### DA-14: 4단계 — 디자인 실무자 (디자인 조정 + HTML 조립) + 5단계 재검토 +- **파일:** src/pipeline.py, src/renderer.py +- **내용:** + - 4단계 (AI + 코드): 편집자 텍스트에 맞게 디자인 조정 (폰트/여백/박스 — 텍스트 자르지 않음) + + Jinja2 HTML 조립, 이미지 object-fit:contain, 표 container query, `
` 접기, 인쇄 펼침 JS + - 5단계 (AI): 팀장이 전체 균형 재검토 → 채움 비율, 블록 균형, 이미지/표 크기 점검 → 2차 조정 +- **기술:** Anthropic API Sonnet (디자인 조정 + 재검토) + Jinja2/CSS (조립) - **의존성:** DA-11, DA-12, DA-13, DA-13b -- **완료 기준:** 텍스트 입력 → 완성 슬라이드 HTML 출력 (엔드투엔드, 다중 페이지 포함) +- **완료 기준:** 텍스트 입력 → 균형 잡힌 슬라이드 HTML (이미지/표/자세히보기 포함, 재검토 완료) --- @@ -148,13 +170,14 @@ ## 의존 관계 ``` -DA-1 → DA-2 → DA-12 → DA-13 ─┐ - ├→ DA-14 → DA-15 → DA-16 -DA-3 → DA-4~DA-10 → DA-11 ────┘ +DA-1 → DA-2 → DA-12(실장) → DA-13(팀장) → DA-13b(편집자) ─┐ + ├→ DA-14(조립+재검토) → DA-15 → DA-16 +DA-3 → DA-4~DA-10 → DA-11(렌더러) ─────────────────────────┘ ``` -Phase 1(DA-1~3)과 Phase 2(DA-4~11)는 AI 없이 진행 가능. -Phase 3(DA-12~14)부터 Kei API + Anthropic API 필요. +- Phase 1~2: AI 없이 진행 가능 +- Phase 3: Anthropic API 필요 (5단계 파이프라인) +- 5단계 흐름: 실장 → 팀장 → 편집자 → 조립 → 재검토 --- diff --git a/PROGRESS.md b/PROGRESS.md index e7515f1..e4c90cd 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -37,10 +37,10 @@ | 태스크 | 상태 | 담당 | 시작 | 완료 | 메모 | |--------|------|------|------|------|------| -| DA-12: Kei API 연동 (Opus) | done | - | - | - | DA-2 이후 | -| DA-13: 디자인 팀장 — 레이아웃 컨셉만 | todo | - | - | - | 기존에서 텍스트 정리 제거. 컨셉만 반환 | -| DA-13b: 텍스트 편집자 (Kei 역할) | todo | - | - | - | 신규. 도메인 전문가로 슬롯 텍스트 정리 | -| DA-14: 전체 파이프라인 (3단계) | todo | - | - | - | 분류→컨셉→텍스트→렌더링. 다중 페이지 | +| DA-12: 1단계 Kei 실장 (꼭지 추출+분석) | todo | - | - | - | 2~5개 꼭지 + 레이어 + 강조 + 이미지/표/상세 판단. 페이지 분리 | +| DA-13: 2단계 디자인 팀장 (레이아웃 설계) | todo | - | - | - | 블록 매핑 + 이미지/표 배치 + 공간 배분 + 글자 수 가이드 | +| DA-13b: 3단계 텍스트 편집자 (Kei 역할) | todo | - | - | - | 의미 우선 편집 + 표 편집 + 자세히보기(요약+상세) | +| DA-14: 4단계 실무자(AI+코드) + 5단계 재검토 | todo | - | - | - | 디자인 조정 + HTML 조립 + 팀장 균형 재검토 | ## Phase 4: UI + 출력 diff --git a/docs/FIGMA-COMPONENT-EXTRACTION-PLAN.md b/docs/FIGMA-COMPONENT-EXTRACTION-PLAN.md index 3e3c477..d5d1050 100644 --- a/docs/FIGMA-COMPONENT-EXTRACTION-PLAN.md +++ b/docs/FIGMA-COMPONENT-EXTRACTION-PLAN.md @@ -2,7 +2,20 @@ ## 목적 -Figma 디자인(바론컨설턴트 홈페이지 기획팀 공유)에서 재사용 가능한 슬라이드 콘텐츠 블록을 추출하고, 디자인 팀장(Sonnet)이 선택할 수 있는 카탈로그로 체계화한다. +Figma 디자인(바론컨설턴트 홈페이지 기획팀 공유)에서 재사용 가능한 **콘텐츠 블록**을 추출하고, 디자인 팀장(Sonnet)이 선택할 수 있는 카탈로그로 체계화한다. + +**핵심 원칙: 블록은 모드 독립적이다.** +- 블록 자체는 "슬라이드 전용"이 아니라 **HTML/CSS 콘텐츠 블록** +- 슬라이드 모드(100vh, overflow:hidden)와 웹/스크롤 모드(auto, overflow:visible)는 **컨테이너(base 템플릿)**가 결정 +- 블록은 높이를 고정하지 않음 → 어떤 컨테이너에도 들어갈 수 있음 +- 현재는 `slide-base.html`(슬라이드)에 집중하되, 향후 `page-base.html`(웹) 추가 가능 + +``` +블록 (카드, 표, 인용 등) — 모드와 무관, 재사용 가능 + ↓ +slide-base.html → height:100vh, overflow:hidden (슬라이드 모드) +page-base.html → height:auto, overflow:visible (웹/스크롤 모드, 향후) +``` --- @@ -57,6 +70,8 @@ Figma 디자인(바론컨설턴트 홈페이지 기획팀 공유)에서 재사 | **아이콘 리스트** | ❌ | ✅ (아이콘+제목+설명) | **신규** | | **Hero 섹션** | ❌ | ✅ (배경+원형이미지+텍스트) | **신규** | | **CTA 버튼 바** | ❌ | ✅ (자세히보기 버튼) | **필요 시** | +| **이미지 블록** | ❌ | ✅ (도표, 참고자료) | **신규** (3변형: full/side/thumb) | +| **자세히보기 블록** | ❌ | ✅ (상세 콘텐츠 접기/펼치기) | **신규** (`
/`) | --- @@ -66,19 +81,41 @@ Figma 디자인(바론컨설턴트 홈페이지 기획팀 공유)에서 재사 #### A-1: Figma 전체 섹션 이미지 렌더링 - **작업:** 각 섹션/프레임을 이미지로 렌더링하여 시각적으로 패턴 식별 -- **방법:** Figma API `/v1/images/{file_key}?ids={node_ids}` +- **방법:** + - **1차:** Framelink MCP `get_figma_data` — CSS-ready 데이터로 노드 구조 + 스타일 동시 추출 + - **2차:** Figma 공식 MCP `get_screenshot` — 시각 참고용 스크린샷 + - **fallback:** Figma REST API `/v1/images/{file_key}?ids={node_ids}` (MCP 미설치 시) - **산출물:** `docs/figma-screenshots/` 폴더에 PNG 저장 - **완료 기준:** 모든 자세히보기 프레임(8개)의 스크린샷 확보 #### A-2: Figma 노드 구조 심층 분석 -- **작업:** 각 프레임의 depth=5 수준까지 노드 트리 분석 -- **방법:** Figma API `/v1/files/{key}/nodes?ids={ids}&depth=5` +- **작업:** 각 프레임의 상세 스타일 + 레이아웃 정보 추출 +- **방법:** + - **1차:** Framelink MCP `get_figma_data` (nodeId 지정, depth 조절) + - 자동 CSS 변환: 색상→hex/rgba, 레이아웃→flex 용어, 그림자→box-shadow, 그라데이션→linear-gradient() + - 스타일 중복 제거 (글로벌 변수로 추출) + - 토큰 효율적 (raw API 대비 1/5 크기) + - **2차:** Figma 공식 MCP `get_variable_defs` — 디자인 토큰/변수 추출 + - **fallback:** Figma REST API `/v1/files/{key}/nodes?ids={ids}&depth=5` (MCP 미설치 시) - **추출 정보:** - - TEXT 노드: 폰트, 크기, 색상, 내용 - - FRAME/GROUP: 레이아웃 방식 (auto-layout, constraints) - - RECTANGLE: 배경색, 테두리, 둥근 모서리 - - INSTANCE: 재사용 컴포넌트 식별 + - TEXT 노드: fontFamily, fontSize, fontWeight, lineHeight, letterSpacing, color, 텍스트 내용 + - FRAME/GROUP: auto-layout (direction, gap, padding, alignItems, justifyContent), constraints + - RECTANGLE: fills (solid/gradient/image), strokes, cornerRadius, effects + - INSTANCE: componentId (재사용 컴포넌트 식별) +- **Figma → CSS 매핑 (Framelink MCP가 자동 처리, REST API 시 수동):** + - `layoutMode: "VERTICAL"` → `flex-direction: column` + - `primaryAxisAlignItems: "CENTER"` → `justify-content: center` + - `itemSpacing: 20` → `gap: 20px` + - `paddingLeft/Right/Top/Bottom` → `padding` + - `fills[].color {r,g,b,a}` → `rgba()` 또는 `#hex` + - `fills[].type: "GRADIENT_LINEAR"` → `linear-gradient(...)` + - `cornerRadius` → `border-radius` + - `strokes + strokeWeight` → `border` + - `effects[].type: "DROP_SHADOW"` → `box-shadow` + - `fontSize` → `font-size` (px 단위) + - `lineHeightPercentFontSize: 170` → `line-height: 1.7` - **산출물:** `docs/figma-analysis/` 폴더에 구조 문서 +- **주의:** Figma API rate limit 심함 — depth 깊은 요청은 30분 차단 가능. 얕게 요청 후 필요한 노드만 상세 조회 #### A-3: 디자인 패턴 분류 + 명명 - **작업:** 추출된 시각 요소를 재사용 가능한 블록 단위로 분류 @@ -90,20 +127,50 @@ Figma 디자인(바론컨설턴트 홈페이지 기획팀 공유)에서 재사 ### Phase B: HTML/CSS 컴포넌트 제작 -#### B-1: 신규 블록 템플릿 제작 (6~8종) -- **파일:** `templates/blocks/{name}.html` +#### B-1: 신규 블록 템플릿 제작 (8~10종) +- **파일:** `templates/blocks/{name}/` 폴더별 정리 (변형별 파일 + preview.png) - **제작 순서 (우선순위):** - 1. `section-title.html` — 공통 헤더 (모든 슬라이드에서 사용) - 2. `example-card.html` — 사례 카드 (출처+불릿, 정책 문서 인용) - 3. `image-gallery.html` — 이미지 갤러리 (2~4장, 근거 자료) - 4. `timeline.html` — 타임라인 (세로/가로, 연혁/로드맵) - 5. `big-number.html` — 핵심 지표 (큰 숫자 + 보조 텍스트) - 6. `icon-list.html` — 아이콘 리스트 (아이콘+제목+설명, 기능 나열) + 1. `section-title/default.html` — 공통 헤더 (모든 슬라이드에서 사용) + 2. `example-card/2col.html` — 사례 카드 (출처+불릿, 정책 문서 인용) + 3. `image-block/full.html`, `side.html`, `thumb.html` — 이미지 블록 3변형 + - full: 전체 너비 (핵심 도표, 가로형) + - side: 텍스트 옆 (보조 이미지, 세로형) + - thumb: 썸네일 (참고 문서 표지) + - CSS: `object-fit: contain` (비율 유지, 잘리지 않음) + - 원본 이미지 그대로 사용, 크기만 조절 (crop 안 함) + 4. `image-gallery/2col.html`, `3col.html`, `2x2.html` — 이미지 갤러리 + 5. `timeline/vertical.html`, `horizontal.html` — 타임라인 (연혁/로드맵) + 6. `big-number/3col.html`, `4col.html` — 핵심 지표 (큰 숫자 + 보조 텍스트) + 7. `icon-list/vertical.html`, `grid.html` — 아이콘 리스트 (기능 나열) + 8. `details-block/default.html` — 자세히보기 (`
/`) + - 슬라이드 표면: 요약만 표시 + - 펼치면: 전체 상세 내용 + - 인쇄 시: `beforeprint` 이벤트로 자동 펼침 - **규칙:** - 디자인 토큰(`var(--color-*)`) 사용 (하드코딩 색상 금지) - Jinja2 슬롯 (`{{ variable }}`) 형식 - `