bodalab/doc/figma-specs/README.md

8.6 KiB

Figma 섹션별 스펙 JSON 모음

왜 이 폴더가 있는가

figma-mcpadd_figma_file 도구는 항상 문서 전체(01_HOME부터)를 JSON으로 덤프하고, URL에 node-id를 넣어도 무시한다. 파일이 커서 도구 결과 토큰 한도(약 25,000 토큰)에 걸려 03_HISTORY 중반에서 항상 잘리기 때문에, 04_VISION부터는 이 방법으로 데이터를 받은 적이 없었다.

대신 Figma REST API의 nodes 엔드포인트는 ids 파라미터로 노드 하나만 스코프해서 받을 수 있다. .mcp.json에 이미 설정된 FIGMA_API_KEY로 직접 호출하면 섹션당 수십 KB 수준이라 잘리지 않는다.

curl -s -H "X-Figma-Token: $FIGMA_API_KEY" \
  "https://api.figma.com/v1/files/MnwN1Uzg5F6ks9Clr1brLW/nodes?ids=<node-id>" \
  -o "<name>.json"

$FIGMA_API_KEY는 프로젝트 루트 .mcp.jsonmcpServers.figma.env.FIGMA_API_KEY 값이다 (.mcp.json.gitignore 대상이라 이 문서에는 실제 키를 적지 않는다).

파일 구성

섹션마다 두 파일이 있다:

  • *.json — Figma REST API 원본 응답 (필요시 정확한 수치를 다시 뽑을 수 있는 원천 데이터)
  • *.txt — 그 안의 모든 TEXT 노드를 "내용" — 폰트크기 / weight / 색상 형태로 평탄화한 요약 (빠르게 훑어볼 때 사용)

.txt는 아래 스크립트로 재생성한다 (JSON을 재호출할 필요 없이 로컬에서 즉시 재실행 가능):

python3 << 'EOF'
import json, glob

def rgb(c):
    a = c.get('a', 1)
    return f"#{round(c['r']*255):02x}{round(c['g']*255):02x}{round(c['b']*255):02x}" + (f" a{a}" if a < 1 else "")

def walk(node, depth=0, out=None):
    out = out if out is not None else []
    if node.get('type') == 'TEXT':
        style = node.get('style', {})
        fills = node.get('fills', [])
        color = rgb(fills[0]['color']) if fills and fills[0].get('color') else '?'
        chars = node.get('characters', '')[:40].replace('\n', '\\n')
        out.append(f"{'  '*depth}- \"{chars}\" — {style.get('fontSize')}px / weight {style.get('fontWeight')} / {color}")
    for child in node.get('children', []):
        walk(child, depth + 1, out)
    return out

for f in sorted(glob.glob("*.json")):
    with open(f) as fh:
        data = json.load(fh)
    node_id = list(data['nodes'].keys())[0]
    doc = data['nodes'][node_id]['document']
    lines = walk(doc)
    with open(f.replace('.json', '.txt'), 'w') as fh:
        fh.write(f"# {f} (node {node_id})\n\n")
        fh.write('\n'.join(lines))
EOF

섹션 / 노드 ID 매핑

File key: MnwN1Uzg5F6ks9Clr1brLW

섹션 PC node-id PC 파일 Mobile node-id Mobile 파일
01 HOME 2247:2094 01-home-pc.json / .txt 2319:2232 01-home-mobile.json / .txt
02 ABOUT US (Expertise 포함) 2247:2230 02-about-pc.json / .txt 2319:2288 02-about-mobile.json / .txt
03 HISTORY 2247:2121 03-history-pc.json / .txt 2319:2433 03-history-mobile.json / .txt
04 VISION 2247:2183 04-vision-pc.json / .txt 2319:4183 04-vision-mobile.json / .txt
05 PROJECT 2247:2202 05-project-pc.json / .txt 2319:4231 05-project-mobile.json / .txt
06 CONTACT/FOOTER (문서상 라벨은 "Expertise"지만 실제 내용은 CONTACT/FOOTER) 2247:2253 06-contact-pc.json / .txt 2319:5082 06-contact-mobile.json / .txt
GNB 모바일 드로어 (열린 상태) 2319:5998 gnb-drawer-mobile.json / .txt

Components 캔버스 (디자인 시스템 원본)

문서에는 Screen Pages 캔버스 말고 **Components 캔버스(id 12:92)**가 별도로 있다. 버튼/인풋/체크박스/GNB/footer/프로젝트 카드/배지/아이콘 등 32개 컴포넌트의 "원본" 정의가 여기 있고, 페이지 정적 렌더에는 안 보이는 호버/액티브 같은 variant도 포함되어 있다.

  • 07-components.json — 캔버스 전체 원본 (32개 컴포넌트, ~600KB)
  • 07-components.txt — 컴포넌트별로 배경색/보더/radius/padding/gap/텍스트 스타일을 평탄화한 요약

.txt는 위 스크립트와 다른(배경·보더·radius·padding까지 같이 뽑는) 별도 스크립트로 생성했다 — 필요하면 같은 패턴으로 재생성 가능 (fills/strokes/cornerRadius/paddingLeft 등 노드 속성을 그대로 읽으면 됨).

MAIN_NEW_PC, MAIN_NEW_MO 프레임 말고도 NEW 섹션 바로 아래에 화면에는 안 보이는 노드들이 더 있었다 (문서 전체를 depth=4로 한 번 훑어서 발견함). 자세한 내용과 구현 영향은 11-interaction-notes.md 참고.

  • 08-footer-instance-pc.json / 08-footer-instance-mobile.json — footer 전용 인스턴스 PC(2247:2294) / Mobile(2319:4996, 2026-06-29 누락 발견 후 추가 수집). 둘 다 내용(THE BODA LAB / Mail koji@bodalab.co.kr / Tel 010-4169-4728 / © 2026 BODA LAB)이 기존 구현과 일치, 수정 불필요.
  • 09-privacy-modal-pc.json / 09-privacy-modal-mobile.json — 개인정보 수집·이용 동의 모달 (2319:2118 / 2376:2184). 현재 코드에 미구현.
  • 10-history-duplicate-ref.json — HISTORY 중복 프레임(2301:1896, 참고용 사본으로 추정, 내용은 03-history-pc와 동일).
  • 11-interaction-notes.md — 디자이너가 텍스트 노트로 남긴 동작 스펙 모음 (아코디언 단일열림, PROJECT/태그 더보기 페이지네이션, SEND 버튼 유효성 검증 등). 다수가 현재 코드에 미구현 상태.

완전성 체크 (2026-06-28 기준)

  • GET /v1/files/:key?depth=4 로 문서 전체 캔버스/섹션 구조를 확인함 → 캔버스는 Screen Pages, Components 2개뿐, NEW 섹션의 직계 자식도 전부 나열해서 확인함 (위 footer/모달/주석 포함).
  • 이미 받은 13개 섹션 .txt 안에 동작 주석이 섞여있는지 grep으로 재검색함 → 없음 (06-contact의 "동의" 매칭은 이미 아는 체크박스 라벨 텍스트).
  • 스타일(폰트/색상/간격/보더) 스펙은 사실상 전부 확보, 동작(behavior) 스펙도 이번에 전부 찾아서 11-interaction-notes.md에 정리. 단, 이미지/비트맵 자산은 여전히 미포함(사용자가 직접 export), 이 모든 건 캡처 시점 스냅샷이라 Figma 원본이 바뀌면 재동기화 필요.

재검증 (2026-06-29)

  • depth=4 구조를 다시 받아 위 매핑표·컴포넌트 개수(32개)와 노드 단위로 대조함. PC/모바일 6섹션, 컴포넌트 캔버스, 모달, HISTORY 중복 프레임, 인터랙션 노트 텍스트는 전부 일치 확인.
  • 누락 발견 및 보완: NEW 섹션 형제 노드 중 모바일 footer 인스턴스(2319:4996)가 그동안 한 번도 수집되지 않았었음(PC footer 2247:2294만 받아뒀었음). REST API로 추가 수집해서 08-footer-instance-mobile.json으로 저장. 내용은 PC와 동일(koji@bodalab.co.kr / 010-4169-4728)하고 현재 구현과도 일치 — 추가 수정 불필요.
  • 그 외 visible: false로 꺼진 미사용 초안 프레임(2319:2392, "Expertise" 텍스트, ABOUT US 섹션 내용과 중복) 하나를 발견했으나 비활성 상태라 무시함.

사용 시 주의

  • 좌표는 모두 Figma 캔버스 절대좌표(absoluteBoundingBox)다. CSS 값으로 옮길 때는 같은 프레임 안의 다른 좌표와의 차이(간격, 오프셋)로 환산해서 써야 한다 — 절대값 자체를 그대로 px로 쓰면 안 된다.
  • 프레임 폭은 PC 1920px / Mobile 390px 캔버스 기준이다. clamp()로 반응형 값을 만들 때는 (figma px / 캔버스 폭) * 100 으로 vw 비율을 환산한다.
  • 이 JSON은 캡처 시점(2026-06-28) 스냅샷이다. Figma 원본이 그 뒤에 수정됐다면 재호출해서 갱신해야 한다.