Communitygithub.com

biokineX/figma-landing

Figma 디자인을 블록 단위로 순수 HTML/CSS/JS 랜딩 페이지로 변환하며, 각 블록마다 사용자 확인을 받습니다.

figma-landing란 무엇인가요?

이 스킬은 Figma MCP를 통해 전달받은 Figma 링크를 기반으로 랜딩 페이지를 순수 HTML, CSS, JavaScript로 변환합니다. 큰 디자인을 한 번에 변환하지 않고, 섹션별(헤더, 히어로, 장점, 푸터 등)로 나누어 각 블록을 구현한 후 사용자에게 확인을 요청하는 인터랙티브한 방식을 채택하고 있습니다. 이를 통해 사용자는 각 섹션의 디자인과 정확성을 단계적으로 검토할 수 있습니다. 데스크톱과 모바일 버전 모두 지원하며, Figma 파일에서 프레임과 노드 정보를 추출하여 각 기기에 맞는 반응형 디자인을 적용합니다. 또한 BEM 방법론, 접근성, 호버 효과, 이미지 최적화(WebP), 로컬 서버를 통한 실시간 미리보기 등 실무에 바로 사용 가능한 프런트엔드 개발 모범 사례를 포함하고 있습니다. AGENTS.md 템플릿을 통해 프로젝트별 규칙을 관리하며, UI 상태(호버, 포커스 등)는 사용자와 협의하여 결정합니다. 이 스킬은 Claude Code, Cursor, Codex 등 Figma MCP를 지원하는 모든 AI 에이전트 플랫폼에서 사용할 수 있습니다.

지원 대상~Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/biolineX/figma-landing/tree/HEAD

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

Figma → HTML/CSS/JS 랜딩 페이지

이 스킬은 Figma 디자인 레이아웃을 정적인 HTML, CSS, JS 랜딩 페이지 코드로 변환합니다. 작업은 블록 단위로 진행되며, 각 블록 이후 에이전트는 중단하고 사용자의 확인을 기다립니다.

자세한 코딩 규칙(구조, BEM, 단위, 이미지, 호버 등)은 templates/AGENTS.md 파일에 정의되어 있습니다. 3단계에서 이 파일을 프로젝트 루트에 복사한 후 계속 적용합니다.

요구 사항

  • Figma MCP가 연결되어 있어야 합니다 (get_metadata, get_design_context, get_screenshot, 가능하면 get_variable_defs). 연결되어 있지 않으면 사용자에게 알리고 작업을 중단합니다.
  • 사용자가 https://www.figma.com/design/:fileKey/:fileName?node-id=1-2 형식의 링크를 제공해야 합니다.
  • 로컬 서버, 스크린샷, WebP 변환을 위해 Node.js가 필요합니다. npx 명령어는 최초 실행 시 패키지를 다운로드하므로 Codex가 권한을 요청할 수 있습니다. 이는 정상적인 동작입니다.

작업 순서

순서대로 단계를 수행하며 건너뛰지 마세요.

1단계: 링크 분석

  • fileKey: /design/ 다음 부분입니다. 링크에 /branch/:branchKey/가 포함된 경우 branchKey를 사용합니다.
  • nodeId: node-id 값이며, 하이픈(-)을 콜론(:)으로 바꿉니다 (예: 1-2 → 1:2).
  • 링크는 전체 문서, 페이지, 데스크톱 프레임 또는 모바일 프레임을 가리킬 수 있습니다. 유형은 2단계에서 결정합니다.

2단계: 레이아웃 맵

  1. 링크의 노드에 대해 get_metadata를 호출합니다 (전체 문서의 경우 node-id 없이 또는 루트 페이지로 호출).
  2. 랜딩 페이지의 버전별 프레임(데스크톱, 모바일, 가끔 태블릿)을 찾습니다. 너비는 레이아웃에서 직접 결정하며 표준 값을 사용하지 않습니다. 또한 페이지에 모달 창(팝업)과 열린 모바일 메뉴의 별도 프레임이 있는지 찾습니다.
  3. 각 프레임 내에서 상위 수준의 섹션(헤더, 히어로, 장점, 리뷰, 푸터 등)을 식별합니다.
  4. 버전 간 섹션을 매핑합니다: "데스크톱 섹션 ↔ 모바일 섹션" (레이어 이름, 순서, 내용 기준).
  5. 사용자에게 맵을 보여주고 확인을 기다립니다:
너비: 데스크톱 1440, 모바일 375
1. header      — 12:30 ↔ 40:2
2. hero        — 12:45 ↔ 40:18
3. advantages  — 13:10 ↔ 41:5
...
모달 창 / 메뉴:
- mobile-menu  — 45:12
- popup-order  — 46:01

모바일 버전이 없으면 사용자에게 알리고 진행 방법을 문의합니다.

3단계: 프로젝트 골격 및 기본 UI

  1. 프로젝트 루트에 AGENTS.md가 없으면 스킬 폴더에서 templates/AGENTS.md를 복사합니다. AGENTS.md의 "이 랜딩 페이지" 섹션을 2단계의 데이터(너비, 컨테이너, 글꼴)로 채웁니다. 중단점은 기본값으로 두고, 레이아웃이 다른 너비에서 깨지는 경우에만 변경하고 새 값을 기록합니다.
  2. index.html, style.css, script.js, assets/icons/ 디렉토리를 만듭니다.
  3. index.html: <!doctype html>, lang="ko", charset, viewport, 랜딩 페이지 의미에 맞는 <title>과 <meta name="description">을 포함합니다. 파비콘은 추가하지 않습니다. script.js는 defer 속성으로 연결합니다.
  4. 글꼴: get_design_context/get_variable_defs에서 가져오고, 필요한 굵기만 Google Fonts로 연결합니다 (display=swap). Google Fonts에 없는 글꼴이면 사용자에게 파일을 요청하고 assets/fonts/에 @font-face로 추가합니다.
  5. style.css: 스타일 리셋(AGENTS.md 참조) 후 :root에 색상, 글꼴, 간격, 컨테이너 너비 변수를 선언합니다. 값은 get_variable_defs에서 가져오고, 변수가 없으면 레이아웃에서 추출하여 반올림합니다.
  6. 기본 컴포넌트: 레이아웃에서 반복되는 요소(버튼, 섹션 제목, 입력 필드)를 재사용 가능한 클래스(.btn, .section-title, .input, .container)로 추출합니다. 레이아웃에 UI 키트(호버, 포커스, 액티브 상태)가 없으면 한 번 사용자에게 일반적인 버튼과 링크의 마우스 오버 규칙을 전체 프로젝트에 대해 질문합니다. 답변은 AGENTS.md의 "이 랜딩 페이지" 섹션 "UI 상태" 줄에 기록합니다.
  7. 도구 (한 번만):
    • 프로젝트 루트에서 백그라운드 로컬 서버 실행: npx -y serve -l 3000 (대안: python3 -m http.server 3000). 모든 스크린샷은 http://localhost:3000에서 촬영하며 file://은 사용하지 않습니다.
    • 스크린샷 촬영 방법 확인: Playwright MCP가 연결되어 있으면 사용; 그렇지 않으면 scripts/shot.cjs 스크립트 사용 ("자체 확인" 참조).
    • 이미지 변환기 확인 ("이미지" 참조) 및 결과 기억.
  8. 사용자에게 골격이 준비되었음을 알리고 첫 번째 블록으로 이동합니다.

4단계: 블록 단위 작업

맵의 각 섹션에 대해 위에서 아래로 순서대로 엄격히 진행합니다 (양식 섹션 포함):

  1. 데이터. 데스크톱 섹션과 해당 모바일 섹션에 대해 get_design_context 및 get_screenshot을 호출합니다.
    • 응답이 잘렸거나 너무 크면 get_metadata로 섹션 정보를 가져오고 하위 노드를 개별적으로 가져옵니다.
    • 응답의 코드(보통 React + Tailwind)는 크기, 색상, 구조에 대한 참고 자료로만 사용합니다. 스타일을 복사하지 마세요.
  2. 이미지. 블록의 에셋을 다운로드하고 처리합니다 ("이미지" 참조).
  3. 마크업. index.html에 블록 HTML을 추가하고, style.css에 주석 /* ===== hero ===== */와 함께 별도 섹션으로 스타일을 추가하며, JS가 필요하면 script.js에 추가합니다. 3.6단계의 기본 클래스를 사용하며 버튼과 제목 코드를 중복하지 않습니다. 먼저 데스크톱을 작성한 후 clamp()와 미디어 쿼리를 사용하여 모바일까지 반응형으로 만듭니다.
    • header의 경우 모바일 너비에서 즉시 버거 메뉴를 구현합니다 (맵의 프레임을 기반으로 하거나 사용자에게 유형 확인).
    • 블록에 양식이 있으면 기본 브라우저 유효성 검사 속성(required, type="email", type="tel", pattern)을 포함하여 마크업하지만, JS 전송 로직은 구현하지 않습니다.
  4. 자체 확인. 데스크톱, 모바일 및 중간 너비(1024, 768)에서 현재 섹션만 스크린샷을 촬영합니다. Figma 스크린샷과 비교하여 여백, 크기, 글꼴, 색상, 줄바꿈을 확인하고 수정한 후 다시 촬영합니다.
    • Playwright MCP를 통해 각 너비에서 섹션 요소의 스크린샷을 촬영합니다.
    • MCP가 없으면 스킬 폴더의 스크립트를 사용합니다:
      # 한 번만
      mkdir -p .screens && cp <skill-folder>/scripts/shot.cjs .screens/
      npm i playwright --prefix .screens && npx -y playwright install chromium
      # 각 블록 후
      node .screens/shot.cjs http://localhost:3000 .hero 1440,1024,768,375
      
      스크립트는 .screens/<section>-<width>.png를 저장하고 페이지가 화면 너비를 초과하면 ⚠ horizontal scroll 경고를 출력합니다. 모든 경고는 원인을 수정해야 합니다 (body에 overflow: hidden을 사용하여 숨기지 않음).
    • 섹션 스크린샷은 블록 확인 후 삭제합니다. 스크립트와 node_modules는 .screens/에 유지합니다 (6단계까지).
  5. 보고 및 중단. 사용자에게 간단히 보고합니다: 완료된 작업, 레이아웃과의 차이점 및 이유, 블록의 고유한 인터랙티브 요소(비표준 카드 호버, 슬라이더 매개변수)에 대한 확인 사항. 사용자의 확인을 기다립니다. 사용자의 수정 사항을 동일한 블록에 반영한 후 다시 기다립니다.
  6. "확인" 후에만 다음 블록으로 진행합니다.

5단계: 모달 창 및 양식 로직

모든 주요 섹션 구현 후:

  1. 2단계에서 발견된 숨겨진 모달 창(팝업)을 구현하고 열기/닫기 트리거(버튼, Esc, 오버레이 클릭)를 연결합니다. 동작은 AGENTS.md의 "JavaScript" 섹션을 따릅니다.
  2. 각 모달 창은 별도 블록으로 처리: 열린 상태의 스크린샷 자체 확인, 보고, 사용자 확인 대기.
  3. 페이지의 모든 양식이 제대로 작동하는지 확인합니다. 사용자가 명시적으로 요청하고 엔드포인트 또는 명세를 제공하지 않는 한 데이터 전송(fetch/AJAX)은 구현하지 않습니다.

6단계: 마무리

마지막 단계 확인 후: 전체 페이지를 모든 너비에서 확인하고, 임시 파일 및 폴더(assets/_raw/, .screens/ 전체)를 삭제하고, 백그라운드 로컬 서버를 중지하고, 사용되지 않는 스타일과 이미지를 제거합니다. 간단한 요약문을 작성합니다.

이미지

  1. 블록의 에셋은 Figma MCP 응답(get_design_context의 이미지 링크)에서 가져옵니다. localhost 주소가 반환되면 그대로 다운로드합니다. 대체 이미지나 타사 아이콘 세트를 사용하지 마십시오.
  2. 임시 디렉토리 assets/_raw/<block>/에 다운로드하고, 래스터 이미지는 레이아웃 크기의 2배(2x)로 다운로드합니다.
  3. 반응형 그래픽: 모바일 버전에서 크롭된 이미지(다른 비율) 또는 의미가 다른 이미지를 사용하는 경우 두 버전을 모두 다운로드하고 (hero-bg-desktop.webp 및 hero-bg-mobile.webp), <picture> 요소로 연결합니다.
  4. 분류:
    • 호버 시 색상이 변경되어야 하는(fill/stroke) 인터랙티브 요소(버튼, 링크) 내부의 작은 아이콘: HTML에 fill="currentColor"를 사용한 인라인 <svg> (또는 CSS mask-image 사용).
    • 정적 아이콘, 로고, 간단한 그래픽: assets/icons/에 SVG 파일로 저장하고 <img>로 연결 (또는 큰 그래픽의 경우 블록 폴더에 저장). 아이콘이 래스터로 제공되면 사용자에게 알립니다.
    • 사진 및 복잡한 이미지: assets/<block>/에 WebP로 저장.
  5. WebP 변환, 품질 80. 시도 순서:
    1. npx -y sharp-cli -i in.png -o out.webp -f webp -q 80 (Node.js 필요);
    2. cwebp -q 80 in.png -o out.webp;
    3. 도구가 없으면 원본 형식을 유지하고 한 번 사용자에게 도구 설치(Node.js 또는 cwebp)를 알리되 작업을 중단하지 않습니다.
  6. WebP가 원본보다 용량이 크면 원본을 유지합니다.
  7. 파일 이름: 라틴 문자, 소문자, 하이픈 연결, 의미에 따라 (hero-photo.webp, arrow-right.svg).
  8. 블록 확인 후 assets/_raw/<block>/ 디렉토리를 삭제합니다.

호버, 애니메이션, 슬라이더

  • 호버: 기본 버튼 및 링크는 AGENTS.md의 "UI 상태" 줄에 정의된 규칙을 따릅니다. 블록에 레이아웃에 상태가 정의되지 않은 고유한 인터랙티브 카드/요소가 있는 경우 임의로 만들지 말고 블록 보고서에서 사용자에게 문의합니다.
  • 스크롤 애니메이션 및 사용자 정의 애니메이션: 사용자가 직접 요청한 경우에만 구현합니다. 먼저 정확히 어떤 동작을 원하는지 확인합니다. 간단한 애니메이션(스크롤 시 나타나기)은 IntersectionObserver를 사용하고, 복잡한 애니메이션(휠에 연결, 고정 섹션, 패럴랙스)은 사용자 동의를 받은 후에만 CDN의 GSAP를 사용합니다. 항상 prefers-reduced-motion을 고려합니다.
  • 슬라이더: 간단한 슬라이더(화살표, 점, 스와이프)는 CSS scroll-snap과 약간의 JS로 직접 구현합니다. 복잡한 슬라이더(무한, 자동 재생, 효과, 연결된 슬라이더)는 CDN의 Swiper를 사용합니다.

일반적인 문제

  • Figma 응답 잘림 → 섹션에 get_metadata를 호출한 후 하위 노드에 대해 get_design_context를 호출합니다.
  • 섹션의 모바일 쌍 또는 모바일 메뉴 프레임이 보이지 않음 → 사용자에게 문의하고 임의로 만들지 않습니다.
  • 글꼴 너비가 레이아웃과 일치하지 않음 → 굵기와 letter-spacing을 확인하고 글꼴 크기를 조정하지 않습니다.
  • 이미지 다운로드 실패 → Figma MCP가 실행 중인지 확인하고 링크를 그대로 사용합니다.
  • 스크린샷에서 글꼴 또는 아이콘이 누락됨 → localhost:3000에서 서버가 실행 중이고 file://이 아닌 해당 주소에서 스크린샷을 촬영하는지 확인합니다.
  • 스크립트가 "가로 스크롤"을 출력함 → 화면보다 넓은 요소(고정 너비, 큰 gap, 가장자리 장식)를 찾아 수정합니다. 가장자리 장식은 해당 섹션에 overflow-x: clip을 적용합니다.
  • 접근성 또는 기술적 제약으로 인한 레이아웃 차이 → 허용되지만 블록 보고서에 언급해야 합니다.

관련 스킬