@infomind-ux/infoux-mcp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +81 -0
  2. package/bin/server.js +331 -0
  3. package/data/contract.md +215 -0
  4. package/data/manifest.json +286 -0
  5. package/data/references/accessibility.md +243 -0
  6. package/data/references/forbidden-patterns.md +462 -0
  7. package/data/references/guide-import.md +93 -0
  8. package/data/references/html-semantics.md +475 -0
  9. package/data/references/krds-components.md +1426 -0
  10. package/data/references/krds-source.md +1125 -0
  11. package/data/references/krds-tokens.md +201 -0
  12. package/data/references/project-profiles.md +99 -0
  13. package/data/references/snippet-template.md +185 -0
  14. package/data/references/tailwind-mapping.md +53 -0
  15. package/data/rules.json +780 -0
  16. package/data/snippets/accordion.md +49 -0
  17. package/data/snippets/alert.md +37 -0
  18. package/data/snippets/badge.md +29 -0
  19. package/data/snippets/boilerplate.md +125 -0
  20. package/data/snippets/breadcrumb.md +26 -0
  21. package/data/snippets/btn.md +63 -0
  22. package/data/snippets/calendar.md +64 -0
  23. package/data/snippets/card.md +50 -0
  24. package/data/snippets/carousel.md +43 -0
  25. package/data/snippets/check-radio.md +55 -0
  26. package/data/snippets/disclosure.md +44 -0
  27. package/data/snippets/file-upload.md +34 -0
  28. package/data/snippets/form.md +68 -0
  29. package/data/snippets/header.md +56 -0
  30. package/data/snippets/list.md +64 -0
  31. package/data/snippets/main-menu.md +49 -0
  32. package/data/snippets/modal.md +54 -0
  33. package/data/snippets/pagination.md +41 -0
  34. package/data/snippets/progress.md +30 -0
  35. package/data/snippets/select.md +34 -0
  36. package/data/snippets/side-panel.md +57 -0
  37. package/data/snippets/spinner.md +24 -0
  38. package/data/snippets/step-indicator.md +38 -0
  39. package/data/snippets/switch.md +32 -0
  40. package/data/snippets/tab.md +52 -0
  41. package/data/snippets/table.md +63 -0
  42. package/data/snippets/tag.md +42 -0
  43. package/data/snippets/toast.md +48 -0
  44. package/data/snippets/tooltip.md +38 -0
  45. package/data/tokens.css +390 -0
  46. package/data/workflows/change-token.md +20 -0
  47. package/data/workflows/create-component.md +71 -0
  48. package/data/workflows/design-form.md +20 -0
  49. package/data/workflows/design-page.md +22 -0
  50. package/data/workflows/design-widget.md +19 -0
  51. package/data/workflows/init-project.md +68 -0
  52. package/data/workflows/review-ui.md +14 -0
  53. package/package.json +34 -0
@@ -0,0 +1,286 @@
1
+ {
2
+ "version": "c8f34dd",
3
+ "generated": "scripts/build-mcp.js",
4
+ "references": [
5
+ {
6
+ "id": "accessibility",
7
+ "file": "accessibility.md",
8
+ "chars": 5489,
9
+ "summary": "KRDS는 **WCAG 2.1 Level AA 이상 + KWCAG 2.1/2.2** 준수를 강제한다. 본 스킬도 이를 그대로 따른다."
10
+ },
11
+ {
12
+ "id": "forbidden-patterns",
13
+ "file": "forbidden-patterns.md",
14
+ "chars": 10600,
15
+ "summary": "이 문서의 패턴이 코드에서 발견되면 **즉시 작업 중단**하고 사용자에게 보고한다."
16
+ },
17
+ {
18
+ "id": "guide-import",
19
+ "file": "guide-import.md",
20
+ "chars": 1550,
21
+ "summary": "이 문서는 **UX팀이 개발팀·협력사 환경에 infoUX 기준을 배포하는 방법**과 **개발자가 활성화하는 방법**을 다룬다."
22
+ },
23
+ {
24
+ "id": "html-semantics",
25
+ "file": "html-semantics.md",
26
+ "chars": 19682,
27
+ "summary": "1. **시맨틱 우선** — 의미가 일치하는 HTML5 태그를 최우선 (`<button>` `<nav>` `<article>` `<dialog>` 등)."
28
+ },
29
+ {
30
+ "id": "krds-components",
31
+ "file": "krds-components.md",
32
+ "chars": 33775,
33
+ "summary": "아래 카탈로그에 없는 컴포넌트는 임의 생성 금지. § \"카탈로그에 없는 컴포넌트 요구 시\" 절차 따름."
34
+ },
35
+ {
36
+ "id": "krds-source",
37
+ "file": "krds-source.md",
38
+ "chars": 34433,
39
+ "summary": "- **시스템명**: KRDS (Korea Government Design System) — 한국명 \"범정부 UI/UX 디자인 시스템\""
40
+ },
41
+ {
42
+ "id": "krds-tokens",
43
+ "file": "krds-tokens.md",
44
+ "chars": 6700,
45
+ "summary": "색상, 기본 폰트, 브레이크포인트는 이 문서의 토큰을 사용한다. 임의 hex/rgb/hsl 색상 작성은 금지한다. 간격·크기·타이포 스케일·모션·z-index는 토큰 카탈로그 대상이 아니며 CSS/Tailwind 직접값으로 작성한다."
46
+ },
47
+ {
48
+ "id": "project-profiles",
49
+ "file": "project-profiles.md",
50
+ "chars": 4256,
51
+ "summary": "KRDS 체크리스트는 모든 프로젝트에 같은 방식으로 적용하지 않는다. 코드 생성 전 사이트 유형을 먼저 판정하고, 공통 품질 규칙과 조건부 정부/공공 규칙을 분리한다."
52
+ },
53
+ {
54
+ "id": "snippet-template",
55
+ "file": "snippet-template.md",
56
+ "chars": 3913,
57
+ "summary": "```markdown"
58
+ },
59
+ {
60
+ "id": "tailwind-mapping",
61
+ "file": "tailwind-mapping.md",
62
+ "chars": 1699,
63
+ "summary": "INFOUX는 Tailwind v4 `@theme`에 색상과 폰트만 공개한다."
64
+ }
65
+ ],
66
+ "workflows": [
67
+ {
68
+ "id": "change-token",
69
+ "file": "change-token.md",
70
+ "chars": 829,
71
+ "summary": "색상, 폰트, 브레이크포인트 등 INFOUX 토큰을 추가·변경·재매핑할 때 사용. foundation, semantic alias, 생성 CSS와 starter 영향 범위를 먼저 확인한다."
72
+ },
73
+ {
74
+ "id": "create-component",
75
+ "file": "create-component.md",
76
+ "chars": 1590,
77
+ "summary": "BEM 컴포넌트 일괄 생성. 컴포넌트명 입력 시 CSS + 스니펫 + playground HTML + site 문서 페이지를 생성한다. \"컴포넌트 추가\", \"새 컴포넌트\", \"create component\" 요청 시 사용."
78
+ },
79
+ {
80
+ "id": "design-form",
81
+ "file": "design-form.md",
82
+ "chars": 643,
83
+ "summary": "입력폼, 신청, 문의, 검색 조건, 로그인, 결제 정보 등 form UI를 설계하거나 수정할 때 사용. label, 도움말, 오류, 필수 상태와 제출 흐름을 구현 전에 확정한다."
84
+ },
85
+ {
86
+ "id": "design-page",
87
+ "file": "design-page.md",
88
+ "chars": 775,
89
+ "summary": "INFOUX 기준으로 새 페이지, 화면, 랜딩, 상세, 목록, 관리자 화면을 설계하거나 구현할 때 사용. 코드 작성 전에 사이트 유형, 사용자 핵심 과업, page shell, section 패턴과 재사용 컴포넌트를 확정한다."
90
+ },
91
+ {
92
+ "id": "design-widget",
93
+ "file": "design-widget.md",
94
+ "chars": 693,
95
+ "summary": "modal, tab, accordion, disclosure, tooltip, carousel, calendar, combobox 같은 인터랙티브 위젯을 설계하거나 구현할 때 사용. 상태 모델, ARIA 관계, 키보드와 포커스 이동을 코드 전에 확정한다."
96
+ },
97
+ {
98
+ "id": "init-project",
99
+ "file": "init-project.md",
100
+ "chars": 1478,
101
+ "summary": "INFOUX 스타터 기반 새 프로젝트 초기화. 프로젝트 유형과 브랜드 토큰을 반영해 프로젝트 컨트랙트와 토큰을 설정한다. \"새 프로젝트\", \"프로젝트 시작\", \"init project\" 요청 시 사용."
102
+ },
103
+ {
104
+ "id": "review-ui",
105
+ "file": "review-ui.md",
106
+ "chars": 429,
107
+ "summary": "INFOUX 기준으로 UI 구현을 리뷰하거나 규칙 준수 여부를 점검할 때 사용. 검사 결과만 나열하지 않고 Task Contract, 승인 패턴, 실제 구현의 차이를 우선 분석한다."
108
+ }
109
+ ],
110
+ "snippets": [
111
+ {
112
+ "id": "accordion",
113
+ "file": "accordion.md",
114
+ "chars": 1260,
115
+ "summary": "native `<details>`/`<summary>` 활용 — JS 없이 동작."
116
+ },
117
+ {
118
+ "id": "alert",
119
+ "file": "alert.md",
120
+ "chars": 961,
121
+ "summary": "페이지에 고정 노출되는 정보/경고/오류 메시지."
122
+ },
123
+ {
124
+ "id": "badge",
125
+ "file": "badge.md",
126
+ "chars": 553,
127
+ "summary": "작은 알림 표시기 (카운트 / 상태 / 새 항목)."
128
+ },
129
+ {
130
+ "id": "boilerplate",
131
+ "file": "boilerplate.md",
132
+ "chars": 3524,
133
+ "summary": "기본 마크업은 일반사이트, 공공서비스, 공공기관, CMS·관리자, 커머스·예약 모두에 적용 가능한 공통 골격이다. 공식 배너, 정부 상징, 운영기관 식별자, 공공 푸터 필수 링크는 사이트 유형 판정에서 적용 대상이 확인된 경우에만 추가한다."
134
+ },
135
+ {
136
+ "id": "breadcrumb",
137
+ "file": "breadcrumb.md",
138
+ "chars": 634,
139
+ "summary": "페이지 경로 표시. 사용자의 현재 위치를 보여주고 상위 페이지로 빠르게 이동할 수 있게 한다."
140
+ },
141
+ {
142
+ "id": "btn",
143
+ "file": "btn.md",
144
+ "chars": 2098,
145
+ "summary": "```html"
146
+ },
147
+ {
148
+ "id": "calendar",
149
+ "file": "calendar.md",
150
+ "chars": 2016,
151
+ "summary": "날짜 선택 그리드. 단독 사용 또는 date input의 팝업으로 사용."
152
+ },
153
+ {
154
+ "id": "card",
155
+ "file": "card.md",
156
+ "chars": 1199,
157
+ "summary": "```html"
158
+ },
159
+ {
160
+ "id": "carousel",
161
+ "file": "carousel.md",
162
+ "chars": 1483,
163
+ "summary": "스크롤 스냅 기반 슬라이드 컨테이너."
164
+ },
165
+ {
166
+ "id": "check-radio",
167
+ "file": "check-radio.md",
168
+ "chars": 1428,
169
+ "summary": "```html"
170
+ },
171
+ {
172
+ "id": "disclosure",
173
+ "file": "disclosure.md",
174
+ "chars": 1026,
175
+ "summary": "단일 \"더보기/접기\" 토글. Accordion(다중 그룹)과 달리 단독 토글에 사용."
176
+ },
177
+ {
178
+ "id": "file-upload",
179
+ "file": "file-upload.md",
180
+ "chars": 815,
181
+ "summary": "```html"
182
+ },
183
+ {
184
+ "id": "form",
185
+ "file": "form.md",
186
+ "chars": 1869,
187
+ "summary": "KRDS 입력폼 구성: **레이블 → 보조설명 → 입력박스 → 시스템메시지** (요소 간 8px gap)"
188
+ },
189
+ {
190
+ "id": "header",
191
+ "file": "header.md",
192
+ "chars": 1561,
193
+ "summary": "사이트 유형과 무관하게 사용할 수 있는 공통 헤더 패턴. 브랜드 + 주 메뉴 + 액션 영역을 기본으로 하며, 공식 배너·정부 상징·운영기관 식별자는 공공서비스/공공기관에서 적용 대상이 확인된 경우에만 별도 추가한다."
194
+ },
195
+ {
196
+ "id": "list",
197
+ "file": "list.md",
198
+ "chars": 1129,
199
+ "summary": "두 가지 변형 — 텍스트 목록과 구조화 목록(정의 목록)."
200
+ },
201
+ {
202
+ "id": "main-menu",
203
+ "file": "main-menu.md",
204
+ "chars": 1257,
205
+ "summary": "드롭다운형 주 내비게이션. 헤더 안에서 사용."
206
+ },
207
+ {
208
+ "id": "modal",
209
+ "file": "modal.md",
210
+ "chars": 1546,
211
+ "summary": "```html"
212
+ },
213
+ {
214
+ "id": "pagination",
215
+ "file": "pagination.md",
216
+ "chars": 1110,
217
+ "summary": "목록을 여러 페이지로 나눠 탐색."
218
+ },
219
+ {
220
+ "id": "progress",
221
+ "file": "progress.md",
222
+ "chars": 579,
223
+ "summary": "native `<progress>` + 시각 커스텀."
224
+ },
225
+ {
226
+ "id": "select",
227
+ "file": "select.md",
228
+ "chars": 696,
229
+ "summary": "native `<select>` 기반. input과 동일 사이즈/패딩 토큰."
230
+ },
231
+ {
232
+ "id": "side-panel",
233
+ "file": "side-panel.md",
234
+ "chars": 1476,
235
+ "summary": "우측에서 슬라이드 인하는 보조 패널. 모달과 달리 본문 스크롤을 차단하지 않는다."
236
+ },
237
+ {
238
+ "id": "spinner",
239
+ "file": "spinner.md",
240
+ "chars": 375,
241
+ "summary": "로딩 표시기. 진행 시간을 알 수 없을 때 사용."
242
+ },
243
+ {
244
+ "id": "step-indicator",
245
+ "file": "step-indicator.md",
246
+ "chars": 1000,
247
+ "summary": "다단계 폼/프로세스의 현재 단계 표시."
248
+ },
249
+ {
250
+ "id": "switch",
251
+ "file": "switch.md",
252
+ "chars": 660,
253
+ "summary": "```html"
254
+ },
255
+ {
256
+ "id": "tab",
257
+ "file": "tab.md",
258
+ "chars": 1535,
259
+ "summary": "```html"
260
+ },
261
+ {
262
+ "id": "table",
263
+ "file": "table.md",
264
+ "chars": 1141,
265
+ "summary": "데이터 표. 모바일에서는 가로 스크롤 컨테이너로 감싸서 사용."
266
+ },
267
+ {
268
+ "id": "tag",
269
+ "file": "tag.md",
270
+ "chars": 752,
271
+ "summary": "카테고리, 필터, 속성 라벨."
272
+ },
273
+ {
274
+ "id": "toast",
275
+ "file": "toast.md",
276
+ "chars": 986,
277
+ "summary": "일시적 피드백 메시지. 화면 우측 상단/하단에 잠시 노출 후 자동 사라짐."
278
+ },
279
+ {
280
+ "id": "tooltip",
281
+ "file": "tooltip.md",
282
+ "chars": 788,
283
+ "summary": "짧은 보조 설명 팝업. **JS 트리거 변형 권장** (키보드/터치 호환)."
284
+ }
285
+ ]
286
+ }
@@ -0,0 +1,243 @@
1
+ # 접근성 — info-design 강제 규정
2
+
3
+ KRDS는 **WCAG 2.1 Level AA 이상 + KWCAG 2.1/2.2** 준수를 강제한다. 본 스킬도 이를 그대로 따른다.
4
+
5
+ ---
6
+
7
+ ## 1. 색상 대비 (필수)
8
+
9
+ | 텍스트 종류 | AA 최소 | AAA 권장 |
10
+ |------------|--------|---------|
11
+ | 일반 텍스트 (18pt 미만 / 14pt bold 미만) | **4.5:1** | 7:1 |
12
+ | 큰 텍스트 (18pt+ 또는 14pt bold+) | **3:1** | 4.5:1 |
13
+ | UI 컴포넌트 (버튼·아이콘) | **3:1** | — |
14
+ | 아이콘 (장식이 아닌 의미) | **3:1** | 7:1 (고대비 모드) |
15
+
16
+ ### 매직넘버 50 규칙 (KRDS)
17
+
18
+ KRDS 색상 단계에서 **두 단계 차이가 50 이상이면 4.5:1 자동 충족**.
19
+ - 예: `gray.10` (#e6e8ea) ↔ `gray.60` (#58616a) → 차이 50 → AA 충족
20
+ - 예: `gray.5` (#f4f5f6) ↔ `gray.50` (#6d7882) → 차이 45 → 검증 필요
21
+
22
+ 토큰 시맨틱 별칭 (`--color-text-*`)을 쓰면 KRDS가 이미 AA를 보장하는 조합으로 만들어졌다.
23
+
24
+ ---
25
+
26
+ ## 2. 포커스 (필수)
27
+
28
+ ```css
29
+ /* ❌ 절대 금지 */
30
+ :focus { outline: none; }
31
+ button:focus { outline: 0; }
32
+
33
+ /* ✅ KRDS 기본 — reset.css 전역 처리됨 */
34
+ :focus-visible {
35
+ outline: 0.4rem solid var(--color-border-primary);
36
+ outline-offset: 2px;
37
+ }
38
+ ```
39
+
40
+ - **모든 인터랙티브 요소**: `<button>` `<a>` `<input>` `<select>` `<textarea>` `[tabindex]` `[contenteditable]`
41
+ - 두께: **4px**
42
+ - 색상: `var(--color-border-primary)` (KRDS primary)
43
+ - offset: 2px (요소 윤곽이 보이도록)
44
+
45
+ ---
46
+
47
+ ## 3. 터치/클릭 영역 (필수)
48
+
49
+ | 컨텍스트 | 최소 크기 |
50
+ |---------|----------|
51
+ | 모바일 | **44 × 44px** (`var(--touch-target-min)`) |
52
+ | 데스크탑 dense UI | 32 × 32px (KRDS xsmall) 허용 |
53
+ | 권장 기본 | 48 × 48px (KRDS medium = button medium 기본) |
54
+
55
+ 작은 시각 요소(체크박스 24×24, 토글 트랙 44×24)에서 터치 영역 확보:
56
+ - `<label>`로 감싸 클릭 영역 확장
57
+ - `min-height: var(--touch-target-min)` 적용
58
+
59
+ ---
60
+
61
+ ## 4. 시맨틱 HTML (필수)
62
+
63
+ | 의도 | 사용 |
64
+ |------|------|
65
+ | 클릭 액션 | `<button type="button">` |
66
+ | 페이지 이동 | `<a href="...">` |
67
+ | 폼 제출 | `<button type="submit">` 또는 `<form>` |
68
+ | 헤더 | `<header>` |
69
+ | 푸터 | `<footer>` |
70
+ | 내비게이션 | `<nav aria-label="...">` |
71
+ | 본문 영역 | `<main>` (페이지당 하나) |
72
+ | 독립 콘텐츠 | `<article>` |
73
+ | 관련 섹션 | `<section>` (제목 필수) |
74
+ | 보조 콘텐츠 | `<aside>` |
75
+
76
+ **`div/span 클릭 핸들러 패턴` 절대 금지.** 클릭 가능한 요소는 button 또는 a.
77
+
78
+ ---
79
+
80
+ ## 5. 폼 접근성
81
+
82
+ ### 레이블 연결
83
+
84
+ ```html
85
+ <!-- ✅ -->
86
+ <label for="email">이메일</label>
87
+ <input type="email" id="email">
88
+
89
+ <!-- ❌ placeholder만으로 레이블 대체 -->
90
+ <input type="email" placeholder="이메일">
91
+ ```
92
+
93
+ ### 필수 표시
94
+
95
+ ```html
96
+ <label for="name">
97
+ 이름
98
+ <span class="form-field__required" aria-label="필수">*</span>
99
+ </label>
100
+ <input type="text" id="name" required>
101
+ ```
102
+
103
+ ### 에러 안내
104
+
105
+ ```html
106
+ <input type="email" id="email" aria-invalid="true" aria-describedby="email-error">
107
+ <p id="email-error" class="form-field__message form-field__message--error">
108
+ 올바른 이메일 형식이 아닙니다
109
+ </p>
110
+ ```
111
+
112
+ ### 라디오 그룹
113
+
114
+ ```html
115
+ <fieldset>
116
+ <legend class="form-field__label">결제 수단</legend>
117
+ <label class="radio">...</label>
118
+ <label class="radio">...</label>
119
+ </fieldset>
120
+ ```
121
+
122
+ ---
123
+
124
+ ## 6. ARIA 속성 — 핵심 패턴
125
+
126
+ ### 현재 상태
127
+
128
+ | 속성 | 용도 |
129
+ |------|------|
130
+ | `aria-current="page"` | 현재 페이지 (메뉴, breadcrumb) |
131
+ | `aria-current="step"` | 현재 단계 (step-indicator) |
132
+ | `aria-selected="true"` | 선택됨 (tab, table row) |
133
+ | `aria-checked="true"` | 체크됨 (custom checkbox 시 — native input 사용 시 불필요) |
134
+ | `aria-expanded="true|false"` | 펼침 (disclosure, dropdown, accordion) |
135
+ | `aria-pressed="true|false"` | 토글 버튼 ON 상태 |
136
+ | `aria-hidden="true"` | 시각만 (장식 아이콘) |
137
+ | `aria-disabled="true"` | 비활성 (disabled 속성과 같이 사용) |
138
+ | `aria-invalid="true"` | 검증 실패 |
139
+
140
+ ### 라이브 영역
141
+
142
+ | 속성 | 용도 |
143
+ |------|------|
144
+ | `role="alert"` + `aria-live="assertive"` | 즉시 안내 (오류, 긴급) |
145
+ | `role="status"` + `aria-live="polite"` | 정중한 안내 (저장 완료, 로딩) |
146
+
147
+ ### 다이얼로그
148
+
149
+ ```html
150
+ <div role="dialog" aria-modal="true" aria-labelledby="modal-title">
151
+ <h2 id="modal-title">...</h2>
152
+ </div>
153
+ ```
154
+
155
+ ### 컨트롤 연결
156
+
157
+ | 속성 | 용도 |
158
+ |------|------|
159
+ | `aria-controls="패널id"` | 트리거 → 제어 대상 |
160
+ | `aria-haspopup="true"` | 팝업/드롭다운 트리거 |
161
+ | `aria-describedby="설명id"` | 추가 설명 연결 (보조설명, 에러) |
162
+ | `aria-labelledby="제목id"` | 레이블 대체 (단, label 더 우선) |
163
+ | `aria-label="..."` | 레이블 대체 (텍스트 없는 아이콘 버튼) |
164
+
165
+ ---
166
+
167
+ ## 7. 키보드 네비게이션 (필수)
168
+
169
+ | 컴포넌트 | 키 |
170
+ |---------|-----|
171
+ | Modal | `Esc` 닫기, `Tab` 트랩 (포커스 가두기) |
172
+ | Dropdown | `Esc` 닫기, `↑↓` 이동, `Enter` 선택 |
173
+ | Tab | `←→` 탭 이동, `Home/End` 처음/끝 |
174
+ | Accordion | `Tab` 항목 간 이동, `Space/Enter` 펼침 |
175
+ | Calendar | `←→` 일, `↑↓` 주, `Page Up/Down` 월, `Home/End` 주 시작/끝 |
176
+ | Carousel | `←→` 슬라이드 이동 |
177
+
178
+ 모든 인터랙티브 요소는 **마우스만으로 가능한 모든 것이 키보드로도 가능**해야 한다.
179
+
180
+ ---
181
+
182
+ ## 8. 스크린 리더
183
+
184
+ - 모든 페이지에 **Skip Link** (`.skip-to-content`) — 본문으로 바로 이동
185
+ - 페이지 제목(`<h1>`) 페이지당 1개
186
+ - 헤딩 레벨 순서 지키기 (`<h1>` → `<h2>` → `<h3>`, 건너뛰지 않기)
187
+ - `<nav>`에 `aria-label`로 식별 (페이지에 nav가 여러 개면 필수)
188
+ - 장식 아이콘은 `aria-hidden="true"`
189
+
190
+ ---
191
+
192
+ ## 9. 동작·모션
193
+
194
+ - `prefers-reduced-motion: reduce` 미디어 쿼리로 **자동 비활성화** — 불필요한 transition·animation은 모션 감소 시 제거
195
+ - **자동 재생 슬라이드/캐러셀 금지** (사용자가 명시 활성화 안 했으면 OFF) — WCAG 2.2.2
196
+ - 자동 재생 시 **일시정지 버튼 필수**
197
+
198
+ ```css
199
+ @media (prefers-reduced-motion: reduce) {
200
+ *,
201
+ *::before,
202
+ *::after {
203
+ animation-duration: 0.01ms !important;
204
+ animation-iteration-count: 1 !important;
205
+ transition-duration: 0.01ms !important;
206
+ }
207
+ }
208
+ ```
209
+
210
+ ---
211
+
212
+ ## 10. 다크/고대비 모드
213
+
214
+ KRDS는 **light + high-contrast** 두 모드 시스템 차원에서 지원.
215
+
216
+ ```html
217
+ <!-- 토글 -->
218
+ <html data-color-mode="high-contrast">
219
+ ```
220
+
221
+ - 컴포넌트 코드는 **모드 분기 작성 금지** — 토큰이 자동 분기됨
222
+ - 새 토큰 추가 시 light + high-contrast **양쪽 모드 정의 필수**
223
+
224
+ ---
225
+
226
+ ## 자가 점검 체크리스트
227
+
228
+ 페이지·컴포넌트 작성 후 PR 올리기 전:
229
+
230
+ - [ ] 모든 색상이 KRDS 토큰 (raw hex/rgb 0건)?
231
+ - [ ] 모든 인터랙티브 요소가 시맨틱 HTML (`<button>`/`<a>`)?
232
+ - [ ] 모든 `<img>`에 `alt` 속성?
233
+ - [ ] 모든 폼 요소가 `<label for>` + `id` 연결?
234
+ - [ ] focus-visible 처리 (`:focus { outline: none }` 0건)?
235
+ - [ ] 터치 영역 44px 이상 (모바일)?
236
+ - [ ] 키보드 네비게이션 작동 (Tab, Enter, Esc, 화살표)?
237
+ - [ ] ARIA 속성 정확 (`aria-current`, `aria-selected`, `aria-expanded`, `aria-label`)?
238
+ - [ ] 헤딩 레벨 순서 준수 (h1 → h2 → h3)?
239
+ - [ ] Skip link 제공?
240
+ - [ ] 다크/고대비 토글 시 깨지지 않음 (raw 색 0건이면 자동)?
241
+ - [ ] `prefers-reduced-motion` 대응?
242
+
243
+ 위 12개 중 하나라도 No → 작업 미완으로 간주.