디자인 시스템
"맡아 두기" 시범 화면을 네 책방 주인에게 보여 준 날, 헌책방 나무 주인이 물었다. "우리 가게 화면인데 왜 책방 E 초록이에요?" 작은 숲 주인은 노란색을, 한 줄 주인은 빨간색을 원했다. 그 자리에서 서윤이 화면을 네 벌 그렸다면 버튼은 네 가지 색, 네 가지 크기로 갈라졌을 것이고, 지후는 같은 버튼을 네 번 만들었을 것이다. 한 달 뒤 오류 메시지 색 하나를 고치려면 네 군데를 찾아다녀야 한다. 디자인 시스템은 이런 일을 막으려고 결정을 한 번 내리고 여러 곳에서 나눠 쓰는 방법이다. 이 장은 그 결정이 어떤 층으로 쌓이는지, 어디까지 같게 하고 어디서 다르게 둘지, 그리고 그 규칙을 누가 어떻게 지키는지를 본다.
- 디자인 시스템을 토큰, 컴포넌트, 패턴, 문서, 운영 규칙의 층으로 나눠 설명하고, 의미 토큰이 값과 뜻을 떼어 놓는 까닭을 안다.
- "강조색 한 칸"처럼 바꿀 수 있는 자리를 좁게 정해 여러 브랜드를 한 시스템에 담고, 바꾼 값이 대비와 구별 기준을 지키는지 계산으로 확인한다.
- 변형의 수가 속성의 곱으로 늘어나는 것을 계산하고, 속성을 의미로 제한해 조합을 줄인다.
- 색 감사로 비슷한 값들을 묶어 토큰 후보를 찾고, 컴포넌트 문서에 무엇을 적어야 하는지 안다.
- 요청이 왔을 때 기존 것을 쓸지, 변형을 더할지, 예외로 둘지를 판단하는 기준과, 시스템이 시간이 지나며 흩어지지 않게 하는 운영 방식을 고른다.
같은 버튼을 네 번 그리지 않으려면
디자인 시스템(Design system)은 한 제품(또는 제품군)의 화면을 만들 때 함께 쓰는 결정의 묶음이다. 색과 간격 같은 가장 작은 값, 그 값으로 만든 버튼과 입력 칸 같은 부품, 부품을 엮어 자주 쓰는 화면 조각, 그리고 그것들을 언제 어떻게 쓰는지 적은 문서와, 바꾸고 더하는 절차까지 포함한다. 흔히 "컴포넌트 모음"이나 "디자인 파일의 스티커 시트"로 오해하지만, 부품만 있고 쓰는 규칙과 고치는 절차가 없으면 몇 달 안에 부품의 복사본이 부품보다 많아진다.
시스템의 결정은 층으로 쌓인다. 아래 그림은 이 장에서 쓰는 네 층이다. 아래층이 위층의 재료가 되고, 문서와 운영 규칙이 네 층 모두를 감싼다.
#22342a, 간격 16 px), 의미 토큰은 그 값이 맡은 역할(주 행동의 바탕색), 컴포넌트는 역할을 조합한 부품(주 버튼), 패턴은 부품을 엮은 화면 조각(검색 결과 한 줄)이다. 문서는 각 층을 언제 쓰고 언제 쓰지 않는지를, 운영 규칙은 누가 어떤 절차로 바꾸는지를 적는다.층을 나누는 방식은 팀마다 다르다. 웹 디자이너 브래드 프로스트(Brad Frost)가 『아토믹 디자인』(Atomic Design, 2016)에서 화학의 비유를 빌려 원자·분자·유기체·템플릿·페이지의 다섯 단계로 나눈 틀이 널리 알려졌지만, 이것은 생각을 정리하는 비유이지 표준이 아니다. 어떤 팀은 셋으로, 어떤 팀은 여섯으로 나눈다. 중요한 것은 층의 이름이 아니라 한 결정이 어느 한 곳에만 적혀 있는가다. 버튼의 바탕색이 토큰 파일에도, 버튼 코드에도, 디자인 파일의 버튼에도 따로 적혀 있다면, 그 셋은 언젠가 서로 달라진다.
이 장은 WebBook 6장의 토큰과 WebBook 7장의 컴포넌트를 출발점으로 삼는다. 거기서는 웹사이트 하나를 만드는 사람의 눈으로 토큰과 상태를 봤다. 여기서는 여러 사람과 여러 가게가 오래 함께 쓰는 체계를 운영하는 눈으로 본다. 만드는 일보다 지키고 바꾸는 일이 더 길기 때문이다.
토큰: 이름 붙인 결정
디자인 토큰(Design token)은 색, 글자 크기, 간격, 모서리 둥글기, 그림자 같은 디자인 값에 이름을 붙여 한곳에 모아 둔 것이다. 이 말은 2014년 무렵 한 대형 소프트웨어 회사의 디자인 시스템 팀이 쓰기 시작해 퍼졌다고 흔히 설명된다. 토큰은 디자인 도구와 코드가 같은 값을 읽게 해 주는 공용어 구실을 한다. W3C의 디자인 토큰 커뮤니티 그룹(Design Tokens Community Group)이 도구끼리 토큰을 주고받는 파일 형식을 정리해 왔다. 커뮤니티 그룹의 문서이며 W3C 권고(표준)는 아니다.
토큰은 보통 두 단계 이상으로 나눈다. 원시 토큰(Primitive token)은 "이런 색이 있다"는 목록이다. green-600 = #2f7d5b처럼 값에 붙인 이름이라, 이름에 쓰임이 들어 있지 않다. 의미 토큰(Semantic token)은 "이 역할에는 이 색을 쓴다"는 결정이다. action.primary = {ink-900}처럼 다른 토큰을 가리킨다. 컴포넌트는 의미 토큰만 읽는다. 아래는 그 모양을 줄여 적은 것이다(형식은 커뮤니티 그룹 초안의 $value와 중괄호 참조를 따랐다).
{
"color": {
"ink-900": { "$value": "#22342a" },
"green-600": { "$value": "#2f7d5b" },
"red-500": { "$value": "#d24f39" }
},
"action": { "primary": { "$value": "{color.ink-900}" } },
"text": { "default": { "$value": "{color.ink-900}" } },
"feedback": { "danger": { "$value": "{color.red-500}" } }
}
같은 ink-900을 action.primary와 text.default가 함께 가리킨다는 데 주목한다. 지금은 우연히 같은 값이지만, 뜻은 다르다. 언젠가 "주 버튼만 조금 더 밝게"라는 결정이 나오면 action.primary가 가리키는 곳 하나만 바꾸면 된다. 컴포넌트가 원시 토큰을 곧바로 읽고 있었다면, ink-900을 바꾸는 순간 본문 글자까지 함께 밝아진다. 그걸 피하려면 ink-900을 쓰는 곳을 하나하나 찾아 "이건 버튼 뜻, 이건 글자 뜻"을 가려야 한다.
아래 시뮬레이터는 "맡아 두기" 서비스의 토큰과 컴포넌트, 패턴을 이은 연결망이다. 노드를 누르면 그 값을 바꿀 때 함께 바뀌는 것이 표시된다. 위쪽 단추로 의미 단계를 거치는 연결과 원시 값을 직접 읽는 연결을 바꿔 본다.
값을 바꾸면 어디까지 번지나
ink-900을 누른다. 주 행동과 기본 글자, 두 의미 토큰을 거쳐 거의 모든 컴포넌트가 물든다. 원시 값은 함부로 바꾸는 것이 아니다. ② 의미 토큰 action.primary를 누른다. 버튼과 상태 배지 두 컴포넌트만 바뀌고, 뜻이 섞인 쓰임은 0이다. "주 버튼 색 바꾸기"라는 결정은 여기서 한 번에 끝난다. ③ "원시 값을 직접 읽음"으로 바꾸고 다시 ink-900을 누른다. 어떤 컴포넌트는 이 값을 버튼 바탕으로, 어떤 것은 글자로 쓰고 있어 "뜻이 다른 쓰임"이 여럿 나온다. 주 버튼만 바꾸려면 그 쓰임들을 하나씩 찾아 가려야 한다. (연결망은 이 장이 줄여 그린 "맡아 두기"의 일부다. 실제 시스템의 토큰은 수십에서 수백 개다.)의미 단계는 값과 뜻 사이에 놓인 완충재다. 이 완충재 덕분에 테마도 가능해진다. 다크 모드는 원시 값을 바꾸는 것이 아니라 의미 토큰이 가리키는 곳을 바꾸는 일이고(WebBook 6장에서 "다크 모드는 반전이 아니다"라고 한 이유다), 다음 절에서 볼 책방별 강조색도 의미 토큰 하나가 책방마다 다른 원시 값을 가리키게 하는 일이다. 반대로 의미 단계가 너무 잘게 쪼개지면(버튼마다, 화면마다 의미 토큰을 하나씩 만들면) 원시 값을 직접 쓰는 것과 다를 바가 없어진다. 의미 토큰의 이름은 역할로 짓고, 그 역할을 쓰는 곳이 둘 이상일 때 만든다는 규칙이 흔히 쓰인다.
button.primary.bg = {action.primary}처럼 특정 컴포넌트의 특정 부분에 이름을 붙이는 것이다. 버튼 하나만 따로 바꿔야 할 일이 잦은 큰 시스템에서는 쓸모가 있지만, 토큰 수가 컴포넌트 수만큼 늘어난다. 작은 서비스라면 두 단계로 시작하고, 같은 의미 토큰을 쓰는 컴포넌트들 가운데 하나만 자꾸 달라져야 할 때 그 하나에만 컴포넌트 토큰을 두는 편이 가볍다. "맡아 두기"는 두 단계로 시작했다.
한 칸만 바꾸는 테마
네 책방이 저마다 자기 색을 원하는 것은 당연하다. 손님은 "책방 E에서 맡겼다"는 것을 알아야 하고, 주인에게 가게의 색은 간판만큼 중요하다. 그렇다고 네 책방이 버튼 색, 글자 색, 배경 색을 모두 고를 수 있게 하면 서비스는 네 개로 쪼개진다. 손님은 책방을 옮겨 다닐 때마다 "맡아 두기" 버튼이 무슨 색인지 새로 배워야 하고, 오류 메시지의 빨강과 어느 책방의 빨강이 섞인다.
그래서 여러 브랜드를 한 시스템에 담을 때는 바꿀 수 있는 자리를 좁게 정한다. 이런 체계를 멀티 브랜드 테마(Multi-brand theming)라고 부른다. 서윤은 의미 토큰 가운데 딱 하나, shop.accent만 책방마다 다르게 두는 안을 냈다. 이 색은 책방 이름 배지와 책방 화면 머리의 얇은 띠에만 쓴다. 버튼, 링크, 상태 표시, 오류는 네 책방이 같은 색을 쓴다. 그리고 한 칸에 들어올 색에는 세 가지 조건을 건다.
- 배지 글자 대비 4.5:1 이상. 배지 위 글자는 흰색과 짙은 잉크색(
#22342a) 가운데 대비가 큰 쪽을 자동으로 쓰고, 그 대비가 WCAG 2.2의 1.4.3(최소 대비, 보통 글자 4.5:1)을 넘어야 한다. - 위험 색과 구별.
feedback.danger(#d24f39)와의 색차 ΔE2000이 15 이상이어야 한다. 책방 배지가 오류 표시처럼 보이면 안 된다. - 다른 책방과 구별. 한 검색 결과에 네 책방의 배지가 함께 나오므로, 가장 가까운 다른 책방 색과도 ΔE2000이 15 이상이어야 한다.
ΔE2000 15라는 문턱은 이 책이 정한 값이다. 표준이 정한 구별 기준은 없고, 작은 배지끼리 나란히 놓였을 때 한눈에 다른 색으로 보이는 정도를 어림한 것이다(색차 ΔE2000은 ColorBook 3장과 14장에서 다뤘다). 아래 종합 시뮬레이터에서 책방을 고르고 그 책방의 강조색을 명도와 색상으로 바꿔 본다. 가상 화면은 그 책방의 소개 화면이다.
책방별 강조색 한 칸
한 칸 규칙의 핵심은 정체성과 조작을 떼어 놓는 것이다. 책방의 색은 "여기가 어디인가"를 말하고, 서비스의 색은 "무엇을 누를 수 있는가"를 말한다. 두 말을 같은 색에 맡기면 둘 다 흐려진다. 주 버튼까지 책방 색으로 칠하는 순간 버튼 컴포넌트의 변형은 책방 수만큼 곱해지고(다음 절), 대비 검사도 네 번 해야 하며, 다섯 번째 책방이 들어오면 또 늘어난다.
| 책방 | 처음 원한 색 | 배지 글자 | 배지 대비 | 위험 색과 ΔE | 판정 |
|---|---|---|---|---|---|
| 책방 E | #2f7d5b 책방 초록 | 흰색 | 4.99 | 55.0 | 통과 |
| 헌책방 나무 | #8b5a2b 고동색 | 흰색 | 5.84 | 19.6 | 통과 |
| 작은 숲 | #f2c230 노랑 | 잉크색 | 7.87 | 42.2 | 통과(글자색 자동) |
| 한 줄 | #c0392b 빨강 | 흰색 | 5.44 | 6.7 | 위험 색과 겹침 |
표의 값은 이 책의 계산 엔진(ART.contrast, ART.diff)으로 낸 것이다. 한 줄의 빨강은 배지만 보면 문제가 없지만, 맡기기가 실패했을 때 나오는 오류 표시와 색이 거의 같다(ΔE 6.7). 손님이 한 줄의 책을 맡기다 오류가 나면, 오류 표시와 책방 배지가 같은 색으로 나란히 놓인다.
변형의 폭발
컴포넌트 하나에는 여러 변형(Variant)이 있다. 버튼이라면 크기(크게·보통·작게), 스타일(주·보조·텍스트·위험), 아이콘 자리(없음·앞·뒤), 그리고 WebBook 7장에서 정한 상태 다섯 가지(기본·호버·포커스·눌림·비활성)가 있다. 이 속성들은 서로 곱해진다.
180은 디자인 파일에 그려야 할 버튼 그림의 수이고, 개발자가 확인해야 할 조합의 수이며, 접근성 검사(대비, 포커스 표시)를 해야 할 경우의 수다. 여기에 책방 색 네 가지를 버튼 스타일로 넣으면 스타일이 4에서 8로 늘어 360이 된다. 속성 하나를 더하는 일은 늘 "하나만 더"처럼 보이지만, 곱셈이라 실제로는 전체를 몇 배로 만든다. 아래에서 속성의 값 수를 바꾸며 조합이 어떻게 불어나는지, 그리고 규칙 몇 줄이 그것을 어떻게 줄이는지 본다.
버튼 변형 계산기
규칙으로 줄인다는 것은 속성의 값을 뜻으로 이름 짓는다는 뜻이다. 버튼에 "색"이라는 속성을 열어 두면 누구든 아무 색이나 넣을 수 있고, 그 순간 조합은 무한해진다. 대신 "어조"라는 속성에 주·보조·텍스트·위험 네 값만 허락하면, 새 화면을 만드는 사람은 넷 중 하나를 고르기만 하면 되고, 시스템은 넷만 책임지면 된다. 개발자들은 이것을 컴포넌트의 속성(props)을 좁힌다고 말한다.
<!-- 열어 둔 속성: 조합이 무한하다 -->
<Button color="#c0392b" size="38px" iconRight="arrow">맡아 두기</Button>
<!-- 뜻으로 좁힌 속성: 네 가지 어조 × 두 가지 크기 × 아이콘 있음·없음 -->
<Button tone="primary" size="default" icon="bookmark">맡아 두기</Button>
속성을 좁히면 처음에는 불편하다는 말이 나온다. "딱 이 화면에서만 버튼을 조금 작게 하고 싶은데요." 그 불편이 바로 시스템이 하는 일이다. 작게 해야 할 이유가 정말 있다면 그 이유를 문서에 남기고 변형을 더하거나(그러면 모든 화면이 그 변형을 쓸 수 있다), 이유가 약하면 원래 크기를 쓴다. 어느 쪽이든 결정이 한곳에 남는다. 이 판단은 뒤의 "일관성과 예외" 절에서 다시 본다.
얼마나 달라야 다른 색인가: 색 감사
시스템을 처음 만들 때는 빈 종이에서 시작하지 않는다. 이미 화면들이 있고, 그 화면들에는 이미 쓰인 색과 간격과 버튼이 있다. 이미 쓰인 것을 모두 모아 늘어놓고 세어 보는 일을 인터페이스 목록 만들기(Interface inventory)라고 한다. 브래드 프로스트가 이름 붙여 널리 퍼진 방법이다. 모아 보면 대개 놀란다. 같은 초록이라고 생각한 색이 일곱 가지, 같은 크기라고 생각한 버튼이 다섯 가지쯤 나온다.
서윤은 시범 운영 화면과 네 책방이 각자 만들어 둔 안내문, 기존 웹사이트에서 쓰인 색 28개를 뽑았다(가상 자료). 이 가운데 무엇을 같은 색으로 묶고 무엇을 남길지는 "얼마나 달라야 다른 색인가"라는 문턱에 달려 있다. 아래에서 그 문턱을 ΔE2000으로 바꿔 본다. 묶음마다 가장 많이 쓰인 색이 대표(큰 칸)가 되고, 나머지(작은 칸)가 그 대표로 바뀐다.
색 감사: 28개의 색을 몇 개로
문턱을 하나로 정해 기계적으로 묶으면 안 된다는 것이 이 시뮬레이터의 결론이다. 문턱 3 아래의 차이는 거의 늘 실수다. 누군가 색을 눈대중으로 다시 뽑았거나, 이미지 압축이 색을 조금 바꿨다. 문턱 20 근처의 차이는 대개 일부러 둔 것이다. 책방 초록 #2f7d5b과 차분한 초록 #567666은 ColorBook에서 서로 다른 일을 맡도록 고른 두 색이다. 그 사이의 회색 지대에서는 사람이 판단한다. 두 색이 같은 역할을 하는가, 다른 역할을 하는가. 같은 역할이면 하나로 합치고, 다르면 각자 의미 토큰을 준다.
문서: 쓰는 법과 쓰지 않는 법
컴포넌트를 만들어 두기만 하면 사람들이 알아서 쓸 것 같지만, 그렇지 않다. 버튼이 있다는 것을 몰라서 새로 만들고, 있는 줄 알아도 언제 주 버튼을 쓰고 언제 보조 버튼을 쓰는지 몰라서 화면마다 다르게 쓴다. 컴포넌트 문서는 그 판단을 대신 내려 주는 곳이다. 아래 그림은 "맡아 두기"의 버튼 문서 한 쪽을 줄여 그린 것이다.
좋은 컴포넌트 문서에 흔히 들어가는 것을 정리하면 다음과 같다.
| 칸 | 무엇을 적나 | 빠지면 생기는 일 |
|---|---|---|
| 이름과 한 줄 설명 | 무슨 일을 하는 부품인가 | 비슷한 부품이 다른 이름으로 또 생긴다 |
| 쓰는 때 · 쓰지 않는 때 | 판단 기준과 대안(버튼 대신 링크 등) | 한 화면에 주 버튼이 셋이 된다 |
| 변형과 상태 | 규칙 안에 남은 조합만 | 규칙 밖의 조합이 "있는 것"처럼 쓰인다 |
| 문구 규칙 | 어조, 길이, 동사(10장) | 같은 버튼이 "확인", "OK", "좋아요"로 갈린다 |
| 접근성 | 대비, 포커스, 누르는 자리, 화면 낭독기 이름 | 모양만 같고 키보드로는 못 쓰는 복사본 |
| 바뀐 기록 | 버전, 날짜, 이유, 영향 받는 화면 | 왜 그렇게 정했는지 아무도 모른다 |
일관성과 예외
시스템의 가치는 일관성에서 나온다. 같은 일은 같은 모양으로, 같은 자리에서 일어난다. 손님은 한 화면에서 배운 것을 다른 화면에서 다시 쓰고(6장의 멘탈 모델), 만드는 사람은 같은 판단을 매번 새로 내리지 않는다. 그러나 일관성이 목적이 되면 시스템은 감옥이 된다. 시집 전문 책방 한 줄의 소개 화면에서 시 한 구절을 세로로 쓰고 싶다는 요청을 "시스템에 세로쓰기 컴포넌트가 없어서 안 됩니다"로 막는다면, 시스템이 제품을 섬기는 것이 아니라 제품이 시스템을 섬기는 셈이다.
그래서 요청이 올 때마다 같은 질문을 같은 순서로 던지는 판단 나무를 둔다. 아래에서 네 가지 요청을 골라 나무를 따라가 본다. 질문 상자를 누르면 그 답을 뒤집을 수 있다. 답이 하나 바뀌면 결론이 어떻게 달라지는지 본다.
일관성과 예외의 판단 나무
판단 나무에서 가장 중요한 갈림은 "두 곳 이상에서 필요한가"다. 한 곳에서만 필요한 것을 시스템에 넣으면 시스템이 불어나고, 여러 곳에서 필요한 것을 예외로 두면 같은 예외가 여러 벌 생긴다. 두 번째로 중요한 것은 예외에도 기록과 기한이 있다는 점이다. 한 줄의 세로쓰기는 "6월 시 낭독 주간 동안, 한 줄 소개 화면 머리에만"이라는 범위와 함께 예외 목록에 오른다. 기한이 지나면 지우거나, 그사이 다른 곳에서도 필요해졌다면 시스템으로 들인다. 기록 없는 예외는 몇 달 뒤 아무도 이유를 모르는 "원래 그랬던 것"이 된다.
마지막 갈림, "해가 없는가"는 다음 장(12장)으로 이어진다. 버튼을 깜빡이게 하자는 요청은 일관성의 문제이기 전에 손님을 압박하고 주의를 빼앗는 문제다. 깜빡이는 요소는 주의가 쉽게 흩어지는 손님에게 화면을 읽기 어렵게 만들고, WCAG 2.2의 2.2.2(일시 정지, 정지, 숨기기)는 5초 넘게 움직이거나 깜빡이는 내용을 멈출 수 있게 하라고 한다. 시스템은 이런 요청에 "규칙에 없어서"가 아니라 "이런 이유로"라고 답할 수 있어야 한다.
기여와 거버넌스
시스템은 만든 날이 가장 깔끔하다. 그 뒤로 새 화면이 생길 때마다 시스템이 아직 다루지 못한 필요가 나타난다. 그때 만드는 사람에게는 두 길이 있다. 시스템에 새 부품이나 변형을 기여하거나, 자기 화면에만 쓸 것을 따로 만드는 것이다. 기여하는 길이 멀고 복잡할수록 사람들은 따로 만든다. 따로 만든 것은 다른 사람이 복사해 쓰고, 복사본이 또 복사된다. 시스템을 누가 어떤 절차로 바꾸고 지키는지에 대한 약속을 거버넌스(Governance)라고 한다.
아래 모형은 2년 동안 "맡아 두기"에 매달 새 화면 여덟 개가 생긴다고 가정한다. 시스템이 다루지 못하는 필요가 생기면, 기여 문턱이 높을수록 따로 만들 확률이 커진다. 따로 만든 변형은 다른 화면에 조금씩 복사되고, 정기 정리를 하면 그때마다 떠도는 변형의 일부가 시스템으로 들어오거나 지워진다.
떠도는 변형: 기여 문턱과 정리 주기
모형은 단순하지만 방향은 분명하다. 떠도는 변형을 줄이는 방법은 둘이다. 생긴 것을 주기적으로 치우거나, 애초에 덜 생기게 하는 것. 둘 다 필요하지만, 뒤쪽이 더 싸다. 기여 문턱을 낮춘다는 것은 기준을 낮춘다는 뜻이 아니다. 요청 양식을 한 장으로 줄이고, 누구에게 보내면 되는지 분명히 하고, 답이 언제 오는지 약속하는 것이다. 요청을 보내고 3주 동안 답이 없으면 사람들은 다음부터 묻지 않는다.
시스템을 누가 맡는지에도 몇 가지 모양이 있다. 디자인 시스템 컨설턴트 네이선 커티스(Nathan Curtis)가 2015년 글에서 정리한 구분이 자주 인용된다. 한 사람이나 한 팀이 자기 제품을 위해 만든 것을 남들이 가져다 쓰는 홀로 형, 시스템만 전담하는 팀이 있는 중앙 형, 여러 제품 팀의 사람들이 시간을 나눠 함께 맡는 연합 형이다. 어느 것이 옳다기보다 규모에 따라 다르다. 디자이너 한 명과 개발자 한 명, 주인 네 명인 "맡아 두기"는 홀로 형에서 시작할 수밖에 없다. 대신 네 주인이 "요청할 수 있는 사람"으로 절차 안에 들어온다.
서윤의 서비스 노트
네 책방, 한 서비스, 강조색 한 칸
"맡아 두기"의 첫 화면들은 WebBook 때 만든 책방 E의 토큰을 그대로 가져다 썼다. 책방 초록 버튼, 크림 바탕, 짙은 잉크 글자. 시범 화면을 본 헌책방 나무 주인의 질문("우리 가게 화면인데 왜 책방 E 초록이에요?")이 이 장의 출발점이었다. 작은 숲 주인은 노란색을, 한 줄 주인은 도장의 인주 같은 빨간색을 원했다. 지후는 처음에 "책방마다 테마 파일을 따로 만들면 되죠"라고 했다가, 버튼 변형이 몇 개가 되는지 이 장의 계산기로 세어 보고 말을 바꿨다. "스타일 여덟 개면 버튼만 360가지예요. 저 혼자 다 못 봐요."
서윤은 먼저 주 행동의 색을 책방 E의 초록에서 떼어 냈다. 네 책방이 함께 쓰는 서비스의 버튼이 한 가게의 색을 달고 있을 이유가 없었다. 주 버튼은 손님 화면의 "맡아 두기"부터 6장에서 책방 초록으로 칠했던 주인 화면의 "수락"까지 모두 잉크색 #22342a(흰 글자 대비 13.19)로 바꾸고, 의미 토큰 action.primary가 그것을 가리키게 했다. 그리고 책방마다 다르게 둘 자리를 shop.accent 한 칸으로 정했다. 이 색은 책방 이름 배지와 책방 소개 화면 머리의 얇은 띠에만 쓴다. 세 조건(배지 글자 대비 4.5 이상, 위험 색과 ΔE2000 15 이상, 다른 책방 색과 15 이상)을 걸고 네 주인이 원한 색을 넣어 보니 셋은 그대로 통과했다. 작은 숲의 노랑은 흰 글자로는 1.68이었지만 배지 글자를 잉크색으로 자동으로 바꾸자 7.87이 되었다. 한 줄의 빨강은 오류 표시와 ΔE 6.7로 겹쳤다. 서윤이 시뮬레이터에서 색상각을 돌려 보이자, 한 줄 주인은 시집 표지에 자주 쓰던 먹자주 #6b2f4a를 골랐다(흰 글자 9.86, 위험 색과 ΔE 30.1).
하린은 색보다 이름을 먼저 챙겼다. "배지에 색만 있고 이름이 없으면, 흑백으로 인쇄한 주문 목록에서는 구별이 안 돼요." 그래서 배지에는 늘 책방 이름을 쓴다. 색 감사에서는 기존 화면과 안내문의 색 28개(가상 자료)를 ΔE 3 아래에서 기계적으로 합치고, 그 위는 역할을 따져 사람이 정했다. 마지막으로 컴포넌트 목록과 변형 규칙, 요청 절차를 한 장에 적어 네 주인에게 나눠 주었다.
| 항목 | 서윤의 선택 | 확인한 값 |
|---|---|---|
| 주 행동 색 | action.primary → 잉크 #22342a(책방 E 초록에서 분리). 손님 "맡아 두기", 주인 "수락" 모두 | 흰 글자 대비 13.19 |
| 책방별 한 칸 | shop.accent: 배지와 머리 띠에만. 버튼·링크·상태·오류에는 쓰지 않음 | 배지에는 책방 이름 글자를 함께 |
| 책방 E | #2f7d5b, 배지 글자 흰색 | 4.99 · 위험 색과 ΔE 55.0 |
| 헌책방 나무 | #8b5a2b, 흰색 | 5.84 · ΔE 19.6 |
| 작은 숲 | #f2c230, 잉크색 글자(자동) | 7.87 · ΔE 42.2 |
| 한 줄 | #6b2f4a 먹자주(처음 원한 #c0392b에서 바꿈) | 9.86 · ΔE 30.1 |
| 컴포넌트(9) | 버튼, 검색 칸, 책 카드, 재고 줄, 상태 배지, 책방 배지, 토스트, 확인 대화상자, 빈 상태 | 모두 문서 한 쪽씩 |
| 버튼 변형 규칙 | 어조 4(주·보조·텍스트·위험) × 크기 2(기본 48 · 조밀 44) × 아이콘 2(없음·앞), 텍스트·위험은 기본 크기만, 상태 5는 모두 | 버튼 조합 60(규칙 없을 때 360) |
#22342a로 네 책방이 같이 쓰고, 책방마다 다른 것은 shop.accent 하나(책방 E #2f7d5b, 헌책방 나무 #8b5a2b, 작은 숲 #f2c230, 한 줄 #6b2f4a)다. 강조색의 조건은 배지 글자 대비 4.5 이상(글자색은 흰색과 잉크색 중 자동), 위험 색 #d24f39과 ΔE2000 15 이상, 다른 책방 색과 15 이상. 컴포넌트는 아홉 개, 버튼 변형은 어조 4 × 크기 2 × 아이콘 2에 텍스트·위험 버튼은 기본 크기만(상태 다섯은 빠짐없이). 새 변형은 두 곳 이상에서 필요할 때만 더하고, 한 곳만의 요청은 범위와 기한을 적은 예외로 둔다. 요청은 누구나 한 장으로 보내고 2주 안에 답한다. 한 줄 소개 화면의 세로쓰기 시구가 첫 번째 기록한 예외다.핵심 정리
- 디자인 시스템은 부품 모음이 아니라 결정을 한 번 내리고 나눠 쓰는 방법이다. 원시 토큰 → 의미 토큰 → 컴포넌트 → 패턴의 층과, 문서와 운영 규칙으로 이루어진다.
- 의미 토큰은 값과 뜻을 떼어 놓는다. 컴포넌트가 의미 토큰만 읽으면 결정 하나를 한 곳에서 바꿀 수 있고, 다크 모드나 브랜드별 테마도 의미 토큰이 가리키는 곳을 바꾸는 일이 된다.
- 여러 브랜드를 담을 때는 바꿀 수 있는 자리를 좁게 정한다. 정체성(어디인가)과 조작(무엇을 누르는가)을 같은 색에 맡기지 않고, 바꾼 값에는 대비와 구별의 조건을 건다. 색만으로 구별하게 하지 않는다.
- 변형의 수는 속성의 곱 \(N = \prod n_i\)으로 늘어난다. 속성을 뜻으로 이름 짓고 값을 좁히면 조합이 크게 준다. 줄일 것은 선택지이고, 상태(피드백)는 줄이지 않는다.
- 색 감사는 이미 쓰인 것을 모아 묶는 일이다. 아주 작은 차이는 실수로 보고 합치되, 일부러 둔 차이는 역할을 따져 사람이 판단한다.
- 요청은 같은 질문 순서로 판단한다. 있는 것으로 되는가, 두 곳 이상에서 필요한가, 속성 하나로 되는가, 해가 없는가. 예외에도 범위와 기한을 적는다. 떠도는 변형은 정기 정리보다 기여 문턱을 낮추는 쪽이 더 싸게 막는다.
확인 퀴즈
1. 버튼 컴포넌트가 원시 토큰 ink-900을 바탕색으로 직접 읽고, 본문 글자도 ink-900을 직접 읽는다. "주 버튼만 조금 밝게" 하라는 결정이 나왔을 때 생기는 문제로 가장 알맞은 것은?
action.primary를 두고 버튼이 그것을 읽게 하면, 그 토큰이 가리키는 곳 하나만 바꿔 결정이 끝난다.2. 버튼에 크기 3, 스타일 4, 아이콘 자리 3, 상태 5가 있다. 여기에 책방 색 넷을 스타일로 더하면 조합은 몇 개가 되는가?
3. 한 책방이 자기 브랜드 색인 빨강 #c0392b를 강조색으로 쓰고 싶어 한다. 흰 글자 대비는 5.44로 4.5를 넘는다. 이 장의 규칙으로 볼 때 가장 알맞은 판단은?
#d24f39과 ΔE2000이 6.7로, 이 장이 정한 구별 문턱 15에 크게 못 미친다. 색 심리에 대한 일반론으로 금지하는 것이 아니라 이 서비스 안에서 색이 맡은 역할이 겹치기 때문이다. 이름을 지우는 것은 색만으로 정보를 전하게 되어 거꾸로 간다.4. 시집 책방 한 곳이 6월 행사 동안 자기 소개 화면 머리에만 시구를 세로로 쓰고 싶어 한다. 다른 책방에서는 필요하지 않다. 판단 나무에 따른 처리로 가장 알맞은 것은?