Files
C.E.L_Slide_test2/figma_to_html_agent/PHASE-FIGMA-BLOCKS.md
kyeongmin 51548fdc41 figma_to_html_agent 추가 + MCP/Claude 설정
figma_to_html_agent/:
- Figma MCP 기반 블록 추출 에이전트 (CLAUDE.md, PLAN.md, PROCESS.md 등)
- block-tests/: Figma→HTML 변환 결과물 (bim-3roles-cards 등)
- templates_staging/: Jinja2 템플릿 + meta.yaml + example.yaml
- figma-analysis/, figma-assets/: Figma 분석 데이터 + 에셋
- scripts/: gradient_math.py 등 유틸리티

설정:
- .mcp.json: Figma MCP 서버 연결 설정
- .claude/settings.json: Claude Code 프로젝트 설정

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 11:00:31 +09:00

17 KiB
Raw Blame History

Phase 2: Figma Block Design Specification

7개 블록 + 2개 서브 컴포넌트 상세 설계 기준: FIGMA-DESIGN-LANGUAGE.md 분석 결과 최종 업데이트: 2026-04-08


Block 1: hero-icon-cards

1.1 시각적 구조

┌──────────────────────────────────────────────┐
│      [Hero Statement - 큰 텍스트, 중앙]        │  ← zone: header or full-width
│                                              │
│          ┌─[Badge Title]─┐                   │
│──────────┤               ├───────────────────│
│  ┌─────┐ │ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │
│  │icon │ │ │icon │ │icon │ │icon │ │icon │ │  ← N개 카드 (2~6)
│  │     │ │ │     │ │     │ │     │ │     │ │
│  │Title│ ╎ │Title│ │Title│ │Title│ │Title│ │  ← 세로 구분선
│  │(sub)│ │ │(sub)│ │(sub)│ │(sub)│ │(sub)│ │
│  └─────┘ │ └─────┘ └─────┘ └─────┘ └─────┘ │
│          └───────────────────────────────────│
└──────────────────────────────────────────────┘

1.2 슬롯 정의

슬롯 필수 타입 설명
statement O string Hero 메시지 (1-2줄)
badge_title X string 배지 바 텍스트
cards[] O array 카드 배열
cards[].icon X string 아이콘 이미지 URL 또는 이모지
cards[].title O string 영문 또는 주제목
cards[].subtitle X string 한국어 부제
cards[].color X string 개별 카드 강조색

1.3 동적 재구성 규칙

그리드 계산

입력: N = cards.length, W = container_width_px

N ≤ 5:  1행 N열
  col_count = N
  card_width = (W - padding*2 - gap*(N-1)) / N

N = 6:  1행 6열 (gap 축소)
  col_count = 6
  gap = 8px (기본 16px에서 축소)

N > 6:  2행
  col_count = ceil(N / 2)
  row_count = 2

폰트 스케일링

card_width ≥ 200px → title: 20px, subtitle: 14px
card_width ≥ 150px → title: 16px, subtitle: 12px
card_width < 150px → title: 14px, subtitle: 11px

높이 계산

hero_height = statement_lines * line_height + padding
badge_height = 44px (고정)
card_area_height = icon_height + title_lines * title_lh + subtitle_lh + padding
  - 1행: card_area_height
  - 2행: card_area_height * 2 + gap

total_min_height = hero_height + badge_height + card_area_height + gaps

1.4 catalog.yaml schema

- id: hero-icon-cards
  name: 히어로 문구 + 아이콘 카드
  category: cards
  template: blocks/cards/hero-icon-cards.html
  height_cost: xlarge
  min_height_px: 280
  relation_types: [definition, flow]
  min_items: 2
  max_items: 6
  visual: >
    상단에 큰 Hero 메시지(24px bold, 중앙) + 배지 바 + 
    하단에 N열 아이콘 카드(둥근 흰색 컨테이너, 세로 구분선).
    각 카드는 아이콘 이미지 + 영문 제목(20px/900) + 한국어 부제(14px/500).
  when: >
    핵심 목표나 가치를 N개 키워드로 선언할 때. 
    각 키워드에 아이콘이나 이미지가 있을 때.
    "우리가 추구하는 5가지 가치" 같은 구조.
  not_for: >
    비교/대조 구조 → compare-2col-badge.
    상세 설명이 길 때 → card-icon-desc.
    순서/단계 → card-step-vertical 또는 process-horizontal.
  purpose_fit: [핵심전달, 가치선언]
  zone: full-width-only
  slots:
    required: [statement, cards[]]
    optional: [badge_title, cards[].icon, cards[].subtitle, cards[].color]
  schema:
    statement:
      max_lines: 2
      font_size: 24
      ref_chars:
        body: 60
      note: "24px bold, 중앙정렬, 흰색 스트로크"
    badge_title:
      max_lines: 1
      font_size: 18
      ref_chars:
        body: 20
      note: "18px bold white, 배지 바 위"
    card_title:
      max_lines: 2
      font_size: 20
      ref_chars:
        body: 15
      note: "20px black/900, 중앙정렬"
    card_subtitle:
      max_lines: 1
      font_size: 14
      ref_chars:
        body: 10
      note: "14px medium, 한국어 부제"
  padding_overhead_px: 60
  padding_h_px: 32

Block 2: compare-2col-badge

2.1 시각적 구조

┌──────────────────────────────────────────────┐
│            ┌─[Badge Title]─┐                 │
│────────────┤               ├─────────────────│
│                                              │
│  ┌── Left Column ──┐ ╎ ┌── Right Column ──┐ │
│  │                  │ ╎ │                  │ │
│  │  [Big Title]     │ ╎ │  [Big Title]     │ │
│  │                  │ ╎ │                  │ │
│  │  body text...    │ ╎ │  body text...    │ │
│  │  body text...    │ ╎ │  body text...    │ │
│  │                  │ ╎ │                  │ │
│  └──────────────────┘ ╎ └──────────────────┘ │
│                                              │
│       [Optional: Hero Statement]             │
└──────────────────────────────────────────────┘

2.2 슬롯 정의

슬롯 필수 타입 설명
badge_title O string 배지 바 텍스트
left_title O string 좌측 열 대제목
left_body O string 좌측 열 본문
right_title O string 우측 열 대제목
right_body O string 우측 열 본문
statement X string 하단 Hero 메시지
left_color X string 좌측 강조색 (기본: --color-teal)
right_color X string 우측 강조색 (기본: --color-teal)

2.3 동적 재구성 규칙

레이아웃 계산

container_width = 컨테이너 전체 폭
padding_h = 32px * 2

2열 모드 (기본):
  col_width = (container_width - padding_h - divider_gap) / 2
  divider_gap = 32px

1열 모드 (sidebar zone, 폭 < 500px):
  좌/우가 세로 스택
  col_width = container_width - padding_h

높이 계산

badge_height = 44px
left_height = title_height + body_lines * line_height + padding
right_height = title_height + body_lines * line_height + padding
content_height = max(left_height, right_height)
statement_height = statement ? (statement_lines * 28 + 16) : 0

total = badge_height + content_height + statement_height + gaps

텍스트 피팅

col_width에 따른 body 글자수 제한:
  col_width ≥ 500px → ~40자/줄, font: 16px
  col_width ≥ 350px → ~28자/줄, font: 14px
  col_width < 350px → ~20자/줄, font: 13px

2.4 catalog.yaml schema

- id: compare-2col-badge
  name: 배지 헤더 2열 비교
  category: cards
  template: blocks/cards/compare-2col-badge.html
  height_cost: large
  min_height_px: 200
  relation_types: [comparison, contrast]
  visual: >
    상단 배지 바(이미지/그라디언트 배경 + 흰색 텍스트) 아래
    2열 비교 레이아웃. 좌/우 각각 대제목(24px/900) + 본문(16px/700).
    중앙 세로 구분선. 둥근 흰색 컨테이너(r:20). 
    선택적 하단 Hero 메시지.
  when: >
    두 개념/방법/전략을 나란히 비교할 때.
    배지 헤더로 상위 주제를 명시.
    예: "Engn. Solution vs DfMA", "현재 vs 미래"
  not_for: >
    3개 이상 항목 비교 → compare-3col-badge.
    장/단점 목록 → comparison-2col.
    상세 내용이 길고 섹션이 많을 때 → compare-detail-gradient.
  purpose_fit: [비교대조, 개념정의]
  zone: full-width-only
  slots:
    required: [badge_title, left_title, left_body, right_title, right_body]
    optional: [statement, left_color, right_color]
  schema:
    badge_title:
      max_lines: 1
      font_size: 18
      ref_chars:
        body: 15
      note: "18px bold white, 배지 바"
    left_title:
      max_lines: 1
      font_size: 24
      ref_chars:
        body: 15
      note: "24px black/900, 흰색 스트로크"
    left_body:
      max_lines: 6
      font_size: 16
      ref_chars:
        body: 200
      note: "16px/700, 틸 색상"
    right_title:
      max_lines: 1
      font_size: 24
      ref_chars:
        body: 15
      note: "24px black/900, 흰색 스트로크"
    right_body:
      max_lines: 6
      font_size: 16
      ref_chars:
        body: 200
      note: "16px/700, 틸 색상"
    statement:
      max_lines: 2
      font_size: 20
      ref_chars:
        body: 50
      note: "20px bold, 중앙정렬"
  padding_overhead_px: 56
  padding_h_px: 32

Block 3: compare-detail-gradient

3.1 시각적 구조

┌──────────────────────────────────────────────────────────┐
│ ┌───── Left Header Bar (gradient) ─────┐┌── Right ─────┐│
│ │   [Left Column Title]                ││ [Right Title] ││
│ └──────────────────────────────────────┘└───────────────┘│
│ ┌─────── Left BG (warm) ──────┐┌──── Right BG (teal) ──┐│
│ │                              ││                       ││
│ │ [Section 1 Title]            ││ [Section 1 Title]     ││
│ │  • body text                 ││  • body text          ││
│ │  • body text                 ││  • body text          ││
│ │                              ││                       ││
│ │ [Section 2 Title]            ││ [Section 2 Title]     ││
│ │  • body text                 ││  • body text          ││
│ │  • body text                 ││  • body text          ││
│ │                              ││                       ││
│ │ [Section N Title]            ││ [Section M Title]     ││
│ │  • body text                 ││  • body text          ││
│ └──────────────────────────────┘└───────────────────────┘│
└──────────────────────────────────────────────────────────┘

3.2 슬롯 정의

슬롯 필수 타입 설명
left_header O string 좌측 열 헤더 타이틀
right_header O string 우측 열 헤더 타이틀
left_sections[] O array 좌측 섹션 배열
left_sections[].title O string 섹션 소제목
left_sections[].body O string 섹션 본문 (줄바꿈 허용)
right_sections[] O array 우측 섹션 배열
right_sections[].title O string 섹션 소제목
right_sections[].body O string 섹션 본문
left_color_theme X string 좌측 테마 (기본: warm)
right_color_theme X string 우측 테마 (기본: teal)

3.3 동적 재구성 규칙 (★ 가장 수학적으로 복잡)

그리드 계산

container_width에서 2열 분할:
  col_width = (container_width - gap) / 2
  gap = 0px (그라디언트가 맞닿음)

섹션 높이 계산 (핵심)

header_bar_height = 48px (고정)

각 섹션의 높이:
  section_height(s) = 
    title_height(s.title, title_font_size, col_width) +
    body_height(s.body, body_font_size, col_width) +
    section_padding

  title_height = ceil(char_count / chars_per_line) * title_line_height
  body_height = line_count * body_line_height
  
  chars_per_line = floor(col_width / (font_size * 0.55))  // 한글 평균 0.55em

좌측 전체:
  left_total = header_bar + sum(section_height for s in left_sections) + gaps
  
우측 전체:
  right_total = header_bar + sum(section_height for s in right_sections) + gaps
  
content_height = max(left_total, right_total)

오버플로 방지 — Fit 검증

if content_height > container_available_height:
  
  전략 1: 폰트 축소
    body_font_size -= 1px (최소 12px)
    재계산
  
  전략 2: 섹션 본문 줄 수 제한
    max_body_lines = floor(
      (available_per_section - title_height) / body_line_height
    )
    available_per_section = (container_height - header*2 - gaps) / max(N_left, N_right)
  
  전략 3: Kei 에스컬레이션 (기존 파이프라인)
    content 요약 요청

색상 테마 매핑

warm (좌측 기본):
  header_gradient: rgba(165,161,150,0.10) → rgba(57,50,30,1.00)
  section_title_color: var(--color-warm-brown)
  bg: rgba(255,255,255,0.30) → rgba(57,50,30,0.30)

teal (우측 기본):
  header_gradient: rgba(41,107,85,0.10) → rgba(3,33,24,1.00)
  section_title_color: var(--color-dark-teal)
  bg: rgba(41,107,85,0.30) → rgba(255,255,255,0.30)

3.4 catalog.yaml schema

- id: compare-detail-gradient
  name: 그라디언트 상세 2열 비교
  category: cards
  template: blocks/cards/compare-detail-gradient.html
  height_cost: xlarge
  min_height_px: 300
  relation_types: [comparison, contrast, process]
  min_items: 2  # 좌/우 최소 1섹션씩
  max_items: 10  # 좌+우 합계
  visual: >
    좌우 그라디언트 배경(워 브라운 vs 다크틸)으로 나뉜 2열 비교.
    각 열 상단에 그라디언트 헤더 바 + 큰 제목(28px/900).
    하단에 N개 섹션(소제목 22px/900 + 본문 16px/700) 반복.
    좌측은 따뜻한 톤(과정/As-Is), 우측은 차가운 톤(결과/To-Be).
  when: >
    두 카테고리를 상세하게 비교할 때.
    각 카테고리에 여러 하위 항목이 있을 때.
    과정 vs 결과, As-Is vs To-Be, 문제 vs 해결 구조.
  not_for: >
    간단한 2항목 비교(본문 짧을 때) → compare-2col-badge.
    3열 비교 → compare-3col-badge.
    비교가 아닌 단독 리스트 → dark-bullet-list.
  purpose_fit: [비교대조, 구조시각화, 근거사례]
  zone: full-width-only
  slots:
    required: [left_header, right_header, left_sections[], right_sections[]]
    optional: [left_color_theme, right_color_theme]
  schema:
    left_header:
      max_lines: 1
      font_size: 28
      ref_chars:
        body: 20
      note: "28px black/900, 그라디언트 바 위"
    right_header:
      max_lines: 1
      font_size: 28
      ref_chars:
        body: 20
      note: "28px black/900, 그라디언트 바 위"
    section_title:
      max_lines: 2
      font_size: 22
      ref_chars:
        body: 30
      note: "22px/900, 색상 테마별 (브라운 or 틸)"
    section_body:
      max_lines: 4
      font_size: 16
      ref_chars:
        body: 120
      note: "16px/700, black"
  padding_overhead_px: 48
  padding_h_px: 0

서브 컴포넌트

S1. 장식 이미지 (3D 화살표 등)

  • 블록이 아닌 콘텐츠 이미지로 처리
  • cards[].icon 또는 별도 decoration_image 슬롯으로 전달
  • 블록은 <img> 태그로 렌더링, 크기는 CSS로 컨테이너에 맞춤

S2. CTA 버튼

  • 독립 블록이 아닌 다른 블록 내 선택적 요소
  • cta_text 슬롯으로 전달 (없으면 미표시)
  • CSS: 그라디언트 바 + 둥근 버튼 (r:7)

구현 결과 (전체 7개 블록)

# 블록 카테고리 출처 상태 핵심 수학
1 hero-icon-cards cards Page 1/Frame 2 완료 3D 리본 fold_offset 계산 (badge_y→box_y×scale)
2 compare-2col-badge cards Page 1/Frame 3 완료 3D 리본 fold_offset + 틸 테두리
3 compare-detail-gradient cards Page 1/Frame 4 완료 CSS Grid 행 공유 + As-Is/To-Be + 연속 그라디언트
4 category-strip-table cards Page 2/001_개요 완료 scale=1200/2123, N열 동적 Grid
5 checklist-dark emphasis Page 3/f5 완료 scale=1200/1770, 행 간격 계산
6 system-2col-center cards Page 3/f8 완료 scale=1200/2446, 3열 Grid
7 cycle-orbit visuals Page 4/Frame 1 완료 3D 원 Z축 기울임(80°) → 2D 투영, 사이각 축소, 접선 회전

핵심 교훈

  1. 수학적 계산 필수: Figma 좌표 → 스케일 → CSS값. 시행착오 금지.
  2. 3D 리본은 이미지 추출: CSS로 재현 불가, Figma에서 PNG 추출.
  3. CSS Grid 행 공유: 좌/우 섹션 Y선 정렬 문제 해결.
  4. 연속 그라디언트: 셀별 배경 → Grid 전체 배경으로 끊김 방지.
  5. 3D 원 투영: project(α) = (cx+R×cos(α), cy+R×sin(α)×cos(θ)) — N개 노드 자동 배치.
  6. 텍스트 배치: 좌측 노드→이름 좌측에, 우측/상단 노드→이름 우측에.
  7. 비교 리뷰 필수: Figma PNG vs HTML을 같은 폭으로 위/아래 비교.