Tailwind 계열 디자인 토큰 킷(Figma)을 받아 스타일가이드와 tokens.css를 만드는 절차 문서다. 프로젝트가 바뀌어도 그대로 쓰고, { } 자리만 갈아 넣는다. 킷을 처음 열어 보는 사람도 이 순서대로 따라가면 세 가지가 남는다 — 선택표(남길 토큰 목록과 근거), tokens.css(Tailwind v4 @theme 블록), Figma Style Guide 페이지.
맨 뒤 8장에 실제 킷 하나를 이 절차로 진단한 결과를 붙였다. 본문을 읽다 “실제로는 어떤 모양인가”가 궁금하면 그 장을 함께 본다.
0 – 이 문서 쓰는 법
문서 안의 { }는 프로젝트마다 채워 넣는 값이다. 작업을 시작하기 전에 아래 표를 먼저 채운다. 채우다 막히는 자리가 곧 아직 결정되지 않은 항목이다.
| 자리표시자 | 뜻 | 채운 값 |
|---|---|---|
{파일} | 디자인 토큰 킷 Figma 파일 이름 | |
{fileKey} | 그 파일의 fileKey (URL의 /design/ 다음 문자열) | |
{색상 프레임 id} | Color Palette 프레임의 node-id | |
{아이콘 프레임 id} | 아이콘 세트 프레임의 node-id | |
{프로젝트} | 만들 사이트의 성격 (예: 기업 ESG 소개 사이트) | |
{페이지 목록} | 만들 페이지 이름 | |
{브랜드 스케일} | 브랜드 주색으로 쓸 색상 스케일 이름 | |
{중립 스케일} | 본문·배경·테두리에 쓸 회색 계열 스케일 이름 | |
{폰트} | 확정한 웹폰트 이름 | |
{기존 시맨틱} | 킷에 이미 만들어져 있는 시맨틱 컬렉션 이름 (없으면 “없음”) | |
{목업 티어} | 목업을 만들 화면 폭 (예: 390 / 1440) |
node-id는 Figma에서 프레임을 선택한 뒤 링크를 복사하면 URL 끝의 node-id=12-34 형태로 나온다. 도구에 넣을 때는 하이픈을 콜론으로 바꿔 12:34로 쓴다.
마지막 두 줄은 이 문서에서 새로 추가한 항목이다. {기존 시맨틱}이 “없음”이 아니면 4.1의 작업 성격이 달라진다. 이름을 새로 만드는 작업이 아니라, 이미 있는 이름에 값을 연결하는 작업이 된다.
1 – 킷 현황 파악
여기서는 킷에 무엇이 얼마나 들어 있는지 세고, 앞선 작업자가 손댄 부분이 있는지 확인한다. 규모를 모르고 값을 고르기 시작하면 팀원마다 다른 자리에서 다른 값을 집는다.
1.1 – 먼저 규모를 센다
Tailwind 토큰 킷은 보통 아래 프레임으로 구성된다. 각 프레임에 몇 개가 들어 있는지, 그중 실제로 몇 개가 필요한지를 먼저 적는다.
| 프레임 | 들어 있는 양(일반적) | 4~6페이지 정적 사이트에 필요한 양 |
|---|---|---|
| Color Palette | 20개 이상 스케일 × 약 11단계 ≒ 250개 | 14~18개 |
| Typography | 12크기 × 9굵기 = 108개 조합 | 9개 |
| Breakpoint | xs~2xl 6단계 + width·container 규칙 | 2개 (base 포함 3티어) |
| Sizing | width / max-width / min-width 전체 | 4~5개 |
| Spacing | 간격 스케일 전체 | 8~9개 |
| Border | radius 8단계 + width 5단계 + 방향별 변형 | 5개 |
| Shadow | 전체 단계 | 2개 |
| Filter | blur / backdrop 전체 | 0~1개 |
| Icon set | 노드 이름 기준 1,000개 이상 | 12~16개 |
이런 킷은 브랜드가 반영된 스타일가이드가 아니라 원재료 창고다. 전체의 5% 남짓만 쓰게 된다. 옷장 문을 열어 옷을 다 꺼내 놓은 상태와 같아서, 입을 옷을 고르는 일이 남아 있다.
1.2 – 커스텀 작업이 이미 있는지 확인한다
원본 킷에 없는 것이 추가돼 있으면 그것이 작업의 출발점이다. 앞선 작업자의 결정을 지우고 다시 시작하면 같은 판단을 두 번 하게 된다. 자주 보이는 세 유형이다.
커스텀 색상 스케일 — 원본 Tailwind에 없는 이름의 색 스케일이 들어 있으면, 앞선 작업자가 브랜드 컬러로 쓰려 한 것이다. 값이 온전한지(단계 누락 없는지) 확인한다.
뷰포트 매핑 메모 — “목업은 몇 개 티어에서만 만든다”는 규칙이 프레임 안에 글로 적혀 있는 경우가 있다. 있으면 그대로 채택한다. 없으면 3.4에서 정한다.
이미 만들어진 시맨틱 컬렉션 — Variables 화면에 Semantic 같은 이름의 컬렉션이 있고 그 안에 surface/bg-default처럼 역할 이름이 들어 있는 경우다. 이 경우 4.1에서 이름을 새로 만들지 않는다. 있는 이름에 값을 연결하는 것으로 작업이 바뀐다.
기존 시맨틱 컬렉션을 못 보고 이름을 새로 만들면, 뜻이 같은 이름이 두 벌 생긴다. 팀원 절반이 brand/primary를, 나머지가 surface/bg-brand를 쓰게 되고 어느 쪽이 맞는지 아무도 판단하지 못한다. Variables 화면의 컬렉션 목록을 먼저 확인한 다음 4장으로 넘어간다.
목업 티어는 3개면 충분하다. 아래는 예시 값이다.
| 티어 | 목업 프레임 폭 | Tailwind 대응 | 콘텐츠 폭 | 좌우 패딩 |
|---|---|---|---|---|
| 모바일 | 390 | 없음(base) | 358 | px-4 |
| 태블릿 | 768 | md 768 | 720 | px-6 |
| 데스크톱 | 1440 | xl 1280 | 1280 | — |
나머지 브레이크포인트는 container가 자동 처리하므로 목업을 만들지 않는다.
프로젝트에서 목업을 2티어(모바일·데스크톱)로만 만들기로 정한 경우도 있다. 그때도 태블릿 폭에서 화면이 깨지지 않는지는 확인해야 한다. 목업을 안 만든 폭은 아무도 안 본 폭이 되므로, 3.4에서 md 브레이크포인트를 남기고 브라우저 창을 줄여 눈으로 확인하는 절차를 따로 넣는다.
1.3 – 받은 링크의 노드가 실재하는지 확인한다
작업을 시작하기 전에 반드시 확인한다. 전달받은 Figma 링크의 node-id가 현재 파일에 없는 경우가 흔하다. 원인은 셋 중 하나다.
- 해당 노드를 삭제한 뒤 링크만 남았다.
- 브랜치(branch, 원본 파일에서 갈라낸 작업용 사본) 파일에서 복사한 링크다.
- 다른 파일의 링크를 잘못 붙였다.
확인 방법은 파일의 최상위 페이지 목록부터 훑어 내려가며 노드 번호대를 보는 것이다. 파일 전체가 60:xxxx 대인데 링크가 2000:xxxx를 가리키면 그 링크는 이 파일 것이 아니다.
번호대가 아니라 목록끼리 어긋나는 경우도 있다. 라이브러리에 발행된 컴포넌트를 검색하면 이름이 잡히는데, 그 파일의 페이지 구조를 훑어보면 그 컴포넌트가 어디에도 없는 경우다. 이때는 브랜치에서 발행된 것이거나 페이지 목록이 온전히 읽히지 않은 것이므로, 값을 바꾸기 전에 파일 안에서 직접 확인한다.
없는 노드를 그대로 두고 진행하면 나중에 “그 프레임에 있던 규칙”을 놓친 채 작업이 끝난다.
1.4 – 진단 결과를 한 번에 받는다
1.1부터 1.3까지를 손으로 훑는 대신 프롬프트 한 벌로 받을 수 있다. 파일을 바꾸지 않고 상태만 물어보는 프롬프트이므로, 값을 고치기 전에 이것부터 돌린다.
- Chrome 주소창을 클릭한다.
{파일}의 Figma URL을 입력하고 Enter 키를 누른다.- 파일이 열리면 AI 에이전트 대화창을 연다.
- 바탕화면에서 마우스 오른쪽 버튼을 클릭한다.
- [새로 만들기] → [텍스트 문서]를 선택한다.
- 파일 이름을
"styleguide_notes.txt"로 입력하고 Enter 키를 누른다. - 5.0의 진단 프롬프트를 복사해 대화창에 붙여 넣는다.
- 답이 오면 답 전체를
"styleguide_notes.txt"에 붙여 넣는다.
메모 파일을 따로 두는 이유는 진단 답과 나중에 정한 결정을 갈라 두려는 것이다. 한자리에 몰아 적으면 어디까지가 파일에서 읽은 사실이고 어디부터가 팀이 정한 값인지 나중에 구분되지 않는다.
프롬프트를 붙여 넣을 창은 두 가지 중 팀이 이미 쓰는 쪽을 고른다.
Figma 파일 화면에서 오른쪽 위의 [AI] 아이콘을 클릭해 대화창을 연다. 파일이 이미 열려 있으므로 fileKey를 따로 알릴 필요가 없다.
터미널에서 claude를 실행해 세션을 연다. /mcp로 Figma MCP 서버 연결을 확인한다. 이 세션에는 파일이 열려 있지 않으므로 프롬프트에 fileKey를 반드시 적는다.
두 방법 모두 프롬프트 내용은 같다. 차이는 fileKey를 적어야 하는지 여부뿐이다.
2 – 먼저 고쳐야 할 결함
토큰 값을 훑어 아래 네 가지를 점검한다. 바이브 코딩(AI에게 요청해 코드를 받아내는 개발 방식)에서 AI가 값을 고를 때 판단을 흐리는 지점이므로 선택 작업 이전에 정리한다.
2.1 – 값이 중복된 토큰
같은 스케일 안에서 인접한 두 단계의 값이 동일한 경우다. 킷을 손으로 옮겨 적는 과정에서 흔히 생긴다.
실제로 확인된 사례다. 받은 킷에서도 같은 지점을 먼저 본다.
| 토큰 | 발견된 값 | Tailwind 원본 |
|---|---|---|
neutral/800, neutral/900 | 둘 다 #262626 | 900은 #171717 |
zinc/700, zinc/800 | 둘 다 #3f3f46 | 800은 #27272a |
indigo/500, indigo/600 | 둘 다 #6366f1 | 600은 #4f46e5 |
이것이 왜 문제인지는 검수 자리에서 드러난다. “본문은 neutral-800″이라고 지시해도 팔레트에서 800과 900이 같은 색으로 보이면 사람이 검수할 때 어느 쪽이 맞는지 판별할 수 없다. 명도 단계가 무너진 스케일은 대비 계산도 틀어진다.
점검 방법은 스케일별로 50부터 950까지 값을 나열해 인접 값이 같은 곳을 찾는 것이다. Tailwind 공식 색상표와 대조한다.
2.2 – 누락된 토큰
커스텀 스케일에서 중간 단계가 비어 있는 경우다. 특히 500 단계 누락이 잦다. 가장 자주 쓰는 값이므로 반드시 채운다.
인접 단계의 명도 간격을 보고 보간한 값을 넣는다. 500이 없으면 버튼 마우스 오버 같은 미세 조정 단계를 만들 수 없다.
2.3 – 한글 폰트 미정의
font/family/sans 값이 라틴 전용 폰트 하나로만 돼 있는 경우다. 이 상태로 코드를 뽑으면 한글은 브라우저 기본 폰트로 렌더링돼 Figma 시안과 실제 화면이 달라진다.
Google Fonts는 Noto Sans와 Noto Sans Korean을 서로 다른 패밀리로 제공한다.
Noto Sans 소개 문구는 라틴·키릴 계열 문자를 위한 디자인이라고 밝히고 있다.
즉 킷에 font/family/sans = Noto Sans라고 적혀 있어도 그것만으로 한글이 같은 글꼴로 나온다고 볼 수 없다.
한국어가 주 언어면 셋 중 하나를 결정한다.
Pretendard단일 — 라틴과 한글을 한 패밀리에서 다룬다.Noto Sans KR단일.- 라틴 폰트와 한글 폰트를 함께 적는다. 예:
font-family: "Inter", "Noto Sans KR", sans-serif.
결정한 뒤 실제 한국어 문장을 목업에 넣어 눈으로 확인한다. 라틴 더미 텍스트로만 검증하면 한글에서 행간이 좁아 보이는 문제와 글꼴이 대체된 문제를 둘 다 놓친다.
2.4 – 자간 일괄 0
킷의 타이포 토큰은 letterSpacing이 전부 0인 경우가 많다. 라틴 기준값이다.
한글 제목을 큰 크기로 쓸 때는 음수 자간(-0.02em 내외)이 일반적이다. 제목용 토큰만 별도 자간을 갖게 할지 결정한다.
3 – 무엇을 남기고 무엇을 버릴지
앞에서 킷의 규모와 결함을 확인했으니, 이제 실제로 쓸 것만 골라낸다. 이 장이 이 문서의 중심이다.
3.1 – 왜 줄이는가
- 사람 쪽 — 팀원 여럿이 각자 250개 색에서 고르면 같은 회색을 저마다 다르게 집는다. 페이지마다 다른 사이트처럼 보이는 원인의 대부분이 여기서 나온다.
- AI 쪽 — “카드 배경은 연한 회색”이라고 말하면 AI는
bg-gray-50,bg-slate-100,bg-zinc-50,bg-neutral-100중 아무거나 고른다. 선택지를 남겨 두면 매번 다르게 고른다. 선택지를 미리 좁혀 주는 것이 바이브 코딩 품질 관리의 거의 전부다.
3.2 – 남길지 버릴지 판단하는 세 질문
셋을 모두 통과해야 남긴다.
질문 1 — 화면에 실물이 있는가. “있으면 좋을 것 같아서”는 안 된다. 와이어프레임이나 목업에 그 속성을 쓴 요소가 실제로 그려져 있어야 한다. 예를 들어 shadow-2xl을 쓴 요소가 어느 페이지에도 없으면 버린다.
질문 2 — 두 번 이상 쓰이는가. 한 곳에서만 쓰는 값은 토큰으로 만들지 않는다. 토큰의 목적은 반복되는 것을 한 이름으로 묶는 것이다. 특정 페이지 지도 영역 높이 480px 같은 값은 그 자리에 직접 적는다.
질문 3 — 팀원이 이름을 외울 수 있는가. 카테고리별 개수 상한을 미리 정하고 그 안에서만 고른다. 못 외우면 안 쓰고, 안 쓰면 하드코딩이 돌아온다. 경험적 상한은 카테고리당 10개 안팎이며, 색만 18개까지 허용한다.
3.3 – 선택 절차 — 화면에서 역산한다
팔레트를 펼쳐 놓고 고르면 사람마다 다른 값을 집으므로 방향을 반대로 잡는다. 아래 다섯 단계를 차례로 밟는다.
- 전체 페이지의 화면 요소 목록 만들기
- 요소마다 필요한 속성 종류 적기 (수치는 아직 안 적음)
- 같은 속성끼리 묶어 빈도 세기
- 빈도 낮은 것부터 잘라 상한 맞추기
- 남은 것에 시맨틱 이름 붙이기
이 순서를 지키면 선택의 근거가 화면에 남는다. 나중에 “왜 이 색은 없느냐”는 질문을 받아도 표를 짚어 답할 수 있다.
첫째로 화면 요소 목록을 만든다. 모든 페이지에 나오는 요소를 빠짐없이 적는다. 이 표가 선택의 근거 자료가 된다. 아래는 작성 형식 예시이므로 {페이지 목록}에 맞춰 채운다.
| 페이지 | 섹션 | 요소 |
|---|---|---|
| 메인 | 헤더 | 로고, 메뉴 5개, 언어 전환, 햄버거(모바일) |
| 메인 | 히어로 | 배경 이미지, 대제목, 부제목, 주 버튼 |
| 메인 | 소개 영역 | 아이콘, 소제목, 설명문, 더보기 링크 × 3 |
| 메인 | 목록 미리보기 | 카드 3개(썸네일·배지·제목·링크) |
| 메인 | 푸터 | 로고, 주소, 연락처, 링크 목록, 저작권 |
| 서브 | 브레드크럼 | 홈에서 현재 페이지까지의 경로 |
| 서브 | 페이지 헤더 | 제목, 설명, 배경 |
| 서브 | 본문 | 소제목, 문단, 목록, 이미지, 인용 |
| 목록 | 필터 | 선택 상자, 카테고리 탭 |
| 목록 | 목록 | 표 또는 카드(제목·부가정보·동작 버튼) |
| 문의 | 폼 | 입력칸, 선택칸, 체크박스, 전송 버튼, 오류 메시지 |
| 문의 | 정보 | 주소, 전화, 이메일, 지도 |
둘째로 속성을 태깅한다. 요소마다 어떤 속성이 필요한지만 적고 값은 아직 정하지 않는다.
| 요소 | 색 | 글자 | 간격 | 모서리 | 그림자 | 아이콘 |
|---|---|---|---|---|---|---|
| 주 버튼 | 배경·글자·마우스 오버 배경 | 라벨 | 안쪽 여백 | 있음 | 없음 | — |
| 카드 | 배경·테두리 | 제목·본문 | 안쪽 여백·요소 간격 | 있음 | 약함 | — |
| 메뉴 링크 | 기본·마우스 오버·현재 | 라벨 | 좌우 여백 | 없음 | 없음 | 하위 표시 |
| 입력칸 | 배경·테두리·포커스·오류 | 입력값·라벨 | 안쪽 여백 | 있음 | 없음 | — |
셋째로 빈도를 집계하고 자른다. 같은 성격끼리 묶어 세고, 3.4의 상한에 맞춰 자른다. 컷 순서는 빈도가 낮은 것부터다. 단 접근성에 필요한 항목(포커스 표시, 오류 표시)은 빈도가 1이어도 자르지 않는다.
화면에 그려지지 않았어도 완성된 사이트에서 반드시 나타나는 상태가 네 가지다. 마우스를 올린 상태, 누른 상태, 키보드로 이동해 선택된 상태, 값이 잘못됐다고 알리는 상태. 목업은 정상 상태만 그리는 때가 많아 이 네 가지가 통째로 빠진다. 빈도표에 이 네 줄을 손으로 넣고 시작한다.
3.4 – 카테고리별 상한과 컷 규칙
아래는 4~6페이지 정적 사이트 기준 제안값이다. 프로젝트 규모가 다르면 조정한다.
색 — 상한 18개. 프리미티브 스케일은 4개만 남긴다.
| 역할 | 스케일 | 남길 단계 |
|---|---|---|
| Brand | {브랜드 스케일} | 50, 500, 600, 700 |
| gray | {중립 스케일} | 50, 200, 400, 600, 900 |
| error | red | 50, 600 |
| success | green (브랜드가 green이면 생략) | 50, 600 |
컷 규칙은 네 가지다.
- 한 스케일에서 11단계를 다 쓰지 않는다. 실제 필요한 것은 아주 연함·중간·진함·아주 진함 4~5단계다.
- 중립 스케일은 반드시 하나만 남긴다.
slate와gray를 같이 쓰면 미묘하게 다른 회색이 섞여 지저분해진다. fuchsia,violet,lime,cyan같은 장식용 색은 전부 버린다. 기업 사이트에 쓸 자리가 없다.- 경고(
amber)는 선택 사항이다. 경고 상태가 실제로 화면에 있는지 확인하고 없으면 버린다.
타이포그래피 — 상한 9개. 크기와 굵기를 묶어 하나의 이름으로 만든다.
| 이름 | 크기 | 굵기 | 어디에 | 반응형 |
|---|---|---|---|---|
| display | 5xl (48) | bold | 히어로 대제목 | 모바일에서 3xl |
| heading-1 | 4xl (36) | bold | 페이지 제목 | 모바일에서 2xl |
| heading-2 | 2xl (24) | semibold | 섹션 제목 | 모바일에서 xl |
| heading-3 | xl (20) | semibold | 카드 제목 | 고정 |
| body-lg | lg (18) | normal | 리드 문단 | 고정 |
| body | base (16) | normal | 본문 | 고정 |
| body-sm | sm (14) | normal | 표 내용 | 고정 |
| label | sm (14) | medium | 폼 라벨, 버튼 | 고정 |
| caption | xs (12) | normal | 각주, 출처 | 고정 |
컷 규칙은 네 가지다.
- 굵기는 3종만 쓴다.
normal(400)과medium(500)에semibold(600)또는bold(700)를 더한다.thin,extralight,light,extrabold,black은 버린다. 한글 웹폰트에서 100·200·900 굵기는 가독성이 떨어지고, 웹폰트 용량도 굵기 개수에 비례해 커진다. - 크기는 건너뛰며 고른다. xs → sm → base → lg → xl → 2xl → 4xl → 5xl 순이다. 인접한 크기(4xl 36과 5xl 48)를 둘 다 쓰면 눈으로 구분이 안 돼 일관성이 깨진다.
- 6xl 이상(60·72·128)은 일반 기업 사이트에 쓸 자리가 없다.
- 반응형 축소 규칙을 여기서 확정한다. 코딩 단계에서 정하면 팀원마다
md:text-4xl을 다르게 붙여 페이지 간 제목 크기가 어긋난다.
간격 — 상한 9개. 2(8px) 3(12px) 4(16px) 6(24px) 8(32px) 12(48px) 16(64px) 24(96px)를 쓴다.
컷 규칙은 세 가지다.
- 2 또는 4의 배수 계열만 남긴다.
5,7,9,11같은 값은 버린다. 값이 촘촘하면 팀원마다 다른 값을 집는다. - 작은 값(2~4)은 요소 안쪽, 중간 값(6~12)은 요소 사이, 큰 값(16~24)은 섹션 사이로 용도 구역을 나눈다.
- 섹션 상하 여백은 티어별로 고정한다. 예를 들어 모바일
py-12(48), 태블릿py-16(64), 데스크톱py-24(96)로 정한다.
사이징 — 상한 5개. 컷 규칙은 네 가지다.
max-width는 콘텐츠 폭(1280px)과 읽기 폭(720px내외) 둘만 남긴다. 읽기 폭은 글이 긴 본문 문단에 쓴다. 한 줄이 너무 길면 눈이 다음 줄을 못 찾는다.width스케일 전체는 버린다. 실무에서는 대부분w-full과 그리드로 처리한다.- 1.2에서 확인한 뷰포트 매핑을 그대로 채택한다.
- 그리드 규칙도 여기서 정한다. 예를 들어 카드 목록은 모바일 1열, 태블릿 2열, 데스크톱 3열로 정한다.
모서리·테두리 — 상한 5개.
| 종류 | 남길 것 | 어디에 |
|---|---|---|
| radius | md(6px) | 버튼, 입력칸 |
| radius | lg(8px) | 카드, 이미지 |
| radius | full | 배지, 원형 아이콘 배경 |
| border width | 1px | 카드, 입력칸, 구분선 |
| border width | 2px | 포커스 표시 |
radius는 3단계까지만 남긴다. 4단계 이상이면 화면에서 구분이 안 된다. 방향별 radius와 border는 특정 요소 한 곳(예: 탭 위쪽만 둥글게)에만 쓰이므로 토큰으로 만들지 않고 그 자리에 직접 적는다.
그림자 — 상한 2개. shadow-sm(카드 기본)과 shadow-md(카드 마우스 오버)를 쓴다.
shadow-lg 이상은 모달·드롭다운 전용이다. 모달이 없으면 버린다. 모바일 메뉴 드로어가 있으면 shadow-lg 하나를 추가한다. 3단계 이상 쓰면 화면의 깊이 위계가 무너진다.
Filter — 원칙적으로 0개. 정적 사이트에서 blur가 필요한 곳은 사실상 없다. 하나 고려할 수 있는 것이 고정 헤더의 반투명 배경(backdrop-blur)인데, 두 가지를 알고 결정한다.
backdrop-filter는 모바일에서 스크롤할 때 프레임 저하를 일으킬 수 있다. 헤더처럼 항상 화면에 있는 요소에 걸면 스크롤 내내 계속 계산된다.- Safari에서
-webkit-backdrop-filter접두사가 필요한 경우가 있다. AI 생성 코드에서 이 접두사가 자주 빠진다.
불투명 배경에 아래쪽 1px 테두리를 더하는 방식으로 처리하면 성능 문제도 브라우저 문제도 없다. 비전공자 팀 프로젝트에서는 이쪽을 권한다.
브레이크포인트 — 상한 2개. Tailwind 기준 md(768)와 xl(1280)만 남기고, 그 아래는 base(접두사 없음)로 처리한다. sm, lg, 2xl은 쓰지 않는다. 티어가 늘수록 확인해야 할 화면이 늘고, 확인 안 된 티어에서 레이아웃이 깨진다.
목업을 모바일과 데스크톱 2티어로만 만드는 프로젝트에서도 md는 남긴다. 목업이 없는 태블릿 폭에서 2열 그리드로 접히게 하려면 이 접두사가 필요하다.
아이콘 — 상한 16개. 변형은 하나만 쓴다. 아이콘 세트는 보통 24px outline, 24px solid, 20px solid, 16px solid 변형을 함께 제공하는데, 섞으면 선 굵기가 달라 어색해진다.
변형은 24px outline 단일 사용이 일반적인 권장이지만, 킷에 outline 변형이 아예 없고 solid만 들어 있는 경우도 있다. 그때는 없는 변형을 찾아 헤매지 말고 킷에 있는 변형 하나로 통일한다. 중요한 것은 특정 변형을 쓰는 것이 아니라 한 가지로 통일하는 것이다.
화면 요소 목록에 아이콘이 필요하다고 적힌 자리만 센다. 아래는 일반적인 기업 사이트에서 필요한 아이콘 후보이므로, 세트에 실제로 있는지 확인한 뒤 확정한다.
| 용도 | 후보 이름 (Heroicons 기준) |
|---|---|
| 모바일 햄버거 메뉴 | bars-3 |
| 메뉴 닫기 | x-mark |
| 드롭다운·아코디언 | chevron-down |
| 브레드크럼 구분, 더보기 | chevron-right |
| 링크 강조 | arrow-right |
| 파일 다운로드 | document-arrow-down |
| 문서 항목 | document-text |
| 이메일 | envelope |
| 전화 | phone |
| 주소 | map-pin |
| 외부 링크 | arrow-top-right-on-square |
| 전송 완료 | check-circle |
원하는 모양이 세트에 없을 수 있다. Heroicons에는 잎사귀(leaf)가 없다. 환경·자연 주제 사이트에서 흔히 찾는 모양인데 실제로 검색하면 나오지 않는다. 이런 경우 세트 안의 다른 아이콘(globe-asia-australia, sun, sparkles 등)으로 대체한다. 다른 세트를 섞으면 선 굵기가 달라지므로 대체 쪽을 권한다.
3.5 – 선택 순서상 주의점
색을 가장 나중에 고른다. 직관과 반대지만, 타이포·간격·컴포넌트 구조를 먼저 확정하고 색을 마지막에 얹는 편이 결과가 좋다. 색을 먼저 정하면 색으로 위계를 만들려 들고, 그러면 색 개수가 늘어난다. 흑백 상태에서 위계가 이미 보이면 색은 강조 한두 곳에만 쓰면 된다.
권장 순서는 타이포 → 간격 → 컴포넌트 구조 → 색 → 아이콘이다.
앞선 일정에서 무드보드를 만들어 브랜드 색을 이미 확정한 프로젝트라면 이 순서를 지킬 수 없다. 그때는 확정된 색을 브랜드 주색 자리에만 넣고, 나머지 색(중립·상태)은 여전히 마지막에 고른다. 순서 규칙의 목적은 “색으로 위계를 만들지 않기”이므로, 주색 하나가 먼저 정해진 것 자체는 문제가 되지 않는다.
컷은 두 번에 나눈다. 1차로 넉넉히 고르고, 목업 1페이지를 만든 뒤 실제로 안 쓴 것을 2차로 자른다. 처음부터 최소로 자르면 목업 도중 계속 추가하게 되고, 추가된 것은 기록이 안 남아 선택표와 코드가 어긋난다.
3.6 – 미선택 토큰 처리
버린 토큰을 Figma에서 지우지 않는다. 지우면 시맨틱 토큰이 참조할 대상을 잃고, 이미 그 값으로 칠해진 목업의 색도 함께 풀린다. 남겨 두되 직접 쓰지 못하게 하는 것이 목적이다.
방법은 세 가지이고, 위에서부터 순서대로 시도한다.
- Variables 화면에서 컬렉션을 프리미티브 전체와 선택된 시맨틱으로 나누고, 팀원에게는 시맨틱만 쓰게 한다.
- Figma의 [Hide from publishing] 기능으로 팀 라이브러리 공유 목록에서만 감춘다. 이 기능은 변수를 지우지 않으므로 이미 칠해진 색은 그대로 남는다.
- 화면 정리가 더 필요하면 Color Palette 프레임에서 안 쓰는 스케일 프레임을 레이어 숨김 처리한다.
[Hide from publishing]과 [Delete variable]은 결과가 다르다. 앞의 기능은 공유 목록에서만 감추고, 뒤의 기능은 변수를 없애 목업에 칠해진 색을 풀어 버린다. 목업 제출일이 가까우면 정리 작업 자체를 제출 이후로 미룬다.
4 – 선택한 것을 스타일가이드로 만드는 순서
3장에서 무엇을 남길지 정했으니, 이제 남긴 값에 이름을 붙이고 문서와 코드로 만든다.
4.1 – 시맨틱 이름 붙이기
살아남은 값에 역할 이름을 붙인다. 색 이름이 아니라 쓰임새 이름이다. 먼저 두 용어를 갈라 둔다.
프리미티브 토큰은 색 그 자체에 붙인 이름이다. color/slate/900처럼 무슨 색인지만 말한다. 킷에 있는 것이 전부 여기 해당한다.
시맨틱 토큰은 화면에서 맡는 역할에 붙인 이름이다. color/brand/primary처럼 어디에 쓰는지를 말한다. 값은 프리미티브를 가리킨다.
시맨틱 층을 두는 이유는 두 가지다. 브랜드 컬러가 바뀔 때 brand/primary가 가리키는 프리미티브 하나만 갈아 끼우면 전체가 따라 바뀐다. 그리고 AI에게 색 이름으로 지시하면 매번 기억시켜야 하지만, 역할 이름으로 지시하면 AI가 규칙을 스스로 지킬 수 있다.
여기서 갈림길이 하나 있다. 0장에서 채운 {기존 시맨틱}이 “없음”인지 아닌지에 따라 작업이 달라진다.
{기존 시맨틱}이 “없음”인 경우 — Figma Variables에 semantic 컬렉션을 만들고 아래 이름으로 변수를 만든 뒤, 값은 프리미티브를 참조하도록 연결한다.
| 시맨틱 토큰 | 참조 예시 | 쓰이는 곳 |
|---|---|---|
brand/primary | {브랜드 스케일}/600 | 주 버튼, 활성 링크, 강조 |
brand/primary-hover | {브랜드 스케일}/700 | 주 버튼 마우스 오버 |
brand/subtle | {브랜드 스케일}/50 | 강조 영역 옅은 배경 |
text/primary | {중립 스케일}/900 | 본문 |
text/secondary | {중립 스케일}/600 | 부가 설명 |
text/inverse | white | 어두운 배경 위 글자 |
surface/default | white | 페이지 기본 바탕, 카드 안쪽 |
surface/subtle | {중립 스케일}/50 | 섹션 구분 배경 |
border/default | {중립 스케일}/200 | 카드·입력창 테두리 |
border/strong | {중립 스케일}/400 | 강조 구분선 |
border/focus | {브랜드 스케일}/600 | 키보드 포커스 표시 |
state/error | red/600 | 오류 |
state/error-subtle | red/50 | 오류 메시지 배경 |
state/success | green/600 | 전송 완료 |
{기존 시맨틱}이 있는 경우 — 위 이름을 새로 만들지 않는다. 이미 있는 이름을 그대로 쓰고, 그 이름에 프리미티브 별칭만 연결한다. 위 표는 그때 “이 역할에 해당하는 이름이 기존 컬렉션에 있는가”를 확인하는 대조 기준으로만 쓴다.
대조에서 세 가지 경우가 나온다.
- 역할이 1:1로 맞는다 — 기존 이름에 값을 연결한다.
- 기존 컬렉션에만 있는 역할이 있다 — 그대로 남기고 어디에 쓸지 정한다. 비활성 상태(grey-out)나 포커스 바깥선(focus-offset)처럼 위 표보다 촘촘한 이름이 들어 있는 킷도 있다.
- 위 표에만 있는 역할이 기존 컬렉션에 없다 — 그 역할이 화면에 실제로 필요한지 3.2의 세 질문으로 따진 뒤, 필요하면 기존 컬렉션의 이름 규칙을 따라 이름을 추가한다.
3번에서 이름을 추가할 때는 기존 컬렉션의 표기 습관을 따른다. 기존 이름이 surface/bg-default처럼 그룹 이름을 접두어로 되풀이하는 방식이면, 새로 넣는 이름도 surface/bg-success 형태로 맞춘다. 한 컬렉션 안에서 표기 방식이 두 갈래로 갈리면 팀원이 이름을 외우지 못한다.
surface가 무엇인지 짚어 둔다. 화면에서 콘텐츠가 얹히는 바탕 면이다. 실제 화면은 종이가 여러 겹 겹친 구조다. 페이지 바닥 면 위에 섹션 면이 깔리고 그 위에 카드 면이 얹힌다. background라 부르면 맨 뒤 배경 하나라는 느낌이라 층이 여럿일 때 이름이 꼬여서 surface를 쓴다.
주의할 것은 버튼 배경이 surface가 아니라 brand라는 점이다. surface는 콘텐츠를 담는 면이고 brand는 누르라고 강조하는 색이라 역할이 다르다. 섞으면 나중에 브랜드 색을 바꿀 때 섹션 배경까지 같이 바뀐다.
대비 검증은 건너뛰지 않는다. 각 조합의 명도 대비를 WCAG 2.1 AA 기준으로 확인한다.
- 본문 텍스트는 배경 대비 4.5:1 이상이다.
- 18pt 이상 큰 텍스트, 아이콘, 테두리는 3:1 이상이다.
surface는 항상 text와 짝으로 검증한다. surface 하나만 놓고는 통과 여부를 판단할 수 없다.
브랜드 색이 아주 어두운 계열이면 흰 배경 대비는 넉넉하지만, 그 색 위에 흰 글자를 얹는 버튼은 대비가 과해 눈이 피로할 수 있다. 반대로 중간 밝기 색에 흰 글자를 얹으면 4.5:1을 못 넘길 가능성이 있으므로 실측이 필요하다.
4.2 – 컴포넌트 스펙 작성
필요한 컴포넌트를 목록화하고 상태별 스타일을 지정한다. 전체 목록은 아홉 가지이지만, 일정이 빡빡하면 앞의 넷을 먼저 만들고 나머지를 뒤로 미룬다.
먼저 만드는 넷은 Header·GNB(데스크톱 가로 메뉴와 모바일 햄버거·드로어), Button(primary·secondary·ghost), Card, Form Field다. 이 넷이 없으면 어느 페이지도 목업을 완성할 수 없다.
뒤로 미룰 수 있는 다섯은 Footer, Section Heading, List·Table, Badge, Breadcrumb다. 이들은 앞의 넷에서 정한 색·간격·글자 규칙을 그대로 물려받으므로, 나중에 만들어도 결과가 어긋나지 않는다.
각 컴포넌트마다 다섯 가지를 명시한다.
- 시맨틱 토큰으로 표기한 색. hex 직접 표기는 하지 않는다.
- 패딩과 간격. Tailwind 스케일 숫자로 적는다.
- radius와 shadow.
- 상태 변화. 기본, 마우스 오버,
focus-visible, 비활성 네 가지다. - 티어별 크기 변화.
focus-visible을 반드시 넣는 이유가 있다. 키보드 사용자가 Tab 키로 이동할 때 현재 위치가 보이지 않으면 접근성 기준 위반이다. AI는 지시하지 않으면 이 상태를 자주 빠뜨린다.
4.3 – 선택 결과 기록 양식
아래 표가 곧 스타일가이드의 본문이다. 별도로 문서를 또 쓰지 않는다.
| 카테고리 | 시맨틱 이름 | 프리미티브 참조 | 쓰이는 곳 | 근거(화면 요소) |
|---|---|---|---|---|
| 색 | brand/primary | 주 버튼 배경, 활성 링크 | ||
| 색 | surface/subtle | 섹션 구분 배경 | ||
| 타이포 | heading-2 | 2xl / semibold | 섹션 제목 | |
| 간격 | section-y | 12 / 16 / 24 | 섹션 상하 여백 | |
| 아이콘 | icon/download | document-arrow-down | 다운로드 버튼 |
근거 칸을 반드시 채운다. 여기가 비면 그 토큰은 3.2의 질문 1을 통과하지 못한 것이다. 채우다 보면 스스로 걸러진다.
4.4 – tokens.css 산출
Tailwind CSS v4는 설정 파일(tailwind.config.js)이 아니라 CSS 안의 @theme 블록으로 토큰을 정의한다. 최종 산출물은 이 블록이 든 CSS 파일 하나다. Tailwind 공식 문서는 @theme을 유틸리티 클래스와 직접 연결할 디자인 토큰에 쓰고, 유틸리티가 필요 없는 값은 :root에 쓰라고 구분한다.
여기서 먼저 확인할 것은 무엇을 적지 않아도 되는지다. 킷이 Tailwind 기본 스케일을 그대로 옮겨 둔 것이면 아래 항목은 값이 일치하므로 @theme에 다시 적지 않는다. 같은 값을 두 곳에서 관리하게 되기 때문이다.
| 항목 | 킷의 이름 | Tailwind v4 기본 |
|---|---|---|
| 화면 폭 기준 | breakpoint/sm~2xl (640·768·1024·1280·1536) | --breakpoint-sm 40rem 등, 환산하면 같음 |
| 최대 폭 | container/3xs~7xl (256~1280) | --container-3xs 16rem 등, 환산하면 같음 |
| 글자 크기 | font/size/base·2xl·3xl (16·24·30) | --text-base 1rem 등, 환산하면 같음 |
| 줄 높이 | font/line-height/* (24·32·36) | 계산값으로 같음 |
| 글자 굵기 | font/weight/medium·semibold·bold (500·600·700) | --font-weight-* 같음 |
| 간격 | spacing/* (4의 배수) | --spacing 0.25rem에 배수를 곱한 값 |
반대로 반드시 적어야 하는 것은 둘이다. 첫째는 시맨틱 색 이름이다. brand/primary나 surface/bg-default 같은 이름은 Tailwind에 없으므로 --color-* 자리에 넣어야 유틸리티 클래스가 생긴다. 둘째는 글꼴이다. Tailwind 기본 --font-sans는 시스템 글꼴 목록이므로 2.3에서 정한 글꼴로 덮어쓴다.
아래 코드를 src/styles/tokens.css에 넣는다.
@import "tailwindcss";
@theme {
/* 글꼴 — 2.3에서 정한 값 */
--font-sans: "{폰트}", sans-serif;
/* 브랜드 프리미티브 — 2장에서 값 교정 후 확정 */
--color-brand-50: #......;
--color-brand-500: #......;
--color-brand-600: #......;
--color-brand-700: #......;
/* 중립 프리미티브 — 킷의 hex 값을 그대로 적는다 */
--color-gray-50: #......;
--color-gray-200: #......;
--color-gray-600: #......;
--color-gray-900: #......;
/* 시맨틱 — 4.1에서 확정한 매핑 */
--color-brand-primary: var(--color-brand-600);
--color-brand-primary-hover: var(--color-brand-700);
--color-text-primary: var(--color-gray-900);
--color-text-secondary: var(--color-gray-600);
--color-surface-default: #ffffff;
--color-surface-subtle: var(--color-gray-50);
--color-border-default: var(--color-gray-200);
/* 브레이크포인트 — 3.4에서 확정 */
--breakpoint-md: 768px;
--breakpoint-xl: 1280px;
}이 파일이 있으면 코드에서 bg-brand-primary, text-text-secondary 같은 클래스를 바로 쓸 수 있다. Tailwind v4가 @theme 안의 --color-* 변수를 읽어 유틸리티 클래스를 자동 생성하기 때문이다.
중립 프리미티브를 hex로 직접 적은 이유가 있다. 여기서 var(--color-slate-900)처럼 Tailwind 기본 색 변수를 참조하면 색이 시안과 미세하게 어긋난다. Tailwind v4는 기본 색 팔레트를 rgb에서 oklch로 바꿨다. oklch는 사람 눈에 색이 보이는 방식에 가까운 색 표기 방식이다. 공식 문서 표현은 sRGB 색공간에 갇혀 있던 자리에서 더 선명하게 만들었다는 것이고, 균형은 v3와 비슷하게 유지했다고 덧붙인다.
그런데 킷의 값은 #f9fafb처럼 hex인 경우가 많다. 이름은 같아도 표기가 다르고 값도 그대로는 아니다. 그래서 시맨틱 토큰이 가리킬 프리미티브는 킷의 hex를 그대로 적어 두고, 코드에서는 시맨틱 이름만 부른다.
코드 생성 지시문에 bg-red-500 같은 원천값 유틸리티를 쓰지 말라고 반드시 적어 둔다. 이 규칙이 없으면 AI가 익숙한 원천값 이름을 그대로 생성하고, 브라우저 색이 시안과 어긋난다. 어긋난 폭이 작아 눈으로는 잘 안 보이므로 원인을 찾기 어렵다.
킷의 값을 Tailwind v4의 oklch로 아예 갱신하는 방법도 있다. 근본 해결이지만 색 100개 이상을 다시 넣는 작업이라, 목업 제출이 가까운 시점에는 무리다. 시간이 남는 프로젝트에서만 고른다.
4.5 – Style Guide 페이지 제작
Figma에 Style Guide 페이지를 만들고 결과를 사람이 읽을 수 있게 배치한다. 이 페이지가 팀원 공용 참조 화면이 되고, 발표 자료의 컬러시스템·타이포그래피·UI컴포넌트 슬라이드 원본이 된다.
배치 순서는 일곱 가지다.
- 표지 — 프로젝트명, 팀명, 버전, 갱신일
- 브랜드 컬러 — 프리미티브 스케일과 시맨틱 매핑표, 대비 검증 결과
- 타이포그래피 — 축약 스케일 실물 샘플. 한글 문장으로 넣는다
- 레이아웃 — 티어별 그리드 도해
- 간격·radius·shadow
- 컴포넌트 — 상태별 실물
- 사용 금지 예시 (Do / Don’t)
7번을 넣는 이유는 재사용성에 있다. “브랜드 컬러를 본문 텍스트에 쓰지 않는다”, “제목에 3가지 이상 굵기를 섞지 않는다” 같은 금지 규칙은 AI에게 넘길 지시문에 그대로 옮겨 쓸 수 있다.
각 프레임에는 변수 이름을 글자로 함께 적는다. 색 견본만 있으면 값은 보이지만 이름이 보이지 않아, 코드에서 무엇으로 불러야 하는지 알 수 없다.
4.6 – 검증
- 토큰 커버리지 — 목업 화면에서 하드코딩된 hex를 찾아 시맨틱 토큰으로 교체한다.
- 대비 재검증 — 실제 컴포넌트 조합(버튼 위 글자, 카드 위 캡션)에서 다시 측정한다.
- 한글 실물 확인 — 결정한 폰트로 실제 한국어 문장을 넣어 줄바꿈과 자간을 본다.
- 코드 왕복 —
tokens.css로 버튼 하나를 만들어 Figma 시안과 나란히 놓고 비교한다.
아래 다섯 가지를 확인한다. 다섯 가지가 모두 맞으면 스타일가이드 확정으로 보고 Figma 공유링크를 제출한다. 하나라도 어긋나면 그 항목을 지적해 다시 요청한다.
- 시맨틱 토큰 가운데 값이 비어 있는 이름이 하나도 없다.
- 시맨틱 토큰의 값이 모두 프리미티브 별칭이고, 색 값이 직접 입력된 것이 없다.
- 글자 크기·간격·모서리 둥글기 후보가 각각 3.4의 상한 안에 있다.
- 컴포넌트의 모든 변형에
focus-visible상태가 있다. Style Guide페이지의 일곱 프레임이 모두 있고, 각 항목에 변수 이름이 글자로 함께 적혀 있다.
어긋난 항목을 지적할 때는 “3번이 안 맞다”가 아니라 “글자 크기가 아홉 단계 남았으니 여섯 단계 이내로 줄여라”처럼 무엇을 어떻게 바꿀지 적어 보낸다. AI가 어디를 고쳐야 하는지 짐작하지 않게 하려는 것이다.
5 – 작업 지시 프롬프트
각 단계에서 AI에 그대로 붙여 넣는다. { }는 0장 표에서 채운 값으로 바꾼다.
5.0 – 모든 프롬프트에 붙이는 안전 규칙
아래 다섯 줄을 5.1부터 5.9까지 모든 프롬프트의 제약 항목에 넣는다. 이 규칙이 없으면 AI가 값을 바꾸는 과정에서 목업에 이미 칠해진 색을 풀어 버리거나, 확인 없이 팀 라이브러리에 발행해 다른 파일까지 흔든다.
- 기존 변수·컬렉션·프레임·컴포넌트를 지우지 않는다. 값을 바꾸거나 새로 추가하는 것만 한다.
- 기존 컬렉션 이름을 바꾸지 않는다.
- 파일을 바꾸기 전에 "무엇을 무엇으로 바꿀지" 목록을 먼저 보여 주고 내 승인을 기다린다.
- 팀 라이브러리 발행을 실행하지 않는다. 발행 대상 목록만 보고한다.
- 확인되지 않은 값·이름·속성은 "확인 필요"로 표시하고 추측으로 채우지 않는다.세 번째 줄이 특히 중요하다. 승인 절차가 없으면 AI가 스스로 정한 값이 그대로 파일에 들어가고, 나중에 그 값의 근거를 아무도 설명할 수 없다.
5.1 – 킷 현황 진단 (1장)
파일을 바꾸지 않고 상태만 받는 프롬프트다. 다른 프롬프트보다 먼저 돌린다.
Figma 파일 fileKey {fileKey} 의 디자인 시스템 상태를 진단해 보고만 해라. 이번 요청에서는 어떤 노드·변수·컴포넌트도 만들거나 바꾸거나 지우지 않는다.
보고할 항목은 아래 일곱 가지다. 항목마다 실제 이름과 개수를 그대로 적고, 확인하지 못한 것은 "확인 못 함"으로 적어라. 추측으로 채우지 마라.
1. 이 파일의 페이지 목록. 페이지 이름과 각 페이지의 최상위 프레임 이름.
2. 변수 컬렉션 목록. 컬렉션마다 이름, 모드 이름, 변수 개수.
3. 시맨틱 성격의 컬렉션이 있으면 그 변수 전체 목록. 이름마다 (a) 지금 값이 들어 있는지, (b) 그 값이 어떤 프리미티브를 가리키는 별칭인지, (c) 아무것도 연결되지 않은 빈 상태인지 구분해 표로 적어라.
4. 색 스케일 목록과 각 스케일의 단계 개수. Tailwind 원본에 없는 이름의 커스텀 스케일이 있으면 따로 표시하라.
5. font/family 값과 letterSpacing 값의 분포.
6. 이 파일에 있는 컴포넌트와 컴포넌트 세트 전체 목록. 이름과 변형 속성값까지 적어라. 아이콘 세트가 있으면 어떤 변형(outline/solid, 크기)이 들어 있는지 밝혀라.
7. 프레임 안에 글로 적힌 규칙·메모가 있으면 원문 그대로 옮겨라.
마지막에 두 가지를 정리해라.
- 스타일가이드로 쓰기에 아직 비어 있는 것
- 페이지 구조와 컴포넌트 목록이 서로 어긋나는 곳이 있으면 그 내용
출력은 표 형식. 코드 실행 결과는 표시하지 마라.답에 “확인 못 함”이 있으면 그 항목만 다시 물어본다. 대충 답한 자리를 지나가면 뒤 단계에서 없는 값을 바꾸려다 오류가 난다.
5.2 – 프리미티브 정리 (2장)
Figma 파일 fileKey {fileKey} 의 Color Palette 프레임(node-id {색상 프레임 id})의 변수 정의를 읽어라.
작업:
1. Tailwind CSS 공식 색상 값과 대조해, 값이 중복되거나 원본과 다른 토큰을 모두 찾아 [토큰명 / 현재값 / 올바른값] 표로 출력하라.
2. 커스텀 색상 스케일(Tailwind 원본에 없는 이름)에서 빠진 단계를 찾고, 인접 단계의 명도를 기준으로 보간한 값을 제안하라. 보간 근거(HSL 명도 간격)를 함께 적어라.
3. font/family/sans 값을 확인하고, 그 글꼴이 한글 글리프를 포함하는지 판단하라. 판단 근거를 함께 적고, 확인할 수 없으면 "확인 필요"로 표시하라.
4. 아래 용도에 맞는 색상 스케일을 이 팔레트에서 골라 추천하라. 추천마다 이유를 1문장으로 적어라.
- 브랜드 주색: {프로젝트의 성격과 원하는 인상}
- 중립색: 본문·배경·테두리 전용 1개 스케일
- 상태색: 오류/경고/성공/정보 각 1개
제약:
- 팔레트에 없는 색을 새로 만들지 마라.
- 5.0의 안전 규칙 다섯 줄을 지켜라.
- 출력은 표 형식. 코드 실행 결과는 표시하지 마라.5.3 – 화면 요소에서 필요 속성 뽑기 (3.3의 1~2단계)
아래는 {프로젝트}의 화면 요소 목록이다.
{3.3 1단계 표 붙여넣기}
작업:
1. 각 요소가 필요로 하는 스타일 속성을 아래 카테고리로 나눠 표로 정리하라.
색 / 글자 / 간격 / 모서리 / 테두리 / 그림자 / 아이콘
구체적 수치는 적지 마라. "무엇이 필요한지"만 적는다.
2. 같은 성격의 속성끼리 묶어 빈도를 세고, 많이 쓰이는 순으로 정렬하라.
3. 접근성상 반드시 필요한 항목을 별도 목록으로 표시하라. 빈도가 낮아도 여기 넣는다. 최소한 아래 네 가지 상태를 포함하라.
마우스 올림 / 누름 / 키보드 포커스 / 오류 표시
제약:
- 목록에 없는 요소를 추가하지 마라.
- 구체적 색상값·픽셀값을 제안하지 마라. 이 단계에서는 종류만 센다.
- 출력은 표 형식.5.4 – 상한에 맞춰 자르기 (3.3의 3단계)
아래 속성 빈도표를 받아, 정해진 상한에 맞게 잘라라.
빈도표: {5.3 결과}
상한:
- 색 시맨틱 토큰 18개 이하 (프리미티브 스케일 4개 이내에서 파생)
- 타이포 조합 9개 이하 (굵기는 3종만)
- 간격 9개 이하 (2 또는 4의 배수만)
- max-width 2개, radius 3개, border width 2개, shadow 2개
- 브레이크포인트 2개 (md 768, xl 1280)
- 아이콘 16개 이하 (변형 한 가지로 통일)
작업:
1. 상한을 넘는 카테고리마다 빈도가 낮은 것부터 잘라라.
2. 자른 항목마다 "무엇으로 대체하는지"를 적어라. 대체 불가능한 것은 자르지 말고 "대체 불가"로 표시하라.
3. 접근성 필수 항목은 빈도와 무관하게 남겨라.
4. 최종 목록을 [카테고리 / 이름 / 개수] 로 집계해 상한 준수 여부를 표시하라.
제약:
- 상한을 넘긴 채로 답하지 마라. 넘으면 더 잘라라.
- 자른 이유를 추측으로 쓰지 마라. 빈도표에 있는 근거만 쓴다.5.5 – 아이콘 선별 (3.4)
Figma 파일 fileKey {fileKey} 의 아이콘 프레임(node-id {아이콘 프레임 id})에서 아래 용도에 맞는 아이콘 이름을 찾아라.
용도 목록: {화면 요소 목록에서 아이콘이 필요한 자리}
작업:
1. 이 세트에 들어 있는 변형(outline/solid, 크기)을 먼저 밝혀라. 그중 하나를 골라 전체를 통일하고, 고른 이유를 적어라.
2. 용도마다 후보 아이콘 이름을 최대 2개씩 제시하고, 각각 어떤 모양인지 1문장으로 설명하라.
3. 해당 용도에 맞는 아이콘이 이 세트에 없으면 "없음"이라고 명시하고, 세트 안에서 대체 가능한 아이콘을 제안하라.
4. 최종 목록을 [용도 / 아이콘 이름 / 변형] 표로 출력하라.
제약:
- 세트에 존재하지 않는 아이콘 이름을 만들어내지 마라. 이름이 실재하는지 확인하고, 확인 못 하면 "확인 필요"로 표시하라.
- 다른 아이콘 세트를 섞지 마라.
- 16개를 넘기지 마라.5.6 – 시맨틱 토큰 매핑 (4.1)
{기존 시맨틱}이 “없음”이면 아래 프롬프트의 1번을 “시맨틱 토큰을 새로 정의하라”로 바꿔 쓴다.
아래 프리미티브 목록을 받아, 시맨틱 토큰 매핑표를 작성하라.
프리미티브: {5.4에서 확정한 색 목록}
기존 시맨틱 컬렉션: {기존 시맨틱}
용도: {프로젝트} / 페이지 구성: {페이지 목록}
작업:
1. 기존 시맨틱 컬렉션에 이미 있는 이름을 그대로 쓰고, 그 이름에 프리미티브 별칭을 연결하는 표를 만들어라. 새 이름을 만들지 마라.
2. brand / text / surface / border / state 다섯 역할 가운데 기존 컬렉션에 대응 이름이 없는 역할이 있으면 따로 표시하라. 그 역할이 화면에 필요한지 내게 묻고, 이름을 임의로 추가하지 마라.
3. 기존 컬렉션에만 있고 위 다섯 역할에 없는 이름이 있으면 그대로 남기고, 어디에 쓸지 후보를 제안하라.
4. 각 매핑에 대해 "어떤 화면 요소에 쓰는지"를 1문장으로 적어라.
5. 텍스트-배경 조합마다 WCAG 2.1 명도 대비를 계산해 다음 표로 출력하라.
[조합 / 대비비 / AA 통과여부 / 판정 근거]
본문 4.5:1, 큰 텍스트·UI 요소 3:1 기준.
6. 기준 미달 조합은 대체 프리미티브를 제안하라.
제약:
- 시맨틱 토큰 개수는 18개를 넘기지 마라.
- 토큰 이름에 색 이름(purple, green 등)을 쓰지 마라. 역할 이름만 쓴다.
- 이름을 추가할 때는 기존 컬렉션의 표기 방식을 따르라.
- 5.0의 안전 규칙 다섯 줄을 지켜라.5.7 – 컴포넌트 스펙 (4.2)
아래 조건으로 컴포넌트 스펙 시트를 작성하라.
시맨틱 토큰: {5.6 결과}
타이포 스케일: {5.4 결과}
간격 규칙: {5.4 결과}
브레이크포인트: {목업 티어} (Tailwind 기준 base / md / xl)
대상 컴포넌트 (이 순서로 작업하라)
1차 — Header·GNB, Button(primary/secondary/ghost), Card, Form Field
2차 — Footer, Section Heading, List·Table, Badge, Breadcrumb
각 컴포넌트마다 다음을 표로 작성하라:
- 구성 요소 (하위 요소 목록)
- 색: 반드시 시맨틱 토큰 이름으로만 표기 (hex 금지)
- 여백: Tailwind 간격 숫자
- radius / shadow
- 상태: default / hover / focus-visible / disabled 각각의 변화
- 티어별 변화
제약:
- focus-visible 상태를 빠뜨리지 마라. 키보드 접근성 필수 항목이다.
- Tailwind v4에 존재하지 않는 클래스명을 만들어내지 마라.
- 이 파일에 이미 있는 컴포넌트는 지우지 말고, 변형 구조와 이름 규칙을 새로 만드는 것과 맞춰라.
- 아이콘은 5.5에서 고른 변형만 쓴다.
- 5.0의 안전 규칙 다섯 줄을 지켜라.5.8 – tokens.css 생성 (4.4)
아래 선택표를 Tailwind CSS v4 @theme 블록으로 변환하라.
선택표: {4.3 표}
폰트: {폰트}
작업:
1. src/styles/tokens.css 전체 내용을 출력하라.
2. @import "tailwindcss"; 로 시작한다.
3. @theme 안에 --color-* / --font-* / --breakpoint-* 형식으로 정의하라.
4. 프리미티브 색은 킷의 hex 값을 그대로 적어라. Tailwind 기본 색 변수(var(--color-slate-900) 등)를 참조하지 마라. v4 기본 팔레트는 oklch로 값이 다시 계산돼 킷의 hex와 어긋난다.
5. 시맨틱 토큰은 4번에서 적은 프리미티브를 var()로 참조하게 하라.
6. Tailwind v4 기본값과 값이 일치하는 항목(breakpoint, container, text 크기, line-height, font-weight, spacing)은 적지 마라. 어느 항목을 왜 뺐는지 목록으로 함께 보고하라.
7. 각 그룹 위에 한국어 주석 한 줄로 용도를 적어라.
제약:
- 선택표에 없는 토큰을 추가하지 마라. 하나도 추가하지 마라.
- tailwind.config.js(v3) 방식으로 쓰지 마라. v4는 CSS 안에서 설정한다.
- @theme 네임스페이스 규칙이 확실하지 않은 항목은 "확인 필요"로 표시하고 근거 문서 URL을 함께 제시하라.5.9 – 위반 검출 (4.6)
아래 코드에서 선택표에 없는 값을 쓴 곳을 찾아라.
선택표: {4.3 표}
tokens.css: {파일 내용}
검사 대상: {HTML 파일 내용}
검사 항목:
1. 선택표에 없는 Tailwind 색 클래스 (예: bg-zinc-100)
2. 원천값 색 유틸리티 (예: bg-teal-600) — 시맨틱 이름으로만 써야 한다
3. 선택표에 없는 글자 크기·굵기
4. 선택표에 없는 간격 값
5. hex·rgb 직접 입력
6. 선택표에 없는 브레이크포인트 접두사 (sm: lg: 2xl:)
7. 선택표에 없는 아이콘, 또는 변형이 섞인 아이콘
8. focus-visible 스타일이 누락된 상호작용 요소
9. 명도 대비 AA 미달 가능성이 있는 조합
출력: [줄번호 / 발견한 값 / 왜 문제인지 / 선택표의 어떤 값으로 바꿔야 하는지]
문제가 없으면 "위반 없음"이라고만 답하라. 없는 문제를 만들지 마라.6 – AI 협업 가이드
바이브 코딩은 AI에게 맡기고 결과를 받는 방식이 아니다. 사람이 규칙을 정하고, AI가 그 규칙 안에서 생산하고, 사람이 규칙 위반을 잡아내는 세 박자 반복이다. 규칙이 없으면 AI는 매번 다른 결과를 낸다.
6.1 – 역할 분담
| 작업 | AI | 사람 |
|---|---|---|
| 화면 요소에서 속성 종류 뽑기 | 잘함 | 검토만 |
| 빈도 세기, 상한 맞춰 자르기 | 잘함 | 검토만 |
| 어떤 색을 브랜드 색으로 할지 | 못함 | 결정 |
| 상한 숫자를 몇으로 할지 | 못함 | 결정 |
| 시맨틱 토큰 이름 확정 | 초안만 | 결정 |
| 아이콘이 세트에 있는지 확인 | 자주 틀림 | 확인 필요 |
| 대비 계산 | 계산은 함 | 결과 검증 |
tokens.css 문법 | 잘함(v4 지정 시) | 검토 |
| 코드에서 위반 찾기 | 잘함 | 최종 판단 |
| 팀 라이브러리 발행 | 시키지 않음 | 사람이 직접 |
색 선택을 AI에 넘기지 않는 이유가 있다. 브랜드 색은 정체성 결정이지 최적화 문제가 아니다. AI는 무난한 답을 내며, 그 결과 여러 팀의 산출물이 서로 비슷해진다.
아이콘 존재 여부를 AI가 자주 틀리는 이유도 밝혀 둔다. AI는 아이콘 이름을 그럴듯하게 지어낸다. 있을 법한 이름이 실제 세트에는 없는 경우가 잦다. 반드시 파일에서 이름을 검색해 확인하고, 확인 못 한 것은 “확인 필요”로 남긴다.
발행을 AI에 시키지 않는 이유는 되돌리기 어렵기 때문이다. 발행하면 이 라이브러리를 쓰는 다른 파일에 변경이 한꺼번에 퍼진다. 목록만 받아 확인한 뒤 사람이 버튼을 누른다.
6.2 – 컨텍스트를 주는 순서
매 세션 시작 시 아래 순서로 넣는다. 순서를 바꾸면 AI가 앞선 제약을 무시한다.
- 역할과 결과물 — “너는 Tailwind v4 정적 사이트를 만든다”
- 제약 조건 — 쓸 수 있는 기술, 금지 항목
- 참조 자료 —
tokens.css전문, 선택표 - 이번 작업 — 구체적 지시 하나
- 출력 형식 — 파일 경로, 형식
- 검증 요구 — “확인 불가한 것은 확인 필요로 표시하라”
6.3 – 항상 붙이는 제약 문구
- 선택표에 없는 값을 추가하지 마라. 필요하다고 판단되면 추가하지 말고 "선택표에 없음: {항목} — 추가 검토 필요"로 보고하라.
- Tailwind CSS v4 문법만 사용한다. v3의 tailwind.config.js 방식을 쓰지 마라.
- 색은 시맨틱 토큰 이름으로만 쓴다. bg-teal-600 같은 원천값 유틸리티를 쓰지 마라.
- 프레임워크(React·Vue)를 도입하지 마라. 정적 HTML5 + Vanilla JS다.
- 외부 라이브러리를 임의로 추가하지 마라. 필요하면 먼저 이유와 함께 제안하라.
- 확인되지 않은 API·속성·클래스명은 "확인 필요"로 표시하고 근거 문서 URL을 함께 제시하라. 추측으로 채우지 마라.
- 기존 파일을 수정할 때는 바꾼 부분만 표시하라. 전체를 다시 쓰지 마라.마지막 두 항목이 특히 중요하다. AI는 모르는 것을 그럴듯하게 지어내며, 파일 전체를 다시 쓰면서 앞서 사람이 손으로 고친 부분을 조용히 되돌린다.
6.4 – AI 출력을 믿으면 안 되는 지점
| 항목 | 흔한 오류 |
|---|---|
| Tailwind v4 문법 | v3 문법을 섞어 쓴다. 학습 데이터에 v3이 압도적으로 많다 |
| 색 표기 | 원천값 유틸리티를 써서 시안과 미세하게 어긋나게 만든다 |
| 명도 대비 수치 | 계산 없이 “AA 통과”라고 단정한다 |
| 아이콘 이름 | 세트에 없는 이름을 지어낸다 |
| 접근성 속성 | aria-label, alt를 빠뜨리거나 무의미하게 채운다 |
| 모바일 메뉴 | 열림 상태 관리와 포커스 트랩을 빠뜨린다 |
| 이미지 경로 | 존재하지 않는 파일명을 만들어낸다 |
| 폼 검증 | 오류 메시지를 시각으로만 표시하고 스크린리더 연결을 빠뜨린다 |
backdrop-filter | -webkit- 접두사를 빠뜨린다 |
6.5 – 팀 운영 규칙
- 선택표와
tokens.css수정 권한은 한 사람에게 둔다. 팀원이 각자 AI에게 토큰 추가를 시키면 선택표와 코드가 어긋난다. 추가가 필요하면 담당자에게 요청하고, 담당자가 선택표를 갱신한 뒤tokens.css를 고친다. - “선택표에 없음” 보고를 기록한다. AI가 이 보고를 낼 때마다 팀 문서에 남긴다. 같은 항목이 3회 이상 나오면 실제로 빠뜨린 토큰이므로 추가한다. 1회만 나온 것은 그 자리에 직접 적는다.
- AI 대화 로그를 남긴다. 어떤 지시로 어떤 코드가 나왔는지 기록해야 문제가 생겼을 때 되짚을 수 있다.
- AI 생성 코드를 그대로 커밋하지 않는다. 최소한 셋은 사람이 확인한다. 하드코딩된 색이 없는가, 모든 티어가 동작하는가, 키보드 Tab 키로 모든 링크·버튼에 접근되는가.
- 한 번에 한 컴포넌트씩 만든다. “전체 페이지를 만들어줘”는 검증 불가능한 결과물을 낳는다.
- 목업 1페이지 완성 시점에 2차 컷을 한다. 실제로 안 쓴 토큰을 지우고 선택표와 코드를 맞춘다.
- 확정 결과를 팀 기록에 남긴다. Figma [Share] → [Copy link]로 링크를 뽑고, 선택표와 판정에서 갈렸던 항목의 결정 근거를 함께 적는다. 짝이 바뀌어도 다음 사람이 같은 기준으로 이어 가려면 결정 배경이 남아 있어야 한다.
여러 팀이 같은 킷을 쓰는 경우에는 서로 다른 디자인을 만들되 관리 난이도는 같게 한다. 개수 상한과 이름 체계만 공유하고 실제 값은 팀별로 정한다. 이러면 각 팀의 tokens.css 구조가 동일해 같은 기준으로 검토할 수 있고, 결과물은 서로 다르게 나온다.
7 – 착수 전 결정 기록
아래를 정하지 않으면 진행이 막힌다. 프로젝트 시작 시 한 번에 결정해 이 표를 채운다.
| 항목 | 참조 | 결정 |
|---|---|---|
| 받은 링크의 node-id가 실재하는가 | 1.3 | |
| 기존 시맨틱 컬렉션이 있는가 | 1.2 | |
| 브랜드 주색으로 쓸 스케일 | 3.4 | |
| 중립 스케일 (하나만) | 3.4 | |
| 한글 폰트 | 2.3 | |
| 목업을 만들 티어 개수 | 1.2 | |
고정 헤더에 backdrop-blur를 쓸지 | 3.4 | |
| 아이콘 세트의 어느 변형으로 통일할지 | 3.4 | |
| 세트에 없는 아이콘의 대체안 | 3.4 | |
| 프리미티브 색을 hex로 적을지 oklch로 갱신할지 | 4.4 | |
| 여러 팀이면 상한만 공유할지 값까지 공유할지 | 6.5 |
8 – 적용 사례 — ESG_DesignSystem 실측
아래는 실제 킷 하나를 이 절차로 진단한 결과다. 본문의 일반 절차가 특정 파일에서 어떤 모양으로 나타나는지 보여 주는 예시이므로, 다른 프로젝트에서는 값이 다르다.
대상은 Figma 파일 ESG_DesignSystem(fileKey t3mJ2pOkrBuV3gtUc5mvUi)이고, 진단 시점은 2026-08-03이다.
8.1 – 확인된 구조
이 킷은 변수 컬렉션이 세 개다.
| 컬렉션 | 들어 있는 것 |
|---|---|
Primitives | color/{계열}/{50~950}, font/size·font/line-height·font/weight·font/family, spacing/*, breakpoint/*, container/*, radius/*, border-width/* |
Semantic | surface/bg-*, text/text-*, icon/icon-*, border/border-* |
Theme controller | Semantic과 같은 이름이 다시 들어 있다. 모드 전환용이다 |
Semantic 컬렉션이 이미 있으므로 4.1에서 이름을 새로 만들지 않는다. 확인된 이름은 아래와 같다.
| 그룹 | 확인된 이름 |
|---|---|
| surface | bg-default, bg-brand, bg-brand-secondary, bg-brand-contrast, bg-minimal, bg-grey-out |
| text | text-brand, text-secondary |
| icon | icon-secondary |
| border | border-secondary, border-tertiary, border-negative, border-grey-out, border-focused-outline, border-focused-offset |
4.1 표준 이름과 대조하면 대응이 이렇게 잡힌다. 확인 상태를 함께 적었다.
| 4.1 표준 이름 | 이 킷의 이름 | 확인 상태 |
|---|---|---|
surface/default | surface/bg-default | 이름 확인됨 |
surface/subtle | surface/bg-minimal | 이름 확인됨, 역할 추정 |
brand/primary | surface/bg-brand | 이름 확인됨 |
brand/primary-hover | surface/bg-brand-secondary | 이름 확인됨, 역할 추정 |
text/inverse | surface/bg-brand-contrast | 이름 확인됨, 역할 추정 |
text/primary | 대응 이름 확인 못 함 | 확인 필요 |
text/secondary | text/text-secondary | 이름 확인됨 |
border/default | border/border-secondary | 이름 확인됨 |
border/strong | border/border-tertiary | 이름 확인됨, 역할 추정 |
border/focus | border/border-focused-outline | 이름 확인됨 |
state/error | border/border-negative(테두리 전용) | 색 계열 확인 못 함 |
state/success | 대응 이름 확인 못 함 | 확인 필요 |
| 표준에 없음 | surface/bg-grey-out, border/border-grey-out | 비활성 상태용. 표준보다 촘촘하다 |
| 표준에 없음 | border/border-focused-offset | 포커스 바깥선용 |
“확인 필요”로 남긴 세 줄은 5.1 진단 프롬프트로 파일 안에서 확정한다. 이 표만 보고 값을 바꾸면 없는 이름을 고치려 들게 된다.
이 킷의 Semantic은 4.1 표준보다 비활성 상태와 포커스 표시가 촘촘하다. 반대로 성공·오류 상태 그룹은 확인되지 않았다. 즉 킷마다 빠진 자리와 넘치는 자리가 다르므로, 표준 이름표를 그대로 얹는 대신 대조표를 만들어 갈라 보는 편이 안전하다.
8.2 – 확인된 결함과 판단
첫째, 글꼴이다. font/family/sans 값이 Noto Sans다. Google Fonts는 Noto Sans와 Noto Sans Korean을 서로 다른 패밀리로 제공하므로, 2.3에 따라 한글 글꼴을 다시 정해야 한다.
둘째, 아이콘 변형이다. 이 킷에서 검색되는 아이콘은 heroicons-solid/*다. 3.4의 일반 권장은 outline 단일 사용이지만, 이 킷에 outline 변형이 있는지는 확인되지 않았다. solid만 있으면 solid로 통일한다.
셋째, 컴포넌트다. 발행된 컴포넌트로 검색되는 것은 Text Input(component set, 2026-07-29 갱신)과 heroicons-solid/* 아이콘뿐이다. 4.2의 1차 목록 가운데 Header·GNB, Button, Card가 비어 있다.
넷째, 페이지 구조와 컴포넌트 목록이 어긋난다. 페이지 목록에는 Tailwind CSS 한 장만 잡히는데 Text Input이 그 페이지 구조에 없다. 1.3에 따라 값을 바꾸기 전에 파일 안에서 직접 확인할 항목이다.
다섯째, 프레임 안 메모다. 캔버스에 상태 에러-red 주의-yellow 지연-green 성공-blue라고 적혀 있다. 통상 쓰임은 성공이 green, 안내가 blue다. 어느 쪽을 따를지 팀이 먼저 정한 뒤 5.6으로 넘어간다.
8.3 – Tailwind v4 대조 결과
이 킷의 Primitives 값을 Tailwind v4 기본과 대조하면 아래 항목이 모두 일치한다. 따라서 4.4의 @theme에 다시 적지 않는다.
| 항목 | 이 킷의 값 | Tailwind v4 기본 | 16px 환산 |
|---|---|---|---|
breakpoint/sm~2xl | 640·768·1024·1280·1536 | --breakpoint-sm 40rem 등 | 같음 |
container/3xs~7xl | 256·288·320·384·448·512·576·672·768·896·1024·1152·1280 | --container-3xs 16rem 등 | 같음 |
font/size/base·2xl·3xl·8xl·9xl | 16·24·30·96·128 | --text-base 1rem 등 | 같음 |
font/line-height/base·2xl·3xl | 24·32·36 | 계산값 | 같음 |
font/weight/medium·semibold·bold | 500·600·700 | --font-weight-* | 같음 |
spacing/36·40·48·80 | 144·160·192·320 | --spacing 0.25rem × 배수 | 같음 |
radius/*는 이름만 확인했고 값은 대조하지 못했다. Tailwind v4 기본은 --radius-xs 0.125rem(2px)부터 --radius-4xl 2rem(32px)까지이므로, 이 킷 값이 같은지는 5.1 진단 답에서 확인한다.
Theme controller 컬렉션은 이 프로젝트의 완료 조건에 다크 모드가 없으므로 손대지 않는다. 3.6에 따라 지우지 않고 그대로 남긴다.