Wanted Montage (원티드)
쿨 뉴트럴 회색 위 단일 블루 #0066FF, 투명도로 쌓는 라벨·라인 위계
Brand DNA
브랜드 DNA
- 브랜드명: Wanted Montage (원티드 몬타주, 원티드랩 디자인 시스템)
- 한 줄 정체성: 채용 플랫폼 원티드의 웹·iOS·Android 화면을 한 벌의 토큰과 컴포넌트로 묶는 공개 디자인 시스템
- 공식 디자인 철학: 「몬타주」 — 영화에서 여러 장면을 이어 새 이미지를 만들듯, 개별 스타일과 컴포넌트를 조합해 더 아름답고 직관적인 서비스를 만든다. 최근에는 AI 가 디자인을 해석·생성하는 「에이전틱 디자인 시스템」을 표방한다(MCP 패키지
wds-mcp공개). - 시그니처 요소 1개: 쿨 뉴트럴 회색 위의 단일 블루
#0066FF와, 글자·선 색을 불투명 hex 가 아니라 같은 회색의 투명도 단계(88%·61%·28%·16%) 로 쌓는 라벨·라인 위계
Tone & Mood
톤 & 무드
- 핵심 키워드 3개: 명료, 담백, 체계
- 무드 설명: 흰 바탕에 거의 검은 라벨(#171719), 행동은 파란색 하나로만 표시한다. 색 면보다 얇은 안쪽 테두리(inset 1px)와 옅은 채움(fill 8%)으로 구획을 나눠, 채용 공고처럼 정보가 많은 화면도 조용하게 읽힌다.
- 비주얼 스타일: 모던 미니멀
- 밀도(Density): Comfortable — 공고 목록·필터가 많은 화면이지만 버튼 기본 높이 48px(large)·본문 16px 로 모바일 터치 여유를 둔다
- 모서리 성향: Round (12px) — 버튼 large·카드·입력창 모두 12px, 작은 버튼은 10·8px
- 평면성: Subtle — 카드는 xsmall 그림자 + 안쪽 1px 라인, 떠 있는 레이어만 medium 이상
Color System
컬러 시스템 (CSS 변수)
공식 토큰 패키지 @wanteddev/wds-theme 의 atomic(blue·coolNeutral·green·orange·red) → semantic(light/dark) 값을 그대로 옮겼다. 9단계 primary 는 공식 blue 스케일(95→20)에서 골라 매핑했다.
:root {
/* Primary - Wanted Blue (atomic blue 95 → 20) */
--color-primary-50: #EAF2FE; /* blue 95 · 선택 배경, info 면 */
--color-primary-100: #C9DEFE; /* blue 90 */
--color-primary-200: #9EC5FF; /* blue 80 */
--color-primary-300: #69A5FF; /* blue 70 */
--color-primary-400: #3385FF; /* blue 60 · 다크 모드 primary normal */
--color-primary-500: #0066FF; /* blue 50 · primary normal (기본) */
--color-primary-600: #005EEB; /* blue 45 · primary strong (hover) */
--color-primary-700: #0054D1; /* blue 40 · primary heavy (pressed) */
--color-primary-800: #003E9C; /* blue 30 */
--color-primary-900: #002966; /* blue 20 */
/* Secondary - inverse 배경 (토스트·툴팁) */
--color-secondary-500: #1B1C1E; /* coolNeutral 15 */
/* Neutral - Cool Neutral */
--color-neutral-0: #FFFFFF;
--color-neutral-50: #F7F7F8; /* coolNeutral 99 · background alternative */
--color-neutral-100: #F4F4F5; /* coolNeutral 98 · interaction disable */
--color-neutral-200: #E1E2E4; /* coolNeutral 96 · line solid normal */
--color-neutral-300: #C2C4C8; /* coolNeutral 90 */
--color-neutral-500: #70737C; /* coolNeutral 50 · 라인·채움의 기준색 */
--color-neutral-700: #37383C; /* coolNeutral 25 · 라벨 투명도 기준색 */
--color-neutral-900: #171719; /* coolNeutral 10 · label normal */
--color-neutral-1000: #000000;
/* Semantic - status 는 원색, 배경은 같은 색 8% */
--color-success-bg: rgba(0,191,64,0.08);
--color-success-fg: #00BF40; /* green 50 · positive */
--color-warning-bg: rgba(255,146,0,0.08);
--color-warning-fg: #FF9200; /* orange 50 · cautionary */
--color-error-bg: rgba(255,66,66,0.08);
--color-error-fg: #FF4242; /* red 50 · negative */
--color-info-bg: #EAF2FE;
--color-info-fg: #0066FF;
/* Surface */
--bg-base: #FFFFFF; /* background normal */
--bg-subtle: #F7F7F8; /* background alternative · 섹션 구분 */
--bg-elevated: #FFFFFF; /* elevated normal · 카드 */
--bg-overlay: rgba(23,23,25,0.52); /* material dimmer */
/* Text - label 위계 (회색 + 투명도) */
--text-primary: #171719; /* label normal */
--text-secondary: rgba(46,47,51,0.88); /* label neutral */
--text-tertiary: rgba(55,56,60,0.61); /* label alternative */
--text-on-primary: #FFFFFF; /* static white */
--text-disabled: rgba(55,56,60,0.16); /* label disable */
--text-assistive: rgba(55,56,60,0.28); /* label assistive · placeholder */
/* Border - line (투명) + solid */
--border-default: rgba(112,115,124,0.22); /* line normal normal */
--border-subtle: rgba(112,115,124,0.08); /* line normal alternative */
--border-strong: rgba(112,115,124,0.43); /* (추정) 강조 라인 */
--border-focus: #0066FF;
--border-solid: #E1E2E4; /* line solid normal */
/* Fill - 칩·아이콘 버튼 바탕 */
--fill-normal: rgba(112,115,124,0.08);
--fill-strong: rgba(112,115,124,0.16);
--fill-alternative: rgba(112,115,124,0.05);
}
[data-theme="dark"] {
--color-primary-500: #3385FF; /* dark primary normal = blue 60 */
--color-primary-600: #1A75FF; /* strong = blue 55 */
--color-primary-700: #0066FF; /* heavy = blue 50 */
--color-success-fg: #1ED45A;
--color-warning-fg: #FFA938;
--color-error-fg: #FF6363;
--bg-base: #1B1C1E; /* coolNeutral 15 */
--bg-subtle: #0F0F10; /* coolNeutral 5 */
--bg-elevated: #212225; /* coolNeutral 17 */
--bg-overlay: rgba(23,23,25,0.74);
--text-primary: #F7F7F8;
--text-secondary: rgba(194,196,200,0.88);
--text-tertiary: rgba(174,176,182,0.61);
--text-disabled: rgba(152,155,162,0.16);
--border-default: rgba(112,115,124,0.32);
--border-subtle: rgba(112,115,124,0.22);
--border-solid: #37383C;
--border-focus: #3385FF;
}
Typography
타이포그래피
- 폰트 페어링:
- 한글: Pretendard JP (SIL OFL) — Montage 문서의 타이포그래피 기본 서체. 제작자 길형진은 원티드랩 디자인팀 소속으로 브랜드 서체 제작에도 참여했다(Pretendard 자체는 개인 오픈소스 프로젝트).
- 영문: Pretendard JP 동일 사용 · 브랜드 표현용 Wanted Sans (SIL OFL, 2023년 원티드랩 디자인팀 제작)
- 위계 (공식 variant 명 병기, 굵기는 Display·Title=700, 그 외 bold=600):
- Display (display1): 56px / 700 / 72px / -0.0319em
- H1 (title1): 32px / 700 / 44px / -0.0253em
- H2 (title3): 24px / 700 / 32px / -0.023em
- H3 (heading2): 20px / 600 / 28px / -0.012em
- Body Large (headline1): 18px / 600 / 26px / -0.002em
- Body (body1): 16px / 400 / 24px / 0.0057em — 긴 글은 body1-reading(26px)
- Body Small (label1): 14px / 500 / 20px / 0.0145em
- Caption (caption1): 12px / 500 / 16px / 0.0252em
- 공식 스케일은 display1~3, title1~3, heading1~2, headline1~2, body1~2, label1~2, caption1~2 의 17단계(+ reading 변형). 큰 글자일수록 자간을 좁히고, 작은 글자일수록 넓힌다.
Spacing
스페이싱
- Base unit: 4px (공식 spacing 토큰은 0·1·2·4·6·8·10·12·14·16·20·24·32·40·48·56·64·72·80px)
- 토큰: ``
css :root { --space-xs: 4px; --space-sm: 8px; --space-md: 16px; --space-lg: 24px; --space-xl: 32px; --space-2xl: 48px; --space-3xl: 64px; }`` - Container: 문서 사이트 기준 좌우 패딩 20px(
--layout-padding-inline), 서비스 콘텐츠 폭 1060px 전후 (추정)
Border Radius
Border Radius
:root {
--radius-none: 0;
--radius-sm: 6px; /* 배지 (추정) */
--radius-md: 8px; /* small 버튼 · 칩 */
--radius-lg: 12px; /* large 버튼 · 카드 · 입력창 */
--radius-xl: 16px; /* 바텀시트 · 모달 (추정) */
--radius-full: 9999px;
}
medium 버튼은 10px. 크기가 작아질수록 반경도 2px씩 줄인다.
Shadow / Elevation
Shadow / Elevation
:root {
--shadow-none: none;
--shadow-xs: 0 1px 2px -1px rgba(23,23,23,0.10); /* 카드 기본 */
--shadow-sm: 0 2px 4px -2px rgba(23,23,23,0.06), 0 4px 6px -1px rgba(23,23,23,0.06); /* 카드 hover · 칩 */
--shadow-md: 0 4px 6px -2px rgba(23,23,23,0.07), 0 10px 15px -3px rgba(23,23,23,0.07); /* 드롭다운 · 팝오버 */
--shadow-lg: 0 6px 10px -4px rgba(23,23,23,0.08), 0 16px 24px -6px rgba(23,23,23,0.08); /* 모달 */
--shadow-xl: 0 10px 15px -5px rgba(23,23,23,0.10), 0 24px 38px -10px rgba(23,23,23,0.12); /* 풀스크린 다이얼로그 */
--shadow-spread: 0 15px 75px 0 rgba(23,23,23,0.16); /* 넓게 퍼지는 플로팅 레이어 */
}
그림자 색은 파란빛 없이 순수 neutral 10(#171717) 기반. 카드는 그림자와 함께 안쪽 1px 라인(inset 0 0 0 1px)을 겹쳐 외곽을 잡는다.
Iconography
Iconography
- 스타일: Outline + Filled 쌍 — 같은 아이콘을
icon-bookmark/icon-bookmark-fill두 벌로 제공, 선택 상태에서 Fill 로 바꾼다 - Stroke 굵기: 약 1.8px 상당 (추정 — 공식 아이콘은 선이 아니라 채움 path 로 그려져 있다)
- 모서리 처리: Round
- 추천 라이브러리: 공식
@wanteddev/wds-icon(React 컴포넌트) · 대체로 Lucide(stroke 1.75)
Component Guide
컴포넌트 가이드 (상태별 CSS)
Button
.btn {
font: 600 16px/24px Pretendard, -apple-system, BlinkMacSystemFont, 'Apple SD Gothic Neo', sans-serif;
letter-spacing: 0.0057em;
border: 0; cursor: pointer;
border-radius: var(--radius-lg);
padding: 12px 28px; /* large */
display: inline-flex; align-items: center; justify-content: center; gap: 6px;
transition: background-color var(--duration-fast) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out);
}
.btn-md { padding: 9px 20px; border-radius: 10px; font-size: 15px; line-height: 22px; }
.btn-sm { padding: 7px 14px; border-radius: var(--radius-md); font-size: 13px; line-height: 18px; }
/* Primary (solid) */
.btn-primary { background: var(--color-primary-500); color: var(--text-on-primary); }
.btn-primary:hover { background: var(--color-primary-600); }
.btn-primary:active { background: var(--color-primary-700); }
.btn-primary:disabled { background: var(--color-neutral-100); color: var(--text-disabled); cursor: not-allowed; }
.btn-primary.is-loading { color: transparent; position: relative; }
/* Secondary (outlined) */
.btn-secondary { background: transparent; color: var(--color-primary-500); box-shadow: inset 0 0 0 1px var(--border-default); }
.btn-secondary:hover { background: var(--fill-alternative); }
.btn-secondary:active { background: var(--fill-normal); }
.btn-secondary:disabled { color: var(--text-disabled); }
/* Ghost (assistive · medium 굵기) */
.btn-ghost { background: transparent; color: var(--text-secondary); font-weight: 500; box-shadow: inset 0 0 0 1px var(--border-default); }
.btn-ghost:hover { background: var(--fill-alternative); }
.btn-ghost:active { background: var(--fill-normal); }
/* Danger */
.btn-danger { background: var(--color-error-fg); color: #FFFFFF; }
.btn-danger:hover { filter: brightness(0.94); }
.btn-danger:disabled { background: var(--color-neutral-100); color: var(--text-disabled); }
Input
.input {
width: 100%; box-sizing: border-box;
font: 400 16px/24px Pretendard, -apple-system, sans-serif;
padding: 12px; border: 0; border-radius: var(--radius-lg);
background: var(--bg-elevated); color: var(--text-primary);
box-shadow: inset 0 0 0 1px var(--border-default);
transition: box-shadow var(--duration-base) ease;
}
.input::placeholder { color: var(--text-assistive); }
.input:focus { outline: none; box-shadow: inset 0 0 0 2px var(--border-focus); }
.input.is-error { box-shadow: inset 0 0 0 2px var(--color-error-fg); }
.input:disabled { background: var(--color-neutral-100); color: var(--text-disabled); }
Card
.card {
border-radius: var(--radius-lg); padding: 12px;
background: var(--bg-elevated);
box-shadow: var(--shadow-xs), inset 0 0 0 1px var(--border-subtle);
}
.card-emphasis { background: var(--color-primary-50); box-shadow: inset 0 0 0 1px rgba(0,102,255,0.28); }
.card-outlined { background: transparent; box-shadow: inset 0 0 0 1px var(--border-default); }
Badge / Tag
.badge { display: inline-flex; align-items: center; gap: 2px; padding: 2px 6px; border-radius: var(--radius-sm); font: 600 12px/16px Pretendard, sans-serif; letter-spacing: 0.0252em; }
.badge-solid { background: var(--color-primary-500); color: #FFFFFF; }
.badge-subtle { background: var(--fill-normal); color: var(--text-secondary); }
.badge-outline { box-shadow: inset 0 0 0 1px var(--border-default); color: var(--text-tertiary); }
.badge-positive { background: var(--color-success-bg); color: #00A13A; }
Navigation
.gnb {
height: 62px; display: flex; align-items: center; gap: 24px; padding: 0 20px;
background: var(--bg-base); border-bottom: 1px solid var(--border-subtle);
}
.gnb-logo { display: flex; align-items: center; color: var(--text-primary); }
.gnb-link { font: 600 15px/22px Pretendard, sans-serif; color: var(--text-primary); text-decoration: none; }
.gnb-link[aria-current="page"] { color: var(--color-primary-500); }
.gnb-chip { padding: 7px 14px; border-radius: var(--radius-md); font: 500 13px/18px Pretendard, sans-serif; box-shadow: inset 0 0 0 1px var(--border-default); color: var(--text-tertiary); }
.gnb-chip.is-active { background: var(--text-primary); color: var(--bg-base); box-shadow: none; font-weight: 600; }
Motion
Motion
:root {
--duration-fast: 150ms;
--duration-base: 200ms; /* 입력창 테두리 전환 ease 0.2s (공식) */
--duration-slow: 300ms;
--ease-out: cubic-bezier(0.2, 0, 0, 1); /* (추정) */
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1); /* (추정) */
}
눌림은 크기 변화 없이 배경색 한 단계(strong→heavy)만 바꾼다. 캐릭터성 모션은 별도 wds-lottie 패키지로 분리돼 있다.
Anti-patterns
Anti-patterns
1. 라벨 색을 임의 hex 회색으로 새로 만들지 않는다 — label normal/neutral/alternative/assistive/disable 5단계 투명도만 쓴다 2. 한 화면에 파란색 외의 강조색으로 행동(CTA)을 표시하지 않는다 — 초록·주황·빨강은 상태 전달 전용 3. 카드에 두꺼운 외곽선이나 진한 그림자를 쓰지 않는다 — xsmall 그림자 + 1px 안쪽 라인까지만 4. 다크 모드에서 라이트용 blue 50 을 그대로 쓰지 않는다 — 다크 primary 는 한 단계 밝은 blue 60(#3385FF) 5. 큰 제목에 기본 자간을 두지 않는다 — display·title 은 -2~-3% 로 좁히고, caption 은 오히려 넓힌다
Sources
출처
- https://www.wanted.co.kr/
- https://montage.wanted.co.kr/
- https://montage.wanted.co.kr/docs/getting-started
- https://github.com/wanteddev/montage-web
- https://github.com/wanteddev/montage-web/blob/main/packages/wds-theme/src/theme/semantic/index.ts
- https://github.com/wanteddev/montage-web/blob/main/packages/wds-theme/src/theme/atomic/blue.ts
- https://github.com/wanteddev/montage-web/blob/main/packages/wds/src/components/typography/style.ts
- https://github.com/wanteddev/montage-ios
- https://github.com/wanteddev/wanted-sans
- https://brunch.co.kr/@wanteddesign/28
- https://en.sedaily.com/finance/2026/03/25/wanted-lab-unveils-agentic-design-system-montage