designpaca/packages/skill/references/product-copy.md
Yun Chan 6805fb2be7 feat(skill): absorb external design skills, restore interview gate, add review route
- Restore the step-0 interview as a mechanical gate the skill explicitly
  depends on; add harness.md (per-harness question tools, limits,
  fallbacks) and brief-interview.md (slots, question cards, rounds).
- Add 10 reference docs absorbed from external design skills
  (accessibility, interaction-feel, elevation, color, icons, product-copy,
  component-systems, critique, change-review, print-email) and extend
  existing references.
- Add a review-only route and two hard-gate clauses (truncated content
  reachability, three-flashes limit).
- design-gate: split tap targets into WCAG 2.5.8 and 44px contract layers,
  run axe-core when available, and fix false positives found on a real
  site (decorative alt="", stacked wordmark line count, url-only pages).
- lint-skill: fail if the interview gate section or its links disappear.
- Ship agents/openai.yaml and THIRD_PARTY_NOTICES.md.
2026-09-24 13:26:03 +09:00

241 lines
23 KiB
Markdown

# product-copy — 제품 UI 카피
4단계에서 버튼·폼 라벨·상태 메시지·오류·빈 상태·토글처럼 제품이 스스로 말하는 문구를 쓸 때 읽는다. 5단계 프리플라이트의 카피 검토에서 다시 연다.
브랜드 차별성을 주장하는 마케팅 헤드라인·브랜드 약속의 슬롭 지문(`so you can…` 테스트, 구문·어휘 지문)은 이 문서가 아니라 [antipatterns.md](antipatterns.md) 6절이 정본이다. 두 문서는 같은 대상을 다른 각도에서 본다 — 헤드라인이 버튼·토글 같은 제품 UI 라벨을 겸하면 두 문서를 모두 확인한다.
라벨은 셋 중 하나다. **하드 게이트**는 위반하면 통과시키지 않는다(WCAG 등 규범·기능 요건). **프로젝트 계약**은 이 프로젝트가 그 조건을 선택했을 때 지키는 약속이다(용어 체계, 어투 통일 같은 자체 결정). **관찰 후보**는 시작값이고 실제 렌더·독자 반응에서 확인해 조정한다. 절 제목에 주된 위계를 붙이고, 절 안에서 다른 위계가 섞이면 문장 앞에 굵게 라벨을 따로 단다.
## 이 문서를 읽는 법
| 상황 | 읽을 곳 |
|---|---|
| 새 카피를 쓰기 전에 뭘 먼저 봐야 하나 | §1 |
| 같은 개념을 화면마다 다르게 부르고 있는 것 같다 | §2 |
| 오류·삭제 확인·결제 화면의 톤이 다 같아 보인다 | §3 |
| 한 화면에 해요체와 합니다체가 섞인다 | §4 |
| 버튼 라벨을 어떻게 짓나 | §5 |
| 오류 메시지를 쓴다 | §6 |
| 빈 상태·빈 목록 문구를 쓴다 | §7 |
| 내부 개발 용어가 라벨에 새어 나온 것 같다 | §8 |
| `{name}을(를) 삭제했습니다` 같은 변수 삽입 문장 | §9 |
| 토글·링크 텍스트·placeholder | §10 |
| 물음표·느낌표·줄임표를 언제 쓰나 | §11 |
| 영문 라벨의 대소문자 규칙 | §12 |
| 실제 서비스 사례가 궁금하다 | §13 |
| 카피 findings를 어떻게 검증·보고하나 | §14 |
| 감사 직전 | §15 |
---
## 0. 언제·범위
이 문서는 4단계에서 폼·상태·오류·빈 상태·토글처럼 **제품이 스스로 말하는 문구**를 쓸 때 연다. 5단계 프리플라이트에서 카피만 따로 다시 훑을 때도 연다. 링크 텍스트·placeholder의 접근성 배선(스크린리더 순서, `aria-describedby`, 포커스 이동)은 이 문서가 아니라 [accessibility.md](accessibility.md)가 정본이며, 이 문서는 그 위에 얹히는 **문구 내용**만 다룬다.
---
## 1. 기존 보이스·용어 확인 — 프로젝트 계약
새 카피를 쓰기 전에 프로젝트에 이미 있는 카피를 읽는다. `design.md`, 기존 화면의 라벨·토스트·오류 문구, 저장소에 남은 스타일 가이드를 먼저 훑어 제품이 이미 쓰고 있는 용어·어투·로케일 관행을 파악한다[SKILL-BETTER-WRITING]. SKILL.md의 우선순위 원칙(사용자 지시 → design.md → 기존 토큰·코드 → designpaca 기본값)이 토큰·코드에 대해 요구하는 것과 같은 태도를 카피에도 적용한다 — 새로 지어내기 전에 이미 있는 답을 먼저 찾는다.
---
## 2. 용어 일관성 — 프로젝트 계약
한 개념에는 한 용어만 쓴다. 메뉴에서 `보관함`이라고 부른 것을 토스트에서 `저장소로 이동`이라고 부르면, 사용자는 같은 일을 두 번 배워야 한다[SKILL-BETTER-WRITING].
**grep 방법**
1. 화면에 쓰인 명사·동사를 후보로 뽑는다(예: `삭제`/`제거`/`지우기`, `보관`/`저장소`/`아카이브`).
2. 저장소 전체에서 각 후보를 `grep`해 실제로 몇 군데서 어떤 말로 쓰이는지 센다.
3. 가장 많이 쓰인 쪽을 기준으로 정하거나, 사용자에게 더 명확한 쪽을 고른다. 어느 쪽이든 design.md에 기록한다.
4. 소수파 표현을 전부 grep으로 찾아 바꾼다. 코드 식별자(`archiveItem` 같은 함수명)까지 바꾸라는 뜻은 아니다 — 사용자가 보는 문자열만 대상이다.
---
## 3. 톤과 위험 매트릭스 — 관찰 후보
모든 문구를 같은 톤으로 쓰면, 정말 조심해야 하는 순간(삭제·결제)도 일상 안내와 구분되지 않는다. 상황의 위험 수위에 따라 톤 강도를 다르게 가져간다[SKILL-BETTER-WRITING].
| 위험 수위 | 상황 예 | 톤 | 이유 |
|---|---|---|---|
| 일상 | 목록 화면, 설정, 일반 안내 문구 | 중립·간결 | 매번 감정을 실으면 정말 중요한 순간의 톤이 묻힌다 |
| 주의 | 로그아웃, 구독 변경, 여러 항목 일괄 처리 | 신중·결과를 분명히 말함 | 다음에 무슨 일이 벌어지는지 오해하면 안 된다 |
| 파괴 | 삭제 확인, 탈퇴, 결제 취소 | 차분·군더더기 없음(장난기·이모지 배제) | 가벼운 톤은 행동의 무게와 어긋난다 |
| 오류 | 폼 검증 실패, 저장 실패, 네트워크 오류 | 담백·비난하지 않음 | §6 참고 — 과한 사과·느낌표는 문제를 가리지 않는다 |
| 금전·보안 | 결제, 개인정보 변경, 본인 인증 | 진지·조건을 흐리지 않고 명시 | 오해가 실제 손실로 이어질 수 있다 |
이 위험 수위는 0단계 인터뷰에서 정한 브리프의 톤 프리셋([brief-interview.md](brief-interview.md))과 다른 층이다 — 브리프의 톤이 전체 브랜드 인상을 정하고, 이 표는 그 톤 안에서 상황별 강도를 조절한다. 장난스러운 브랜드 톤이라도 결제·보안 화면까지 그 장난기를 그대로 옮기지 않는다.
---
## 4. 어투 일관성 — 프로젝트 계약
한 제품 안에서 해요체(`~해요`, `~돼요`)와 합니다체(`~합니다`, `~됩니다`)를 섞으면 어투가 흔들려 보인다. 어느 쪽을 쓸지는 브랜드 톤에 따라 프로젝트가 정하고, 정했으면 화면 전체에서 지킨다.
이 규칙의 근거는 1차 출처로 확인되지 않았다 — 실무에서 두 어체를 상황별로 섞어 쓰는 사례가 보고되긴 하나, 그 출처가 1차 공식 자료가 아니라서 이 문서는 규범이 아니라 **프로젝트 계약**으로만 둔다. 브리프나 기존 화면이 이미 특정 어체를 쓰고 있으면 그것을 따르고(§1), 새로 정해야 하면 0단계 인터뷰의 톤 질문과 함께 확정한다. 확정한 뒤에는 §2와 같은 방법으로 grep해 혼용된 곳을 찾는다.
---
## 5. 버튼 레이블 — 프로젝트 계약
행정안전부 KRDS(공공 디자인 시스템) 지침은 버튼 텍스트를 원칙적으로 동사형으로 쓰도록 규정한다. `완료`·`닫기`·`취소`·`추가`·`삭제`처럼 이미 관용적으로 쓰이는 명사형은 예외다[KO-KRDS]. 명사·형용사 라벨(`저장 버튼입니다` 같은 서술이 아니라 그냥 `저장 완료` 같은 애매한 상태명)은 버튼을 눌렀을 때 무슨 일이 일어나는지 예측하기 어렵게 만든다.
- **결과를 말한다.** 버튼을 누르면 정확히 무슨 일이 일어나는지 동사구로 쓴다 — `제출` 대신 `변경사항 저장`, `확인` 대신 `계정 삭제`[SKILL-FRONTEND-DESIGN].
- **확인 대화상자 버튼은 결과를 반복한다.** `이 프로젝트를 삭제할까요?`라는 대화상자의 버튼은 `확인`/`취소`가 아니라 `삭제`/`취소`로 쓴다. `예`/`아니오`로 두면 사용자가 방금 읽은 질문을 다시 떠올려야 동의 대상을 알 수 있다[SKILL-BETTER-WRITING].
- **같은 행동은 버튼 → 확인 → 토스트까지 같은 이름을 쓴다.** `게시` 버튼을 누르면 `게시됨` 토스트를 띄운다. 버튼은 `게시`인데 토스트가 `발행을 완료했습니다`로 바뀌면 같은 행동인지 다시 확인해야 한다[SKILL-FRONTEND-DESIGN].
- **다단계 플로우의 어휘를 한 체계로 고정한다.** 진입은 `시작하기`, 진행은 `계속` 또는 `다음` 중 하나만(둘을 같은 플로우에서 섞지 않는다), 종료는 `완료`처럼 각 단계 역할에 한 단어만 배정하고 프로젝트 전체에서 유지한다[SKILL-BETTER-WRITING].
---
## 6. 오류 문구 — 프로젝트 계약(내용) / 관찰 후보(어휘)
오류 상태가 **존재**해야 한다는 요구는 [preflight.md](preflight.md) §4-1의 상태 완결성 검사가 이미 다룬다. 여기서는 그 오류 문구가 실제로 무엇을 말해야 하는지를 다룬다. 화면에서 문구가 나타나는 위치·타이밍(실시간 검증인지 제출 시인지)·`aria-live`·포커스 이동 같은 배선은 [accessibility.md](accessibility.md) §6(타이밍·포커스 이동)·§7(상태 알림)이 정본이다.
**프로젝트 계약 — 오류 문구는 항상 두 가지를 함께 말한다.** 무엇이 잘못됐는지, 그리고 어떻게 고치는지다. 하나만 있으면 사용자는 다음 행동을 스스로 추측해야 한다[SKILL-BETTER-WRITING].
**하드 게이트 — 입력 오류가 감지되고 고칠 방법을 알고 있으면 그 방법을 제시해야 한다**(WCAG 3.3.3 Error Suggestion, AA)[WCAG-22]. 그 밖의 오류 문구 기준(어휘·톤·비난 주어 회피 등)은 기존대로 프로젝트 계약이다.
**관찰 후보 — 어휘 선택.** 비난하는 주어를 쓰지 않는다(`당신이 잘못 입력했습니다` 대신 `형식이 올바르지 않습니다`처럼 상황을 주어로 둔다). 과한 사과와 느낌표를 쓰지 않는다 — §3의 `오류` 톤과 같은 이유다.
| 상황 | 나쁜 예 | 좋은 예 | 왜 |
|---|---|---|---|
| 필수 입력 누락 | 오류가 발생했습니다 | 이메일을 입력해 주세요 | 무엇이 비었는지 말하지 않음 → 말함 |
| 형식 오류 | 잘못된 값입니다 | 전화번호는 숫자만 10~11자리로 입력해 주세요 | 고치는 법이 없음 → 있음 |
| 저장 실패 | 죄송합니다ㅠㅠ 문제가 생겼어요! | 저장하지 못했습니다. 다시 시도해 주세요 | 과한 사과·느낌표 → 담백하게, 다음 행동 제시 |
같은 오류가 반복해서 발생한다면 문구를 더 다듬기보다 왜 반복되는지(입력 제약, 폼 흐름)를 4단계 인터랙션 설계에서 다시 본다. 이 문서는 문구 내용만 다루며, 인터랙션 재설계는 이 문서의 범위 밖이다.
---
## 7. 빈 상태 — 프로젝트 계약(내용) / 관찰 후보(어휘)
**프로젝트 계약 — 빈 상태는 세 가지를 한 번에 말한다.** 무엇이 비었는지(정체성), 왜 비었는지, 다음에 무엇을 할 수 있는지다. `항목이 없습니다` 한 줄만 있으면 사용자는 이 화면이 고장인지 정상인지부터 판단해야 한다[SKILL-BETTER-WRITING].
**관찰 후보 — 검색·필터 빈 상태는 사용자가 입력한 조건을 그대로 보여준다.** `검색 결과가 없습니다`보다 `'디자인'에 대한 검색 결과가 없습니다`가 사용자의 입력을 그대로 확인해 주고, 이어서 탈출구(필터 초기화, 다른 검색어 제안)를 함께 둔다.
| 상황 | 나쁜 예 | 좋은 예 |
|---|---|---|
| 첫 사용, 데이터 없음 | 항목이 없습니다 | 아직 등록한 프로젝트가 없습니다. 새 프로젝트를 만들어 보세요 |
| 검색 결과 없음 | 검색 결과가 없습니다 | `'디자인'`에 대한 검색 결과가 없습니다. 다른 검색어를 시도하거나 필터를 초기화해 보세요 |
| 필터로 전부 걸러짐 | 결과 없음 | 적용한 필터와 일치하는 항목이 없습니다. 필터 초기화 |
도움말 링크 같은 지속적인 정보를 빈 상태에만 있게 두지 않는다 — 데이터가 채워진 뒤에도 같은 도움말을 찾을 수 있어야 한다.
---
## 8. 평이한 말·기기 동사·독자 지칭·내부 용어 — 관찰 후보
- **최종 사용자 어휘로 쓴다.** 시스템 구현 방식이 아니라 사용자가 실제로 하는 일로 이름 붙인다 — `webhook`이 아니라 `알림`, `payload`가 아니라 `보낸 내용`. 이 검사는 [antipatterns.md](antipatterns.md) §6(진단)·§9(grep)의 내부 구현 용어 grep 후보(`webhook`·`config`·`payload`·`schema`)와 같은 검사이며, 여기서는 화면에 노출되는 **모든** 라벨·설정 이름에 같은 기준을 적용한다[SKILL-FRONTEND-DESIGN].
- **입력 방식에 맞는 동사를 쓴다.** 터치 인터페이스 안내에 `클릭`을, 마우스 중심 안내에 `탭`을 쓰지 않는다. 입력 방식을 특정할 수 없는 라벨(아이콘 버튼 등)은 동사 없는 명사형도 대안이다[SKILL-BETTER-WRITING].
- **독자 지칭과 소유격을 절제한다.** 안내문은 한국어의 주어 생략을 살려 `-하세요`체로 직접 쓰는 편이 자연스럽다. 오류 문구에서 `저희가`·`우리가` 같은 서비스 쪽 주어를 남용하지 않는다(§6의 `불러오지 못했습니다`처럼 상황 주어가 더 담백하다). 소유격도 필요할 때만 쓴다 — `내 즐겨찾기`가 다른 사용자의 즐겨찾기와 헷갈릴 우려가 없으면 `즐겨찾기`로 충분하다[SKILL-BETTER-WRITING].
- **특정 집단을 전제하는 표현을 쓰지 않는다.** 성별·연령 등을 전제한 예시 문구나 관용구는 다른 독자를 배제할 수 있다.
---
## 9. 문장 조각 조립 금지와 한국어 조사 처리 — 관찰 후보
**관찰 후보(엔지니어링 관행).** 변수 주변에 고정 문구를 이어 붙여 문장을 조립하지 않는다. `${count} 개의 항목이 삭제되었습니다`처럼 숫자·이름 앞뒤에 고정된 조각을 붙이는 방식은 그 변수가 조사·복수형·문장 구조에 영향을 주는 언어에서 깨지기 쉽다[SKILL-BETTER-WRITING]. 완성된 문장을 통째로 템플릿화하거나, 조사가 필요 없는 문장 구조로 바꾼다.
한국어에서는 조사(을/를, 이/가, 은/는, 으로/로)가 변수의 마지막 글자 받침 유무에 따라 갈린다는 문제가 하나 더 있다. 완성형 한글 음절(유니코드 `U+AC00`~`U+D7A3`, 11,172자)은 마지막 글자의 코드값에서 `0xAC00`을 뺀 값을 28로 나눈 나머지가 0이면 받침이 없다.
```js
// 받침 유무로 조사 짝을 고른다
function hasBatchim(syllable) {
const code = syllable.charCodeAt(syllable.length - 1) - 0xAC00;
if (code < 0 || code > 11171) return null; // 완성형 한글 음절이 아님(로마자·숫자 등)
return code % 28 !== 0;
}
function pickJosa(word, withBatchim, withoutBatchim) {
const has = hasBatchim(word);
if (has === null) return null; // 판별 불가 — 아래 재구성 대안을 쓴다
return has ? withBatchim : withoutBatchim;
}
// "${name}을(를) 삭제했습니다" 대신
const josa = pickJosa(name, '을', '를');
`${name}${josa} 삭제했습니다`
```
**로마자·숫자로 끝나는 변수는 코드로 판별할 수 없다.** `iPhone`, `3번` 처럼 완성형 한글 음절이 아닌 문자로 끝나면 받침 여부가 발음마다 갈려 규칙 하나로 못 맞힌다. 이런 값이 들어갈 자리는 조사가 아예 필요 없도록 문장을 다시 짠다 — 예: `${name}${josa} 삭제했습니다` 대신 `${name} 항목을 삭제했습니다`처럼 조사 앞에 고정 명사(`항목`)를 끼워 받침 문제를 피한다.
---
## 10. 토글 라벨·링크 텍스트·placeholder
### 10-1. 토글 라벨 — 관찰 후보
토글은 **켜졌을 때 일어나는 일**을 기준으로 라벨링한다. `알림 끄기`라는 라벨의 토글을 껐을 때 알림을 받는 상태가 되면(이중 부정), 사용자는 지금 상태가 무엇인지 헷갈린다. `알림 받기`로 쓰고 켜진 상태 = 알림을 받는 상태로 맞춘다[SKILL-BETTER-WRITING].
### 10-2. 링크 텍스트
**하드 게이트** — 링크의 목적은 링크 텍스트만으로, 또는 텍스트와 프로그램적으로 결정 가능한 맥락을 합쳐서 알 수 있어야 한다[WCAG-LINK].
**관찰 후보** — 스크린리더의 링크 목록 탐색 모드는 맥락 없이 링크 텍스트만 순서대로 읽으므로, 그런 상황에서도 통하도록 목적어를 넣는다 — `더보기` 단독 대신 `가격표 보기`[SKILL-BETTER-WRITING]. 한 화면에 `더보기` 링크가 여러 개면 각각 접미사로 구분한다(`사례 더보기`, `요금제 더보기`).
링크 존재 여부 자체는 이미 [preflight.md](preflight.md) §4-1이 확인한다 — 이 절은 그 링크의 문구 작성법만 더한다.
### 10-3. placeholder는 라벨이 아니다 — 하드 게이트
모든 입력에는 보이는 `<label>`이 있어야 하고, placeholder는 그 label을 대신할 수 없다. 이 요건의 정본은 [accessibility.md](accessibility.md)와 [preflight.md](preflight.md) §1이다. 이 문서가 더하는 내용은 카피뿐이다 — placeholder에는 예상 형식의 예시만 넣는다(`010-1234-5678`처럼 전화번호 형식 예시). 실제로 입력해야 할 값이나 지시문을 placeholder에만 넣지 않는다.
### 10-4. 아이콘 버튼의 라벨과 접근 가능한 이름 일치 — 하드 게이트
아이콘+텍스트 버튼에서 화면에 보이는 문구와 별도로 `aria-label`을 새로 지어 붙이면, 보이는 텍스트가 접근 가능한 이름 안에 포함되어야 한다 — 음성 입력 사용자가 화면에서 읽은 말을 그대로 불러 조작할 수 있어야 한다[WCAG-LABEL-NAME]. 아이콘 전용 버튼의 이름을 어떻게 배선하는지(`aria-label` vs 시각적으로 숨긴 텍스트)는 [accessibility.md](accessibility.md)와 [icons.md](icons.md) §8이 정본이다.
---
## 11. 문장 부호 — 관찰 후보
한국어 문장 부호는 2014년 12월 개정, 2015년 1월 시행된 한글 맞춤법 규정을 따른다. 마침표·물음표·느낌표·쉼표·가운뎃점·쌍점·빗금·따옴표(2종)·괄호(3종)·낫표(2종)·화살괄호(2종)·줄표·붙임표·물결표·드러냄표·숨김표·빠짐표·줄임표 등 약 20개 범주로 규정돼 있다[KO-PUNCT]. 개별 부호의 세부 적용 범위(가운뎃점의 정확한 용법, 따옴표 종류별 우선순위 등)는 이번 조사에서 1차 출처로 확인하지 못했다 — 세부 판정이 필요하면 국립국어원 어문 규정 원문을 프로젝트에서 직접 재확인한다.
제목·라벨에서 가운뎃점·em dash를 남용하는 구체적 지문은 이 문서가 아니라 [antipatterns.md](antipatterns.md) §4·§6이 맡는다(중복 규정하지 않는다). 이 문서가 더하는 것은 상태 문구 관행뿐이다.
- 진행 중 상태는 줄임표로 표시할 수 있다(`저장 중…`, `불러오는 중…`). 스피너·프로그레스 표시와 함께 써도 된다.
- 물음표·느낌표는 §3의 톤과 위험 수위를 넘지 않는 범위에서만 쓴다. 오류·파괴적 확인에는 느낌표를 쓰지 않는다(§6과 같은 이유).
---
## 12. 라틴 문자 UI의 대소문자 정책 — 관찰 후보
언제: 프로젝트 UI에 영문 라벨이 있을 때 연다. 한국어는 대소문자 구분이 없어 이 절이 적용되지 않는다.
버튼·메뉴·제목 같은 요소 유형별로 타이틀 케이스(`Save Changes`)와 문장체(`Save changes`) 중 하나를 정해 그 유형 전체에서 통일한다. 같은 유형 안에서 섞이면(`Save Changes` 버튼 옆에 `Discard changes` 버튼) 비일관으로 읽힌다. 확신이 안 서면 문장체가 더 안전한 시작값이다[SKILL-BETTER-WRITING]. 군더더기 없는 평이한 동사와 문장체 톤을 기본으로 한다는 원칙도 같은 방향이다[SKILL-FRONTEND-DESIGN].
---
## 13. 사례 — 토스 글쓰기 원칙
토스 기술 블로그가 공개한 글쓰기 원칙은 핵심 가치 5가지(Clear·Concise·Casual·Respect·Emotional)와 실행 원칙 8가지로 구성된다[KO-TOSS-WRITING]. 예를 들어 Clear는 단어의 의미가 모호하지 않고 한 번에 이해되는 문장인지 점검하는 것이고, Casual은 금융·IT 업계에서 쓰던 어려운 용어와 딱딱한 뉘앙스를 쉽고 친절하게 고쳐 쓰는 것이다.
이 사례는 한 회사가 실제로 공개한 원칙의 예시이지, 모든 프로젝트가 그대로 따라야 할 규범이 아니다. 공공기관·의료·B2B처럼 브리프의 톤이 다르면 그대로 옮기지 않는다. §1의 원칙대로, 새 프로젝트의 어투는 그 프로젝트의 브리프와 기존 카피에서 먼저 확인한다.
---
## 14. 검증
카피 findings는 1차로 소스(코드·design.md) 대조만으로 판정할 수 있다 — 용어 일관성(§2), 버튼 동사(§5), 오류·빈 상태 문구 내용(§6·§7)은 렌더를 새로 켜지 않아도 확인 가능하다[SKILL-BETTER-WRITING]. 다만 잘림·줄바꿈의 영향을 받는 카피(버튼 라벨, 제목, 좁은 카드 안 문구)는 소스만으로 판정하지 않는다 — 실제 렌더에서 줄바꿈·말줄임(`text-overflow: ellipsis`)·좁은 폭 재배치를 확인한다.
카피 결함에도 별도 심각도 체계를 두지 않는다. 이 문서 각 절에 붙은 하드 게이트/프로젝트 계약/관찰 후보 라벨을 그대로 finding의 위계로 쓴다 — 예: 링크 텍스트 위반(§10-2)은 하드 게이트, 오류 문구에 수정법이 없는 것(§6)은 프로젝트 계약, 어휘 선택(비난 주어, 과한 사과)은 관찰 후보다.
---
## 15. 체크리스트
- [ ] 새 카피를 쓰기 전에 기존 화면·design.md의 용어를 확인했다(§1)
- [ ] 같은 개념을 화면마다 다른 말로 부르지 않는다 — grep으로 소수파 표현을 찾아 통일했다(§2)
- [ ] 일상·주의·파괴·오류·금전 상황의 톤 강도가 다르다(§3)
- [ ] 한 화면·한 제품 안에서 해요체·합니다체가 섞이지 않는다(§4)
- [ ] 버튼 라벨이 동사형이고 결과를 말한다. 파괴적 확인 버튼은 결과를 반복한다(§5)
- [ ] 같은 행동이 버튼 → 확인 → 토스트까지 같은 이름을 쓴다(§5)
- [ ] 오류 문구가 무엇이 잘못됐는지와 어떻게 고치는지를 함께 말한다. 비난·과한 사과·느낌표가 없다(§6)
- [ ] 빈 상태가 정체성·이유·다음 행동을 말한다. 검색 빈 상태는 입력한 조건을 보여준다(§7)
- [ ] 내부 구현 용어(webhook·config·payload·schema)가 사용자 라벨로 새지 않았다(§8)
- [ ] 변수 주변에 문장 조각을 조립하지 않았다. 조사가 필요한 자리는 받침 판별 또는 문장 재구성으로 처리했다(§9)
- [ ] 토글 라벨이 켜진 상태를 기준으로 쓰였다(§10-1)
- [ ] 링크 텍스트가 맥락 없이도 목적지를 알려준다(§10-2)
- [ ] placeholder가 라벨을 대신하지 않고 형식 예시로만 쓰였다(§10-3)
- [ ] 아이콘 버튼의 `aria-label`이 화면에 보이는 문구를 포함한다(§10-4)
- [ ] 영문 라벨이 있다면 요소 유형별로 대소문자 정책이 통일돼 있다(§12)
- [ ] 잘림·줄바꿈에 영향받는 카피(버튼·제목·좁은 카드)는 실제 렌더로 확인했다(§14)