---
name: arc-design
description: GroundBasic의 디자인 시스템 ARC로 리바운드(rebound-biz) 화면을 만들 때 쓰는 규칙. "ARC", "리바운드", "그라운드베이직", "디자인 시스템", "템플릿" 이라는 말이 나오거나 gb-design-7ob.pages.dev 주소가 주어지면 반드시 이 스킬을 적용한다. 화면·컴포넌트·페이지를 만들거나 고치는 모든 작업에 해당.
---

# ARC 디자인 시스템 · 구현 스킬

- 버전 1.1 · 2026-09-21 · 최신본: https://gb-design-7ob.pages.dev/skill/SKILL.md
- 문서: https://gb-design-7ob.pages.dev/docs.html · 토큰: https://gb-design-7ob.pages.dev/tokens/arc.json
- 작업을 시작하기 전에 위 최신본의 버전이 이 파일과 다르면, 최신본을 다시 읽고 그것을 따른다.

## 0. 이 스킬이 하는 일

리바운드는 채권자와 채무자가 상환 흐름을 함께 보는 B2B 제품이다. ARC는 그 제품의 색·글자·간격·컴포넌트 규칙이다. 이 스킬은 AI 코딩 도구가 새 화면을 만들 때 **디자이너가 옆에 앉아 있는 것처럼** 같은 규칙으로 만들게 한다. 규칙과 사용자의 요청이 부딪히면 임의로 절충하지 말고 **한 문장으로 물어보고** 진행한다.

## 1. 시작 절차

1. **템플릿 URL을 받았으면** 같은 주소에서 확장자만 `.md`로 바꿔 먼저 읽는다. 예) `…/templates/form-grid.html` → `…/templates/form-grid.md`.
   - 템플릿 갤러리(https://gb-design-7ob.pages.dev/templates/)는 **회사 번호로 잠겨 있다.** 저장소 안에 `design/templates/<이름>.md` 사본이 있으면 그것을 먼저 읽는다. 없으면 사용자에게 번호를 물어 `…/templates/<이름>.md?key=<번호>` 로 가져온다. 번호를 코드·커밋·로그에 남기지 않는다.
   - 둘 다 안 되면 `.html` 본문 텍스트를 쓴다.
2. 템플릿의 **화면 구조 표**(카드 개수, 섹션 구분, 주 CTA 위치, 폭)를 먼저 그대로 맞춘다. 사용자의 요청이 구조와 다르면 어디를 바꿀지 한 번 확인한다.
3. 그다음 **토큰**(3장)과 **컴포넌트**(6장)로 채운다. 토큰에 없는 색·간격·라운드를 새로 만들지 않는다.
4. 끝나면 **9장 체크리스트**로 스스로 점검하고, 어떤 컴포넌트와 토큰을 썼는지 세 줄로 요약한다.
5. 템플릿 없이 요청받았으면 가장 가까운 템플릿(목록 · 폼 · 폼+요약 · 대시보드 · 상세 · 온보딩 단계 · 결과 · 로그인)을 골라 그 구조를 따른다.

## 2. 절대 규칙 (어기면 다시 만든다)

- **오렌지(Primary #FF5900)는 한 화면에 한 곳.** 주 CTA, 활성 내비 항목, 진행 표시, 날짜 선택에만. 강조·아이콘·배지 색으로 쓰지 않는다.
- **입력·선택은 파랑(Information #2768FF).** 필드 포커스 테두리, 체크박스·라디오·스위치 켜짐, 표의 선택 행 틴트. 오렌지 체크박스 금지.
- **카드는 흰 면, 테두리·그림자 없음, radius 12.** 회색 페이지(#F0F1F3) 위에 놓여 대비로 구분한다. 흰 배경 위에 놓일 때만 `shadow-card`. 카드 안에 카드 금지 → 회색 블록(#F7F8FA).
- **버튼 기본은 회색 Neutral(#F0F0F0).** Primary는 주 행동 하나. 검정 버튼 금지, 테두리(outline) 버튼 금지, CTA 안에 아이콘 금지. 답이 하나뿐인 대화상자는 Primary 글자 버튼(채움 없음).
- **라운드는 8(버튼·필드) / 12(카드·표·모달) / 16(메뉴·바텀시트) / 6(배지·툴팁).** 다른 값 금지.
- **글꼴은 Pretendard 한 벌.** 숫자·금액은 `tabular-nums`. 라임(#C7F64F)과 민트는 글자에 쓰지 않는다.
- **표는 전부 왼쪽 정렬**, 머리글 회색 띠(#F0F0F0), 세로선·줄무늬 금지, 마지막 행 아래선 없음.
- **포커스 링·글로우 금지.** 테두리 색만 바뀐다. 그림자는 Elevation 토큰 셋(card · dropdown · modal)만.
- **문구는 "~해요"체, 과거형 결과("저장했어요"), 다음 행동을 말한다.** "성공적으로", "유효하지 않은 값", "예/아니오", 느낌표 금지. 취소 버튼 라벨은 늘 "취소".

## 3. 토큰

CSS 변수: https://gb-design-7ob.pages.dev/tokens/arc.css · Tailwind 프리셋: https://gb-design-7ob.pages.dev/tokens/tailwind.preset.js

| 뜻 | 값 | Tailwind | 쓰는 곳 |
|---|---|---|---|
| Primary/Normal | #FF5900 | `bg-primary` `text-primary` | 주 CTA, 활성 내비, 진행 |
| Primary/Strong · Heavy | #E14E00 · #AD3A00 | `primary-strong` `primary-heavy` | hover · pressed |
| Information (포커스·선택) | #2768FF | `border-info` `bg-info` `text-info` | 포커스, 체크, 스위치, 선택 행 6% |
| Success · Warning · Danger | #008A1E · #FFB724 · #EB003B | `success` `warning` `danger` | 상태 배지 점, 결과, 오류 |
| Label/Title | #1D1D1D | `text-label-title` | 제목, 값, 입력 글 |
| Label/Body | #555555 | `text-label-body` | 본문, 표 셀 |
| Label/Alternative | #8E8E8E | `text-label-alt` | 도움말, 머리글, 플레이스홀더 |
| Label/Disable | #C6C6C6 | `text-label-disable` | 비활성 글 |
| Fill/Normal · Strong | #F0F0F0 · #E4E4E4 | `bg-fill` `bg-fill-strong` | Neutral 버튼, 호버, 트랙 |
| Line/Normal · Strong · Alternative | #E4E4E4 · #C6C6C6 · #F0F0F0 | `border-line` `border-line-strong` `border-line-alt` | 필드 테두리, 체크박스 선, 행 구분선 |
| Background/Normal · Alternative · Page | #FFFFFF · #F7F8FA · #F0F1F3 | `bg-white` `bg-bg-alt` `bg-bg-page` | 카드, 회색 블록·호버 행, 페이지 |
| Scrim | rgba(22,22,22,.4) | `bg-black/40` | 모달 뒤 |

간격 스케일: 2 · 4 · 6 · 8 · 12 · 16 · 20 · 24 · 32 · 40 · 48 · 64. 자주 쓰는 값 — 라벨→필드 6, 필드→도움말 6, 필드 사이 20, 카드 안쪽 24(KPI·선택 카드 20), 카드 사이 16, 섹션 사이 32, 페이지 안쪽 40 32.

라운드: 6 · 8 · 12 · 16 · full. 그림자: `shadow-card` `shadow-dropdown` `shadow-modal`. 모션: 0.15s(호버) · 0.2s(색·펼침) · 0.25~0.3s(이동·전환), `cubic-bezier(.4,0,.2,1)`. 무한 반복 애니메이션은 스피너·스켈레톤만.

## 4. 글자

Pretendard. 계열 + 크기로만 부른다.

| 이름 | 크기(데스크톱/태블릿/모바일) | 굵기 | 행간 | 쓰는 곳 |
|---|---|---|---|---|
| Display L·M·S | 64/48/36 · 56/40/32 · 48/36/28 | 700 | 125% | 히어로, 큰 섹션 제목, 결과 화면 |
| Title L·M·S | 36/28/24 · 24/22/20 · 20/18/18 | 700 | 140% | 페이지 제목 · 카드/모달 제목 · 작은 카드 제목 |
| Body L·M | 18/16/16 · 16/14/14 | 400 | 180% | 본문 · 표 본문 |
| Label L·M·S | 18/16/16 · 16/14/14 · 14/12/12 | 400(버튼 600~700) | 24/24/20px | 버튼·탭·필드 라벨 · 배지·머리글 |
| Caption | 14/12/12 | 400 | 16px | 도움말, 메타 |

숫자·금액·날짜는 tabular. 금액은 천 단위 콤마 + 단위는 머리글이나 뒤 단위(원). 날짜는 `2026.09.25`, 시각은 `09:30` 24시간.

## 5. 레이아웃

- 데스크톱: 왼쪽 사이드바 256(흰 면, 오른쪽 Line/Alternative), 위 헤더 64(sticky, 반투명 blur), 콘텐츠 회색 페이지(#F0F1F3) 안쪽 40 32, 최대 1280. 최소 폭 1080 아래는 모바일 구조(바닥 탭).
- 콘텐츠는 **회색 페이지 위 흰 카드**. KPI는 3열 그리드 gap 16, 그 아래 표 카드는 폭 100%.
- 폼은 한 열, 최대 폭 480(카드 안). 짝인 값(시작일·종료일)만 2열 gap 12. 버튼은 맨 아래 오른쫁: 취소(Neutral) → 주 행동(Primary).
- 표는 카드(radius 12, overflow hidden) 안에, 도구 줄(검색 · 필터)은 표 위, 페이지네이션은 표 아래 가운데.
- 모바일 640 미만: 카드 좌우 16, 필드 16px, 모달은 Bottom sheet, CTA는 바닥 고정.

## 6. 컴포넌트 (29) — 이름 · 쓸 때 · 핵심 규칙 · 문서

문서 기본 주소 `https://gb-design-7ob.pages.dev/docs.html#/components/`. 코드에서는 `src/components/ui/<Name>.tsx`가 있으면 그것을 쓰고, 없으면 아래 클래스 규칙으로 만든 뒤 재사용한다. 화면마다 스타일을 복사하지 않는다.

**Actions**
- **Button** `button` — 변형 `neutral`(기본) · `primary`(화면에 하나) · `ghost` · `danger`. 크기 sm 32 / md 36 / lg 48. 아이콘은 라벨 앞에만, 로딩은 스피너 + 라벨 유지.
- **Icon button** `icon-button` — 32 정사각 Ghost, `aria-label` 필수 + Tooltip. 더보기(⋯)는 Menu를 연다.

**Data Display**
- **Badge** `badge` — Status(점 6 + 글, 기본) · Tinted(톤 10% 채움, 카드 제목 옆 셋 이하) · Solid(어두운 면 위만) · Count(오렌지 알약, 내비·탭·아이콘 버튼에만). 톤: success · warning · danger · info · brand · neutral.
- **Board row** `board-row` — 공지·문의·알림 목록 한 줄. 안 읽음 점, 제목 15 600, 설명 13, 메타, chevron. 숫자 열이 둘 넘으면 Table.
- **Card** `card` — 흰 면 radius 12 안쪽 24. KPI(안쪽 20, 값 26 tabular) · Selectable(회색 채움 → 고르면 오렌지 테두리) · Elevated(흰 배경 위만).
- **Table** `table` — 머리글 44 회색 띠, 행 48(S 40), 전부 왼쪽, 숫자 tabular 600. Row link(호버 + chevron) · Selectable(파란 체크) · Summary. 20건 넘으면 Pagination. 결과 없으면 표 안에 한 문장 + 버튼.

**Inputs**
- **Form** `form` — 라벨 위 13 600, 필드 40, 도움말 12 아래 6. 오류는 떠날 때(blur), 도움말 자리에 대신. 필수 표시 없이 선택만 (선택).
- **Text field** `textfield` — Affix(₩ · 원 · %) · Leading icon · Clearable · Action(옆 Neutral 버튼) · Password(눈). 오른쪽 자리는 지우기/상태 아이콘/뒤 단위 중 하나. 아이디 중복은 입력 멈춘 뒤 500ms 서버 확인(스피너 → 초록 체크/빨간 X), 비밀번호 규칙은 체크리스트(빨강 없음).
- **Textarea** `textarea` — 손잡이 없음. 시작 줄(Short 2 · Default 3 · Long 6)에서 글에 맞춰 최대 줄(4 · 8 · 12)까지 자동, 그 뒤 스크롤. 제한 있으면 글자 수 오른쪽 아래.
- **Checkbox** `checkbox` — 16 radius 4 선 1px, 켜지면 파랑. 저장 버튼과 함께 쓰는 선택. 전체 선택은 indeterminate.
- **Radio** `radio` — 16 원, 고르면 파랑 링 5. 2~5개, 여섯 넘으면 Select. 켜기/끄기는 Switch.
- **Switch** `switch` — 44×24, 켜짐 파랑. 누르는 즉시 저장되는 설정에만.
- **Search field** `search` — 회색 채움 + 검색 아이콘 + 지우기, 검색 버튼 없이 300ms 자동, URL `?q=`.
- **Date picker** `datepicker` — 달력 아이콘 트리거, 한 달 격자, 오늘 점, 고른 날 오렌지, 범위는 옅은 오렌지. 값 `YYYY.MM.DD`. 네이티브 date 금지.
- **Time picker** `timepicker` — 시계 아이콘 트리거, 시·분 두 열(분 5 단위), `HH:MM`.
- **Select** (Form 안) — 브라우저 기본 목록 금지. 트리거는 Text 필드 + chevron, 메뉴 radius 14, 항목 40, 고른 항목 600 + 체크.

**Feedback**
- **Modal** `modal` — Dialog 448 · Sheet 560(머리·발 고정, 몸통 스크롤) · 모바일 Bottom sheet. 머리 24 24 8, 발 20 24 24, 취소 Neutral → 주 행동. ESC·스크림으로 닫힘. 모달 위에 모달 금지(Alert만 예외).
- **Alert** `alert` — 폭 360 확인 대화상자. 제목은 질문, 버튼은 행동 이름. Confirm(취소+Primary) · Destructive(취소+Danger, 포커스는 취소) · Acknowledge(Primary 글자 버튼 하나). 스크림 클릭으로 닫히지 않음.
- **Banner** `banner` — 화면에 남는 알림 띠(톤 8% 채움). info·success는 닫기 가능, warning·danger는 해결되면 사라짐. 한 영역에 하나.
- **Toast** `toast` — 화면 아래 가운데 바닥 32, 어두운 반투명, 3초(행동 있으면 5초), 한 번에 하나. 고쳐야 할 오류는 Toast 금지.
- **Tooltip** `tooltip` — #555 말풍선 12px, 최대 240, 호버 300ms 뒤. 필수 정보·링크 금지.
- **Result** `result` — 흐름의 끝과 대체 화면. 톤 색 원 64 + 흰 아이콘 30, 제목 22, 설명 15(폭 340), 버튼 Neutral + Ghost 나란히. 오렌지 없음. Success · Failure · Pending · Empty · Error · No access.

**Loading**
- **Loading** `loading` — 스피너 16/20/32, 300ms 지연 후 표시. 버튼 안에서는 라벨 "~하는 중" + 다른 버튼 비활성.
- **Skeleton** `skeleton` — 구조를 아는 목록·카드·표는 스피너 대신 스켈레톤. 글 줄 높이 = 글자 − 4, 폭 40·60·90%만, shimmer 1.6s, 최대 5행. 스피너와 같이 쓰지 않는다.

**Navigation**
- **Navigation** `navigation` — 사이드바 256, 항목 38, 활성은 오렌지 글자+아이콘 + Fill/Normal 배경(채움 금지). 잠긴 항목 opacity .4 + Tooltip. 모바일 바닥 탭 다섯까지.
- **Menu** `menu` — 트리거 아래 6, radius 16 안쪽 8, 항목 44 radius 10, 위험 항목은 구분선 아래 맨 끝 Danger. 체크 메뉴는 왼쪽 체크 + 오렌지 글자.
- **Pagination** `pagination` — 32 Ghost 번호 다섯 + 말줄임 + 화살표 아이콘, 현재만 Primary, 표 아래 가운데, `?page=`.
- **Segmented control** `segmented` — 회색 트랙 안 흰 판이 0.25s 미끄러짐. 2~5조각, 같은 데이터를 다르게 볼 때. 페이지 이동은 Tabs/Navigation.
- **Stepper** `stepper` — Line(트랙 12, 옅은 오렌지 채움 그라데이션, 지금 점 14 + 링) · Pill · Vertical · List. 3~5단계, 라벨 명사 2~4자.

## 7. 코드 관습 (rebound-biz)

- React + TypeScript + Tailwind + lucide-react. 새 스타일은 클래스 조각 복사가 아니라 `src/components/ui/`의 공용 컴포넌트에 넣고 재사용한다.
- Tailwind 색 이름은 3장 표의 이름을 쓴다(`primary`, `info`, `label-title`, `fill`, `line`, `bg-alt`). 헥사 직접 쓰기 금지.
- 기존 `.btn-primary .btn-outline .btn-ghost .card .kpi-card .badge-* .table-wrapper .th .td .input`은 유지되지만, 새 화면은 위 규칙(Neutral 기본, outline 금지, 표 왼쪽 정렬, 회색 머리글)으로 만든다. `.btn-outline`은 쓰지 않는다.
- 아이콘은 lucide 16(필드·배지) / 18(아이콘 버튼) / 20(헤더), stroke 2.
- 접근성: 아이콘 버튼 `aria-label`, 모달 `role=dialog aria-modal`, 알림 `role=status|alert`, 스위치 `role=switch aria-checked`, 폼 오류 `aria-invalid + aria-describedby`.
- 문자열은 한국어 "~해요"체. 날짜·금액 형식은 4장.

## 8. 물어봐야 하는 순간

- 템플릿 구조와 요청이 다를 때(카드 개수, CTA 위치, 열 수).
- 오렌지를 두 곳 이상 쓰게 될 때 → 어느 하나가 주 행동인지 묻는다.
- 새 컴포넌트가 필요할 때 → 가장 가까운 기존 컴포넌트를 제안하고 확인 받는다.
- 되돌릴 수 없는 행동(삭제·해지)이 흐름에 있을 때 → Alert Destructive를 넣을지 확인.

## 9. 끝내기 전 체크리스트

- [ ] 오렌지가 한 화면에 한 곳(활성 내비 제외)인가
- [ ] 포커스·체크·라디오·스위치·선택 행이 파랑인가
- [ ] 카드에 테두리·그림자가 없고 radius 12, 회색 페이지 위인가
- [ ] 버튼 기본이 Neutral이고 outline·검정 버튼이 없는가. 취소가 왼쪽인가
- [ ] 표가 전부 왼쪽 정렬, 회색 머리글, 세로선 없음인가
- [ ] 라운드가 6/8/12/16 중 하나인가. 그림자가 토큰 셋 중 하나인가
- [ ] 글자 크기가 4장의 계열 안에 있고 숫자는 tabular인가
- [ ] 문구가 "~해요"체이고 오류 문구가 고치는 법을 말하는가
- [ ] 필드 오류는 blur, 서버 확인은 500ms, 성공 알림은 Toast인가
- [ ] 아이콘 버튼 aria-label, 모달 ESC·포커스 트랩이 있는가
