소개
시도한 것: 웹사이트 하나(nodejs.org)에서 디자인 언어를 자동 추출 → 노이즈 교정 → 상세페이지/PPTX 적용 가이드 작성 → 클로드 디자인(claude.ai/design)에 디자인 시스템으로 업로드까지, 한 세션 안에서 끝내기.
왜 했나:
레퍼런스 사이트의 톤앤매너를 분석할 때 보통 개발자도구로 색을 하나씩 스포이드하거나, 스크린샷을 AI에 던지고 "이런 느낌으로"라고 말합니다. 둘 다 부정확합니다. 정확한 hex와 px을 가진 문서가 있으면 AI에게든 디자이너에게든 훨씬 정확하게 전달됩니다.
다만 자동 추출 도구를 그대로 믿으면 안 될 것 같다는 의심이 있었고, 그 의심이 이번 사례의 핵심이 됐습니다.
진행 방법
사용 도구
Claude Code (Opus 4.8) — 전 과정 진행
designlang v12.21.0 — npx로 실행하는 디자인 언어 추출 CLI
claude.ai/design — 최종 디자인 시스템 호스팅
1단계. 환경 확인
내 컴퓨터에 Node.js가 설치돼 있는지 확인해줘 (node --version 실행).
설치돼 있으면 버전만 알려줘.
안 돼 있으면 내 운영체제에 맞는 방법으로 설치를 진행해줘(Windows면 winget, Mac이면 Homebrew 등). 관리자 권한이나 내 확인이 필요한 부분은 멈춰서 단계별로 안내해줘.
→ v22.23.1 확인. 설치 불필요.
Tip: "안 돼 있으면 ~해줘, 확인 필요하면 멈춰줘"처럼 분기와 정지 조건을 미리 주면 AI가 임의로 설치를 진행하지 않습니다.
2단계. 추출
현재 폴더 안에 "디자인분석"이라는 새 폴더를 만들고, 그 폴더 안에서 아래를 실행한 뒤 생성된 결과 파일들을 정리해서 요약해줘: npx designlang <https://nodejs.org/>
35개 파일이 쏟아졌습니다. Tailwind config, Figma 변수, shadcn 테마, 모션 프리셋 7종(Framer/GSAP/Motion One/WAAPI…), AI 에이전트용 프롬프트팩까지.
동작 원리가 흥미로웠습니다. CSS 소스를 읽는 게 아니라, Playwright로 헤드리스 브라우저를 띄워 DOM 881개 요소에 getComputedStyle()을 호출합니다. 브라우저가 최종적으로 그린 결과를 역으로 수집하는 방식이라 Next.js든 워드프레스든 난독화된 클래스명이든 상관없이 동작합니다.
3단계. 다크모드 추가
라이트 모드와 다크모드가 있을거야. 두가지를 구분해서 모두 포함하면 좋겠어.
-dark플래그가 있었습니다. 재실행하니dark-mode.json이 생기고 shadcn 테마에.dark블록이, Figma 변수에 Light/Dark 컬렉션이 추가됐습니다.
여기서 재밌는 발견 — 라이트에선 Node 그린이 주역이고 앰버가 포인트인데, 다크에선 둘이 뒤바뀝니다. 어두운 배경에서 딥그린(#0d350a)은 대비가 안 나오니 합리적인 전환입니다.
4단계. 노이즈 검증 (여기가 핵심)
designlang이 뽑아준 결과를 바탕으로, 이 도구가 무엇을·어떻게·왜 하는지 직관적으로 설명해줘.
그리고 추출된 핵심 토큰(색·폰트·여백·컴포넌트)을 요약하고,
믿을 수 없는 노이즈(예: 이모지가 폰트로 잡히는 것)가 있으면 짚어줘.
"이모지가 폰트로 잡히는 것" 같은 구체적 예시를 하나 던진 게 결정적이었습니다. 그냥 "검증해줘"라고 했으면 두루뭉술한 답이 왔을 겁니다. 실제로 8개 파일에서 이게 발견됐습니다:
--font-sans: ui-sans-serif, system-ui, sans-serif,
"Apple Color Emoji", "Segoe UI Emoji",
"Segoe UI Symbol", "Noto Color Emoji";
Tailwind 기본 스택의 폴백일 뿐인데 "서체"로 기록된 겁니다.
더 큰 문제도 나왔습니다.
원본 판정
실체
primary: #eceff4 (53회 1위)
그냥 보더용 회색. 브랜드 아이덴티티 없음
진짜 Node 그린 #417e38
21회라서 밀림
secondary(2회), accent(1회)
표본 1~2회를 브랜드 축으로 승격
Nord 팔레트 6색
코드 하이라이터 테마가 팔레트에 침투
--twoslash-* 20개
코드 툴팁 플러그인 변수
spacing 2·32·56·99·112·138
"2px 배수"인데 99가 홀수 → flex/grid 실측 간격 혼입
CTA 동사 res, createServer
히어로의 코드 예제를 버튼으로 오인
결론: 빈도 ≠ 중요도. 이게 이 도구의 구조적 한계입니다.
5단계. 교정 + 적용 가이드
designlang이 뽑아준 토큰과 브랜드 문서를 원본 초안으로 삼아, 다음을 해줘:
1. 추출 노이즈(폰트·색 대비 등) 필요하면 교정하고 대안 제시
2. 이 토큰을 상세페이지(HTML)의 실제 컴포넌트(히어로/가격표/CTA/카드/뱃지)에 매핑한 적용 가이드
3. PPTX 카탈로그용 규칙(표지·본문 슬라이드 색/폰트/여백) 별도 정리
4. 위를 하나의 HTML로 묶어 한눈에 디자인 시스템을 살펴보게 해줘. 보고 피드백할게.
여기서 Claude가 시키지 않은 일을 했는데, 그게 제일 값졌습니다. WCAG 상대휘도 공식으로 대비비 30쌍을 직접 계산했습니다:
def lum(h):
h=h.lstrip('#'); r,g,b=[int(h[i:i+2],16)/255 for i in (0,2,4)]
f=lambda c: c/12.92 if c<=0.03928 else ((c+0.055)/1.055)**2.4
return 0.2126*f(r)+0.7152*f(g)+0.0722*f(b)
def cr(a,b):
l1,l2=lum(a),lum(b); l1,l2=max(l1,l2),min(l1,l2)
return (l1+0.05)/(l2+0.05)
결과가 충격적이었습니다:
색
라이트(#fff)
다크(#0d121c)
#417e38 브랜드 그린
4.92 AA ✅
3.81 FAIL ❌
#84ba64 밝은 그린
2.29 FAIL ❌
8.20 AAA ✅
#0080ff 원본 링크색
3.80 FAIL ❌
—
브랜드 그린은 한 값으로 양쪽 모드를 버틸 수 없습니다. 원본 토큰을 그대로 썼으면 다크모드 접근성이 통째로 깨졌을 겁니다.
그래서 세 가지 규칙을 세웠습니다:
모드별로 다른 브랜드 값 (
-brand시맨틱 토큰)면색과 텍스트색 분리 — 버튼 면엔
#417e38, 소형 텍스트엔#2c682c(6.72)면을 채우지 말고 테두리로 강조 — 이 시스템 머티리얼이
flat(shadow blur 0)이라 면을 채우면 톤이 깨짐
6단계. 클로드 디자인 업로드
방금 우리가 이 대화에서 함께 만든 디자인 시스템을,
클로드 디자인(claude.ai/design)의 디자인 시스템으로 업로드해줘.
- 컴포넌트별 @dsCard 미리보기 카드 + 토큰을 담은 업로드용 패키지로 먼저 재구성해줘 (아직 없으면 지금 만들어줘)
- "우리 브랜드 디자인 시스템" 이라는 새 프로젝트를 만들어 올려줘
- 도중에 디자인 권한 승인 창이 뜨면 알려줘, 내가 승인할게
토큰 CSS를 각 프리뷰 에 인라인하는 빌드 스크립트를 만들어 자립형 HTML 10개를 생성했습니다. 각 파일 첫 줄에 @dsCard 마커:
<!-- @dsCard group="Components" name="가격표" subtitle="3플랜 · 추천은 테두리 2px로 강조" width="900" height="620" -->
빌드 스크립트 핵심부:
import { fileURLToPath } from 'node:url';
const ROOT = fileURLToPath(new URL('.', import.meta.url)); // 한글 경로 대응
const TOKENS = readFileSync(join(ROOT, 'tokens/tokens.css'), 'utf8');
for (const c of C) {
const head = `<!-- @dsCard group="${c.group}" name="${c.name}" ... -->
<!DOCTYPE html>
<html lang="ko"><head><style>
${TOKENS}
${BASE}
${c.css}
</style></head><body>${c.html}</body></html>`;
writeFileSync(join(ROOT, c.file), head, 'utf8');
}
DesignSync 도구로 list_projects → create_project → finalize_plan → write_files 순서로 13개 파일 업로드 완료.
최종 산출물
Foundations 3장 (컬러/타이포/여백)
Components 6장 (버튼/뱃지/카드/가격표/히어로/CTA)
PPTX 1장 (슬라이드 마스터 4종)
tokens.css+tokens.json(DTCG) + README
한국어 텍스트가 있는 웹사이트의 스크린샷
결과와 배운 점
🔑 꿀팁 3가지
1. AI에게 "검증해줘"보다 "이런 노이즈 있으면 짚어줘 (예: ○○)"
구체적 예시를 하나 던지면 AI가 검증의 축을 잡습니다. 저는 "이모지가 폰트로 잡히는 것"만 예로 들었는데, 그 축을 따라 Nord 팔레트 침투, twoslash 변수 오염, 코드블록을 버튼으로 오인한 것까지 줄줄이 나왔습니다.
2. 자동 추출 도구의 출력은 "결과"가 아니라 "초안"
designlang은 훌륭하지만 통계 기반입니다. 가장 많이 쓰인 색을 primary로 뽑는데, 웹사이트에서 가장 많이 쓰이는 색은 대개 보더용 회색입니다. 브랜드 컬러는 오히려 아껴 씁니다. 이 역설을 모르고 쓰면 정반대 결론이 나옵니다.
3. "보고 피드백할게"를 프롬프트에 넣기
이 한마디를 넣으니 Claude가 마지막에 "피드백 주시면 좋을 지점 4가지"를 스스로 정리해줬습니다. 브랜드 그린 톤을 더 진하게 갈지, PPTX 표지를 밝게 바꿀지 같은 판단이 필요한 지점만 골라서 물어봐서 검토가 훨씬 빨랐습니다.
😅 시행착오
① ✖ Extraction failed가 매번 떴는데 파일은 다 생성됨
The "string" argument must be of type string or an instance of Buffer... Received undefined
처음엔 실패한 줄 알고 당황했는데, 파일 생성 후 마무리 단계 버그였습니다. 에러 메시지를 보고 바로 포기하지 말고 결과물을 먼저 확인하세요.
② 도구 자체의 파싱 버그 2건
breakpoints: [object Object]px— 값이 통째로 깨짐semantic/typography/body에fontSize: 48px— body인데 h1 값이 주입됨
이건 교정 불가라 수동으로 재정의했습니다.
③ 한글 경로에서 Node 스크립트가 깨짐
Error: ENOENT: no such file or directory, open '.../23%E1%84%80%E1%85%B5/...'
import.meta.url의 .pathname이 한글을 URL 인코딩해버립니다. fileURLToPath()를 써야 합니다. 한글 폴더명 쓰는 분들은 주의하세요.
④ 승인 창이 안 떴습니다
"권한 승인 창 뜨면 알려줘"라고 했는데, claude.ai 로그인에 design 권한이 이미 있어서 프롬프트 없이 그냥 통과했습니다. 지켜보고 있었다면 헛수고. 다음엔 "권한 상태 먼저 확인해줘"를 앞에 붙이면 좋겠습니다.
⑤ 브라우저 스크린샷이 계속 빈 화면
검증하려고 스크린샷을 찍었는데 백지만 나왔습니다. 알고 보니 브라우저 패널이 숨겨진 상태였고, DOM을 직접 쿼리해서 검증했습니다:
JSON.stringify({plans:document.querySelectorAll('.plan').length,
overflowX:document.documentElement.scrollWidth>document.documentElement.clientWidth})
→ 시각 확인이 막히면 구조 검증 으로 우회하는 것도 방법입니다.
🙋 도움이 필요한 부분
@dsCard마커 스펙이group속성만 문서화돼 있습니다.name/subtitle/width/height도 같이 넣었는데 실제로 파싱되는지 확실치 않습니다. 클로드 디자인 써보신 분 계시면 알려주세요.PPTX는 아직 규칙만 만들고 실제 파일은 안 뽑았습니다. python-pptx로 자동 생성해보신 분 노하우 궁금합니다.
📅 앞으로의 계획
[ ] 확정된 토큰으로 실제 PPTX 카탈로그 파일 생성 (python-pptx)
[ ]
-ignore "pre" "code" --palette 8옵션으로 재추출해 노이즈 감소폭 비교[ ]
designlang drift를 CI에 연결해 디자인 드리프트 감지 실험[ ] 자사 사이트로 같은 파이프라인 돌려보기
도움 받은 글
designlang (npm) — v12.21.0
nodejs.org — 추출 대상
WCAG 2.1 Contrast Minimum — 대비비 판정 기준
W3C Design Tokens (DTCG) — tokens.json 포맷
한 줄 요약
자동 추출 도구는 "정답"이 아니라 "초안"을 줍니다.
빈도 1위 색이 브랜드 컬러가 아니고, 폰트 목록에 이모지가 섞여 있고,
원본 그대로 쓰면 다크모드 대비가 깨집니다.
AI에게 검증을 시킬 때 "이런 노이즈 있는지 봐줘"라고 축을 하나 던지면, 나머지는 알아서 찾아옵니다.