본문으로 건너뛰기
TDSMoring 디자인 시스템

사용 규칙

디자인 시스템을 올바르게 쓰는 기준이다. 모든 규칙에 번호가 있고, 값과 조건으로 적었다. 규칙을 인용할 때는 번호(예: C4)를 쓴다.

이 페이지의 목차

색 조합#

색은 이름(토큰)으로만 쓰고, 이름이 가진 의미를 지킨다.

색 조합 규칙
번호규칙이유와 값
C1화면 바탕은 bg, 대시보드형 화면은 canvas를 깐다. 그 위의 면은 surface다. 면 위에 면을 겹칠 때는 well이나 card를 쓴다.한 화면의 면 색은 3단계(바탕 → 면 → 홈) 이하로 한다.
C2글자는 본문 text, 보조 textSecondary, 입력 안내 문구 textTertiary로 나눈다. 읽어야 하는 내용에 textTertiary를 쓰지 않는다.textTertiary는 흰 면에서 대비가 약하다(색상 페이지의 대비 표).
C3primary는 행동과 선택 표시에만 쓴다. 한 화면에서 primary로 채운 큰 면은 1개(주 버튼)까지다.파란색(초록색)이 여러 곳에 있으면 무엇이 주 행동인지 알 수 없다.
C4색이 채워진 면 위의 글자는 짝을 지킨다: gradient·primaryStrong 위는 onPrimaryStrong, primary 위는 onPrimary, danger 위는 onDanger, successSoft 위는 successText, amberSoft 위는 amberText, dangerSoft 위는 danger.짝이 맞아야 라이트·다크와 두 서비스 모두에서 글자가 읽힌다.
C5상태 색의 뜻은 고정이다. success는 정답과 완료, danger는 오류·오답·삭제, amber는 주의와 추천, primary는 선택과 행동이다. 선택한 보기를 success 색으로 칠하지 않는다.OptionRow는 선택 전 primary, 채점 뒤 정답 success, 오답 danger로 뜻을 나눈다.
C6과목 색은 과목을 구분하는 작은 표식(아이콘 타일, 점, 막대)에만 쓴다. 과목 이름을 글자로 항상 함께 보여 준다.색만으로 과목을 알아보기 어려운 사용자가 있다.
C7색만으로 상태를 알리지 않는다. 정답은 success 색 + 체크 아이콘 + "정답!" 글자를 함께 쓴다.색을 구분하기 어려운 사용자와 Morit(성공과 주색이 같은 초록)을 위해서다.
C8코드에 HEX 값을 직접 쓰지 않는다. 반투명이 필요하면 withAlpha(토큰, 투명도)를 쓴다.서비스와 라이트·다크가 바뀌면 직접 쓴 HEX는 바뀌지 않는다.

간격#

간격 9단계 값만 쓰고, 묶음 안은 좁게 묶음 사이는 넓게 띄운다.

간격 규칙
번호규칙이유와 값
S1간격은 xxs(2) ~ xxxl(40) 9단계 값만 쓴다. 표에 없는 숫자(10, 14, 18 등)를 간격으로 쓰지 않는다.값이 정해져 있어야 화면끼리 리듬이 맞는다.
S2화면의 좌우 여백은 gutter(20)다. 한 화면의 모든 요소가 같은 왼쪽 선에서 시작한다.Screen이 20을 자동으로 넣는다.
S3묶음 안의 간격은 묶음 사이의 간격보다 작다. 예: 묶음 안 8(sm) 또는 12(md), 묶음 사이 24(xl) 이상.간격 차이가 눈으로 묶음을 나눈다.
S4섹션 제목은 위 간격이 아래 간격보다 크다. SectionTitle은 위 24, 아래 12다.제목이 아래 내용에 속한다는 것이 보인다.
S5이웃한 눌림 요소 사이는 8 이상 띄운다.hitSlop(사방 10)으로 넓힌 눌림 영역이 겹치지 않게 한다.
S6카드 안쪽 여백은 Card 16, Panel 18이다. 안쪽 여백을 카드마다 다르게 하지 않는다.같은 종류의 면은 같은 여백을 가진다.

정렬#

왼쪽 정렬이 기본이다. 가운데 정렬은 정해진 경우에만 쓴다.

정렬 규칙
번호규칙이유와 값
A1글자는 왼쪽 정렬이 기본이다. 가운데 정렬은 빈 화면(EmptyState)의 제목과 설명, 버튼·탭 안의 글자, 숫자 하나만 놓인 칸에만 쓴다.여러 줄 글자를 가운데 정렬하면 읽는 시작점이 줄마다 달라진다.
A2목록 행은 앞(아이콘 타일) · 가운데(제목과 보조 줄, 남는 폭 전부) · 뒤(값, 화살표) 순서다. 뒤쪽 요소는 오른쪽 끝에 맞춘다.WellRow, SettingsRow가 이 구조다.
A3표와 차트의 숫자는 오른쪽 끝에 맞추고 단위를 붙여 쓴다.자릿수가 맞아 크기를 비교하기 쉽다.
A4화면 아래에 고정하는 주 버튼은 폭을 가득 채우고(좌우 gutter), Screen의 footer에 넣는다.엄지가 닿는 위치에 하나뿐인 주 행동이 있다.
A5아이콘과 글자는 세로 가운데로 맞춘다. 사이 간격은 버튼 안 6, 행 안 8~12다.PrimaryButton은 6, WellRow는 12를 쓴다.
A6웹에서 긴 글의 한 줄은 약 46rem(736px) 이하로 한다. 한글은 65~75자 안이다.줄이 너무 길면 다음 줄의 시작을 찾기 어렵다.

글자#

글자 스타일은 11종 중에서만 고른다.

글자 규칙
번호규칙이유와 값
T1한 화면에서 글자 스타일은 3~4종만 쓴다.제목, 본문, 보조만으로 위계가 충분하다.
T2화면 제목은 title, 카드 제목은 headline, 본문은 body, 보조 줄은 small 또는 caption이다.글자 스타일 페이지의 "용도" 열과 같다.
T3문제 본문, 보기, 해설은 줄을 자르지 않는다(numberOfLines를 쓰지 않는다). 목록 행의 제목만 1~2줄로 자른다.잘린 문제는 풀 수 없다.
T4버튼 글자는 한 줄이다. 길면 80%까지 줄이고, 그래도 안 들어가면 글자를 짧게 고친다.PrimaryButton은 minimumFontScale 0.8을 쓴다.
T5글자 스타일 밖의 크기를 쓰려면 줄 높이도 함께 지정한다.줄 높이가 모자라면 글자의 아래쪽이 잘린다.
T6한국어 글은 단어 중간에서 줄을 바꾸지 않는다. 앱은 keepWords(), 웹은 word-break: keep-all을 쓴다.Android는 "무엇인가/요?"처럼 단어를 쪼갠다.

행동과 버튼#

화면마다 가장 중요한 행동이 하나이고, 나머지는 무게를 낮춘다.

행동과 버튼 규칙
번호규칙이유와 값
B1한 화면(또는 한 시트)에 PrimaryButton은 1개다.주 행동이 둘이면 사용자가 고르지 못한다.
B2행동의 무게는 PrimaryButton > SecondaryButton > TextButton 순서다. 두 번째 행동은 SecondaryButton, 선택 행동("나중에")은 TextButton이다.무게 차이가 중요도 차이를 보여 준다.
B3되돌릴 수 없는 행동(삭제, 탈퇴)은 dialog.confirm을 tone: "danger"로 호출해 한 번 더 묻는다. 대화상자에 무엇이 사라지는지 적는다.실수로 누른 삭제를 막는다.
B4결과를 기다리는 동안은 busy, 누를 수 없는 이유가 있으면 disabled와 함께 이유를 글자로 알린다.이유 없는 비활성 버튼은 고장으로 보인다.
B5아이콘만 있는 버튼에는 label을 반드시 쓴다.화면 읽기 프로그램이 이름을 읽는다.

모양#

모서리와 그림자는 면의 종류를 나타낸다.

모양 규칙
번호규칙이유와 값
R1시트와 대화상자는 sheet(24), 카드는 card(20) 또는 lg(16), 입력 칸은 md(12), 짧은 눌림 요소만 pill이다.큰 면을 알약으로 만들지 않는다.
R2그림자는 기본 없음이다. 카드와 버튼은 shadow(1), 떠 있는 요소는 shadow(2), 대화상자는 shadow(3)만 쓴다.면 구분은 먼저 배경색 차이와 1px 선으로 한다.
R3카드 안에 카드를 넣지 않는다. 카드(패널) 안의 묶음은 well(홈)이나 구분선으로 나눈다.Panel 안에서 WellRow가 하는 일이다.
R4목록의 행마다 그림자를 주지 않는다.행이 많으면 그림자가 화면을 어지럽힌다.
R5기본 테두리는 1px line이다. 선택된 항목은 primary 테두리 1.2~1.8px을 쓴다.ChoiceCard는 선택 전 1.2, 선택 후 1.8이다.

접근성#

누구나 읽고 누를 수 있어야 한다.

접근성 규칙
번호규칙이유와 값
X1작은 글자는 바탕과 4.5:1 이상, 큰 글자(굵은 18.66px 이상)는 3:1 이상이다.색상 페이지의 "글자 색 대비" 표에서 서비스와 모드별로 확인한다. 웹에서는 textSecondaryInk, primaryInk를 쓴다.
X2눌리는 영역은 48 × 48 이상을 목표로 한다. 보이는 크기가 작으면 hitSlop이나 주변 여백으로 채운다.손끝이 눌리는 영역보다 크다.
X3눌리는 요소에는 역할(accessibilityRole), 이름(accessibilityLabel 또는 안의 글자), 상태(accessibilityState)를 지정한다.화면 읽기 프로그램이 "버튼, 저장, 사용할 수 없음"처럼 읽는다.
X4글자 크기 1.24배(앱 설정)와 시스템 설정 최대 1.6배에서도 글자가 잘리지 않게 한다. 높이는 고정하지 않고 minHeight를 쓴다.Field, WellRow는 minHeight다.
X5상태는 색 + 아이콘 + 글자를 함께 쓴다.C7과 같다.
X6웹에서는 모든 조작을 키보드로 할 수 있게 하고, 포커스 링(2.5px 실선, 3px 띄움, primaryInk 색)을 지운 채로 두지 않는다. prefers-reduced-motion을 지킨다.앱에는 포커스 표시가 없으므로 웹에서 새로 그린다.
X7사진과 그림에는 대체 글(alt, accessibilityLabel)을 쓴다. 장식 아이콘은 읽지 않게 숨긴다.ImageBlock은 alt를 접근성 이름으로 쓴다.

서비스 색 전환#

서비스가 달라도 같은 코드를 쓰고 색 값만 바꾼다.

서비스 색 전환 규칙
번호규칙이유와 값
V1색은 토큰 이름으로만 쓴다. 코드에서 if (service === "morit")처럼 서비스를 보고 색을 고르지 않는다.서비스가 늘어도 코드를 고치지 않게 한다.
V2색 말고는 서비스별로 바꾸지 않는다. 간격, 글자, 모서리, 그림자, 모션은 모든 서비스에서 같다.화면이 같은 시스템에서 나왔다는 것이 보여야 한다.
V3새 색이 필요하면 모든 서비스의 라이트·다크 값을 함께 추가한다.한 서비스에만 값이 있으면 다른 서비스 화면이 깨진다.
V4Morit에서는 success와 primary가 같은 초록이다. 성공은 항상 체크 아이콘과 글자를 함께 쓴다.색으로 성공과 선택을 구분할 수 없다.
V5화면을 만든 뒤 서비스 2개 × 모드 2개(라이트·다크), 모두 4가지 조합에서 확인한다.한 조합에서만 읽히는 색을 막는다.

문구#

앱의 문장은 짧고 구체적으로 쓴다.

문구 규칙
번호규칙이유와 값
W1문장은 해요체로 쓰고, 한 문장에 한 가지 내용만 담는다.앱의 문구("거절했어요", "다시 가입할 수 있어요")가 이 말투다.
W2버튼 글자는 행동의 이름이다. "저장", "다음으로", "지금 풀기"처럼 쓴다. "확인"은 알림을 닫을 때만 쓴다.버튼만 읽어도 무슨 일이 일어나는지 알아야 한다.
W3오류 문구는 무엇이 문제인지와 다음에 할 일을 함께 쓴다.문제만 알리면 사용자가 멈춘다.
W4숫자에는 단위를 붙여 쓴다. "12문제", "약 3분", "D-24".숫자만 있으면 무엇의 수인지 알 수 없다.

그림으로 보는 예#

B1·B2: 행동의 무게

잘한 예주 행동은 PrimaryButton 하나, 두 번째 행동은 SecondaryButton, 선택 행동은 TextButton이다.
잘못한 예세 행동이 모두 같은 무게라서 무엇이 중요한지 알 수 없다.

C4: 채운 면 위의 글자

정답!복습 추천오답
잘한 예짝이 맞는 글자색을 쓴다. 옅은 면 위에는 같은 계열의 진한 글자색이다.
정답!복습 추천
잘못한 예옅은 면 위에 옅은 글자를 쓰면 읽히지 않는다.

C7: 상태는 색 + 아이콘 + 글자

정답!
잘한 예색, 체크 아이콘, "정답!" 글자를 함께 쓴다. 색을 못 보아도 뜻이 전달된다.
잘못한 예색만으로 정답을 알린다. 색을 구분하지 못하면 알 수 없다.

S3: 묶음 안은 좁게, 묶음 사이는 넓게

오늘의 복습자료 18개 · 복습 12개
내 과목과목 6개
잘한 예제목과 설명은 8로 붙이고, 다음 묶음과는 24 띄운다. 어디까지가 한 묶음인지 보인다.
오늘의 복습자료 18개 · 복습 12개내 과목과목 6개
잘못한 예모든 간격이 같아서 제목이 위 묶음에 속하는지 아래 묶음에 속하는지 알 수 없다.