--- name: 토스 slug: toss category: finance last_updated: "2026-05-29" created_at: "2026-05-11" sources: - 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: https://getdesign.kr/logos/toss.png --- # 토스 (Toss) — design.md > 비바리퍼블리카가 운영하는 한국 최대 핀테크 슈퍼앱. 송금·결제·은행·증권·보험·세금·부동산·자동차 관리 등 금융 전반을 단일 모바일 셸로 묶고, "Apps in Toss" 미니앱 플랫폼까지 같은 디자인 시스템 위에 얹는다 [src:2]. 본 문서는 Toss Design System 핸드오프 번들(`TDS_Mobile_for_Apps_in_Toss_(2602-3-2).fig` export → `toss-design-system/{README, chats/chat1, project/{README, SKILL, colors_and_type.css, preview/ 41 cards, ui_kits/mobile/{Components.jsx, Screens.jsx, Send-Money Flow.html, ios-frame.jsx}, assets/toss-logo.png}}`)을 1차 출처로 합성한 결과이며, 공개된 toss.tech 보고서와 toss.im 미니앱 가이드, TDS Mobile docs를 보조 출처로 사용했다. ## Brand & Style 토스는 자신을 **"은행에 다니는 유능한 친구"** 로 포지셔닝한다 — 조용히 일을 처리하고, 사용자의 시간을 낭비시키지 않는다는 어조다. 슬로건과 카피 곳곳에 "투자, 모두가 할 수 있도록", "수수료 걱정 없이"와 같이 진입 장벽을 제거하는 메시지가 반복되며, "토스가 알아서"라는 위임형 표현이 사용자 부담을 줄이는 톤으로 일관된다 [src:11]. 이는 단순한 마케팅 카피가 아니라 인터페이스 전반의 의사결정 기준이다 — 정보 밀도보다 가독성과 행동 유도를 우선하고, "한번에 볼 수 있어요" 같은 통합 뷰 패턴이 반복되는 이유다 [src:11]. 대상 사용자는 일반 소비자 전 연령대이지만, 디자인 시스템(TDS) 자체는 약 **2,000명 규모의 메이커**가 단일 시스템 위에서 일한다는 전제로 설계되었다 [src:2]. 일관성과 확장성은 디자인 가이드라인 차원이 아니라 인프라 차원에서 다뤄지며, 컴포넌트는 "**레고 블록**"으로 비유된다 [src:2]. 새 컴포넌트 결정은 디자이너 직관이 아니라 A/B 테스트 결과로 검증된다 — 예를 들어 Menu 컴포넌트는 10일간의 A/B 테스트에서 Android item-click rate가 10% 더 높게 나온 뒤에야 정식 채택되었다 [src:4]. Apps-in-Toss 미니앱 플랫폼은 제3자가 TDS를 따르도록 강제해 "네이티브처럼 보이게" 하지만, 동시에 토스 자체의 하단 네비게이션을 복제하는 것은 금지한다 — "사용자가 당신의 브랜드를 토스와 혼동해서는 안 된다" [src:6]. 전체 무드는 **차갑고 절제된, 거의 무채색에 가까운 화이트 캔버스 + 선명한 토스 블루 단일 강조색**으로 요약된다. 깊은 한기 어린 cool-blue 중성색(`grey-900`부터 `grey-100`까지)이 표면 전체를 차지하고, 채도가 높은 브랜드 블루(`blue-500`)는 화면당 하나의 가장 중요한 액션에만 예약된다. 모서리는 **공격적으로 둥글지만 결코 귀엽지 않다** — 버튼·카드·hero 블록에 16~32px 라운드, chips·primary CTA에 999px full pill을 쓰며, iOS류 squircle/blob 라운드는 `Templates/Squircle` 전용 페이지를 제외하면 명시적으로 회피된다. 배경은 평면이 기본이며, 그라디언트는 (1) bottom CTA 위쪽 `white → transparent` 보호 그라디언트, (2) 로딩 버튼 내부의 미세한 pressed-blue radial glow, (3) yellow→orange 일러스트 그라디언트 — 세 가지 문서화된 예외만 허용된다. 텍스처·노이즈·전면 사진은 chrome에 사용되지 않는다. Voice는 **해요체(대화형 존댓말) + 위임형 + 일상어**로 요약된다 [src:10]. 종결어미 `-요`로 통일되며 격식체(~니다/~합니다)도, 방송 헤드라인의 단정형 `-다`도 사용하지 않는다 — 한 문장은 목적을 말하고, 다음 한 문장은 *언제 쓰는지*를 말하는 패턴이 표준이다. 토스가 잘못해 발생한 에러 화면에서조차 격식체가 아닌 해요체를 유지하며, 반복되는 시스템 상황은 Figma preset과 개발자 에러 메시지 라이브러리로 템플릿화되어 좋은 카피가 기본 선택지가 되도록 운영된다 [src:10]. 본 카탈로그 메타 문서는 토스 자체 카피와 달리 `~다` 평서체로 기술하며, 토스의 해요체 정책은 product surface 카피에 한해 적용되는 규칙임을 분리해 둔다. ## Colors TDS 컬러 시스템은 **4계층 구조**로 운영된다 [src:3]: 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:3]. 핸드오프 번들 자체는 light 모드 카노니컬 hex 값으로 ship되며, 원본 hex는 `colors_and_type.css`에 정의되어 있다 — 본 문서는 catalog 규약에 따라 OKLCH로 변환해 표기한다. ### Brand 원본 hex는 `colors_and_type.css`에 정의되어 있으며, 본 문서는 OKLCH로 변환해 표기한다. 카노니컬 앵커 `oklch(0.624 0.176 254)`는 미니앱 브랜딩 가이드 `brand.primaryColor` 예시(공식 hex로 노출되는 값)와 일치한다 [src:6]. ```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로 변환해 표기한다. `grey-900`은 순수 검정이 아니라 미세하게 차가운 navy 톤이며, `grey-100`은 거의 인지되지 않는 cool 그레이로 화면 보조 표면으로 사용된다. ```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로 변환해 표기한다. Toss yellow는 표면 색이 아니라 일러스트/이모지 자산의 face 색이며, orange는 시맨틱 warning에 한정된다. ```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로 변환해 표기한다. ```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로 변환해 표기한다. 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 표기로 변환한다. 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:3]. ```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 ``` 새 번들(`HI3LORQulbJJqdr-BrZGMQ`)의 `colors_and_type.css`는 같은 카노니컬 값에 매핑되는 **4-카테고리 정식 변수명**(`--tds-fg-*` / `--tds-bg-*` / `--tds-line-*` / `--tds-press-overlay` / `--tds-disabled-opacity`)을 함께 export한다 — 위 단축 alias가 catalog 문서 관행이라면, 아래 매핑은 prototype에 그대로 inline할 수 있는 CSS custom property 이름이다. ```yaml # Foreground (text · icon) tds-fg-primary: text-primary # grey-900 tds-fg-secondary: text-secondary # grey-700 tds-fg-tertiary: fg-tertiary # navy-900 @ 58% tds-fg-quaternary: fg-quaternary # navy-900 @ 28% tds-fg-disabled: grey-400 tds-fg-inverse: text-alt # white tds-fg-brand: text-brand tds-fg-danger: text-danger tds-fg-success: green-500 # Background (surface · scrim) tds-bg-primary: white tds-bg-secondary: fill-secondary # grey-100 tds-bg-tertiary: grey-200 tds-bg-elevated: white tds-bg-overlay: overlay-scrim tds-bg-brand: fill-brand tds-bg-brand-weak: blue-50 tds-bg-danger: fill-danger # Line (border · divider) tds-line-default: border-secondary # grey-200 tds-line-subtle: border-subtle tds-line-strong: border-strong # grey-400 # Accent / state tds-press-overlay: overlay-press # 검정 26% tds-disabled-opacity: 0.30 ``` 명도 대비 자동 보정 — 미니앱이 자체 brand 컬러를 등록할 때, 등록된 색이 명도 대비 기준을 통과하지 못하면 의도를 유지한 채 자동 보정된다 [src:6]. 토큰 빌드는 Token Studio(Figma 플러그인) → GitHub PR → 플랫폼별 코드 자동 생성 파이프라인을 거친다 [src:3]. ## Typography 본문/UI 서체는 **Toss Product Sans (TPS)**다 [src:8]. 토스가 산돌(2020)과 공동 제작한 자체 서체이며, iOS의 SF, Windows의 맑은 고딕, Android 기본 서체로 플랫폼별 파편화되어 있던 토스 화면을 단일 서체로 통합하기 위해 만들어졌다 [src:8]. 한글 자형은 산돌의 고딕 Neo1을 기반으로 미세 조정되었고, 라틴·문장부호·기타 글리프는 한글 디자인에 맞춰 새로 그려졌다 [src:8]. 디자인 3대 기준은 (1) **밸런스** — 라틴/숫자가 통상 본문 서체보다 크게 그려져 한글과 시각적으로 화합한다, (2) **금융 맥락** — 특수문자(%, comma, 화살표)는 텍스트가 아니라 UI 요소로 재설계되었다, (3) **중립 형태** — "글자 대신 글이, 형태 대신 내용이 보일 수 있도록" 콘텐츠를 가리지 않는 형태를 지향한다 [src:8]. TPS는 자체 라이선스가 적용되어 외부 재배포가 불가능하다. 핸드오프 번들과 토스의 외부 권장 사항은 **Pretendard**를 가장 가까운 무료 한+영 neogrotesque 대체 서체로 명시한다 — 메트릭·한글 자형·tabular figure가 TPS와 거의 1: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가 표준이다. 버튼은 XL/L에서 Bold 700 17px, M/S에서 Semibold 15~13px을 쓴다 — "토스 버튼은 장식이 아니라 문장처럼 읽힌다". 카드 타이틀은 `title-1`(18/600), 카드 본문은 `body-2`(15/400)다. ### 숫자/기호 처리 TPS는 variable·fixed-width 두 폭을 모두 제공하며, 실시간 금융 데이터(주가·환율·잔액)는 tabular figure로, 강조 시 proportional figure를 사용한다 [src:8]: ```yaml font-feature-numeric-tabular: "tabular-nums" font-feature-numeric-proportional: "proportional-nums" ``` `{typography.tabular-nums}`는 실시간 금융 데이터에, `{typography.proportional-nums}`는 강조 시 — 한국 핀테크 앱에서 보기 드문 본격적 숫자 타이포 분리다 [src:8]. 글자 수는 초기 2,350자에서 한글 완성형 전체 11,172자로 확장되어 인앱 타이핑·메시징을 지원한다 [src:8]. ### Tossface (이모지 서체) `{typography.font-family-emoji}`는 Unicode v14.0 전체 셋을 커버하는 자체 이모지 폰트로, TTF/OTF/WOFF/WOFF2로 제공되며 "단순한 형태와 최소한의 묘사"를 지향한다 [src:7]. 작은 사이즈에서도 의미가 분명히 읽히도록 설계되었다. ## Spacing 베이스 단위는 4px이며, 토큰 사다리는 4~80px 12단계로 정의된다: ```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한 간격으로 운영된다. 시스템 룰 오브 섬: **24px** 화면 outer padding, **16px** list-row 간 간격, **8px** 밀접 결합 요소(label + input) 사이. ## Rounded 라운드 토큰은 4~32px 8단계 + `full`(999px) 한 단계로 정의되며, 토스 시스템은 "**프로덕션에서 가장 둥근 모바일 시스템 중 하나**"로 분류된다: ```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로 확인된다. iOS류 squircle/blob 라운드는 `Templates/Squircle` 전용 페이지를 제외하면 사용되지 않는다. ## Elevation & Depth 토스는 평면이 기본이며 그림자는 floating/modal 표면에서만 등장한다. 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)`. inner-shadow 시스템은 없으며, pressed state는 `{colors.press-overlay}`(검정 26% overlay)를 resting fill 위에 얹는 방식으로 구현된다 — 그림자가 아니라 overlay다. ### 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를 대신 쓴다". 모든 모션은 위 5개 토큰 안에서 운용된다. ## Shapes 기하학은 **공격적 라운드 + 평면 표면 + 헤어라인 보더**로 요약된다. 차분한 화이트 캔버스 위에 16~32px 라운드 카드/버튼을 얹고, chips와 primary CTA에는 999px full pill을 적용한다. 강조는 색(토스 블루)과 위계로 표현하며 장식은 절제된다. 기본 보더는 **1px `{colors.grey-200}` 헤어라인**이며, focused input은 1.5px `{colors.blue-500}` 보더로 한 단계 강해진다. 2px 장식용 보더는 사용되지 않고, 컬러 left-rail accent 카드도 사용되지 않는다. 배경은 평면이 기본이며 그라디언트는 세 가지 문서화된 예외(bottom CTA 위쪽 보호 그라디언트, 로딩 버튼 내부 radial glow, yellow→orange 일러스트 그라디언트)에만 허용된다. **Iconography (TDS Icon system)** — 아웃라인(`*-mono`) + 필드(`*-fill`) 두 종 변형, kebab-case 명명(`icon-x-mono`, `icon-setting-mono`, `icon-user-circle-blue-fill`), 사이즈 16/20/24/32. 24px가 워크호스이며, stroke는 24px 그리드 기준 1.5~1.67px, corner는 부드럽게 라운드된다. 필드 변형은 active tab-bar 아이콘에만 사용되고, 모든 아이콘은 `currentColor`를 상속한다 — 외부 컬러 직접 주입은 금지다. 번들이 명시한 production runtime은 단일 SVG sprite로 서빙되며, Figma에서 가장 많이 인스턴스화된 아이콘은 `icon-x-mono`(96회), `icon-setting-mono`(48회), `icon-user-circle-blue-fill`(96회)이다. Apps-in-Toss 미니앱이 외부에서 prototype을 작성할 때는 TDS 아이콘 SVG를 직접 들고 올 수 없으므로 새 번들 ui_kits는 **Lucide**(24px 그리드, 1.5px stroke, rounded line caps)를 동일 격자의 임시 대체로 사용한다 — production 마이그레이션 시 실제 TDS sprite로 교체한다는 substitution 약속이 README에 명시되어 있다. **Tossface illustration asset set** — `{colors.yellow-500}` body + `{colors.brown-900}`·`{colors.brown-700}` facial features의 yellow-faced 평면 이모지 글리프 [src:7]. 빈 상태·성공 화면·bottom sheet 헤더에 시각 자산 컴포넌트로 사용되며, 텍스트 inline punctuation으로는 사용되지 않는다. ## Components 본 섹션은 핸드오프 번들 Figma 라이브러리의 **41개 컴포넌트 페이지**를 functional kind 별로 분해한다. 정확한 token 값(`{spacing.*}`, `{rounded.*}`, `{colors.*}`)이 모두 surface되어 있으므로 prose 본문에서 `{group.name}` 토큰 참조로 호출한다. ### button 토스 Button은 **XL/L/M/S** 4단으로 운영되며, height·radius·label font가 각 사이즈에서 함께 변한다: | 사이즈 | 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)를 적용한다 — 부분 회색 처리하지 않는다. ```tsx ``` ### button-primary `{colors.fill-brand}` (blue-500) 배경 + `{colors.text-alt}` (흰 텍스트). 화면당 단 하나의 가장 중요한 액션에만 사용된다. ### button-secondary `{colors.fill-secondary}` (grey-100) 배경 + `{colors.text-primary}` (grey-900) 텍스트. 같은 화면의 보조 액션을 표현할 때 사용된다. ### button-danger `{colors.fill-danger}` (red-500) 배경 + `{colors.text-alt}` 텍스트. 파괴적 액션 전용. ### button-ghost 투명 배경 + `{colors.text-brand}` (blue-500) 라벨, 보더 없음. 텍스트 링크에 가까운 약한 위계. ### bottom-cta 화면 최하단 고정 56pt 버튼. 좌우 16px padding, 24~32px의 `white → transparent` 보호 그라디언트가 위쪽에 적용되어 스크롤되는 콘텐츠와 시각적으로 충돌하지 않도록 한다. `env(safe-area-inset-*)`로 safe area를 자동 인식한다. ```tsx 다음 ``` ### text-field 48px height, `{rounded.radius-m}` (12) radius, `{colors.fill-secondary}` (grey-100) resting 배경, 1px `{colors.border-secondary}` (grey-200) 보더. focus 상태에서 흰 배경 + 1.5px `{colors.border-primary}` (blue-500) 보더로 전환된다. error 상태는 1.5px `{colors.fill-danger}` (red-500) 보더와 그 아래 `{colors.text-danger}` 컬러의 헬퍼 텍스트로 표현된다. ### chip 34px 높이의 full pill (`{rounded.radius-full}`). 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보다 작고 더 정보 밀도 높은 표면에 사용된다. 시맨틱 색에 매핑된 washed 배경과 페어링된다 (예: red badge는 옅은 분홍 배경 + `{colors.text-danger}` 텍스트; green badge는 옅은 민트 배경 + `{colors.green-500}` 텍스트). 핸드오프 번들의 `colors_and_type.css`는 시맨틱 base step(`red-500/600`, `green-500`)만 정의하고 badge 전용 washed 배경 step은 노출하지 않으므로, washed 톤은 base hue에서 lightness를 끌어올린 추정값으로 운용한다 — red badge ≈ `oklch(0.940 0.040 18)` (정식 토큰 없음, 추정). ### list-row 토스 홈·계좌 목록·거래 내역의 표준 단위. 좌우 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원`)로 표시된다. ```tsx } title="토스뱅크" subtitle="잔액" right={} /> ``` ### list-header list-row 그룹의 헤더 — 섹션 타이틀과 우측 액션 슬롯(예: "전체보기")을 함께 노출한다. ### tab-bar 미니앱의 floating tab-bar 변형 — 420px max-width, `{rounded.radius-3xl}` (24) radius, 흰 배경 + 1px `{colors.border-secondary}` 보더, 2~5개 destination [src:9]. active 아이콘은 filled 변형 + `{colors.text-primary}`, inactive는 outline + `{colors.text-tertiary}`다. ### top-app-bar 56pt 높이, 좌측 정렬 타이틀, 우측 옵션 아이콘 버튼 슬롯. ### toast `{colors.fill-primary}` (grey-900) 표면 + 흰 라벨, `{rounded.radius-l}` (14) radius, `{elevation.shadow-toast}`. 성공 아이콘은 20px `{colors.green-500}` 원 + 흰 체크다. ```tsx 송금이 완료되었어요 ``` ### dialog 흰 표면, `{rounded.radius-2xl}` (20) radius, 24px inner padding, `{elevation.shadow-3}`. 타이틀은 18/700, 본문은 15/400 `{colors.text-secondary}`, primary blue + secondary grey-100 CTA 두 개가 각 48px 높이로 stack된다. ```tsx ``` ### 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. yellow-faced 일러스트 글리프가 sheet 상단에 anchored되는 패턴이 빈번하다. ### keypad 전용 Figma 페이지 — 금액 입력과 PIN 입력에 사용되는 숫자 키패드. backdrop-filter blur는 iOS 네이티브 시트가 카메라/키패드 위에 떴을 때만 적용된다. ### loading 라벨이 0으로 페이드되고 같은 색의 3개 dot이 펄스하면서, 미세한 radial highlight가 버튼을 가로지른다. skeleton shimmer는 의도적으로 사용되지 않는다. ### menu trigger 위치에 즉시 펼쳐지는 셀렉터 컴포넌트 [src:4]. "버튼은 위에서 눌렀는데 응답이 하단 bottom sheet에서 오면 인지 부하가 커진다"는 문제 의식을 바탕으로 시각적 거리(physical distance)를 최적화한 컴포넌트다. 10일 A/B 테스트에서 Android item-click rate 10% 개선이 검증된 뒤 정식 채택되었다 [src:4]. ```tsx 정렬}> 최신순 가나다순 ``` ### icon TDS Icon system — outline (`*-mono`) + filled (`*-fill`) 두 종 변형, 16/20/24/32 사이즈, `currentColor` 상속. filled 변형은 active tab-bar 아이콘에만 사용된다. ### asset (Tossface illustration) `{colors.yellow-500}` body + `{colors.brown-900}`·`{colors.brown-700}` facial features의 평면 일러스트 자산 [src:7]. 빈 상태·성공 화면·bottom-sheet 헤더에 시각 자산 컴포넌트로 사용되며, 텍스트 inline에 emoji 대용으로 절대 사용되지 않는다. ### error-message-library 가이드라인이 아닌 **시스템 형태**의 에러 카피 인프라 [src:10]. 개발자용 라이브러리(코드 컴포넌트 검색 기반)와 디자이너용 프리셋 템플릿(Framering) 두 채널을 갖는다. 핵심 원칙은 **"Navigating error"** — 에러 메시지의 역할은 사용자를 다음 화면으로 옮겨주는 것이며 멈춰 세우는 것이 아니다 [src:10]. 토스가 잘못해 발생한 에러조차 해요체를 유지하며, 반복 시스템 상황은 템플릿화되어 좋은 카피가 기본 선택지가 된다 [src:10]. ### checkbox · switch checkbox는 22px 정사각 + 6px radius, resting은 1.5px `{colors.border-strong}` (grey-300) 보더 + 흰 배경, checked는 `{colors.fill-brand}` (blue-500) 배경 + 흰 체크 글리프로 flip된다. switch는 44×26px 트랙 + 20px 흰 knob, off는 `{colors.grey-300}` 트랙, on은 `{colors.fill-brand}` 트랙으로 전환되며 knob은 `{motion.dur-base}` (200ms) `{motion.ease}`로 18px translate된다. ### segmented-control 여러 옵션 중 하나를 고르는 분절형 컨트롤 [src:9]. 트랙은 `{colors.fill-secondary}` (grey-100) 배경 + `{rounded.radius-m}`~`radius-l` 라운드, 선택된 분절은 흰 배경 + `{elevation.shadow-1}`로 떠오르고, 미선택 라벨은 `{colors.text-secondary}`다. chip이 다중 필터라면 segmented-control은 상호 배타적 단일 선택이다. ### search-field `{component.text-field}`의 변형 — 좌측에 search 아이콘을 둔 48px 높이 입력, `{rounded.radius-m}` (12) radius, `{colors.fill-secondary}` (grey-100) resting 배경. focus 시 흰 배경 + 1.5px `{colors.border-primary}` (blue-500)로 전환되는 규칙은 text-field와 동일하다. ### slider 트랙 + thumb 단일 값 선택 컨트롤. 트랙은 `{colors.grey-200}` baseline 위에 `{colors.fill-brand}` (blue-500) active fill, thumb는 흰 원 + 미세한 그림자다. 값 변화는 `{motion.dur-base}` 안에서만 운용되고 바운스 오버슈트는 없다. ### rating 별점 표시·입력 컴포넌트. 채워진 별은 `{colors.yellow-500}`(일러스트 warm), 빈 별은 `{colors.grey-200}`이며, 반 칸(half) 상태를 지원한다. 숫자 평점은 `{typography.label-m}` Bold로 별 옆에 붙는다. ### progress-bar · progress-stepper progress-bar는 `{colors.grey-200}` 트랙 + `{colors.fill-brand}` (blue-500) fill의 선형 진행 표시이며, 우측에 `{typography.label-s}` tabular 퍼센트를 둔다. progress-stepper는 26px 원형 node를 segment로 연결한 다단계 표시로, 완료 node는 `{colors.fill-brand}` + 흰 체크, 현재 node는 `{colors.fill-brand}` + `{colors.blue-50}` 4px 글로우 링, 미도달 node는 `{colors.grey-200}` + `{colors.text-tertiary}`다. ### numeric-spinner · stepper numeric-spinner는 `− 값 +` 가로 캡슐(`{rounded.radius-full}` 보더 + 흰 배경)로 금액·수량 미세 조정에 쓰이며, 값은 tabular figure, ± 버튼은 `{colors.text-brand}` (blue-500)다. stepper는 같은 역할의 세로 변형(`▲ 값 ▼`)으로 `{rounded.radius-m}` 보더 컨테이너 안에서 값 행을 1px 헤어라인으로 분리한다. 비활성 버튼은 `{colors.text-placeholder}`로 흐려진다. ### tooltip · bubble tooltip은 `{colors.fill-primary}` (grey-900) 표면 + 흰 라벨 + caret을 가진 짧은 보조 설명으로 `{elevation.shadow-2}`를 쓴다. bubble은 채팅 말풍선으로, 상대 발화는 `{colors.grey-200}` 배경 + 좌하단 4px 꼬리(`radius 14/14/14/4`), 본인 발화는 `{colors.fill-brand}` (blue-500) 배경 + 흰 텍스트 + 우하단 4px 꼬리(`radius 14/14/4/14`)다. ### post · board-row · table-row · grid-list 피드·랭킹·표·격자 등 콘텐츠 표시 단위. post는 28px 아바타 + 작성자/시간 헤더 + `{typography.body-3}` 본문 + 반응 strip(♥·💬, active는 `{colors.text-brand}`)으로 구성된다. board-row는 순위 숫자(`{colors.text-brand}`, 1위는 `{colors.text-primary}`) + 36px 원형 아바타 + 우측 tabular 점수의 리더보드 행이다. table-row는 라벨/값/증감 3열을 1px `{colors.border-secondary}` 헤어라인으로 구분하며 수치는 tabular, 등락은 시맨틱 색을 쓴다. grid-list는 2열 격자에 흰 카드(`{rounded.radius-m}` + `{colors.blue-50}` 아이콘 칩)를 배치한다. ### bar-chart 막대형 데이터 시각화. 막대는 `{colors.grey-200}` 기본 + 강조 막대만 `{colors.fill-brand}` (blue-500)이며, 상단만 6px 라운드된다. **axis line·divider를 두지 않는다** — 막대가 차분한 표면 위에 그대로 떠 있는 것이 토스 차트의 규칙이다. ### bottom-info · list-footer bottom-info는 `{component.bottom-cta}` 위에 얹히는 보조 안내 — `{colors.blue-50}` 배경 + `{colors.text-brand}`의 full pill 칩으로 "수수료 없이 보내요" 같은 한 줄 컨텍스트를 전한다. list-footer는 목록 하단의 "더보기" 액션 행으로 44px 높이 + 1px `{colors.border-secondary}` 보더 + 우측 chevron(grey-400)을 둔다. ### result · text-button · icon-button · tab · navigation result는 성공/실패 종료 화면 — 중앙 정렬된 시맨틱 원형 아이콘(성공은 `{colors.green-500}`) + 타이틀 + 보조 카피 + yellow-faced 일러스트 anchor로 구성된다. text-button은 `{component.button-ghost}`에 가까운 보더 없는 텍스트 액션이며, icon-button은 40px 정사각 hit-area 안에 24px 아이콘만 둔 컨트롤이다. tab은 하단 2.5px `{colors.fill-brand}` 언더라인으로 활성 상태를 표시하는 인라인 탭(floating `{component.tab-bar}`와 구분된다). navigation(앱인토스)은 미니앱이 토스 셸 안에서 실행 중임을 알리는 상단 inset 바로, 호스트 표기에 토스 심볼을 작게 동반한다 [src:6]. ### Full component coverage (41 Figma pages) 새 번들 `project/preview/` 디렉터리는 Figma 46개 페이지 중 컴포넌트 페이지 41개를 1:1로 카드화한다. 위 prose 정의 12개는 가장 자주 인용되는 핵심 set이고, 아래 매트릭스는 전체 surface를 한 줄씩 노출한다 — 각 row의 `preview/*.html`은 production 토큰을 inline한 self-contained 데모이며, `Components.jsx` 컬럼은 새 번들의 `ui_kits/mobile/Components.jsx`에 live React 컴포넌트로 추출된 것을 표시한다. | Figma page | preview card | Components.jsx | |---|---|---| | Asset | `asset.html` | — | | Badge | `badge.html` | — | | Bar-Chart | `bar-chart.html` | — | | Board-Row | `board-row.html` | — | | Border | `border.html` | — | | Bottom-CTA | `bottom-cta.html` | ✅ `BottomCTA` | | Bottom-Info | `bottom-info.html` | — | | Bottom-Sheet | `bottom-sheet.html` | — | | Bubble | `bubble.html` | — | | Button | `buttons.html` | ✅ `TButton` | | Checkbox | `checkbox.html` | — | | Chip | `chip.html` | — | | Dialog | `dialog.html` | — | | Grid-List | `grid-list.html` | — | | Icon-Button | `icon-button.html` | — | | Keypad | `keypad.html` | (inline in AmountScreen) | | List-Footer | `list-header-footer.html` | — | | List-Header-V3 | `list-header-footer.html` | — | | List-Row | `list-rows.html` | ✅ `ListRow` | | Loader | `loader.html` | — | | Menu | `menu.html` | — | | Navigation---AppsinToss | `navigation-apps-in-toss.html` | — | | Numeric-Spinner | `numeric-spinner.html` | — | | Post | `post.html` | — | | Progress-Bar | `progress-bar.html` | — | | Progress-Stepper | `progress-stepper.html` | — | | Rating | `rating.html` | — | | Result | `result.html` | (inline in DoneScreen) | | Search-Field | `search-field.html` | — | | Segmented-Control | `segmented-control.html` | — | | Slider | `slider.html` | — | | Stepper | `stepper-spinner.html` | — | | Switch | `switch.html` | — | | Tab | `tab.html` | — | | Tab-Bar | `tab-bar.html` | ✅ `TabBar` | | Table-Row | `table-row.html` | — | | Text-Button | `text-button.html` | — | | Text-Field | `inputs.html` | ✅ `TextField` | | Toast | `toasts-dialogs.html` | ✅ `Toast` | | Tooltip | `tooltip.html` | — | | Top | `top.html` | ✅ `TopBar` | ### Live JSX kit & Send-Money click-through `ui_kits/mobile/Components.jsx`는 위 매트릭스 중 production 흐름에서 가장 자주 쓰이는 **7개**를 plain React 컴포넌트로 추출한다: `TopBar`(56pt 상단바), `BottomCTA`(56pt 하단 고정 액션 + 위쪽 보호 그라디언트), `TButton`(XL/L/M/S × primary/neutral/danger/ghost), `TextField`(48pt resting → focus 1.5px blue), `ListRow`(44pt 아바타 + amount 슬롯), `TabBar`(4-tab floating), `Toast`(grey-900 surface + green-500 check 아이콘). 모두 build 의존성 없이 `