5단계 AI 파이프라인: 1. Kei 실장(Opus via Kei API) — 꼭지 추출 + 정보 구조 파악 2. 디자인 팀장 — FAISS 블록 검색 + Opus 추천 + Sonnet 블록 매핑 3. Kei 편집자(Kei API) — 도메인 전문 텍스트 정리 4. 디자인 실무자(Sonnet + Jinja2) — CSS 변수 조정 + HTML 조립 5. 디자인 팀장(Sonnet) — 균형 재검토 (최대 2회 루프) 블록 라이브러리 46개 (6 카테고리) + _legacy 13개 FAISS 블록 검색 (bge-m3, 1024차원) SVG N개 동적 배치 (cos/sin 좌표 계산) Pillow 이미지 크기 측정 + base64 인라인 컨테이너 예산 기반 블록 배치 (zone별 높이 px) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
29 KiB
Figma → 컴포넌트 추출 + 카탈로그 구축 계획
목적
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 (웹/스크롤 모드, 향후)
현재 상태
보유 자산
| 항목 | 상태 | 위치 |
|---|---|---|
| Figma API 접근 | ✅ 가능 | Token: .env |
| 기존 블록 템플릿 7종 | ✅ 완성 | templates/blocks/ |
| 디자인 토큰 | ✅ 완성 | static/tokens.css |
| 슬라이드 렌더러 | ✅ 완성 | src/renderer.py |
| 디자인 팀장 (DA-13) | ❌ todo | src/design_director.py |
| 블록 카탈로그 | ❌ 없음 | - |
Figma 파일 구조
바론 공유 2025.05.13 (node: 1574-6254)
├── 1장 바론컨설턴트
├── 2장 디지털전환
│ ├── 2-1 건설산업에서의 디지털전환 (1920x8538, 스크롤형)
│ ├── 2-2 디지털전환과 소프트웨어 (1920x9123, 스크롤형)
│ └── 건설산업에서의 디지털전환 (1920x8536, 스크롤형)
│ [자세히보기]
│ ├── 2-1장 자세히보기 (4프레임: 건설산업/BIM/GIS/디지털트윈)
│ ├── 2-2장 자세히보기
│ └── 2-3장 자세히보기
├── 3장 제공서비스
│ ├── 3-1장 솔루션프로그램 자세히보기
│ └── 3-3장 빅룸 자세히보기
└── 모션작업
기존 블록 vs Figma에서 발견된 패턴
| 패턴 | 기존 블록 | Figma에서 발견 | 갭 |
|---|---|---|---|
| 2단 비교 | ✅ comparison | ✅ | - |
| 카드 그리드 | ✅ card-grid | ✅ (변형 다수) | 변형 추가 필요 |
| 벤 다이어그램 | ✅ relationship | ✅ | - |
| 단계 흐름 | ✅ process | ✅ | - |
| 강조 인용 | ✅ quote-block | ✅ (큰따옴표 장식) | 변형 추가 필요 |
| 결론 바 | ✅ conclusion-bar | ✅ | - |
| 비교 테이블 | ✅ comparison-table | ✅ | - |
| 이미지 갤러리 | ❌ | ✅ (2열, 3열, 2x2) | 신규 |
| 타임라인 | ❌ | ✅ (세로 원형 4단계) | 신규 |
| 섹션 타이틀 | ❌ | ✅ (영문+한글 공통 헤더) | 신규 |
| 사례 카드 | ❌ | ✅ (출처+불릿 카드) | 신규 |
| 핵심 지표 | ❌ (정의만) | ✅ (큰 숫자+보조) | 신규 |
| 아이콘 리스트 | ❌ | ✅ (아이콘+제목+설명) | 신규 |
| Hero 섹션 | ❌ | ✅ (배경+원형이미지+텍스트) | 신규 |
| CTA 버튼 바 | ❌ | ✅ (자세히보기 버튼) | 필요 시 |
| 이미지 블록 | ❌ | ✅ (도표, 참고자료) | 신규 (3변형: full/side/thumb) |
| 자세히보기 블록 | ❌ | ✅ (상세 콘텐츠 접기/펼치기) | 신규 (<details>/<summary>) |
작업 계획
Phase A: Figma 분석 + 패턴 추출
A-1: Figma 전체 섹션 이미지 렌더링
- 작업: 각 섹션/프레임을 이미지로 렌더링하여 시각적으로 패턴 식별
- 방법:
- 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 미설치 시)
- 1차: Framelink MCP
- 산출물:
docs/figma-screenshots/폴더에 PNG 저장 - 완료 기준: 모든 자세히보기 프레임(8개)의 스크린샷 확보
A-2: Figma 노드 구조 심층 분석
- 작업: 각 프레임의 상세 스타일 + 레이아웃 정보 추출
- 방법:
- 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 미설치 시)
- 1차: Framelink MCP
- 추출 정보:
- 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: columnprimaryAxisAlignItems: "CENTER"→justify-content: centeritemSpacing: 20→gap: 20pxpaddingLeft/Right/Top/Bottom→paddingfills[].color {r,g,b,a}→rgba()또는#hexfills[].type: "GRADIENT_LINEAR"→linear-gradient(...)cornerRadius→border-radiusstrokes + strokeWeight→bordereffects[].type: "DROP_SHADOW"→box-shadowfontSize→font-size(px 단위)lineHeightPercentFontSize: 170→line-height: 1.7
- 산출물:
docs/figma-analysis/폴더에 구조 문서 - 주의: Figma API rate limit 심함 — depth 깊은 요청은 30분 차단 가능. 얕게 요청 후 필요한 노드만 상세 조회
A-3: 디자인 패턴 분류 + 명명
- 작업: 추출된 시각 요소를 재사용 가능한 블록 단위로 분류
- 기준:
- 2회 이상 반복되는 패턴 → 블록 후보
- 슬롯(교체 가능한 위치)이 명확한 것 → 우선 순위 높음
- 콘텐츠 유형과 매칭되는 것 → 우선 순위 높음
- 산출물: 패턴 목록 + 각 패턴의 Figma 원본 노드 ID
Phase B: HTML/CSS 컴포넌트 제작
B-1: 신규 블록 템플릿 제작 (8~10종)
- 파일:
templates/blocks/{name}/폴더별 정리 (변형별 파일 + preview.png) - 제작 순서 (우선순위):
section-title/default.html— 공통 헤더 (모든 슬라이드에서 사용)example-card/2col.html— 사례 카드 (출처+불릿, 정책 문서 인용)image-block/full.html,side.html,thumb.html— 이미지 블록 3변형- full: 전체 너비 (핵심 도표, 가로형)
- side: 텍스트 옆 (보조 이미지, 세로형)
- thumb: 썸네일 (참고 문서 표지)
- CSS:
object-fit: contain(비율 유지, 잘리지 않음) - 원본 이미지 그대로 사용, 크기만 조절 (crop 안 함)
image-gallery/2col.html,3col.html,2x2.html— 이미지 갤러리timeline/vertical.html,horizontal.html— 타임라인 (연혁/로드맵)big-number/3col.html,4col.html— 핵심 지표 (큰 숫자 + 보조 텍스트)icon-list/vertical.html,grid.html— 아이콘 리스트 (기능 나열)details-block/default.html— 자세히보기 (<details>/<summary>)- 슬라이드 표면: 요약만 표시
- 펼치면: 전체 상세 내용
- 인쇄 시:
beforeprint이벤트로 자동 펼침
- 규칙:
- 디자인 토큰(
var(--color-*)) 사용 (하드코딩 색상 금지) - Jinja2 슬롯 (
{{ variable }}) 형식 <style>태그를 블록 HTML 안에 포함 (자체 완결)- Figma 원본과 시각적으로 유사하되 1:1 복제 아님 (디자인 토큰 기준)
- 높이를 고정하지 않음 (auto 또는 비율 사용) — 모드 독립적
- 각 블록에 사람용 주석 포함 (용도, 적합/부적합, Figma 원본 위치)
- 디자인 토큰(
B-1a: Figma 웹 → 블록 변환 규칙
Figma는 웹사이트 디자인(920px 너비, 세로 스크롤)이므로, 블록으로 변환할 때 아래 규칙을 적용한다:
| Figma 원본 | 블록 변환 | 이유 |
|---|---|---|
| 높이: 고정 px (예: 200px) | height: auto 또는 비율(%) |
720px 안에 들어가야 하고, 웹 모드에서도 동작해야 함 |
| 너비: 고정 px (예: 920px) | fr 또는 % (grid 컬럼에 맞춤) |
컨테이너 너비에 적응해야 함 |
| 색상: Figma 값 (예: #1565c0) | var(--color-accent) 등 디자인 토큰 |
토큰 체계 통일. 필요 시 tokens.css에 토큰 추가 |
| 폰트: Figma 값 (예: Noto Sans CJK KR 24px) | var(--font-subtitle) 등 디자인 토큰 |
Pretendard 기준. 크기 비율만 참고 |
| 간격: Figma 값 (예: padding 20px, gap 80px) | var(--spacing-inner), var(--spacing-block) 등 |
토큰 체계. 비율 참고 |
| 그라데이션 배경 | 제거 | CLAUDE.md 디자인 규칙: 그라데이션 금지 |
| 호버/클릭 효과 | 제거 | CLAUDE.md 디자인 규칙: 호버 금지 |
| 애니메이션/트랜지션 | 제거 | CLAUDE.md 디자인 규칙: 애니메이션 금지 |
| 원형 이미지 마스크 | 제거 (필요 시 별도 변형으로) | 장식 요소는 기본에서 제외 |
| 텍스트 위치 | {{ variable }} Jinja2 슬롯으로 표시 |
교체 가능한 부분 |
원칙: Figma에서 가져오는 것은 **정보 구조(카드 배치, 타임라인 흐름, 비교 레이아웃)**이지, 장식 요소가 아니다.
B-2: 기존 블록 변형 추가
- 대상:
quote-block.html→quote-block-decorated.html(큰따옴표 ::before/::after 장식)card-grid.html→card-grid-icon.html(아이콘 강조 변형)comparison.html→comparison-visual.html(이미지 포함 비교)
- 규칙: 기존 슬롯 구조 유지, CSS만 변형
B-3: slide-base.html 업데이트
- 내용: 신규 블록의 grid-area 지원, 디자인 토큰 추가 (필요 시)
- 주의: 기존 7개 블록의 렌더링이 깨지지 않는지 반드시 검증
Phase C: 카탈로그 구축
C-1: catalog.yaml 생성
- 파일:
templates/catalog.yaml - 구조:
version: "1.0"
blocks:
# --- 기존 블록 ---
- id: quote-block
name: 강조 인용
visual: "좌측 컬러 라인 + 배경색 + 인용 텍스트"
when: "문제 제기, 핵심 주장, 정의 강조할 때"
not_for: "일반 설명문, 사례 나열"
slots:
required: [quote_text]
optional: [source]
character_limits:
quote_text: 150
source: 50
variations: [default, decorated]
figma_ref: null # 기존 블록은 Figma 이전에 제작됨
# --- 신규 블록 ---
- id: example-card
name: 사례 카드
visual: "제목 + 출처(기관/연도) + 불릿 목록, 테두리 박스. 2~3장 나란히."
when: "정책 문서 인용, 법령/지침 사례, 출처가 명확한 근거 제시"
not_for: "용어 정의, 일반 설명, 비교"
slots:
required: [items[].title, items[].bullets[]]
optional: [items[].source_org, items[].source_year]
character_limits:
title: 30
bullet: 60
variations: [single, 2col, 3col]
figma_ref: "1574:54586 > 2-1_01 > examples-row"
- id: image-gallery
name: 이미지 갤러리
visual: "이미지 2~4장 나란히 + 캡션, 중앙 정렬"
when: "근거 자료 사진, 문서 표지, 현장 사진, 참고 이미지"
not_for: "텍스트 콘텐츠, 다이어그램 (다이어그램은 relationship 사용)"
slots:
required: [images[].src, images[].alt]
optional: [images[].caption]
variations: [2col, 3col, 2x2]
figma_ref: "1574:54586 > 2-1_03 > image grid"
- id: timeline
name: 타임라인
visual: "세로/가로 축 위에 원형 마커 + 연도/제목/설명"
when: "연혁, 로드맵, 정책 시행 일정, 단계별 계획"
not_for: "프로세스 흐름 (순서는 있지만 시간이 아닌 것은 process 사용)"
slots:
required: [events[].year, events[].title]
optional: [events[].description]
character_limits:
title: 25
description: 60
variations: [vertical, horizontal]
figma_ref: "1574:54586 > 2-1_01 > timeline"
- id: big-number
name: 핵심 지표
visual: "큰 숫자(2rem+) + 단위 + 보조 설명. 2~4개 나란히."
when: "KPI, 통계, 목표 수치, 성과 지표"
not_for: "텍스트 설명, 정의"
slots:
required: [metrics[].number, metrics[].label]
optional: [metrics[].unit, metrics[].description]
variations: [2col, 3col, 4col]
figma_ref: null
- id: section-title
name: 섹션 타이틀
visual: "영문 소제목(작은 글씨) + 한글 대제목(큰 글씨), 하단 구분선"
when: "모든 슬라이드 상단, 섹션 시작"
not_for: "본문 콘텐츠 영역"
slots:
required: [title_ko]
optional: [title_en, subtitle]
figma_ref: "공통 > section_title 컴포넌트"
- id: icon-list
name: 아이콘 리스트
visual: "아이콘 + 제목 + 설명이 세로로 나열, 좌측 아이콘 정렬"
when: "기능 나열, 특성 목록, 장점 리스트"
not_for: "비교 (comparison 사용), 순서 (process 사용)"
slots:
required: [items[].icon, items[].title, items[].description]
character_limits:
title: 20
description: 80
variations: [vertical, horizontal, grid]
figma_ref: null
layouts:
- id: "65-35"
name: "6.5:3.5 좌우 분할"
grid_columns: "6.5fr 3.5fr"
when: "좌측 메인 콘텐츠 + 우측 보조/정의"
- id: "50-50"
name: "5:5 균등 분할"
grid_columns: "1fr 1fr"
when: "대등한 비교, 병렬 콘텐츠"
- id: "single"
name: "단일 컬럼"
grid_columns: "1fr"
when: "프로세스 흐름, 타임라인, 단순 구조"
- id: "35-65"
name: "3.5:6.5 좌우 분할"
grid_columns: "3.5fr 6.5fr"
when: "좌측 요약/네비게이션 + 우측 메인 콘텐츠"
C-2: 카탈로그 → 디자인 팀장 프롬프트 연결
- 파일:
src/design_director.py수정 - 방법:
catalog.yaml로드 → 블록 목록을 시스템 프롬프트에 삽입 - 프롬프트 구조:
사용 가능한 블록: - quote-block: 좌측 컬러 라인 + 인용 텍스트. 문제 제기할 때 사용. 일반 설명문에는 부적합. - example-card: 제목+출처+불릿. 정책 사례 인용할 때 사용. 2~3장 나란히. - card-grid: 2~4열 카드. 용어 정의 여러 개 나열할 때 사용. ... 사용 가능한 레이아웃: - 65-35: 좌측 메인 + 우측 보조. 메인 콘텐츠가 많을 때. - 50-50: 균등 비교. 대등한 내용일 때. ... 위 블록과 레이아웃만 사용하여 배치해라. 목록에 없는 블록은 만들지 마라.
C-3: renderer.py 업데이트
- 내용: 신규 블록 템플릿 로드 지원
- 주의: 기존
BLOCK_SLOTSdict에 신규 블록 추가
충돌 지점 + 리스크 검토
1. Figma 디자인 ≠ 디자인 토큰
| 리스크 | 설명 | 대응 |
|---|---|---|
| 색상 불일치 | Figma는 파란 그라데이션 배경 사용, 디자인 토큰은 #2563eb 단색 |
Figma 색상을 참고하되 토큰 체계 우선. 필요 시 토큰 추가 (--color-accent-light 등) |
| 폰트 불일치 | Figma는 Noto Sans CJK KR 사용, 토큰은 Pretendard Variable | Pretendard 유지. Figma 폰트 크기 비율만 참고 |
| 여백 불일치 | Figma 920px 프레임 vs 슬라이드 1280px | 비율 기반으로 변환. 고정 px 대신 토큰 사용 |
| 웹 vs 슬라이드 | Figma는 웹사이트(세로 스크롤, 920x1231~2208px), 슬라이드는 고정(1280x720px) | 높이 고정하지 않음(auto). 컨테이너가 모드를 결정 |
원칙: Figma 디자인을 1:1 복제하지 않는다. 패턴(정보 구조)만 추출하고, 스타일은 디자인 토큰으로 통일한다.
디자인 토큰 매핑 테이블 (Figma 추출 시 작성):
Figma에서 추출한 색상/폰트/간격을 기존 tokens.css와 매핑하고, 누락된 토큰이 있으면 추가한다.
| Figma 속성 | 추출값 (예시) | 기존 토큰 매핑 | 신규 토큰 필요? |
|---|---|---|---|
| 배경색 (SOLID fill) | #f8fafc |
--color-bg-subtle |
- |
| 포인트 색상 | #1565c0 |
--color-accent (현재 #2563eb) |
검토 필요 |
| 텍스트 색상 | #1e293b |
--color-primary |
- |
| 보조 텍스트 | #64748b |
--color-neutral |
- |
| 경고/강조 | #dc2626 |
--color-danger |
- |
| 본문 폰트 크기 | 16px |
--font-body (현재 0.95rem ≈ 15.2px) |
비율 확인 |
| 제목 폰트 크기 | 24px |
--font-subtitle (현재 1.25rem = 20px) |
비율 확인 |
| 블록 간 간격 | 20px |
--spacing-block |
- |
| 내부 패딩 | 16px |
--spacing-inner |
- |
| 카드 상단 액센트 | 3px solid |
--accent-border |
- |
이 매핑 테이블은 Phase A-2에서 실제 Figma 값을 추출한 후 정확한 값으로 채운다. 기존 토큰과 차이가 크면 토큰을 추가하되, 기존 토큰의 값을 변경하지 않는다 (기존 7개 블록이 깨질 수 있음).
2. 블록 개수 증가 → 디자인 팀장 혼란
| 리스크 | 설명 | 대응 |
|---|---|---|
| 선택지 과다 | 7개 → 13~15개로 증가 시 Sonnet이 부적절한 블록 선택 가능 | when + not_for 필드로 선택 기준 명확화. 프롬프트에 "이런 콘텐츠에는 이 블록을 쓰지 마라" 명시 |
| 유사 블록 혼동 | card-grid vs example-card vs icon-list 구분 | 카탈로그에 각 블록의 차이점 명시. 예: "card-grid는 정의, example-card는 출처 있는 사례, icon-list는 기능 나열" |
대응: catalog.yaml의 not_for 필드가 핵심. "이 블록은 이것에 쓰지 마라"를 명시해야 혼동 감소.
3. 기존 파이프라인 깨짐
| 리스크 | 설명 | 대응 |
|---|---|---|
| renderer.py 호환성 | 신규 블록 추가 시 기존 렌더링 깨짐 | 기존 7개 블록 테스트 먼저 통과 확인 후 신규 추가 |
| BLOCK_SLOTS 누락 | design_director.py의 BLOCK_SLOTS에 신규 블록 미등록 | catalog.yaml에서 자동 로드하는 방식으로 전환 |
| slide-base.html | grid-template-areas에 신규 area명 미지원 | 동적 생성이므로 문제 없음 (Sonnet이 area명을 직접 지정) |
대응: Phase B 완료 후 기존 테스트 케이스(DA-16) 반드시 재실행.
4. Figma API 제약
| 리스크 | 설명 | 대응 |
|---|---|---|
| CSS 미제공 | Figma REST API는 CSS를 직접 제공하지 않음. 스타일 속성만 제공 | Framelink MCP 사용 시 자동 CSS 변환. REST API만 사용 시 수동 변환 필요 |
| 이미지 에셋 | 벡터(VECTOR, ELLIPSE)는 PNG로 렌더링 가능하나 CSS 재현 필요 | Framelink MCP download_figma_images로 일괄 export. 단순 도형은 CSS, 복잡한 것은 PNG |
| INSTANCE 참조 | Figma 컴포넌트(Instance)의 master 확인 필요 | GET /v1/files/{key}/components로 마스터 컴포넌트 조회 |
| Rate Limit | REST API depth 깊은 요청 시 30분 차단 가능 | Framelink MCP가 토큰 효율적 (raw API 대비 1/5). 얕게 요청 후 필요한 노드만 상세 조회. 결과 캐싱 |
| 디자인 토큰 접근 | REST API로는 Figma 변수/토큰 추출 불가 (별도 scope 필요) | Figma 공식 MCP get_variable_defs 사용. 또는 노드 속성에서 수동 추출 |
| 의미적 HTML 추론 불가 | "버튼"은 FRAME+TEXT, "카드"는 FRAME+FRAME — 태그 구분 없음 | 노드 이름(naming convention)으로 추론. 예: section_title, example-card |
MCP 도구 설정
Framelink MCP (권장, CSS-ready 추출):
// Claude Code MCP 설정
{
"mcpServers": {
"Framelink MCP for Figma": {
"command": "cmd",
"args": ["/c", "npx", "-y", "figma-developer-mcp", "--figma-api-key=YOUR-KEY", "--stdio"]
}
}
}
get_figma_data: 노드 스타일을 CSS-ready YAML로 변환 (색상→hex, 레이아웃→flex, 그림자→box-shadow)download_figma_images: 이미지 일괄 다운로드 (크롭, 중복 제거 자동)
Figma 공식 MCP (디자인 토큰 + 스크린샷):
claude mcp add --transport http figma https://mcp.figma.com/mcp
get_variable_defs: 디자인 토큰(색상, 간격, 타이포) 추출get_screenshot: 시각 참고용 스크린샷- 주의: Free/Starter 플랜 = 월 6회 호출 제한
5. Starlight(.astro) 연결 시 충돌
| 리스크 | 설명 | 대응 |
|---|---|---|
| CSS 변수 충돌 | Starlight 자체 CSS 변수(--sl-*)와 디자인 토큰(--color-*) 충돌 |
네임스페이스 분리: --da-color-* 접두사 사용 검토 |
| 폰트 로딩 | .astro에서 Pretendard CDN 로드 필요 | <style is:global>에 @import 포함 |
<style> 인라인 |
현재 렌더러가 CSS를 인라인하는데, .astro에서 Starlight CSS와 섞임 | .astro 출력 시 scoped style 또는 is:global + 높은 specificity |
대응: .astro 출력은 Phase C 이후 별도 태스크로. 현재는 독립 HTML 출력에 집중.
6. 유사 프로젝트 사례에서 발견된 문제
| 사례 | 문제 | 교훈 |
|---|---|---|
| SlideSpeak | 16개 레이아웃으로 시작했으나 실제 콘텐츠 다양성 커버 못함 | 블록을 조합하는 방식이 고정 레이아웃보다 유연 (현재 방식 유지) |
| PPTAgent (EMNLP 2025) | 레퍼런스 슬라이드 클러스터링 시 과소/과다 분류 문제 | 블록 수를 10~15개로 제한. 너무 세분화하면 AI 선택이 어려워짐 |
| Beautiful.ai | 300개 템플릿 중 실제 사용은 20개 | 처음부터 많이 만들지 않기. 실제 사용 빈도 보고 추가 |
| InfoDesignLM | 텍스트만으로 레이아웃 생성 시 콘텐츠 양 ↔ 공간 불일치 | character_limits를 카탈로그에 명시, 텍스트 편집자가 강제 준수 |
작업 순서 (의존 관계)
A-1 (Figma 스크린샷) ──┐
├→ A-3 (패턴 분류) → B-1 (신규 블록 제작) → B-3 (base 업데이트)
A-2 (노드 구조 분석) ──┘ ↓
C-1 (catalog.yaml)
↓
B-2 (변형 추가) → C-2 (팀장 프롬프트 연결)
↓
C-3 (renderer 업데이트)
↓
기존 테스트 재실행 (DA-16)
예상 소요
| Phase | 작업 | 규모 |
|---|---|---|
| A (분석) | Figma 스크린샷 + 노드 분석 + 패턴 분류 | 탐색/조사 |
| B (제작) | 신규 블록 6~8종 + 변형 3종 + base 업데이트 | 구현 (핵심) |
| C (카탈로그) | catalog.yaml + 팀장 프롬프트 + renderer 업데이트 | 연결/통합 |
핵심 원칙: Phase A에서 패턴을 정확히 분류하지 않으면 Phase B에서 쓸모없는 블록을 만들게 된다. 분석 먼저, 제작은 그 다음.
산출물 목록
docs/
├── figma-screenshots/ # A-1: 각 프레임 PNG
├── figma-analysis/ # A-2: 노드 구조 문서 + 디자인 토큰 매핑 테이블
└── FIGMA-COMPONENT-EXTRACTION-PLAN.md # 이 파일
templates/
├── catalog.yaml # C-1: 블록 카탈로그 (AI용 메뉴판 + 사람용 참고)
├── blocks/
│ ├── comparison/ # 기존 (폴더 구조로 재편)
│ │ ├── default.html
│ │ └── preview.png
│ ├── card-grid/ # 기존
│ │ ├── default.html
│ │ ├── icon.html # B-2: 변형
│ │ └── preview.png
│ ├── relationship/ # 기존
│ ├── process/ # 기존
│ ├── quote-block/ # 기존
│ │ ├── default.html
│ │ ├── decorated.html # B-2: 변형
│ │ └── preview.png
│ ├── conclusion-bar/ # 기존
│ ├── comparison-table/ # 기존
│ ├── section-title/ # B-1: 신규
│ │ ├── default.html
│ │ └── preview.png
│ ├── example-card/ # B-1: 신규
│ │ ├── single.html
│ │ ├── 2col.html
│ │ ├── 3col.html
│ │ └── preview.png
│ ├── image-block/ # B-1: 신규 (3변형)
│ │ ├── full.html # 전체 너비 (핵심 도표)
│ │ ├── side.html # 텍스트 옆 (보조 이미지)
│ │ ├── thumb.html # 썸네일 (참고 문서)
│ │ └── preview.png
│ ├── image-gallery/ # B-1: 신규
│ │ ├── 2col.html
│ │ ├── 3col.html
│ │ ├── 2x2.html
│ │ └── preview.png
│ ├── timeline/ # B-1: 신규
│ │ ├── vertical.html
│ │ ├── horizontal.html
│ │ └── preview.png
│ ├── big-number/ # B-1: 신규
│ │ ├── 3col.html
│ │ ├── 4col.html
│ │ └── preview.png
│ ├── icon-list/ # B-1: 신규
│ │ ├── vertical.html
│ │ ├── grid.html
│ │ └── preview.png
│ └── details-block/ # B-1: 신규
│ ├── default.html
│ └── preview.png
├── slide-base.html # B-3: 업데이트 (슬라이드 모드)
└── page-base.html # 향후: 웹/스크롤 모드
samples/ # 완성 슬라이드 레시피
├── dx-bim-comparison/
│ ├── slide.html # 완성 HTML
│ ├── preview.png # 스크린샷
│ └── meta.yaml # 사용된 블록 조합 + Figma 원본 참조
└── ...
src/
├── design_director.py # C-2: catalog.yaml 연동
└── renderer.py # C-3: 신규 블록 지원
PROGRESS.md 연동
이 계획의 태스크들은 PROGRESS.md에 아래와 같이 등록한다:
Phase F (Figma 컴포넌트 추출) — PROGRESS.md 등록 항목
| 태스크 | 상태 | 의존성 | 메모 |
|---|---|---|---|
| F-A1: Figma 스크린샷 확보 | todo | MCP 설치 후 | Framelink MCP 또는 REST API |
| F-A2: 노드 구조 심층 분석 | todo | F-A1 | CSS-ready 데이터 + 토큰 매핑 테이블 |
| F-A3: 패턴 분류 + 명명 | todo | F-A1, F-A2 | 블록 후보 목록 확정 |
| F-B1: 신규 블록 템플릿 제작 (8~10종) | todo | F-A3 | 폴더 구조, 변환 규칙 적용 |
| F-B1a: Figma 웹→블록 변환 규칙 검증 | todo | F-B1 | 토큰 매핑, 높이 auto 확인 |
| F-B2: 기존 블록 변형 추가 | todo | F-B1 | CSS만 변형, 슬롯 유지 |
| F-B3: slide-base.html 업데이트 | todo | F-B1 | 기존 7개 블록 깨지지 않는지 검증 |
| F-C1: catalog.yaml 생성 | todo | F-B1 | when/not_for/slots/char_limits |
| F-C2: 팀장 프롬프트 연결 | todo | F-C1 | catalog.yaml → 시스템 프롬프트 |
| F-C3: renderer.py 업데이트 | todo | F-C1 | 신규 블록 로드 + BLOCK_SLOTS 동기화 |
| F-T1: 기존 테스트 재실행 | todo | F-B3, F-C3 | DA-16 기존 케이스 전체 통과 확인 |
사전 세팅 (Figma 작업 시작 전 필요):
| 세팅 | 상태 | 설명 |
|---|---|---|
| Framelink MCP 설치 | todo | npx figma-developer-mcp --figma-api-key=... |
| Figma 공식 MCP 설치 | todo | claude mcp add --transport http figma https://mcp.figma.com/mcp |
| 기존 블록 폴더 구조 재편 | todo | 플랫 파일 → 블록별 폴더 (templates/blocks/{name}/) |
| preview.png 생성 방법 확보 | todo | HTML을 브라우저로 열어 스크린샷 (수동 또는 Playwright) |
금지 사항
- Figma 디자인을 1:1 복제하지 않는다 (정보 구조만 추출, 장식은 제거, 스타일은 토큰 기준)
- 기존 7개 블록 템플릿을 수정하지 않는다 (신규/변형은 별도 파일)
- 한 번에 모든 블록을 만들지 않는다 (A-3 분류 결과를 보고 우선순위 재조정)
- catalog.yaml 없이 블록을 추가하지 않는다 (카탈로그 미등록 = 디자인 팀장이 모름)
- Kei Persona Agent 코드를 수정하지 않는다
- 블록의 높이를 고정 px로 하드코딩하지 않는다 (모드 독립적이어야 함)
- 기존
tokens.css의 값을 변경하지 않는다 (신규 토큰 추가는 가능, 기존 값 변경은 7개 블록 깨짐 위험) - 이미지를 crop하지 않는다 (원본 그대로, 크기만 조절)
- 그라데이션, 호버, 애니메이션 등 Figma 장식 요소를 가져오지 않는다