디자인 SSOT와 하네스 한눈에 보기
디자인 시스템 문서에는 무엇을 두고, 하네스 규칙은 그것을 어떻게 가리키고 지키는지 한 번에 정리했습니다. 값은 한 곳에 두고, 나머지는 가리키고, 검사가 지킵니다.
디자인 시스템 문서만으로 화면을 뽑으면 나중에 그 문서를 고칠 일이 제일 신경 쓰입니다. 기본 서체 하나 바꿨다가 작업 규칙 파일마다 복사된 줄 때문에 열 군데 넘게 고친 적이 있는데, 하네스 문서에도 디자인 시스템 내용을 옮겨 적어 두셨나요?
- 값(색·간격·서체)은 토큰 파일
theme.css한 곳에만 둡니다. 화면 코드는var()로, 하네스 규칙은 경로로 그 자리를 가리킵니다. - 하네스 규칙은 값을 옮겨 적지 않고 판정 기준과 금지 목록만 가집니다.
- 배포 CI의 디자인 검사(
lint:design)가 새 위반을 막습니다. 기존 위반은 기준선에 고정합니다.
0한눈에
디자인 값(색·간격·서체)은 토큰 파일 한 곳에만 둡니다. 화면 코드는
var()로, 하네스 규칙 문서는 경로로 그 자리를 가리킵니다.
하네스는 값이 아니라 판정 기준과 금지 목록을 갖고, 배포 CI가 새 위반을
막습니다. 그래서 서체를 바꿀 때 고칠 곳은 한 곳입니다.
Mermaid 소스 보기
flowchart TD T["토큰 파일 theme.css<br/>:root 의 변수 = 정본"] C["화면 코드<br/>var(--변수)로 참조"] R["하네스 규칙 문서<br/>정본 경로 + 판정 기준 + 금지 목록"] S["화면 계약<br/>시각 값의 주인 선언"] G["디자인 검사 lint:design<br/>새 위반만 차단"] CI["배포 CI<br/>검사 실패 시 빌드 중단"] T -->|값을 가져옴| C R -.->|경로로 가리킴| T R -->|판정 기준 제공| S S -->|"contract: 토큰을 따름"| C C --> G --> CI
| 질문 | 답 |
|---|---|
| 값은 어디에 있나요? | 토큰 파일(src/styles/theme.css)의 :root 한
곳. 다크 모드는 .dark가 덮어씁니다 |
| 화면은 값을 어떻게 쓰나요? | 값을 복사하지 않고 var(--변수)로 참조합니다 |
| 하네스 규칙에는 무엇이 있나요? | 정본 경로, 판정 기준, 금지 목록. 값 자체는 없습니다 |
| 누가 막나요? | 수정 루프와 배포 CI가 디자인 검사(lint:design)로 새
위반을 차단합니다 |
1디자인 SSOT: 값은 한 곳에
요점 값은 토큰 파일 한 곳에만 두고, 화면과 문서는 모두 그 자리를 가리킵니다.
SSOT는 "같은 값은 한 곳에만 적고, 나머지는 그 자리를 가리킨다"는 원칙입니다. 값이 두 곳에 있으면 한쪽만 고쳐지는 순간 둘이 어긋나고, 어느 쪽이 맞는지 판단할 근거가 사라집니다.
1-1. 정본의 실제 모습
제품 저장소의 토큰 파일이 정본입니다. 기본값은 :root에
모이고, 다크 모드는 .dark가 필요한 값만 덮어씁니다.
/* src/styles/theme.css: 정본 */
:root {
--primary: #22304a;
--bis-gap: 12px;
--foundation-font-family-sans:
"Pretendard Variable", "Pretendard", -apple-system, sans-serif;
}/* 화면 쪽: 값을 복사하지 않고 가리킨다 */
.title {
font-family: var(--foundation-font-family-sans);
}1-2. 한 줄을 바꾸면 무엇이 따라오나
| 바꾸는 변수 | 따라 바뀌는 곳 | 바꾸지 않아도 되는 곳 |
|---|---|---|
--primary |
주요 버튼, 강조색을 쓰는 모든 화면 | 하네스 규칙 문서, 화면 코드 |
--bis-gap |
카드와 블록 사이 여백 | 하네스 규칙 문서, 화면 코드 |
--foundation-font-family-sans |
제목과 본문 글꼴 | 하네스 규칙 문서, 화면 코드 |
단, 화면 계약에서 "목업이 시각 값을 정한다"고 선언한 화면은 따라오지 않습니다. 이 선언은 3절에서 설명합니다.
1-3. 디자인 시스템 4층
값은 토큰 층에 있고, 위 층으로 갈수록 업무에 가까운 결정이 쌓입니다. 층마다 기준을 두는 곳이 다릅니다.
| 층 | 정의하는 것 | 기준을 두는 곳 |
|---|---|---|
| 01 토큰 | 색, 글자, 간격, 반경 등 반복되는 표현 값 | 토큰 파일 · 테마 |
| 02 컴포넌트 | 버튼·필터·테이블·상태 배지의 속성과 상태 | 컴포넌트 코드 · 사용 문서 |
| 03 업무 패턴 | 사용자가 업무를 마치는 화면 구성과 순서 | 패턴 문서 · 대표 화면 |
| 04 화면 계약 | 그 페이지의 정보·상태·동작·수용 기준 | 화면 명세 · 시나리오 |
권한과 승인 조건 같은 업무 규칙의 정본은 그 업무의 명세에 둡니다. 디자인 시스템은 그것을 화면에 어떻게 표현할지만 연결합니다.
2문서마다 담는 것
요점 문서마다 소유하는 것이 다릅니다. 다른 문서의 것은 옮겨 적지 않고 가리킵니다.
문서마다 소유하는 것이 다릅니다. 한 문서가 다른 문서의 소유물을 옮겨 적기 시작하면 사본이 생깁니다.
| 문서 | 담는 것 | 담지 않는 것 |
|---|---|---|
| 토큰 파일 (theme.css) | 색·간격·서체·반경·그림자 값, 다크 모드 덮어쓰기 | 쓰임새 설명, 금지 목록 |
| 디자인 시스템 문서 | 4층 구성, 컴포넌트 사용법, 업무 패턴, 화면 규칙(그리드·헤더·차트·문구) | 토큰 값 자체 (토큰 파일 경로와 변수 이름만) |
| 하네스 규칙 (스킬·기준서) | 정본 포인터, 판정 축, 금지 목록, 강도 구분, 반복 지적을 규칙으로 올리는 절차 | 토큰 값, 화면 규칙 원문 (요지와 경로만) |
| 화면 계약 (프로토타입·명세) | 화면·구역 식별, 상태, 동작 의도, 데이터 의도, 시각 값의 주인 선언 | 공통 토큰 재정의 |
| 검사 스크립트 | 기계로 판정할 수 있는 금지 패턴 (하드코딩 색, 과한 반경 등) | 취향 판단 |
Mermaid 소스 보기
flowchart TD
subgraph OWN["각자 소유"]
T2["토큰 파일<br/>값"]
D2["디자인 시스템 문서<br/>구성 · 사용법 · 패턴"]
H2["하네스 규칙<br/>판정 축 · 금지 목록"]
L2["검사 스크립트<br/>기계 판정 규칙"]
end
D2 -.->|변수 이름만 인용| T2
H2 -.->|경로로 가리킴| T2
H2 -.->|경로로 가리킴| D2
H2 -->|판정 가능한 금지만 옮김| L2규칙 문서에 서체를 적어야 할 때는 Pretendard처럼 값을
쓰지 말고 --foundation-font-family-sans처럼 변수 이름을
씁니다. 값이 바뀌어도 이름은 그대로라 문서를 고칠 일이 없습니다.
3하네스 규칙은 이렇게 처리합니다
요점 하네스 기준서는 값이 아니라 판정 기준을 가집니다. 시각 값의 주인은 화면마다 선언합니다.
3-1. 기준서는 포인터와 판정 축만 소유합니다
디자인 기준서(하네스 스킬)는 첫머리에 "값의 정본을 복제하지 않고 포인터로 연결한다"고 적어 둡니다. 기준서와 정본이 충돌하면 정본이 이깁니다.
| 정본 | 위치 | 기준서가 하는 일 |
|---|---|---|
| 화면 규칙 RULE 1~17 | 제품 저장소 CLAUDE.md |
요지만 인용하고 경로를 둡니다 |
| 디자인 토큰 | 제품 저장소 theme.css |
경로만 둡니다 |
| 시안 저작 규율 | 프로토타입 작성 스킬 | 경로만 둡니다 |
| 판정 축 · 금지 목록 | 기준서 본문 | 직접 소유합니다 (박스 남발, 보더 과잉, 균등 나열 등) |
3-2. 지키는 강도는 세 단계입니다
프로토타입 작성 스킬이 강도를 나눕니다. 디자인 시스템이 아직 확정 전이라, 토큰과 맞는지는 막지 않고 참고로만 봅니다.
| 강도 | 대상 | 처리 |
|---|---|---|
| 항상 적용 | AI 티 나는 패턴 (이모지 UI, 컬러 바 알림, 한글 필수 CSS, 접근성) | 모든 산출물에서 제거 |
| 참고만 | 토큰 값·12그리드·밀도와 맞는지 | "차이 있음"으로 기록, 위반으로 치지 않음 |
| 화면마다 선언 | 시각 값을 누가 정하는지 | 화면 계약의 data-design-status 로 선언 |
3-3. 시각 값의 주인을 선언합니다
프로토타입의 <main data-design-status="…">가 "이
화면의 시각 값을 목업이 정하는지, 토큰이 정하는지"를 밝힙니다. 구현자는
착수 전에 이 값부터 읽습니다.
| 값 | 구현 대상 | 시각 값은 누가 정하나 | 쓰는 때 |
|---|---|---|---|
normative |
예 | 이 목업 | 시각까지 확정된 정본 |
normative-layout |
예 | 사유에 적은 다른 시안 | 레이아웃만 확정 |
contract |
예 | 토큰 (theme.css) |
구조 계약. 토큰을 바꾸면 따라옴 |
exploratory · exploratory-variant ·
golden-candidate |
아니오 | 후보 | 탐색·비교·승격 심사 중 |
tool-page |
아니오 | 없음 | 검토 도구 페이지 |
마커가 없는 화면은 판정할 수 없는 것으로 보고, 구현 기준으로 쓰지 않습니다.
Mermaid 소스 보기
flowchart TD
M["프로토타입 화면"] --> Q{"data-design-status?"}
Q -->|contract| A["구조만 가져오고<br/>시각은 토큰을 씀"]
Q -->|normative| B["목업의 간격·색·문구를<br/>그대로 옮김"]
Q -->|exploratory 계열| C["구현 기준 아님"]
Q -->|없음| D["판정 불가"]4강제는 세 층에서
요점 같은 디자인 검사를 작성·수정·배포 세 지점에 걸고, 새로 생긴 위반만 막습니다.
원칙만 적어 두면 사본은 조용히 샙니다. 그래서 같은 디자인 검사를 세 지점에 걸어 둡니다.
Mermaid 소스 보기
flowchart TD W["1 작성<br/>하네스 스킬이 정본 경로를 읽음"] -->|권고| X["2 수정 루프<br/>typecheck + lint:design 통과해야 '수정됨'"] X -->|차단| Y["3 배포 CI<br/>dev · staging · prod 빌드 명령"] Y -->|"lint:design 실패"| Z["빌드 중단"] Y -->|통과| OK["배포"]
| 층 | 강도 | 무엇이 | 무엇을 막나 |
|---|---|---|---|
| 1 작성 | 권고 | 하네스 스킬 (기준서 · 프로토타입 작성 스킬) | 정본 경로를 읽게 하고 금지 목록을 적용 |
| 2 수정 루프 | 차단 | 피드백 수정 스킬 | typecheck와 lint:design을 통과해야
"수정됨"으로 기록 |
| 3 배포 CI | 차단 | 배포 워크플로 3개의 빌드 명령 | lint:design 실패 시 빌드 중단 |
4-1. 디자인 검사가 보는 것
lint:design은 화면 코드(.ts,
.tsx, .css)를 보고, 정본인
theme.css는 검사에서 뺍니다. 규칙은 9개입니다.
| 규칙 | 막는 것 |
|---|---|
no-hardcoded-hex-in-ui |
화면 코드에 색 값을 직접 쓰는 것 (등재된 예외 값만 허용) |
no-excessive-radius ·
review-rounded-full |
과한 모서리 반경 |
no-gradient-decoration |
장식 그라디언트 |
no-arbitrary-spacing |
토큰 밖 임의 간격 |
no-undersized-button-text |
너무 작은 버튼 글자 |
no-lorem-placeholder |
자리표시 문구 |
no-forbidden-chart-library |
허용하지 않은 차트 라이브러리 |
no-raw-table-in-domain |
도메인 화면의 raw <table> (공용 테이블 컴포넌트
사용) |
4-2. 래칫: 새 위반만 막습니다
기존 위반은 기준선 파일(design-gate-baseline.json)에
파일×규칙별 건수로 고정하고, 건수가 늘어날 때만
실패시킵니다. 위반을 줄이면 기준선을 갱신해 다시 늘지 못하게 합니다. 한
번에 다 고치지 않아도 나빠지지는 않게 만드는 방식입니다.
5더 넓게 보기: 디자인 하네스 흐름
요점 하네스 전체는 여섯 단계로 돌고, 이번 화면을 고치는 일과 다음 기준을 바꾸는 일을 나눕니다. 전체 내용과 실습은 디자인 하네스 가이드 6판에 있습니다.
디자인 시스템이 "어떤 기준을 지킬지"를 담는다면, 하네스는 그 기준을 언제 읽고 어떻게 검사하며 어디로 되돌릴지를 연결합니다. 핵심은 이번 화면을 고치는 일과 다음 작업의 기준을 바꾸는 일을 구분하는 것입니다.
5-1. 여섯 단계와 두 개선 경로
Mermaid 소스 보기
flowchart TD I["01 Intent<br/>목적과 범위"] --> R["02 Rules<br/>토큰 · 상태 · 동작 · 업무 계약"] R --> G["03 Generate<br/>시안 · 프로토타입 · 코드"] G --> E["04 Execute<br/>브라우저에서 실제 조작"] E --> V["05 Verify<br/>기준과 대조, 증거 남김"] V -->|"A 화면 수정<br/>기준은 맞고 구현이 어긋남"| G V --> F["06 Refine<br/>개선 후보 정리"] F -->|"B 규칙 개선<br/>후보 → 검토 → 반영"| R
| 단계 | 하는 일 | 남기는 것 |
|---|---|---|
| Intent | 사용자와 핵심 업무, 이번에 다룰 범위를 정합니다 | 짧은 브리프 |
| Rules | 토큰·업무 패턴·화면 계약과 골든 셋을 선택합니다 | 기준 버전과 ID를 고정한 작업 계약 |
| Generate | 선택한 컴포넌트와 패턴으로 화면을 만듭니다 | 실행할 수 있는 화면. 이것만으로 완료 판정하지 않음 |
| Execute | 필터를 바꾸고 상세를 열고 닫으며, 빈 결과와 오류를 재현합니다 | 같은 조건의 캡처와 조작 기록 |
| Verify | 골든 화면·상태·동작 계약과 대조하고 차이의 원인을 구분합니다 | 기준별 결과와 근거. 확인 안 한 항목은 미검증 |
| Refine | 구현이 어긋나면 화면을 고치고, 기준이 부족하면 개선 후보로 분리합니다 | 재확인한 화면 또는 규칙 변경안 |
5-2. 골든 셋: 화면과 조건을 함께 묶은 비교 기준
보기 좋은 이미지 한 장으로는 무엇을 지켜야 하는지 설명하기 어렵습니다. 골든 셋은 대표 화면에 조건과 판정 방법을 함께 묶습니다.
| 구성 | 담는 내용 | 없으면 생기는 문제 |
|---|---|---|
| 식별과 이력 | ID, 버전, 적용 메뉴, 검토자, 변경 이유 | 어느 기준으로 만들었는지 추적하기 어려움 |
| 기준 화면 | 뷰포트·테마·데이터·권한·상태가 명시된 캡처 | 환경 차이를 결함으로 오인 |
| 구조와 허용 차이 | 필수 영역, 반응형 재배치, 달라도 되는 콘텐츠 | 모든 메뉴를 같은 모양으로 복제 |
| 상태와 행동 | 로딩·빈 결과·오류, 입력·복귀·재시도 시나리오 | 기본 화면만 맞고 업무가 끊김 |
| 판정과 증거 | 수용 기준 ID, 확인 방법, 미검증 범위 | 보기 좋은 결과를 업무 완료로 오해 |
5-3. 차이를 발견하면
| 관찰 | 먼저 확인할 것 | 처리 |
|---|---|---|
| 같은 기준, 다른 구현 | 토큰·컴포넌트가 올바르게 적용됐나 | 화면을 고치고 같은 기준으로 재검증 (경로 A) |
| 다른 비교 조건 | 뷰포트·데이터·권한·폰트·테마가 같은가 | 조건을 맞춘 뒤 다시 비교 |
| 페이지 목적이 다름 | 이 메뉴에 맞는 패턴·골든인가 | 골든 선택을 재검토 |
| 기준의 누락·충돌 | 누락 범위와 업무 명세를 확인했나 | 판정 보류와 기준 개선 후보를 분리 (경로 B) |
5-4. 자동화와 사람 게이트
문서와 시안은 자동화가 만들고, 품질과 방향은 게이트와 사람이 지킵니다. 되돌리기 어려운 결정(등록·병합·배포)은 자동화가 준비까지만 합니다.
| 디자인 게이트 | 검사 대상 | 판정 방식 |
|---|---|---|
| 문서 정합 검사 | 저장소 구조 · 경로 · 등재 · 보안 규칙 | 스크립트 종료 코드 |
| 수용 기준 린트 | "적절히", "빠르게" 같은 모호한 표현 | 린트 경고 |
| 스코어카드 | 대비 · 타이포 · 위계 · 브리프 적합 | 임계 점수 + 스크린샷 |
| 보드 판정 (사람) | 시안의 막힘 · 거슬림 · 취향 | 막힘만 수정 라운드로 되돌림 |
| 프로토타입 검증 | 선택한 시연 범위의 실제 동작 | PASS · CONDITIONAL · FAIL · BLOCKED, 미실행은 NOT_RUN |
프로토타입에서 통과한 화면도 제품의 서버 저장·권한·동시 편집 검증을 대신하지 않습니다. 두 완료 상태는 따로 기록합니다.
6용어
| 용어 | 뜻 |
|---|---|
| SSOT | 같은 값은 한 곳에만 적고 나머지는 그 자리를 가리키는 원칙 (Single Source of Truth) |
| 정본 | 값이나 규칙의 원래 위치. 다른 문서가 인용할 때 기준이 되는 곳 |
| 토큰 | 색·간격·서체처럼 반복해서 쓰는 디자인 값에 붙인 이름 |
| var() | CSS에서 변수 값을 가져오는 문법. 값을 복사하지 않고 참조한다 |
| 하네스 | 기준을 언제 읽고 어떻게 검사하며 어디로 되돌릴지 연결한 작업 구조 |
| 화면 계약 | 한 페이지의 정보·상태·동작·수용 기준을 정한 명세 |
| 골든 셋 | 대표 화면과 비교 조건·판정 방법을 묶은 비교 기준 |
| lint:design | 화면 코드의 디자인 금지 패턴을 찾는 검사 명령 |
| 래칫 | 기존 위반은 고정하고 새로 늘어나는 위반만 막는 방식 |
| 배포 CI | 코드를 배포하기 전에 자동으로 빌드와 검사를 돌리는 단계 |
7출처
- 디자인 하네스 가이드 6판 (2026-09-20, 확장판): 5절의 단계·골든 셋·차이 처리·디자인 게이트 표를 요약했습니다. 원문의 예시 화면과 수치는 설명용 가상 예시입니다.
- 제품 저장소 dev 브랜치 (2026-09-22 기준):
src/styles/theme.css,scripts/lint-design.cjs, 배포 워크플로 3개. - 문서 저장소 main 브랜치: 디자인 기준서 스킬, 프로토타입 작성 스킬, 프로토타입→React 계약 문서, 문서 정합 CI.
- 4절의 숫자(검사 규칙 9개)는 2026-09-26에 파일을 직접 열어 센 값입니다.