크기
크기는 Senco 컴포넌트의 고정 치수, 컨테이너 폭, 화면비, 터치 타깃을 정한다.
간격이 요소 사이의 틈을 다룬다면, 크기는 요소 자체를 다룬다. 이 제품에서 가장 중요한 규칙은 두 가지다. 흔들리는 버스 안에서도 엄지로 컨트롤을 누를 수 있어야 하고, 고정 높이 때문에 번역된 라벨이 잘리는 일이 있어서는 안 된다.
컴포넌트 치수
Senco 핵심 컴포넌트의 고정 높이다.
| Component | Token | Height | Notes |
|---|---|---|---|
| App bar | --ds-size-appbar | 48px | 고정. 브랜드와 액션 아이콘이 들어간다 |
| List item | --ds-size-list-item | 60px | Avatar(36px) + 위아래 12px 패딩 |
| Bottom nav | --ds-size-bottomnav | 52px | 아이콘(20px) + 라벨 + 패딩 |
| Avatar | --ds-size-avatar | 36px | 수취인 이니셜, 원형 |
| Input | --ds-input-height | 48px | 기본 컨트롤 높이 |
| Input (dense) | --ds-input-height-sm | 36px | 필터 바, 인라인 편집용. 주요 필드에는 쓰지 않는다 |
| Touch target | --ds-size-touch | 48px | 탭할 수 있는 최소 영역 |
아이콘 크기
| Token | Size | Pairs with |
|---|---|---|
--ds-size-icon-sm | 16px | --ds-text-sm 이하. 문장 안 아이콘 |
--ds-size-icon | 20px | --ds-text-base. 내비게이션·액션 아이콘 |
--ds-size-icon-lg | 24px | 단독 아이콘, 빈 상태 마크, App bar |
아이콘 크기는 남는 공간이 아니라 옆에 놓인 글자 크기에 맞춘다. 14px 글자 옆에 24px 아이콘을 두면 아이콘만 튀고, 18px 글자 옆에 16px 아이콘을 두면 아이콘이 묻힌다. 아이콘을 단독으로 쓸 때는 대신 터치 타깃에 맞춘다. 48px 터치 영역 가운데에 20px 아이콘을 두는 식이다.
아이콘 세트
아이콘은 lucide-react(1.x)만 쓴다. 다른 아이콘 소스는 쓰지 않는다. 국기는 아이콘이 아니라 이미지로 다룬다.
| Rule | Value |
|---|---|
| 크기 | --ds-size-icon-sm / --ds-size-icon / --ds-size-icon-lg를 size로 넘긴다 |
| 선 굵기 | 라이브러리 기본값(2). 개별 인스턴스에서 바꾸지 않는다 |
| 색 | currentColor. 스펙에서 아이콘 토큰을 지정한 경우만 예외 |
| 텍스트 라벨 옆 | aria-hidden="true" |
| 단독 사용 | 접근 가능한 이름은 컨트롤에 주고, 아이콘은 aria-hidden으로 둔다 |
기준 매핑이다. 스펙에서 아래 의미를 쓸 때는 이 아이콘을 쓴다. 새로운 의미가 필요하면 쓰기 전에 먼저 여기에 추가한다.
| Meaning | lucide export |
|---|---|
| Pending | Clock |
| Processing, 로딩 스피너 | LoaderCircle |
| Sent | ArrowUpRight |
| Completed, 선택됨, 성공 | Check |
| Failed, 주의, 크립토 위험 | TriangleAlert |
| 에러 노트 | CircleX |
| Cancelled, 닫기, 제거 | X |
| 정보 | Info |
| 팁 | Lightbulb |
| 규제 고지 | ShieldCheck |
| 생체 인증 고지 | Fingerprint |
| 외부 링크 | ExternalLink |
| 펼치기, 드롭다운 | ChevronDown |
| 앞으로, 상세로 들어가기 | ChevronRight |
| 검색 | Search |
| 추가 | Plus |
| 다시 시도 | RotateCw |
| 비밀번호 보기 / 숨기기 | Eye / EyeOff |
| 업로드 | Upload |
| 다운로드 | Download |
| 공유 | Share |
| 날짜 | Calendar |
| 카메라 촬영 | Camera |
| QR 스캔 | ScanLine |
| 직접 입력 | Keyboard |
Check는 "완료"와 "선택됨"을 둘 다 뜻한다. 둘 다 "끝났는가"에 대한 답이고, 체크 모양을 두 가지로 나누면 사용자가 거의 똑같은 글리프 두 개를 비교해야 한다.
높이는 고정값이 아니라 최솟값이다
위 표의 높이는 모두 min-height다. Senco는 여러 언어로 출시되는데, 독일어나 타갈로그어 라벨은 영어보다 30–40% 긴 경우가 흔하다. 버튼에 height를 고정하면 텍스트가 잘리고, min-height를 쓰면 버튼이 두 줄이 된다. 깔끔하지만 깨진 버튼보다, 보기엔 덜 예뻐도 읽히는 버튼이 낫다.
높이가 진짜로 고정인 건 App bar와 Bottom nav뿐이다. 둘은 화면 크롬이라 줄바꿈될 콘텐츠가 없다.
목록 항목을 60px로 둔 이유
거래 행에는 36px 아바타, 텍스트 두 줄, 금액이 들어간다. 56px이면 텍스트 두 줄이 행 가장자리에 닿고, 64px이면 모바일 화면에 거래가 여섯 개가 아니라 다섯 개만 보인다. 60px은 36 + 12 + 12, 즉 아바타에 위아래 space-3을 더한 값이다. 임의로 고른 숫자가 아니라 스케일에서 나온 숫자다.
48px radio cards + 48px CTA. Every target is comfortable to tap.
Cramped 28px controls. Users struggle to select the right option or hit the button accurately.
컨테이너 크기
컨테이너는 콘텐츠 폭을 제한한다.
| Token | Max width | Usage |
|---|---|---|
--ds-container-xs | 320px | 모바일 폼, 모달 |
--ds-container-sm | 480px | 좁은 콘텐츠, 송금 플로우 |
--ds-container-md | 640px | 기본 콘텐츠 폭 |
--ds-container-lg | 960px | 대시보드, 넓은 레이아웃 |
--ds-container-xl | 1200px | 전체 폭 데스크톱 |
--ds-container-max | 1400px | 페이지 최대 폭 |
송금 플로우를 480px로 제한한 이유
송금 플로우는 한 열로 이어지는 결정의 연속이다. 640px로 넓히면 아무 순서로나 채워도 되는 폼처럼 보이고, 사용자는 한 단계씩 진행하지 않고 훑어보기 시작한다. 480px은 대략 휴대폰 한 대 폭이라, 데스크톱에서도 모바일과 같은 모양을 유지한다. 대부분의 사용자가 같은 송금을 양쪽에서 하기 때문에 이 점이 중요하다.
한 줄 길이
본문은 한 줄에 45–75자를 목표로 한다. 시스템 폰트 16px 기준으로 대략 480px에서 720px 사이다. 그래서 콘텐츠 기본 폭은 container-md(640px)이고, container-lg는 긴 글이 아니라 여러 열로 나뉘는 레이아웃에만 쓴다.
화면비
이미지, 카드, 미디어 컨테이너에 일관되게 쓰는 비율이다.
| Ratio | Usage |
|---|---|
| 16:9 | 히어로 배너, 프로모션 카드 |
| 3:2 | 거래 카드, 상세 이미지 |
| 4:3 | 썸네일, 작은 미디어 |
| 1:1 | 아바타, 프로필 이미지 |
| 3:4 | 신분증 업로드 |
3:4는 신분증 때문에 따로 둔 비율이다. 여권 사진면과 국가 신분증은 어떤 가로 비율보다 세로에 가깝다. 촬영 프레임이 문서 모양과 맞지 않으면 인증 단계에서 업로드가 반려된다.
터치 타깃
- 최소 크기: 48 × 48px (
--ds-size-touch) - 타깃 사이 최소 간격: 8px (
space-2) - 아이콘이나 버튼 같은 시각 요소는 48px보다 작아도 되지만, 탭 영역은 그러면 안 된다
- 터치 입력을 받는 모든 기기에 적용한다
기준
| Criterion | Requirement | Senco |
|---|---|---|
| WCAG 2.2 SC 2.5.8 Target Size (Minimum), AA | 24 × 24px | 기준보다 큼 |
| WCAG 2.1 SC 2.5.5 Target Size, AAA | 44 × 44px | 기준보다 큼 |
| Senco 기준 | — | 48 × 48px |
48px은 일부러 모든 기준보다 크게 잡았다. AA 최소치 24px은 어떤 인터페이스에나 적용되는 최소한의 기준이다. 걸으면서 엄지로 누르는 송금 확인 버튼까지 염두에 둔 기준은 아니다. 이 제품에서 잘못 누르면 송금이 엉뚱한 곳으로 간다.
시각 요소는 그대로 두고 타깃만 넓힌다
20px 아이콘 버튼은 아이콘을 20px 그대로 두고, 글리프를 키우는 대신 패딩으로 터치 영역을 확보한다.
visual 20px icon
padding 14px each side
target 48 × 48px
빽빽한 테이블 행의 액션처럼 레이아웃에 공간이 부족한 곳에서는, 상자를 키우지 않고 의사 요소를 덮어 타깃을 넓힌다.
권장과 금지
| Do | Don't |
|---|---|
| Give every icon button a 48px hit area | Ship a 24px icon with a 24px target |
Use min-height on controls | Use height and let a long label clip |
| Keep 8px between adjacent targets | Butt two destructive actions against each other |
| Size icons to their text | Size icons to fill the space available |
| Cap the transfer flow at 480px | Let the flow stretch to the viewport on desktop |
알려진 공백
| Item | Status |
|---|---|
| Dense 컨트롤 높이(36px) | 48px 터치 기준 미달. 포인터 위주 화면에서만 허용하며, 컴포넌트별로 문서화 안 됨 |
--ds-size-touch 강제 | 관례일 뿐. 검증하는 lint 규칙이나 테스트가 없음 |
| 화면비 토큰 | 비율은 문서화했지만 --ds- 변수로 정의하지 않음 |