토스
토스는 자신을 "은행에 다니는 유능한 친구" 로 포지셔닝한다 — 조용히 일을 처리하고, 사용자의 시간을 낭비시키지 않는다는 어조다. 슬로건과 카피 곳곳에 "투자, 모두가 할 수 있도록", "수수료 걱정 없이"와 같이 진입 장벽을 제거하는 메시지가 반복되며, "토스가 알아서"라는 위임형 표현이 사용자 부담을 줄이는 톤으로 일관된다. 이는 단순한 마케팅 카피가 아니라 인터페이스 전반의 의사결정 기준이다 — 정보 밀도보다 가독성과 행동 유도를 우선하고, "한번에 볼 수 있어요" 같은 통합 뷰 패턴이 반복되는 이유다.
toss.md
---
name: 토스
slug: toss
category: finance
last_updated: "2026-05-11"
sources:
- https://api.anthropic.com/v1/design/h/GImiB7s0YWSpgptqODW6lQ
- https://toss.tech
- https://toss.tech/article/toss-design-system
- https://toss.tech/article/tds-color-system-update
- https://toss.tech/article/tds-component-making
- https://tossmini-docs.toss.im/tds-mobile/
- https://developers-apps-in-toss.toss.im/design/miniapp-branding-guide.html
- https://github.com/toss/tossface
- https://toss.im/tossfeed/article/beginning-of-tps
- https://developers-apps-in-toss.toss.im/design/components.html
- https://toss.tech/article/introducing-toss-error-message-system
- https://toss.im
related_services: []
lang: ko
logo: /logos/toss.png
---
# 토스 (Toss) — design.md
> 비바리퍼블리카가 운영하는 한국 최대 핀테크 슈퍼앱. 송금·결제·은행·증권·보험·세금·부동산·자동차 관리 등 금융 전반을 단일 모바일 셸로 묶고, "Apps in Toss" 미니앱 플랫폼까지 같은 디자인 시스템 위에 얹는다 [src:1][src:3]. 본 문서는 Toss Design System 핸드오프 번들(`TDS_Mobile_for_Apps_in_Toss_(2602-3-2).fig` export, `colors_and_type.css` + README + 18 preview cards)을 1차 출처로 합성한 결과이며, 공개된 toss.tech 보고서와 toss.im 미니앱 가이드, TDS Mobile docs를 보조 출처로 사용했다.
## Brand & Style
토스는 자신을 **"은행에 다니는 유능한 친구"** 로 포지셔닝한다 — 조용히 일을 처리하고, 사용자의 시간을 낭비시키지 않는다는 어조다 [src:1]. 슬로건과 카피 곳곳에 "투자, 모두가 할 수 있도록", "수수료 걱정 없이"와 같이 진입 장벽을 제거하는 메시지가 반복되며, "토스가 알아서"라는 위임형 표현이 사용자 부담을 줄이는 톤으로 일관된다 [src:12]. 이는 단순한 마케팅 카피가 아니라 인터페이스 전반의 의사결정 기준이다 — 정보 밀도보다 가독성과 행동 유도를 우선하고, "한번에 볼 수 있어요" 같은 통합 뷰 패턴이 반복되는 이유다 [src:12].
대상 사용자는 일반 소비자 전 연령대이지만, 디자인 시스템(TDS) 자체는 약 **2,000명 규모의 메이커**가 단일 시스템 위에서 일한다는 전제로 설계되었다 [src:3]. 일관성과 확장성은 디자인 가이드라인 차원이 아니라 인프라 차원에서 다뤄지며, 컴포넌트는 "**레고 블록**"으로 비유된다 [src:3]. 새 컴포넌트 결정은 디자이너 직관이 아니라 A/B 테스트 결과로 검증된다 — 예를 들어 Menu 컴포넌트는 10일간의 A/B 테스트에서 Android item-click rate가 10% 더 높게 나온 뒤에야 정식 채택되었다 [src:5]. Apps-in-Toss 미니앱 플랫폼은 제3자가 TDS를 따르도록 강제해 "네이티브처럼 보이게" 하지만, 동시에 토스 자체의 하단 네비게이션을 복제하는 것은 금지한다 — "사용자가 당신의 브랜드를 토스와 혼동해서는 안 된다" [src:7].
전체 무드는 **차갑고 절제된, 거의 무채색에 가까운 화이트 캔버스 + 선명한 토스 블루 단일 강조색**으로 요약된다 [src:1]. 깊은 한기 어린 cool-blue 중성색(`grey-900`부터 `grey-100`까지)이 표면 전체를 차지하고, 채도가 높은 브랜드 블루(`blue-500`)는 화면당 하나의 가장 중요한 액션에만 예약된다 [src:1]. 모서리는 **공격적으로 둥글지만 결코 귀엽지 않다** — 버튼·카드·hero 블록에 16~32px 라운드, chips·primary CTA에 999px full pill을 쓰며, iOS류 squircle/blob 라운드는 `Templates/Squircle` 전용 페이지를 제외하면 명시적으로 회피된다 [src:1]. 배경은 평면이 기본이며, 그라디언트는 (1) bottom CTA 위쪽 `white → transparent` 보호 그라디언트, (2) 로딩 버튼 내부의 미세한 pressed-blue radial glow, (3) yellow→orange 일러스트 그라디언트 — 세 가지 문서화된 예외만 허용된다 [src:1]. 텍스처·노이즈·전면 사진은 chrome에 사용되지 않는다 [src:1].
Voice는 **해요체(대화형 존댓말) + 위임형 + 일상어**로 요약된다 [src:1][src:11]. 종결어미 `-요`로 통일되며 격식체(~니다/~합니다)도, 방송 헤드라인의 단정형 `-다`도 사용하지 않는다 — 한 문장은 목적을 말하고, 다음 한 문장은 *언제 쓰는지*를 말하는 패턴이 표준이다 [src:1]. 토스가 잘못해 발생한 에러 화면에서조차 격식체가 아닌 해요체를 유지하며, 반복되는 시스템 상황은 Figma preset과 개발자 에러 메시지 라이브러리로 템플릿화되어 좋은 카피가 기본 선택지가 되도록 운영된다 [src:11]. 본 카탈로그 메타 문서는 토스 자체 카피와 달리 `~다` 평서체로 기술하며, 토스의 해요체 정책은 product surface 카피에 한해 적용되는 규칙임을 분리해 둔다.
## Colors
TDS 컬러 시스템은 **4계층 구조**로 운영된다 [src:4]:
1. **Target** — 토큰이 칠해지는 표면. `fill`, `text`, `border`.
2. **Role** — 의미 역할. `brand`, `neutral`, `primary`, `secondary`, `weak`, `alt`.
3. **Variant** — 강도 변형. `weak`, `alt`.
4. **Level** — 토큰의 추상화 단계. `base`(원시 팔레트) → `semantic`(역할 alias) → `component`(컴포넌트 전용 alias).
토스는 2025년 production 토큰을 HSL에서 OKLCH로 마이그레이션한다고 공식 발표했으며, 같은 numeric scale(50, 100, …, 900)이 모든 hue에서 동등한 perceived brightness를 갖도록 OKLCH 균질화를 도입한다 [src:4]. 핸드오프 번들 자체는 light 모드 카노니컬 hex 값으로 ship되며, 원본 hex는 `colors_and_type.css`에 정의되어 있다 — 본 문서는 catalog 규약에 따라 OKLCH로 변환해 표기한다 [src:1].
### Brand
원본 hex는 `colors_and_type.css`에 정의되어 있으며, 본 문서는 OKLCH로 변환해 표기한다 [src:1]. 카노니컬 앵커 `#3182F6 → oklch(0.624 0.176 254)`는 미니앱 브랜딩 가이드 `brand.primaryColor` 예시와 일치한다 [src:7].
```yaml
blue-500: oklch(0.624 0.176 254) # 카노니컬 Toss Blue, 화면당 하나의 primary CTA
blue-600: oklch(0.522 0.176 257) # pressed-blue 단계
blue-700: oklch(0.476 0.174 259) # pressed gradient stop
blue-50: oklch(0.965 0.020 250) # brand-weak background
```
### Greyscale (cool-blue tinted neutrals)
원본 hex는 `colors_and_type.css`에 정의되어 있으며, 본 문서는 OKLCH로 변환해 표기한다 [src:1]. `grey-900`은 순수 검정이 아니라 미세하게 차가운 navy 톤이며, `grey-100`은 거의 인지되지 않는 cool 그레이로 화면 보조 표면으로 사용된다 [src:1].
```yaml
grey-900: oklch(0.234 0.030 254) # primary text, never pure black
grey-800: oklch(0.342 0.030 253)
grey-700: oklch(0.452 0.028 253) # secondary text
grey-600: oklch(0.555 0.022 253)
grey-500: oklch(0.652 0.020 252)
grey-400: oklch(0.752 0.016 251) # disabled text, strong line
grey-300: oklch(0.840 0.012 248)
grey-200: oklch(0.913 0.008 247) # default divider/border
grey-150: oklch(0.918 0.007 247)
grey-100: oklch(0.957 0.005 247) # secondary surface
grey-50: oklch(0.978 0.003 247)
white: oklch(1.000 0.000 0)
```
### Toss yellow & orange (illustration warms)
원본 hex는 `colors_and_type.css`에 정의되어 있으며, 본 문서는 OKLCH로 변환해 표기한다 [src:1]. Toss yellow는 표면 색이 아니라 일러스트/이모지 자산의 face 색이며, orange는 시맨틱 warning에 한정된다 [src:1].
```yaml
yellow-500: oklch(0.853 0.156 86) # illustration / emoji body
yellow-400: oklch(0.893 0.123 85)
yellow-300: oklch(0.901 0.124 84)
yellow-600: oklch(0.840 0.171 87)
yellow-700: oklch(0.872 0.169 87)
orange-500: oklch(0.748 0.183 56) # semantic warning
orange-400: oklch(0.828 0.108 52)
orange-300: oklch(0.870 0.078 51)
```
### Semantic palette
원본 hex는 `colors_and_type.css`에 정의되어 있으며, 본 문서는 OKLCH로 변환해 표기한다 [src:1].
```yaml
red-500: oklch(0.628 0.218 22) # error / danger
red-600: oklch(0.626 0.216 22)
green-500: oklch(0.493 0.143 154) # success
navy-900: oklch(0.155 0.060 261) # text-shadow base, source of overlay rgba
```
### Illustration warms (brown facial features)
원본 hex는 `colors_and_type.css`에 정의되어 있으며, 본 문서는 OKLCH로 변환해 표기한다 [src:1]. brown 패밀리는 yellow-faced 일러스트 자산의 facial feature 색이며 UI 표면에는 사용되지 않는다.
```yaml
brown-900: oklch(0.359 0.083 39)
brown-700: oklch(0.444 0.062 30)
brown-500: oklch(0.535 0.073 39)
brown-400: oklch(0.659 0.097 41)
```
### Semantic alpha tokens
원본 정의는 `colors_and_type.css`의 RGBA 토큰이며, 본 문서는 OKLCH alpha 표기로 변환한다 [src:1]. navy-900을 베이스로 한 투명도 계열은 본문 보조 텍스트·헤어라인·스크림에 사용된다.
```yaml
fg-tertiary: oklch(0.155 0.060 261 / 0.58) # 흐린 본문 텍스트
fg-quaternary: oklch(0.155 0.060 261 / 0.28) # placeholder
line-subtle: oklch(0.000 0.000 0 / 0.08) # 그레이 배경 위 카드 보더
bg-overlay: oklch(0.000 0.000 0 / 0.56) # bottom-sheet scrim
press-overlay: oklch(0.000 0.000 0 / 0.26) # 보편 pressed-state tint
disabled-opacity: 0.30 # 컴포넌트 전체 노드에 적용
```
### Semantic alias
product-facing 색은 시맨틱·컴포넌트 토큰으로 호출하고 base 팔레트는 새 role을 만들 때만 직접 참조한다 [src:4].
```yaml
# Fill (배경·표면)
fill-brand: blue-500
fill-primary: grey-900
fill-secondary: grey-100
fill-weak: grey-50
fill-danger: red-500
fill-success: green-500
fill-warning: orange-500
# Text
text-primary: grey-900
text-secondary: grey-700
text-tertiary: fg-tertiary
text-placeholder: fg-quaternary
text-alt: white
text-brand: blue-500
text-danger: red-500
# Border
border-primary: blue-500 # focused input
border-secondary: grey-200 # default divider
border-strong: grey-400
border-subtle: line-subtle
# Overlay & state
overlay-scrim: bg-overlay
overlay-press: press-overlay
```
명도 대비 자동 보정 — 미니앱이 자체 brand 컬러를 등록할 때, 등록된 색이 명도 대비 기준을 통과하지 못하면 의도를 유지한 채 자동 보정된다 [src:7]. 토큰 빌드는 Token Studio(Figma 플러그인) → GitHub PR → 플랫폼별 코드 자동 생성 파이프라인을 거친다 [src:4].
## Typography
본문/UI 서체는 **Toss Product Sans (TPS)**다 [src:9]. 토스가 산돌(2020)과 공동 제작한 자체 서체이며, iOS의 SF, Windows의 맑은 고딕, Android 기본 서체로 플랫폼별 파편화되어 있던 토스 화면을 단일 서체로 통합하기 위해 만들어졌다 [src:9]. 한글 자형은 산돌의 고딕 Neo1을 기반으로 미세 조정되었고, 라틴·문장부호·기타 글리프는 한글 디자인에 맞춰 새로 그려졌다 [src:9]. 디자인 3대 기준은 (1) **밸런스** — 라틴/숫자가 통상 본문 서체보다 크게 그려져 한글과 시각적으로 화합한다, (2) **금융 맥락** — 특수문자(%, comma, 화살표)는 텍스트가 아니라 UI 요소로 재설계되었다, (3) **중립 형태** — "글자 대신 글이, 형태 대신 내용이 보일 수 있도록" 콘텐츠를 가리지 않는 형태를 지향한다 [src:9].
TPS는 자체 라이선스가 적용되어 외부 재배포가 불가능하다. 핸드오프 번들과 토스의 외부 권장 사항은 **Pretendard**를 가장 가까운 무료 한+영 neogrotesque 대체 서체로 명시한다 — 메트릭·한글 자형·tabular figure가 TPS와 거의 1:1로 일치한다 [src:1]. 번들의 폰트 스택:
```yaml
font-family-sans: >
"Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont,
"SF Pro Text", "SF Pro", "Apple SD Gothic Neo", "Noto Sans KR",
Roboto, "Helvetica Neue", Arial, sans-serif
font-family-emoji: "Tossface"
```
### Type ramp (모든 값 `colors_and_type.css`에서 직접 추출)
```yaml
display-1: { size: 56, line-height: 1.30, tracking: -0.005em, weight: 700 }
display-2: { size: 40, line-height: 1.20, tracking: -0.020em, weight: 700 }
h1: { size: 28, line-height: 1.30, tracking: -0.020em, weight: 700 }
h2: { size: 24, line-height: 1.30, tracking: -0.020em, weight: 700 }
h3: { size: 22, line-height: 1.30, tracking: -0.015em, weight: 700 }
h4: { size: 20, line-height: 1.35, tracking: -0.015em, weight: 700 }
title-1: { size: 18, line-height: 1.45, tracking: -0.010em, weight: 600 }
title-2: { size: 17, line-height: 1.45, tracking: -0.010em, weight: 600 }
body-1: { size: 17, line-height: 1.50, tracking: -0.005em, weight: 400 }
body-2: { size: 15, line-height: 1.50, tracking: -0.005em, weight: 400 }
body-3: { size: 13, line-height: 1.50, tracking: 0, weight: 400 }
label-l: { size: 17, line-height: 1.25, tracking: -0.005em, weight: 700 }
label-m: { size: 15, line-height: 1.25, tracking: -0.005em, weight: 600 }
label-s: { size: 13, line-height: 1.25, tracking: 0, weight: 600 }
caption: { size: 12, line-height: 1.40, tracking: 0, weight: 500 }
caption-s: { size: 11, line-height: 1.40, tracking: 0, weight: 500 }
```
display 웨이트는 Bold 700에 tight -1.5%~-2% 트래킹으로 무게감을 잡고, 본문은 15px Regular + 1.5 line-height — 한글 가독성을 위해 1.5가 표준이다 [src:1]. 버튼은 XL/L에서 Bold 700 17px, M/S에서 Semibold 15~13px을 쓴다 — "토스 버튼은 장식이 아니라 문장처럼 읽힌다" [src:1]. 카드 타이틀은 `title-1`(18/600), 카드 본문은 `body-2`(15/400)다 [src:1].
### 숫자/기호 처리
TPS는 variable·fixed-width 두 폭을 모두 제공하며, 실시간 금융 데이터(주가·환율·잔액)는 tabular figure로, 강조 시 proportional figure를 사용한다 [src:9]:
```yaml
font-feature-numeric-tabular: "tabular-nums"
font-feature-numeric-proportional: "proportional-nums"
```
`{typography.tabular-nums}`는 실시간 금융 데이터에, `{typography.proportional-nums}`는 강조 시 — 한국 핀테크 앱에서 보기 드문 본격적 숫자 타이포 분리다 [src:9]. 글자 수는 초기 2,350자에서 한글 완성형 전체 11,172자로 확장되어 인앱 타이핑·메시징을 지원한다 [src:9].
### Tossface (이모지 서체)
`{typography.font-family-emoji}`는 Unicode v14.0 전체 셋을 커버하는 자체 이모지 폰트로, TTF/OTF/WOFF/WOFF2로 제공되며 "단순한 형태와 최소한의 묘사"를 지향한다 [src:8]. 작은 사이즈에서도 의미가 분명히 읽히도록 설계되었다.
## Spacing
베이스 단위는 4px이며, 토큰 사다리는 4~80px 12단계로 정의된다 [src:1]:
```yaml
space-1: 4
space-2: 8
space-3: 12
space-4: 16
space-5: 20
space-6: 24
space-7: 28
space-8: 32
space-10: 40
space-12: 48
space-16: 64
space-20: 80
```
작은 영역(4~32)에서는 모든 4의 배수 단계를 갖고 있으며, 큰 영역(40 이상)은 섹션 구분을 위한 generous한 간격으로 운영된다 [src:1]. 시스템 룰 오브 섬: **24px** 화면 outer padding, **16px** list-row 간 간격, **8px** 밀접 결합 요소(label + input) 사이 [src:1].
## Rounded
라운드 토큰은 4~32px 8단계 + `full`(999px) 한 단계로 정의되며, 토스 시스템은 "**프로덕션에서 가장 둥근 모바일 시스템 중 하나**"로 분류된다 [src:1]:
```yaml
radius-xs: 4 # small badges
radius-s: 8 # inline tags
radius-m: 12 # text inputs
radius-l: 14 # L button (48px)
radius-xl: 16 # XL button (56px), cards
radius-2xl: 20 # sheets, dialogs
radius-3xl: 24 # big cards / sections
radius-4xl: 32 # hero blocks
radius-full: 999 # chips, pills, capsules
```
버튼 라운드는 사이즈에 따라 스케일된다 — XL 16 / L 14 / M 12 / S 10, `buttons.html` preview로 확인된다 [src:1]. iOS류 squircle/blob 라운드는 `Templates/Squircle` 전용 페이지를 제외하면 사용되지 않는다 [src:1].
## Elevation & Depth
토스는 평면이 기본이며 그림자는 floating/modal 표면에서만 등장한다 [src:1]. shadow offset과 blur 값은 `colors_and_type.css`에서 직접 인용되며, 색은 모두 navy-900 베이스의 낮은 알파(0.04~0.16)로 통일된다.
```yaml
shadow-1: >
0 1px 2px oklch(0.155 0.060 261 / 0.04),
0 1px 1px oklch(0.155 0.060 261 / 0.04) # menu
shadow-2: >
0 4px 12px oklch(0.155 0.060 261 / 0.06),
0 1px 2px oklch(0.155 0.060 261 / 0.04) # tooltip
shadow-3: >
0 12px 32px oklch(0.155 0.060 261 / 0.10),
0 2px 6px oklch(0.155 0.060 261 / 0.06) # dialog
shadow-toast: >
0 8px 24px oklch(0.155 0.060 261 / 0.16) # toast
```
bottom-sheet shadow는 README에 명시된 컨벤션이지만 토큰은 아니다 — `0 -2px 12px oklch(0.155 0.060 261 / 0.06)` [src:1]. inner-shadow 시스템은 없으며, pressed state는 `{colors.press-overlay}`(검정 26% overlay)를 resting fill 위에 얹는 방식으로 구현된다 — 그림자가 아니라 overlay다 [src:1].
### Motion
```yaml
ease: cubic-bezier(0.22, 0.61, 0.36, 1) # 기본 ease-out-expo
ease-out: cubic-bezier(0.16, 1, 0.3, 1) # 더 snappy, sheet 진입
dur-fast: 120 # button press
dur-base: 200 # toggle, hover
dur-slow: 320 # sheet, dialog
```
"바운스 오버슈트 없음, 320ms 초과 fade 없음, parallax 없음, skeleton shimmer 없음 — 토스는 3-dot loader를 대신 쓴다" [src:1]. 모든 모션은 위 5개 토큰 안에서 운용된다.
## Shapes
기하학은 **공격적 라운드 + 평면 표면 + 헤어라인 보더**로 요약된다 [src:1]. 차분한 화이트 캔버스 위에 16~32px 라운드 카드/버튼을 얹고, chips와 primary CTA에는 999px full pill을 적용한다. 강조는 색(토스 블루)과 위계로 표현하며 장식은 절제된다.
기본 보더는 **1px `{colors.grey-200}` 헤어라인**이며, focused input은 1.5px `{colors.blue-500}` 보더로 한 단계 강해진다 [src:1]. 2px 장식용 보더는 사용되지 않고, 컬러 left-rail accent 카드도 사용되지 않는다 [src:1]. 배경은 평면이 기본이며 그라디언트는 세 가지 문서화된 예외(bottom CTA 위쪽 보호 그라디언트, 로딩 버튼 내부 radial glow, yellow→orange 일러스트 그라디언트)에만 허용된다 [src:1].
**Iconography (TDS Icon system)** — 아웃라인(`*-mono`) + 필드(`*-fill`) 두 종 변형, kebab-case 명명(`icon-x-mono`, `icon-setting-mono`, `icon-user-circle-blue-fill`), 사이즈 16/20/24/32 [src:1]. 24px가 워크호스이며, stroke는 24px 그리드 기준 1.5~1.67px, corner는 부드럽게 라운드된다. 필드 변형은 active tab-bar 아이콘에만 사용되고, 모든 아이콘은 `currentColor`를 상속한다 — 외부 컬러 직접 주입은 금지다 [src:1].
**Tossface illustration asset set** — `{colors.yellow-500}` body + `{colors.brown-900}`·`{colors.brown-700}` facial features의 yellow-faced 평면 이모지 글리프 [src:1][src:8]. 빈 상태·성공 화면·bottom sheet 헤더에 시각 자산 컴포넌트로 사용되며, 텍스트 inline punctuation으로는 사용되지 않는다.
## Components
본 섹션은 핸드오프 번들 Figma 라이브러리의 **41개 컴포넌트 페이지**를 functional kind 별로 분해한다 [src:1]. 정확한 token 값(`{spacing.*}`, `{rounded.*}`, `{colors.*}`)이 모두 surface되어 있으므로 prose 본문에서 `{group.name}` 토큰 참조로 호출한다.
### button
토스 Button은 **XL/L/M/S** 4단으로 운영되며, height·radius·label font가 각 사이즈에서 함께 변한다 [src:1]:
| 사이즈 | height | radius | label |
|---|---|---|---|
| XL | 56 | `{rounded.radius-xl}` (16) | `{typography.label-l}` (17px Bold) |
| L | 48 | `{rounded.radius-l}` (14) | `{typography.label-l}` (17px Bold) |
| M | 40 | `{rounded.radius-m}` (12) | `{typography.label-m}` (15px Semibold) |
| S | 32 | 10 | `{typography.label-s}` (13px Semibold) |
pressed state는 `{colors.overlay-press}` (검정 26%)를 fill 위에 얹는 방식이고, disabled state는 컴포넌트 전체 노드에 `{colors.disabled-opacity}` (0.30)를 적용한다 — 부분 회색 처리하지 않는다 [src:1].
```tsx
<Button variant="primary" size="xl">송금하기</Button>
<Button variant="ghost" size="m">취소</Button>
```
### button-primary
`{colors.fill-brand}` (blue-500) 배경 + `{colors.text-alt}` (흰 텍스트). 화면당 단 하나의 가장 중요한 액션에만 사용된다 [src:1].
### button-secondary
`{colors.fill-secondary}` (grey-100) 배경 + `{colors.text-primary}` (grey-900) 텍스트. 같은 화면의 보조 액션을 표현할 때 사용된다 [src:1].
### button-danger
`{colors.fill-danger}` (red-500) 배경 + `{colors.text-alt}` 텍스트. 파괴적 액션 전용 [src:1].
### button-ghost
투명 배경 + `{colors.text-brand}` (blue-500) 라벨, 보더 없음. 텍스트 링크에 가까운 약한 위계 [src:1].
### bottom-cta
화면 최하단 고정 56pt 버튼 [src:1]. 좌우 16px padding, 24~32px의 `white → transparent` 보호 그라디언트가 위쪽에 적용되어 스크롤되는 콘텐츠와 시각적으로 충돌하지 않도록 한다. `env(safe-area-inset-*)`로 safe area를 자동 인식한다 [src:1].
```tsx
<BottomCTA onClick={handleNext}>다음</BottomCTA>
```
### text-field
48px height, `{rounded.radius-m}` (12) radius, `{colors.fill-secondary}` (grey-100) resting 배경, 1px `{colors.border-secondary}` (grey-200) 보더 [src:1]. focus 상태에서 흰 배경 + 1.5px `{colors.border-primary}` (blue-500) 보더로 전환된다. error 상태는 1.5px `{colors.fill-danger}` (red-500) 보더와 그 아래 `{colors.text-danger}` 컬러의 헬퍼 텍스트로 표현된다 [src:1].
### chip
34px 높이의 full pill (`{rounded.radius-full}`) [src:1]. resting은 1px `{colors.border-secondary}` 보더 + 흰 배경, active 변형은 `{colors.fill-primary}` (grey-900) 배경 + 흰 텍스트로 flip되며, brand 변형은 `{colors.blue-50}` 배경 + `{colors.text-brand}` (blue-500) 텍스트다.
### badge
22px 높이, 6px radius — chip보다 작고 더 정보 밀도 높은 표면에 사용된다 [src:1]. 시맨틱 색에 매핑된 washed 배경과 페어링된다 (예: red badge는 `oklch(0.940 0.040 18)` 부근의 옅은 분홍 배경 + `{colors.text-danger}` 텍스트; green badge는 옅은 민트 배경 + `{colors.green-500}` 텍스트). 원본 배경 hex는 `colors_and_type.css`에 정의되어 있다 [src:1].
### list-row
토스 홈·계좌 목록·거래 내역의 표준 단위 [src:1]. 좌우 padding 14×24, 14px gap으로 44px 아바타(radius 14) + 타이틀/서브 스택 + 우측 정렬 amount/timestamp/arrow 슬롯을 갖는다. amount는 Bold 700 15px이며, 양수는 `{colors.text-brand}` (예: `+50,000원`), 음수는 `{colors.text-primary}` (예: `−12,300원`)로 표시된다 [src:1].
```tsx
<ListRow
left={<Asset name="bank-account" />}
title="토스뱅크"
subtitle="잔액"
right={<Amount value={1234567} positive />}
/>
```
### list-header
list-row 그룹의 헤더 — 섹션 타이틀과 우측 액션 슬롯(예: "전체보기")을 함께 노출한다 [src:1].
### tab-bar
미니앱의 floating tab-bar 변형 — 420px max-width, `{rounded.radius-3xl}` (24) radius, 흰 배경 + 1px `{colors.border-secondary}` 보더, 2~5개 destination [src:1][src:10]. active 아이콘은 filled 변형 + `{colors.text-primary}`, inactive는 outline + `{colors.text-tertiary}`다.
### top-app-bar
56pt 높이, 좌측 정렬 타이틀, 우측 옵션 아이콘 버튼 슬롯 [src:1].
### toast
`{colors.fill-primary}` (grey-900) 표면 + 흰 라벨, `{rounded.radius-l}` (14) radius, `{elevation.shadow-toast}` [src:1]. 성공 아이콘은 20px `{colors.green-500}` 원 + 흰 체크다.
```tsx
<Toast>송금이 완료되었어요</Toast>
```
### dialog
흰 표면, `{rounded.radius-2xl}` (20) radius, 24px inner padding, `{elevation.shadow-3}` [src:1]. 타이틀은 18/700, 본문은 15/400 `{colors.text-secondary}`, primary blue + secondary grey-100 CTA 두 개가 각 48px 높이로 stack된다.
```tsx
<Dialog
title="송금을 취소할까요?"
body="취소하면 작성하던 내용이 사라져요."
primary="취소"
secondary="계속하기"
/>
```
### bottom-sheet
토스 모바일에서 dialog의 1차 대체 — `{elevation.shadow-bottom-sheet}` (`0 -2px 12px oklch(0.155 0.060 261 / 0.06)`) shadow, `{colors.overlay-scrim}` scrim, 20~24px top corner radius [src:1]. yellow-faced 일러스트 글리프가 sheet 상단에 anchored되는 패턴이 빈번하다.
### keypad
전용 Figma 페이지 — 금액 입력과 PIN 입력에 사용되는 숫자 키패드 [src:1]. backdrop-filter blur는 iOS 네이티브 시트가 카메라/키패드 위에 떴을 때만 적용된다.
### loading
라벨이 0으로 페이드되고 같은 색의 3개 dot이 펄스하면서, 미세한 radial highlight가 버튼을 가로지른다 [src:1]. skeleton shimmer는 의도적으로 사용되지 않는다.
### menu
trigger 위치에 즉시 펼쳐지는 셀렉터 컴포넌트 [src:5]. "버튼은 위에서 눌렀는데 응답이 하단 bottom sheet에서 오면 인지 부하가 커진다"는 문제 의식을 바탕으로 시각적 거리(physical distance)를 최적화한 컴포넌트다. 10일 A/B 테스트에서 Android item-click rate 10% 개선이 검증된 뒤 정식 채택되었다 [src:5].
```tsx
<Menu trigger={<Button variant="ghost">정렬</Button>}>
<Menu.Item>최신순</Menu.Item>
<Menu.Item>가나다순</Menu.Item>
</Menu>
```
### icon
TDS Icon system — outline (`*-mono`) + filled (`*-fill`) 두 종 변형, 16/20/24/32 사이즈, `currentColor` 상속 [src:1]. filled 변형은 active tab-bar 아이콘에만 사용된다.
### asset (Tossface illustration)
`{colors.yellow-500}` body + `{colors.brown-900}`·`{colors.brown-700}` facial features의 평면 일러스트 자산 [src:1][src:8]. 빈 상태·성공 화면·bottom-sheet 헤더에 시각 자산 컴포넌트로 사용되며, 텍스트 inline에 emoji 대용으로 절대 사용되지 않는다.
### error-message-library
가이드라인이 아닌 **시스템 형태**의 에러 카피 인프라 [src:11]. 개발자용 라이브러리(코드 컴포넌트 검색 기반)와 디자이너용 프리셋 템플릿(Framering) 두 채널을 갖는다. 핵심 원칙은 **"Navigating error"** — 에러 메시지의 역할은 사용자를 다음 화면으로 옮겨주는 것이며 멈춰 세우는 것이 아니다 [src:11]. 토스가 잘못해 발생한 에러조차 해요체를 유지하며, 반복 시스템 상황은 템플릿화되어 좋은 카피가 기본 선택지가 된다 [src:11].
## Do's and Don'ts
**Do**
- product-facing 색은 시맨틱·컴포넌트 alias(`{colors.fill-brand}`, `{colors.text-primary}`, `{colors.border-primary}`, `{colors.fill-secondary}`)로만 호출하고, base 팔레트(`{colors.blue-500}`, `{colors.grey-900}` 등)는 새 role을 만들 때만 직접 참조한다 [src:4].
- 화면당 단일 강조색 정책을 유지한다 — primary CTA는 `{colors.fill-brand}` 하나로 통일하고, 보조 액션은 `{colors.fill-secondary}` 또는 ghost 변형으로 분리한다 [src:1][src:4].
- 화면 최하단 강제 액션은 `{component.bottom-cta}`로, 화면 내부 액션은 `{component.button-primary}`로 분리한다 — 두 컴포넌트의 역할이 다르다 [src:1].
- 버튼 라운드는 사이즈와 페어로 운영한다 — XL→`{rounded.radius-xl}` (16), L→`{rounded.radius-l}` (14), M→`{rounded.radius-m}` (12), S→10 [src:1].
- 실시간 금융 데이터(잔액·환율·차트)는 `{typography.tabular-nums}`로, 강조 숫자는 `{typography.proportional-nums}`로 분리한다 [src:9].
- 본문은 `{typography.body-2}` (15px / 1.5 line-height)로 기본화한다 — 한글 가독성을 위한 표준값이다 [src:1].
- product 카피는 **해요체**로 작성한다 — 토스가 잘못해 발생한 에러에도 격식체가 아닌 해요체를 유지한다 [src:1][src:11].
- 에러 메시지는 "Navigating error" 원칙을 따른다 — 사용자를 멈춰 세우지 않고 다음 화면으로 안내한다 [src:11].
- 금액은 한국식 표기를 따른다 — `1,000원` 처럼 세 자리 구분 + `원` 직접 붙임(공백 없음); 퍼센트도 `12%`로 붙여쓴다 [src:1].
- 미니앱 브랜드명은 한국어 표기를 우선한다 — `Toss`보다 `토스`를 권장한다 [src:7].
- 미니앱이 자체 brand 컬러를 등록할 때는 명도 대비 자동 보정 정책을 신뢰한다 — 의도된 색은 유지된다 [src:7].
- 아이콘은 `currentColor`를 상속하게 둔다 — 외부 컬러 직접 주입은 금지다 [src:1].
- pressed state는 `{colors.overlay-press}` (검정 26%) overlay로, disabled state는 컴포넌트 전체 노드에 `{colors.disabled-opacity}` (0.30)를 적용한다 — 부분 회색 처리하지 않는다 [src:1].
**Don't**
- 챗봇 톤("~해보세요!", "~할까요?")이나 마케팅 과장("혁신적", "최고의", "차세대")을 product 카피에 사용하지 않는다 [src:1][src:11].
- 격식체(~십시오/~합니다)를 product 카피에 사용하지 않는다 — 토스가 잘못한 에러 화면에서도 해요체를 유지한다 [src:11].
- 단정형 `-다`나 방송 헤드라인 톤을 사용하지 않는다 — 해요체가 표준이다 [src:1].
- 한 화면에 강조색을 둘 이상 사용하지 않는다 — `{colors.fill-brand}`는 단일 primary CTA에 예약된다 [src:1].
- 그라디언트를 chrome에 사용하지 않는다 — 세 가지 문서화된 예외(bottom CTA 보호 그라디언트, 로딩 버튼 radial glow, yellow→orange 일러스트)만 허용된다 [src:1].
- iOS류 squircle/blob 라운드를 사용하지 않는다 — `Templates/Squircle` 전용 페이지를 제외하고는 표준 9단 `{rounded.*}` ladder만 사용한다 [src:1].
- 2px 장식용 보더, 컬러 left-rail accent 카드를 사용하지 않는다 — 기본 보더는 1px `{colors.border-secondary}` 헤어라인이다 [src:1].
- skeleton shimmer를 사용하지 않는다 — 로딩 상태는 3-dot loader와 미세 radial highlight로 처리한다 [src:1].
- 320ms 초과 fade·바운스 오버슈트·parallax를 사용하지 않는다 — 모션은 `{motion.dur-fast/base/slow}` (120/200/320ms) 안에서만 운용한다 [src:1].
- inner shadow를 사용하지 않는다 — pressed state는 `{colors.overlay-press}` overlay이지 shadow가 아니다 [src:1].
- 이모지를 product 카피에 inline으로 사용하지 않는다 — "emoji" 컨텐츠는 큐레이트된 `{component.asset}` 일러스트 세트로 다뤄지고, 텍스트 punctuation으로 쓰이지 않는다 [src:1].
- `{component.button-primary}`와 `{component.bottom-cta}`를 같은 화면에 동시에 두지 않는다 — 액션 위계가 무너지고 강조점이 분산된다 [src:1].
- 영문 UI 라벨에 ALL CAPS, 헤딩에 `!`, 한국어 문장 중간에 em-dash를 사용하지 않는다; "여기를 눌러주세요" 같은 디렉티브 라벨은 금지된다 — 버튼은 일어날 일을 직접 말한다(`송금하기`, `다음`, `시작하기`) [src:1].
## Responsive Behavior
토스는 **mobile-first** 슈퍼앱이며 [src:1], TDS Mobile / 앱인토스 TDS가 정식 문서화의 1차 표면이다 [src:1][src:10]. 데스크톱 surface는 부수적이며 모바일 인터랙션 패턴을 그대로 옮기지 않는다. README에 명시된 정책 — "토스는 모바일에서 다중 컬럼 레이아웃을 거의 사용하지 않는다" [src:1].
### Breakpoints
공식 breakpoint 토큰 표는 핸드오프 번들에서 별도로 surface되지 않았다 — 아래는 mobile-first 정책 기반의 권장 분기점이며 토스 공식 토큰은 아니다.
| Name | Width | Key Changes |
|---|---|---|
| Mobile | ≤ 640px | 기본 환경 — `{component.bottom-cta}`로 화면 최하단 액션, `{component.bottom-sheet}`를 dialog 기본 대체로 사용 [src:1][src:10] |
| Tablet | 641–1023px | 단일 컬럼 유지 권장 — 토스는 모바일에서 multi-column을 거의 사용하지 않는 정책을 가짐 [src:1] |
| Desktop | ≥ 1024px | 부수적 surface — 별도 위계 재설계 권장 |
### Touch Targets
모든 인터랙티브 표면은 **최소 44×44px** hit area를 보장한다. `{component.list-row}`는 한 줄 전체가 hit area이며, `{component.button}` 사이즈는 S(32)도 손가락 터치를 전제로 충분한 padding을 갖는다 [src:1]. `{component.bottom-cta}`는 56pt 높이로 한 손 엄지 도달성을 최적화한다 [src:1].
### Collapsing Strategy
- **Dialog → BottomSheet**: 모바일에서는 `{component.dialog}` 대신 `{component.bottom-sheet}`를 1차로 사용한다 [src:10].
- **Menu over BottomSheet**: 선택지가 짧으면 `{component.menu}`를 trigger 근처에 펼친다 — 하단 sheet로 떨어뜨리지 않는다 (시각 거리 최적화 정책) [src:5].
- **BottomCTA**: 화면 최하단에 safe-area inset을 고려한 고정 액션 영역으로 운용한다 [src:1].
- **Single column**: 모바일·태블릿 모두 단일 컬럼 유지를 권장한다 [src:1].
### Image Behavior
토스 시스템은 `{component.asset}`을 통해 일러스트·아이콘을 일관된 컨테이너 안에서 노출한다 [src:1]. chrome에는 full-bleed 사진이 사용되지 않으며, 일러스트 자산은 `{colors.yellow-500}` body의 평면 톤을 유지한다 [src:1].
## Known Gaps
- **다크 모드 alias 테이블** — 핸드오프 번들은 light 모드 카노니컬 hex만 제공한다 [src:1]. 다크 모드 전환 시 각 semantic alias의 base 참조 변화(light → dark 매핑)는 공개되지 않았으며, 2025년 OKLCH 마이그레이션 발표 시점에도 다크 alias 전체 테이블은 surface되지 않았다 [src:4].
- **전체 컬러 step ladder** — `colors_and_type.css`에 노출된 step은 brand(blue 50/500/600/700), grey(50~900 + 150), yellow(300~700), orange(300~500), red(500/600), green(500), navy-900, brown(400~900)이다 [src:1]. 그 외 hue별 step(예: blue-100~400, green-50~400, red-50~400 등)의 OKLCH 값은 surface되지 않았다.
- **Toss Product Sans 라이선스** — TPS는 자체 라이선스로 외부 재배포가 금지된다 [src:9]. 본 카탈로그를 적용하는 host 앱은 Pretendard로 substitute해야 하며, 메트릭은 거의 일치하지만 글리프 디테일(특수문자 디자인, fixed-width 숫자)에서는 차이가 발생할 수 있다 [src:1].
- **Token Studio 빌드 산출물 포맷** — 토큰은 Token Studio → GitHub PR → 플랫폼별 코드 자동 생성을 거치며 출력은 RGB/RGBA 포맷이다 [src:4]. 본 카탈로그는 OKLCH로 변환해 표기하나, 자동 생성 산출물의 정확한 포맷·툴체인 디테일은 공개되지 않았다.
- **공식 breakpoint 토큰** — TDS Mobile은 mobile-first 정책상 breakpoint 토큰 자체가 공식 surface되지 않았다 [src:1][src:10]. 본 문서의 Responsive Behavior 분기점은 권장값이며 토스 공식 토큰이 아니다.
## References
1. https://api.anthropic.com/v1/design/h/GImiB7s0YWSpgptqODW6lQ — Toss Design System 핸드오프 번들 (`TDS_Mobile_for_Apps_in_Toss_(2602-3-2).fig` export). `README.md`, `colors_and_type.css`, `SKILL.md`, 18개 `preview/*.html` 카드를 포함하는 로컬 번들로, 본 entry의 1차 출처. © 2025 Viva Republica.
2. https://toss.tech — Toss Tech 블로그 인덱스.
3. https://toss.tech/article/toss-design-system — TDS 디자인 시스템 개요. LEGO-block 비유, 2,000명 메이커 전제, 3-pillar 개선 모델.
4. https://toss.tech/article/tds-color-system-update — TDS 컬러 시스템 OKLCH 마이그레이션, 4계층 토큰 구조(Target/Role/Variant/Level), base/semantic/component 명명.
5. https://toss.tech/article/tds-component-making — 컴포넌트 설계 방법론. Menu 컴포넌트 10일 A/B 테스트, "Will people use this well? Will metrics improve?" 검증 원칙.
6. https://tossmini-docs.toss.im/tds-mobile/ — TDS Mobile foundation, TextField/Modal/Toast/Dialog 및 `useDialog`/`useToast`/`useBottomSheet` 훅.
7. https://developers-apps-in-toss.toss.im/design/miniapp-branding-guide.html — 앱인토스 미니앱 브랜딩 가이드, `brand.primaryColor: #3182F6` 예시, 명도 대비 자동 보정 정책, 한국어 표기 권장.
8. https://github.com/toss/tossface — Tossface 이모지 폰트 공식 레포. Unicode 14.0 전체 셋, TTF/OTF/WOFF/WOFF2.
9. https://toss.im/tossfeed/article/beginning-of-tps — Toss Product Sans 개발기. 산돌 공동 제작, 7 weight, 한글 11,172자 완성형, tabular/proportional 숫자 분리, 디자인 3대 기준.
10. https://developers-apps-in-toss.toss.im/design/components.html — 앱인토스 TDS 컴포넌트 목록 (Badge, Border, BottomCTA, Button, Asset, ListRow, ListHeader, Navigation, Paragraph, Tab, Top).
11. https://toss.tech/article/introducing-toss-error-message-system — Toss 에러 메시지 시스템. Navigating error 원칙, 해요체 채택 의사결정, 개발자 라이브러리 + 디자이너 Framering.
12. https://toss.im — 토스 공식 홈페이지. 슬로건·카피·비주얼 톤 보조 출처.