개요
리바운드 비즈의 고객 페이지 — 채권자와 채무자가 실제로 쓰는 화면 — 를 만들 때 필요한 색·글자·컴포넌트 규칙이에요. 여기 적힌 값은 전부 rebound-biz 저장소에서 지금 돌고 있는 값이고, 새 화면은 이 값을 그대로 가져다 쓰면 됩니다.
이 문서를 쓰는 곳
| 제품 | 저장소 | 적용 |
|---|---|---|
| 리바운드 비즈 | GroundBasic/rebound-biz | 기준 — 이 문서에 적힌 모든 값의 출처 |
| 채무자 페이지 | rebound-biz /debtor | 같은 토큰, 같은 컴포넌트 |
| 신규 고객 페이지 | — | 이 문서대로 시작 |
| 소개 페이지 | GroundBasic/rebound-info | 마케팅 톤은 별도 — 브랜드 색만 공유 |
네 가지 원칙
| 원칙 | 뜻 |
|---|---|
| 데이터가 주인공 | 화면의 대부분은 무채색이에요. 색은 상태를 가리킬 때만 씁니다 — 표 한가득 알록달록한 배지는 읽는 속도를 떨어뜨려요. |
| 채운 색은 하나 | 한 화면에서 #FF5900으로 채운 버튼은 하나. 나머지 행동은 흰 버튼이나 고스트로 내립니다. |
| 선보다 여백 | 카드는 테두리 없이 흰 배경 + 아주 옅은 그림자. 선은 표의 행 사이와 영역 경계에만. |
| 숫자는 줄을 맞춘다 | 금액·건수·날짜는 고정폭 숫자(tabular-nums), 금액 열은 오른쪽 정렬. |
문서의 구성
| 섹션 | 무엇이 있나 |
|---|---|
| Foundations | 팔레트 원본(Primitive)과 역할별 토큰(Semantic), 글자 스케일, 여백·모서리·그림자, 아이콘 |
| Components | 버튼·배지·입력·카드·표·모달·내비 — 디자인 탭은 스펙과 규칙, 코드 탭은 실제 클래스 정의 |
| Patterns | 한 화면을 구성하는 순서, 빈 화면·로딩·오류, 화면에 쓰는 말 |
| Resources | 로고 파일, Tailwind 설정과 CSS 변수 |
설치와 사용
토큰 파일 두 개와 폰트 한 줄이면 준비가 끝나요. 새 저장소든, 이미 있는 페이지든 같습니다.
1. 설치
2. 토큰 가져오기
rebound-biz에서 두 파일을 그대로 복사합니다. 값은 Resources · 토큰에도 전문이 있어요.
| 파일 | 가져올 부분 |
|---|---|
| tailwind.config.js | theme.extend — colors · fontFamily · boxShadow · borderRadius |
| src/index.css | @layer base(바탕·스크롤바·모바일 입력) + @layer components(버튼·입력·표·배지) |
3. 폰트
4. 화면 만들기 전 확인
| 확인 | 기준 |
|---|---|
| 색을 골랐나요 | hex가 아니라 Semantic 토큰의 역할로. 팔레트에 없는 색은 만들지 않아요 |
| 주 행동은 하나인가요 | 채운 오렌지 버튼은 화면에 하나 |
| 숫자 열은 오른쪽인가요 | 금액·비율은 오른쪽 정렬 + 고정폭 숫자 |
| 빈 화면이 있나요 | 데이터가 없을 때 무엇을 보여줄지 먼저 정하기 |
| 모바일에서 열리나요 | 640px 아래에서 입력 글자 16px, 표는 가로 스크롤 |
index.css 아래쪽에 있어요.Primitive
팔레트 원본이에요. 화면에서 직접 부르는 일은 거의 없고, Semantic이 이 값을 가리킵니다. 색을 누르면 hex가 복사돼요.
Primary — 리바운드 오렌지
비즈의 메인 브랜드 색. 주 버튼, 활성 내비, 카운트 배지, 포커스 테두리에 씁니다.
Tertiary — 블루
Figma 디자인 시스템의 보조 블루. 정보·링크·신규 표시처럼 “행동이 아닌 안내”에 씁니다.
Neutral — 회색
화면의 90%는 이 회색들로 만들어져요. 바탕 다섯, 선 둘, 글자 셋.
Status
상환·회수 상태를 가리키는 네 가지. 배지의 점과 차트 계열색으로만 쓰고 배경을 넓게 칠하지 않아요.
이름 규칙
| 그룹 | 단계 | 비고 |
|---|---|---|
| primary | 50 … 900 | Tailwind 기본 규칙(50이 가장 옅음). primary 단독은 500과 같아요. |
| tertiary | 5 … 90 | Figma 토큰 이름을 그대로 가져와서 단계 숫자가 달라요. |
| accent | 5 … 90 | 개인 리바운드의 메인 오렌지 = 비즈의 보조. 값은 primary와 같습니다. |
| status | bad · normal · good · pending | 단계 없이 의미 이름만. |
Semantic
“무슨 색인가”가 아니라 “무엇에 쓰는 색인가”로 정리한 목록이에요. 화면을 만들 때는 hex 대신 이 역할을 기준으로 고릅니다 — 같은 오렌지라도 행동에 쓸 때와 상태에 쓸 때의 뜻이 다르니까요.
Surface — 바탕
Content — 글자
Border — 선
Action — 행동
Status — 상태
고르는 순서
이렇게
- 오렌지는 누를 수 있는 것과 지금 있는 위치에만
- 상태는 status 네 가지 안에서 고르기
- 정보·링크는 tertiary-50 블루
- 바탕 회색은 surface / table-head / row-hover면 충분
이건 피해요
- 제목을 오렌지로 칠하기 — 행동으로 오해돼요
- 한 표 안에 배경 채운 배지 여러 색
- 완료를 파랑으로, 안내를 초록으로 바꿔 쓰기
- 팔레트에 없는 회색을 새로 만들기
Typography
Pretendard 한 벌만 씁니다. 크기를 키우기보다 굵기와 색으로 위계를 만들어요. 기본 줄 높이는 1.6, 큰 제목은 자간을 조입니다.
스케일
비즈 화면에서 가장 많이 쓰이는 크기는 13px이에요(고정 크기 지정의 약 40%). 새 화면도 13px을 기본으로 잡고 필요한 곳만 올리세요.
보기
규칙
| 상황 | 규칙 |
|---|---|
| 숫자 | 금액·건수·날짜는 tabular-nums. 표에서 자릿수가 흔들리지 않게. |
| 금액 | 12,340,000원 — 세 자리 쉼표, 단위는 붙여서. 축약(1.2천만)은 쓰지 않아요. |
| 날짜 | 2026.09.15, 기간은 2026.09.15 ~ 10.14, 남은 기간은 D-7. |
| 줄바꿈 | 한 줄로 끝나야 하는 셀은 truncate, 문장은 break-keep으로 단어를 자르지 않게. |
| 모바일 입력 | iOS Safari는 16px 미만 입력에 포커스하면 화면을 확대해요. 640px 아래에서는 입력 글자를 16px로 강제합니다. |
Layout
여백은 4px 배수, 모서리는 크기에 비례, 그림자는 네 단계. 이 세 가지만 지켜도 화면의 결이 맞아요.
Spacing
| 토큰 | 값 | 쓰는 곳 |
|---|---|---|
| gap-1 | 4px | 배지 점과 글자, 아이콘과 숫자 |
| gap-1.5 | 6px | 한 덩어리로 읽히는 인라인 요소 |
| gap-2 | 8px | 기본 — 버튼 안, 버튼 사이, 아이콘+라벨 |
| gap-3 | 12px | 리스트 행 사이, 폼 필드 사이 |
| gap-4 | 16px | 카드 사이 |
| space-y-5 | 20px | 페이지 섹션 사이 |
| p-5 / p-6 | 20 / 24px | KPI 카드 / 일반 카드 안쪽 |
| px-6 pt-6 | 24px | 모달 헤더·본문 좌우 |
Radius
| 토큰 | 값 | 쓰는 곳 |
|---|---|---|
| rounded-md | 6px | 툴팁, 아주 작은 칩 |
| rounded-lg | 8px | 버튼, 입력, 내비 항목, 아이콘 박스 |
| rounded-xl | 12px | 카드, 리스트 박스 — 가장 많이 씁니다 |
| rounded-2xl | 12px | 모달. 설정에서 16px이 아니라 12px로 덮어썼어요 |
| rounded-full | 999px | 카운트 배지, 아바타, 스텝 동그라미 |
Elevation
| 토큰 | 값 | 쓰는 곳 |
|---|---|---|
| shadow-card | 0 -2px 8px -2px rgba(16,24,40,.02), 0 6px 20px -6px rgba(16,24,40,.04), 0 2px 8px -2px rgba(16,24,40,.02) | 카드 · KPI |
| shadow-md | 0 4px 8px -2px rgba(16,24,40,.08), 0 2px 4px -2px rgba(16,24,40,.06) | 드롭다운 · 팝오버 |
| shadow-xl | Tailwind 기본값 | 모달 |
| shadow-focus | 0 0 0 3px rgba(255,89,0,.25) | 키보드 포커스 |
화면 폭
| 구간 | 기준 | 동작 |
|---|---|---|
| 모바일 | < 640px | 모바일 레이아웃 — 하단 탭, 입력 16px, 카드 1열 |
| 태블릿 | 640 ~ 1023px | 사이드바 접힘, 표는 가로 스크롤 |
| 데스크톱 | ≥ 1024px | 사이드바 256px 고정 + 본문 |
Iconography
아이콘은 lucide-react 하나만 씁니다. 선 굵기 2, 끝은 둥글게 — 기본값 그대로 쓰면 돼요.
크기
| size | 빈도 | 쓰는 곳 |
|---|---|---|
| 14 | 두 번째로 많음 | 표 안, 12~13px 글자 옆 |
| 16 | 가장 많음 (기본) | 버튼, 내비, 리스트 행 |
| 18 | 보통 | 모달 닫기, 섹션 헤더 |
| 20 | 드묾 | 빈 화면, 강조 |
색과 자리
기본은 #a3a3a3, 마우스를 올리면 #161616. 내비에서는 #8A9099 → 활성 시 오렌지. 아이콘 단독 버튼은 28×28 rounded-lg 박스 안에 가운데로 둡니다.
Button
세 가지면 충분해요. 채운 오렌지 하나, 흰 테두리 하나, 배경 없는 하나. 한 화면에서 채운 버튼은 하나만.
종류
| 클래스 | 스펙 | 쓰는 곳 |
|---|---|---|
| .btn-primary | px-4 py-2 · 13/700 · r8 bg #FF5900 · 글자 흰색 | 화면의 주 행동 하나 |
| .btn-outline | px-4 py-2 · 13/600 · r8 border #E8E8E8 · shadow-sm | 보조 행동, 내려받기·필터 |
| .btn-ghost | px-2.5 py-2 · 13/500 배경 없음 · #a3a3a3 | 취소, 표 안 작은 행동 |
| 큰 CTA | px-7 py-3 · 14/700 · r12 | 빈 화면·온보딩의 단 하나의 시작 버튼 |
상태
| 상태 | 표현 |
|---|---|
| hover | opacity .9 — 색을 새로 정의하지 않고 투명도로 낮춰요. |
| active | scale(.98) · 전환 200ms |
| disabled | opacity .4 + cursor-not-allowed. 회색으로 바꾸지 않아요. |
| loading | 라벨을 “신청 중…”으로 바꾸고 비활성. 스피너는 아이콘 자리에. |
라벨
이렇게
- 위임 신청
- 계좌 등록
- 엑셀 내려받기
- 동의하고 계속
이건 피해요
- 확인 — 무엇을 확인하는지 모름
- 제출하기 / ~하기 남발
- OK, Submit 같은 영문
- 느낌표 붙이기
클래스 정의
src/index.css → @layer components에 있는 원본이에요.
쓰기
주의
| 항목 | 설명 |
|---|---|
| background 인라인 | P3 디스플레이에서 bg-primary가 미묘하게 다르게 찍혀서 .btn-primary는 hex를 직접 넣었어요. |
| type | 폼 안의 버튼은 type="button"을 꼭 — 기본값이 submit이라 폼이 날아가요. |
| a 태그 | 이동은 <Link className="btn-outline">로. 버튼처럼 보여도 링크는 링크로. |
Badge
리바운드 비즈의 배지는 배경을 채우지 않아요. 색 점 하나 + 회색 글자 — 표 안에 수십 개가 늘어서도 시끄럽지 않게 하려는 선택이에요.
상태 배지
| 클래스 | 점 색 | 쓰는 곳 |
|---|---|---|
| .badge-active | status.good | 정상 상환, 진행 중 |
| .badge-warn | accent-50 | 연체 주의, 확인 필요 |
| .badge-exit | status.bad | 이탈, 해지 |
| .badge-new | tertiary-30 | 신규 등록 |
| .badge-info | tertiary-50 | 검토 중, 안내 |
| .badge-done | text-muted | 종료 — 글자까지 회색으로 |
공통 스펙 — inline-flex · gap-1.5 · 12px/600 · whitespace-nowrap, 점은 6px 원.
카운트 배지
내비나 탭의 미확인 개수. 여기서만 오렌지를 채웁니다. 99를 넘으면 99+.
규칙
이렇게
- 상태 하나당 배지 하나 — 한 행에 두 개까지
- 끝난 것은 회색(.badge-done)으로 내리기
- 글자는 상태 이름 그대로 — “정상 상환”
이건 피해요
- 배경 채운 알약 배지 새로 만들기
- 배지 안에 숫자와 글자 섞기
- 테두리 두르기
클래스 정의
여섯 가지 모두 같은 틀이고 before:bg-*만 달라요.
쓰기
Form
입력칸은 흰 바탕 + 얇은 테두리. 포커스하면 테두리만 오렌지로 바뀌고 그림자는 생기지 않아요.
입력
등록된 채권 정보와 같아야 해요
10자리 숫자만 입력해 주세요
스펙
| 요소 | 스펙 |
|---|---|
| .input | w-full · px-3.5 py-2.5 · 13px · r8 · border #E8E8E8 · bg #fff |
| :focus | border-color #FF5900 · outline:none · box-shadow:none |
| placeholder | #a3a3a3 — 예시 값을 보여주고(“예) 김리바”), 지시문은 짧게 |
| select | 기본 화살표를 지우고 #98A2B3 셰브런을 data-URI로. 오른쪽 여백 36px |
| 라벨 | 13px / 600, 아래 여백 6px. 선택 항목은 라벨 뒤에 (선택) |
| 도움말 · 오류 | 12px · #a3a3a3 / #EF4444. 둘을 동시에 보여주지 않아요 |
클래스 정의
쓰기
Card
흰 바탕, 라운드 12, 테두리 없음. 그림자는 거의 보이지 않을 만큼 옅게 — 종이가 살짝 떠 있는 정도예요.
KPI 카드
스펙
| 클래스 | 스펙 | 쓰는 곳 |
|---|---|---|
| .card | bg-white · r12 · p-6 | 일반 콘텐츠 묶음 |
| .kpi-card | bg-white · r12 · p-5 flex-col · gap-2 | 대시보드 지표 — 라벨 12, 값 26/800, 델타 배지 |
| 리스트 박스 | r12 · border #E8E8E8 divide-y | 선택지·연락 수단처럼 행이 이어지는 목록 |
규칙
이렇게
- 카드 사이 간격 16px
- 카드 안에서 구분이 필요하면 가로선(divide-y)
- KPI 값은 고정폭 숫자, 단위는 작게 붙여서
이건 피해요
- 카드 안에 또 카드 — 회색 블록(#F7F8FA)으로 대신
- 카드마다 다른 라운드·그림자
- 테두리와 그림자를 같이 쓰기
클래스 정의
쓰기
Table
채권자 화면의 중심이에요. 세로선 없이 가로선만, 머리글은 옅은 회색, 마지막 행의 아래선은 지웁니다.
보기
| 채무자 | 원금 | 상환률 | 상태 | 최근 입금 |
|---|---|---|---|---|
| 김리바 | 8,400,000 | 62% | 정상 상환 | 2026.09.10 |
| 이바운 | 3,200,000 | 18% | 연체 주의 | 2026.08.25 |
| 박그라 | 12,000,000 | 100% | 종료 | 2026.07.30 |
스펙
| 클래스 | 스펙 |
|---|---|
| .table-wrapper | bg-white · border-y #E8E8E8 · overflow-hidden — 좌우 테두리는 없어요 |
| .th | px-5 py-3 · 14/600 · #a3a3a3 · bg #F5F6F8 · 가운데 |
| .td | px-5 py-3 · 15px · #737373 · 가운데 · 아래선 #E8E8E8 |
| .tr-hover | hover:bg #F9FAFB · 행 전체가 링크면 cursor-pointer |
| 마지막 행 | 아래선 제거 — tbody tr:last-child td { border-bottom: 0 } |
비어 있을 때 · 많을 때
| 상황 | 처리 |
|---|---|
| 결과 없음 | 표 자리에 한 문장 — “조건에 맞는 채무자가 없어요.” + 필터 초기화 버튼 |
| 처음부터 없음 | 표 대신 빈 화면 패턴 |
| 20건 초과 | 페이지네이션. 무한 스크롤은 쓰지 않아요 |
| 좁은 화면 | 가로 스크롤. 열을 숨기지 말고 첫 열(이름)을 고정 |
클래스 정의
쓰기
Modal
흐름을 끊어야 할 때만 띄웁니다. 성공 알림은 모달이 아니라 토스트로.
보기
계좌 등록
상환금을 받을 계좌를 등록해 주세요
스펙
| 영역 | 스펙 |
|---|---|
| 배경 | bg-black/40 · 클릭하면 닫힘 · px-4로 모바일 좌우 여백 |
| 패널 | bg-white · rounded-2xl(12px) · shadow-xl · max-w-md(448px) |
| 헤더 | px-6 pt-6 pb-2 · 제목 18/800 · 부제 14 회색 · 오른쪽 닫기(X 18) |
| 본문 | px-6 pt-4 pb-6 · 항목 사이 16px |
| 푸터 | 오른쪽 정렬 · 간격 8px · 취소(outline) → 주 행동(primary) 순 |
| 폭 변형 | 확인용 max-w-sm · 폼 max-w-md · 문서·동의서 max-w-2xl |
규칙
이렇게
- ESC와 바깥 클릭으로 닫히게
- 제목은 무슨 일이 일어나는지 — “계좌 등록”
- 되돌릴 수 없는 행동은 한 번 더 확인
- 본문이 길어지면 헤더·푸터는 고정하고 가운데만 스크롤
이건 피해요
- 모달 위에 모달
- 성공 알림을 모달로 — 토스트로 충분해요
- 닫기 없이 붙잡아 두기
- 본문에 긴 안내문 밀어 넣기
구조
모달은 공용 클래스 없이 매번 같은 뼈대를 씁니다. 이 구조를 그대로 복사해 쓰세요.
ESC와 스크롤
Navigation
왼쪽 사이드바 256px 고정. 지금 있는 위치만 오렌지로, 나머지는 모두 회색이에요.
보기
스펙
| 요소 | 스펙 |
|---|---|
| 사이드바 | 256px · bg #fff · 오른쪽 선 #E8E8E8 · 로고 영역 높이 80px |
| 항목 | px-3 py-2 · r8 · 14px — 기본 500/#52525b, 활성 600/#FF5900 + 배경 #F4F4F5 |
| 권한 없음 | opacity .4 · cursor-not-allowed + 오른쪽 툴팁으로 이유 설명 |
| 그룹 라벨 | 11px / 600 · uppercase · tracking-wider · #a1a1aa |
| 모바일 | 사이드바 대신 하단 탭. 활성 색 규칙은 같아요 |
항목
껍데기
페이지 구성
모든 화면은 같은 순서로 시작해요. 제목 → 한 줄 설명 → 요약 → 목록.
페이지 헤더
섹션 사이 간격은 20px. 인사형 제목은 “안녕하세요, 김리바님” + 오늘 날짜를 부제로 둡니다.
빈 화면
처음 온 사용자가 가장 먼저 보는 화면이에요. 사과하지 말고, 다음에 할 일 하나만 크게 보여줍니다.
첫 채권을 등록하면 상환 일정과 회수 현황을 자동으로 따라가요.
상태별 화면
| 상태 | 표현 |
|---|---|
| 로딩 | 스켈레톤(회색 #F4F4F5 블록). 스피너는 버튼 안에서만 |
| 빈 결과 | 한 문장 + 되돌리는 행동(필터 초기화) |
| 오류 | 무슨 일이 있었는지 + 다시 시도. 코드·스택은 보여주지 않아요 |
| 권한 없음 | 메뉴는 보이되 흐리게 + 툴팁으로 이유 — “관리자만 신청할 수 있어요” |
| 성공 | 토스트 한 줄. 화면을 막지 않아요 |
문구
돈과 법이 걸린 화면이에요. 친근함보다 정확함이 먼저고, 정확한 다음에 짧게 씁니다.
기본
| 항목 | 규칙 |
|---|---|
| 말투 | 존댓말 해요체 — “등록되었습니다”보다 “등록했어요”. 단, 법적 고지·동의서는 문어체 그대로 |
| 용어 | 채권자 / 채무자 / 상환 / 회수 / 위임 / 연체 — 화면마다 다르게 부르지 않아요 |
| 주어 | 사용자가 한 일은 사용자 기준으로. “시스템이 처리했습니다” ✕ |
| 길이 | 버튼 2~6자, 설명 한 문장, 도움말 두 줄 이내 |
숫자 표기
| 대상 | 표기 | 비고 |
|---|---|---|
| 금액 | 12,340,000원 | 축약·소수점 없이 |
| 건수 | 148명 · 7건 | 단위 붙여쓰기 |
| 비율 | 62% | 필요할 때만 소수점 한 자리(62.5%) |
| 날짜 | 2026.09.15 | 요일이 필요하면 2026.09.15 (화) |
| 기간 | 2026.09.15 ~ 10.14 | 같은 해면 뒤쪽 연도 생략 |
| 남은 기간 | D-7 | 당일은 D-day |
예시
이렇게
- 계좌를 등록하면 상환금이 자동으로 들어와요.
- 9월 25일에 출금될 예정이에요.
- 10자리 숫자만 입력해 주세요.
- 관리자만 신청할 수 있어요.
이건 피해요
- 처리 중 오류가 발생하였습니다 (E-500)
- 유효하지 않은 값입니다
- 정말로 삭제하시겠습니까?!
- Loading… 처럼 영문 섞기
로고
심볼과 워드마크, 그리고 쓰면 안 되는 방식이에요.
파일
규칙
| 규칙 | 내용 |
|---|---|
| 최소 크기 | 심볼 20px, 조합 로고 높이 24px 이상 |
| 여백 | 사방으로 심볼 높이의 절반 이상 비워요 |
| 색 | 심볼은 항상 #FF5900. 워드마크만 배경에 따라 #0B1C2C / #FFFFFF |
| 금지 | 비율 변경, 그림자, 그라디언트, 심볼 회전, 임의 재배치 |
코드로 쓰기
토큰
새 프로젝트에 그대로 붙여 넣을 정의예요. 값은 Primitive와 같습니다.
Tailwind 설정
CSS 변수
Tailwind를 쓰지 않는 페이지(정적 HTML, 이메일 템플릿)에서는 이 변수만 복사해 쓰세요.
어디에 있나
| 항목 | 위치 |
|---|---|
| 토큰 원본 | rebound-biz / tailwind.config.js |
| 컴포넌트 클래스 | rebound-biz / src/index.css → @layer components |
| 화면 카탈로그 | rebound-biz / design — 전체 라우트와 모달을 시나리오별로 확인 |
| 아이콘 | lucide-react |
| 폰트 | Pretendard v1.3.9 (jsdelivr static) |