@infomind-ux/infoux-mcp 0.2.0 → 0.3.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.
- package/README.md +2 -2
- package/bin/server.js +192 -4
- package/data/icons.json +1291 -0
- package/data/manifest.json +43 -13
- package/data/profiles.json +1 -1
- package/data/references/accessibility.md +22 -1
- package/data/references/art-direction.md +1 -1
- package/data/references/html-semantics.md +56 -12
- package/data/references/krds-components.md +651 -18
- package/data/references/krds-tokens.md +12 -12
- package/data/references/project-profiles.md +1 -1
- package/data/references/release-checklist.md +2 -0
- package/data/references/tailwind-mapping.md +1 -1
- package/data/references/trade-off-rules.md +5 -0
- package/data/rules.json +62 -3
- package/data/snippets/error-page.md +107 -0
- package/data/snippets/footer.md +150 -0
- package/data/snippets/header.md +6 -3
- package/data/snippets/icon.md +102 -0
- package/data/snippets/main-menu.md +78 -11
- package/data/snippets/mobile-menu.md +99 -0
- package/data/snippets/notice-bar.md +85 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 주 메뉴 (Main Menu) — KRDS
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
드롭다운형·메가형 주 내비게이션. 헤더 안에서 사용한다. 하위 메뉴는 **disclosure 패턴**(버튼이 링크 목록을 열고 닫는다)이다.
|
|
4
4
|
|
|
5
5
|
## 기본 마크업
|
|
6
6
|
|
|
@@ -12,8 +12,9 @@
|
|
|
12
12
|
</li>
|
|
13
13
|
|
|
14
14
|
<li class="main-menu__item">
|
|
15
|
-
<button type="button" class="main-
|
|
15
|
+
<button type="button" class="main-menu__toggle" aria-expanded="false" aria-controls="submenu-services">
|
|
16
16
|
서비스
|
|
17
|
+
<svg class="main-menu__icon icon icon--xsmall" aria-hidden="true"><use href="/assets/icons/sprite.svg#chevron-down"></use></svg>
|
|
17
18
|
</button>
|
|
18
19
|
<ul id="submenu-services" class="main-menu__submenu" hidden>
|
|
19
20
|
<li><a href="/services/a">서비스 A</a></li>
|
|
@@ -29,21 +30,87 @@
|
|
|
29
30
|
</nav>
|
|
30
31
|
```
|
|
31
32
|
|
|
33
|
+
## 시맨틱 구조
|
|
34
|
+
|
|
35
|
+
- **Root 태그**: `<nav class="main-menu" aria-label="주 메뉴">`
|
|
36
|
+
- **자식**: `ul.main-menu__list` → `li.main-menu__item` → `a.main-menu__link`(이동) 또는 `button.main-menu__toggle`(하위 패널 열기)
|
|
37
|
+
- **필수 ARIA**: `nav`에 `aria-label` · 토글 버튼에 `aria-expanded` + `aria-controls` · 현재 페이지에 `aria-current="page"`
|
|
38
|
+
- **쓰지 않는 것**: `role="menu"` · `role="menuitem"` · `aria-haspopup` — 링크 목록을 펼치는 것일 뿐 애플리케이션 메뉴가 아니다
|
|
39
|
+
|
|
40
|
+
> 상세: `references/html-semantics.md#main-menu`
|
|
41
|
+
|
|
42
|
+
## Variant
|
|
43
|
+
|
|
44
|
+
| Variant | 클래스 | 용도 |
|
|
45
|
+
|---------|--------|------|
|
|
46
|
+
| 드롭다운 | (기본) | 항목 아래 작은 목록. 하위 링크가 한 줄로 끝나는 메뉴 |
|
|
47
|
+
| 메가 | `.main-menu--mega` | 헤더 전체 폭 패널에 그룹별로 나눈 링크. 하위 링크가 많거나 그룹이 있는 메뉴 |
|
|
48
|
+
|
|
49
|
+
### 메가 메뉴
|
|
50
|
+
|
|
51
|
+
패널이 헤더 전체 폭으로 열린다. 그룹 제목은 링크가 아니라 텍스트이고, 목록은 `aria-labelledby`로 그룹 이름을 받는다.
|
|
52
|
+
|
|
53
|
+
```html
|
|
54
|
+
<nav class="main-menu main-menu--mega" aria-label="주 메뉴">
|
|
55
|
+
<ul class="main-menu__list">
|
|
56
|
+
<li class="main-menu__item">
|
|
57
|
+
<button type="button" class="main-menu__toggle" aria-expanded="false" aria-controls="mega-service">
|
|
58
|
+
민원 서비스
|
|
59
|
+
<svg class="main-menu__icon icon icon--xsmall" aria-hidden="true"><use href="/assets/icons/sprite.svg#chevron-down"></use></svg>
|
|
60
|
+
</button>
|
|
61
|
+
<div id="mega-service" class="main-menu__panel" hidden>
|
|
62
|
+
<div class="container main-menu__groups">
|
|
63
|
+
<div class="main-menu__group">
|
|
64
|
+
<p class="main-menu__group-title" id="mega-service-apply">신청</p>
|
|
65
|
+
<ul class="main-menu__group-list" aria-labelledby="mega-service-apply">
|
|
66
|
+
<li><a class="main-menu__sublink" href="/apply/permit">허가 신청</a></li>
|
|
67
|
+
<li><a class="main-menu__sublink" href="/apply/report">신고</a></li>
|
|
68
|
+
<li><a class="main-menu__sublink" href="/apply/certificate">증명서 발급</a></li>
|
|
69
|
+
</ul>
|
|
70
|
+
</div>
|
|
71
|
+
<div class="main-menu__group">
|
|
72
|
+
<p class="main-menu__group-title" id="mega-service-lookup">조회</p>
|
|
73
|
+
<ul class="main-menu__group-list" aria-labelledby="mega-service-lookup">
|
|
74
|
+
<li><a class="main-menu__sublink" href="/lookup/status" aria-current="page">처리 현황</a></li>
|
|
75
|
+
<li><a class="main-menu__sublink" href="/lookup/history">신청 내역</a></li>
|
|
76
|
+
</ul>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
</li>
|
|
81
|
+
|
|
82
|
+
<li class="main-menu__item">
|
|
83
|
+
<a class="main-menu__link" href="/notice">공지사항</a>
|
|
84
|
+
</li>
|
|
85
|
+
</ul>
|
|
86
|
+
</nav>
|
|
87
|
+
```
|
|
88
|
+
|
|
32
89
|
## 동작 (JS)
|
|
33
90
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
91
|
+
`src/js/disclosure-nav.js` — 드롭다운·메가 공통.
|
|
92
|
+
|
|
93
|
+
- 토글 버튼 클릭(`Enter`/`Space`) → 해당 `aria-controls` 패널의 `hidden` 토글 + `aria-expanded` 갱신. 다른 패널은 닫는다
|
|
94
|
+
- `Esc` → 열린 패널을 닫고 **초점을 토글 버튼으로 되돌린다**
|
|
95
|
+
- 메뉴 바깥 클릭 → 닫기
|
|
96
|
+
- `Tab`으로 열린 항목 밖으로 초점이 나가면 닫기
|
|
97
|
+
- 방향키 운용은 하지 않는다 — 링크는 `Tab`으로 순서대로 지난다
|
|
98
|
+
- 마우스를 올리는 것만으로는 열지 않는다(클릭 전용). 호버로 열리면 WCAG 1.4.13(호버 콘텐츠)을 따로 만족시켜야 한다
|
|
38
99
|
|
|
39
100
|
## 접근성
|
|
40
101
|
|
|
41
|
-
-
|
|
42
|
-
- `aria-
|
|
43
|
-
- `
|
|
44
|
-
-
|
|
45
|
-
-
|
|
102
|
+
- 하위 메뉴 트리거는 `<button>` (링크가 아니므로 `<a>` 쓰지 않는다)
|
|
103
|
+
- `aria-expanded`(`true`/`false`) + `aria-controls`(패널 id) — 연결 대상 id가 실제로 존재해야 한다
|
|
104
|
+
- 패널은 `hidden` 속성으로 노출을 제어한다 — 닫힌 패널의 링크는 Tab 순서에서 빠진다
|
|
105
|
+
- 현재 페이지는 `aria-current="page"`. 패널 안에 현재 페이지가 있어도 토글 버튼은 그대로 둔다
|
|
106
|
+
- 링크 터치 영역 44px 이상 — 패널 링크는 `min-h-[4.4rem]`를 포함한다
|
|
107
|
+
- 초점 외곽선: 칸을 꽉 채우는 패널 링크는 `outline-offset`을 음수로 두어 안쪽에 그린다
|
|
108
|
+
- 아이콘은 장식 — `aria-hidden="true"`, 의미는 옆 텍스트가 전한다
|
|
109
|
+
- 메가 패널이 열려 있어도 본문 스크롤을 막지 않는다. 포커스 트랩이 없다(모달이 아니다)
|
|
46
110
|
|
|
47
111
|
## 출처
|
|
48
112
|
|
|
113
|
+
- WAI-ARIA APG: Disclosure Navigation Menu (https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/examples/disclosure-navigation/)
|
|
49
114
|
- CSS: `src/styles/6-components/main-menu.css`
|
|
115
|
+
- JS: `src/js/disclosure-nav.js`
|
|
116
|
+
- 아이콘: `chevron-down` 스프라이트 — `/assets/icons/sprite.svg` (아이콘 카탈로그, R-27)
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# 모바일 메뉴 (Mobile Menu) — infoUX
|
|
2
|
+
|
|
3
|
+
헤더 햄버거로 여는 전체 화면 메뉴. 1280px 미만(모바일·태블릿)에서 [주 메뉴](main-menu.md)를 대신한다. 화면 전체를 덮으므로 모달처럼 초점을 가둔다.
|
|
4
|
+
|
|
5
|
+
## 기본 마크업
|
|
6
|
+
|
|
7
|
+
헤더의 햄버거 버튼과 패널은 **한 쌍**이다. 패널은 `header` 바깥(페이지 shell의 `body` 직계)에 둔다.
|
|
8
|
+
|
|
9
|
+
```html
|
|
10
|
+
<header id="header" class="site-header">
|
|
11
|
+
<div class="container site-header__inner">
|
|
12
|
+
<a class="site-header__brand" href="/">
|
|
13
|
+
<img src="/logo.svg" alt="기관명">
|
|
14
|
+
</a>
|
|
15
|
+
<div class="site-header__actions">
|
|
16
|
+
<button type="button" class="site-header__toggle" aria-label="전체 메뉴" aria-expanded="false" aria-controls="mobile-menu" data-mobile-menu-open="mobile-menu">
|
|
17
|
+
<svg class="icon" aria-hidden="true"><use href="/assets/icons/sprite.svg#menu"></use></svg>
|
|
18
|
+
</button>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
</header>
|
|
22
|
+
|
|
23
|
+
<div id="mobile-menu" class="mobile-menu" role="dialog" aria-modal="true" aria-labelledby="mobile-menu-title" hidden>
|
|
24
|
+
<div class="mobile-menu__header">
|
|
25
|
+
<p id="mobile-menu-title" class="mobile-menu__title">전체 메뉴</p>
|
|
26
|
+
<button type="button" class="mobile-menu__close" aria-label="전체 메뉴 닫기" data-mobile-menu-close>
|
|
27
|
+
<svg class="icon" aria-hidden="true"><use href="/assets/icons/sprite.svg#close"></use></svg>
|
|
28
|
+
</button>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
<nav class="mobile-menu__nav" aria-label="주 메뉴">
|
|
32
|
+
<ul class="mobile-menu__list">
|
|
33
|
+
<li class="mobile-menu__item">
|
|
34
|
+
<a class="mobile-menu__link" href="/about">소개</a>
|
|
35
|
+
</li>
|
|
36
|
+
<li class="mobile-menu__item">
|
|
37
|
+
<details class="mobile-menu__group">
|
|
38
|
+
<summary class="mobile-menu__summary">
|
|
39
|
+
서비스
|
|
40
|
+
<svg class="mobile-menu__icon icon icon--xsmall" aria-hidden="true"><use href="/assets/icons/sprite.svg#chevron-down"></use></svg>
|
|
41
|
+
</summary>
|
|
42
|
+
<ul class="mobile-menu__sublist">
|
|
43
|
+
<li><a class="mobile-menu__sublink" href="/services/apply">신청</a></li>
|
|
44
|
+
<li><a class="mobile-menu__sublink" href="/services/lookup" aria-current="page">조회</a></li>
|
|
45
|
+
<li><a class="mobile-menu__sublink" href="/services/guide">이용 안내</a></li>
|
|
46
|
+
</ul>
|
|
47
|
+
</details>
|
|
48
|
+
</li>
|
|
49
|
+
<li class="mobile-menu__item">
|
|
50
|
+
<a class="mobile-menu__link" href="/notice">공지사항</a>
|
|
51
|
+
</li>
|
|
52
|
+
</ul>
|
|
53
|
+
</nav>
|
|
54
|
+
</div>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## 시맨틱 구조
|
|
58
|
+
|
|
59
|
+
- **Root 태그**: `<div class="mobile-menu" role="dialog" aria-modal="true" aria-labelledby="…" hidden>`
|
|
60
|
+
- **자식**: `__header`(제목 + 닫기 버튼) → `nav.mobile-menu__nav` → `ul.mobile-menu__list`
|
|
61
|
+
- **하위 메뉴**: native `<details>/<summary>` — 열고 닫는 상태를 브라우저가 관리한다. ARIA를 덧붙이지 않는다
|
|
62
|
+
- **필수 ARIA**: 패널에 `role="dialog"` + `aria-modal="true"` + `aria-labelledby` · 햄버거에 `aria-expanded` + `aria-controls`
|
|
63
|
+
|
|
64
|
+
> 상세: `references/html-semantics.md#mobile-menu`
|
|
65
|
+
|
|
66
|
+
## 동작 (JS)
|
|
67
|
+
|
|
68
|
+
`src/js/mobile-menu.js`
|
|
69
|
+
|
|
70
|
+
- 열기: 햄버거(`data-mobile-menu-open="패널 id"`) 클릭 → `hidden` 제거 + 햄버거 `aria-expanded="true"` + 본문 스크롤 잠금 + 첫 포커스 가능 요소(닫기 버튼)로 초점 이동
|
|
71
|
+
- 닫기: 닫기 버튼(`data-mobile-menu-close`) 또는 `Esc` → `hidden` 복원 + `aria-expanded="false"` + **햄버거로 초점 복귀**
|
|
72
|
+
- 포커스 트랩: `Tab`/`Shift+Tab`이 패널 안에서만 순환한다. 닫힌 `details` 안의 링크는 순환에서 빠진다
|
|
73
|
+
- 같은 페이지 앵커(`href="#…"`)를 누르면 메뉴를 닫는다
|
|
74
|
+
- 화면이 1280px 이상으로 넓어지면 열려 있던 패널을 정리한다 (주 메뉴가 대신한다)
|
|
75
|
+
|
|
76
|
+
## 사용 조건
|
|
77
|
+
|
|
78
|
+
- 하위 단계는 한 단계까지 — `details` 안에 `details`를 또 넣지 않는다. 더 깊으면 메뉴 구조를 다시 짠다
|
|
79
|
+
- 패널 안에 검색·로그인 같은 유틸리티를 둘 수 있다. 이 경우에도 닫기 버튼이 항상 첫 번째 포커스 대상이다
|
|
80
|
+
- 패널 타이틀은 "전체 메뉴"처럼 기능 이름을 쓴다. 기관 홍보 문구를 넣지 않는다
|
|
81
|
+
- 장식 애니메이션은 쓰지 않는다. 열림은 즉시 나타나는 것이 기본이다 (필요하면 fade 150~200ms, `prefers-reduced-motion` 가드 필수 · R-22)
|
|
82
|
+
|
|
83
|
+
## 접근성
|
|
84
|
+
|
|
85
|
+
- 패널 열림 중 뒤쪽 콘텐츠는 `aria-modal="true"`로 스크린리더 탐색에서 빠진다
|
|
86
|
+
- 햄버거 `aria-label`은 **고정**한다 (`전체 메뉴`). 열림 여부는 `aria-expanded`가 전하므로 라벨을 "열기/닫기"로 바꾸지 않는다
|
|
87
|
+
- 닫기 버튼 `aria-label="전체 메뉴 닫기"` 필수 — 아이콘만 있는 버튼이므로
|
|
88
|
+
- 아이콘은 모두 장식 — `aria-hidden="true"`. 햄버거·닫기 모양의 텍스트 기호로 아이콘을 대신하지 않는다 (R-27)
|
|
89
|
+
- 터치 영역: 햄버거·닫기 44×44px, 항목 56px / 하위 항목 48px (R-13)
|
|
90
|
+
- 초점 외곽선: 스크롤 영역(`overflow-y: auto`) 안에서 칸을 꽉 채우는 항목은 바깥 외곽선이 잘리므로 `outline-offset`을 음수로 두어 안쪽에 그린다
|
|
91
|
+
- 현재 페이지는 `aria-current="page"`
|
|
92
|
+
- 키보드: `Tab` 순환 · `Enter`/`Space`로 `summary` 토글 · `Esc` 닫기
|
|
93
|
+
|
|
94
|
+
## 출처
|
|
95
|
+
|
|
96
|
+
- WAI-ARIA APG: Dialog (Modal) — https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/
|
|
97
|
+
- CSS: `src/styles/6-components/mobile-menu.css`
|
|
98
|
+
- JS: `src/js/mobile-menu.js`
|
|
99
|
+
- 아이콘: `menu` · `close` · `chevron-down` 스프라이트 — `/assets/icons/sprite.svg` (아이콘 카탈로그, R-27)
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# 공지 띠 (Notice Bar) — infoUX
|
|
2
|
+
|
|
3
|
+
페이지 최상단에서 사이트 방문자 모두에게 한 번 알리는 공지. 점검·휴무·운영 변경처럼 **기간이 있는 안내**에 쓴다.
|
|
4
|
+
|
|
5
|
+
## 기본 마크업
|
|
6
|
+
|
|
7
|
+
페이지 shell에서 **건너뛰기 링크(`.skip-to-content`) 다음, `header#header` 앞**에 둔다.
|
|
8
|
+
|
|
9
|
+
```html
|
|
10
|
+
<section class="notice-bar notice-bar--info" aria-label="사이트 공지" data-notice-id="2026-10-maintenance">
|
|
11
|
+
<div class="container notice-bar__inner">
|
|
12
|
+
<span class="notice-bar__label">점검</span>
|
|
13
|
+
<p class="notice-bar__message">
|
|
14
|
+
<a class="notice-bar__link" href="/notice/maintenance">10월 12일 새벽 0시부터 6시까지 시스템 점검이 있습니다</a>
|
|
15
|
+
</p>
|
|
16
|
+
<button type="button" class="notice-bar__close" aria-label="공지 닫기">
|
|
17
|
+
<svg class="icon" aria-hidden="true"><use href="/assets/icons/sprite.svg#close"></use></svg>
|
|
18
|
+
</button>
|
|
19
|
+
</div>
|
|
20
|
+
</section>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## 시맨틱 구조
|
|
24
|
+
|
|
25
|
+
- **Root 태그**: `<section class="notice-bar" aria-label="사이트 공지">` — 이름 있는 영역(region)이 되어 스크린리더 랜드마크 탐색에 잡힌다
|
|
26
|
+
- **자식**: `.container` → `__label`(분류 텍스트) · `__message`(문장 + 링크) · `__close`(닫기 버튼)
|
|
27
|
+
- **필수 ARIA**: `aria-label` (영역 이름) · 닫기 버튼 `aria-label="공지 닫기"`
|
|
28
|
+
- **라이브 영역을 쓰지 않는다**: `role="alert"` · `aria-live`는 붙이지 않는다. 페이지 로드 때 이미 있는 정적 안내이고, 낭독을 강제하면 매 페이지마다 방해가 된다
|
|
29
|
+
|
|
30
|
+
> 상세: `references/html-semantics.md#notice-bar`
|
|
31
|
+
|
|
32
|
+
## Variant
|
|
33
|
+
|
|
34
|
+
| Variant | 클래스 | 용도 | 라벨 예 |
|
|
35
|
+
|---------|--------|------|---------|
|
|
36
|
+
| 정보 | `.notice-bar--info` | 일반 안내 (기본) | 공지 |
|
|
37
|
+
| 주의 | `.notice-bar--warning` | 점검·휴무·일정 변경 | 점검 |
|
|
38
|
+
| 긴급 | `.notice-bar--danger` | 서비스 중단·장애·재난 | 긴급 |
|
|
39
|
+
|
|
40
|
+
톤은 색만으로 전하지 않는다 — 라벨 텍스트가 같은 뜻을 전한다 (WCAG 1.4.1).
|
|
41
|
+
|
|
42
|
+
## 동작 (JS)
|
|
43
|
+
|
|
44
|
+
`src/js/notice-bar.js`
|
|
45
|
+
|
|
46
|
+
- 닫기 버튼 → 띠에 `hidden` 부여. `data-notice-id`가 있으면 `localStorage`에 닫은 기록을 남긴다
|
|
47
|
+
- 다음 방문에는 같은 `data-notice-id`의 띠를 로드 때 숨긴다. **공지 내용이 바뀌면 `data-notice-id`도 바꾼다** — 그래야 새 공지가 다시 보인다
|
|
48
|
+
- 닫은 뒤 초점은 헤더의 첫 링크·버튼으로 옮긴다 (사라진 버튼에 초점이 남지 않게)
|
|
49
|
+
- 저장소를 못 쓰는 환경(시크릿 모드·차단)에서도 닫기 자체는 동작한다. 다음 방문에 다시 보일 뿐이다
|
|
50
|
+
|
|
51
|
+
## 사용 조건
|
|
52
|
+
|
|
53
|
+
- **한 번에 하나만** 둔다. 여러 공지가 있으면 가장 중요한 하나를 띄우고 나머지는 공지사항 목록으로 안내한다
|
|
54
|
+
- **자동으로 넘어가거나 굴러가는 형태(롤링·마키)로 만들지 않는다.** 5초 넘게 움직이는 콘텐츠는 멈출 수 있어야 하고(WCAG 2.2.2), 읽기 어려운 사용자를 만든다
|
|
55
|
+
- 장문의 본문을 띠에 넣지 않는다. 한 줄 요약 + 상세 페이지 링크로 둔다
|
|
56
|
+
- 만료일이 지난 공지는 내린다. 기간 없는 상시 안내(약관 변경 등)에 쓰지 않는다
|
|
57
|
+
- 쿠키·개인정보 동의 배너와 다르다 — 동의 요청은 이 컴포넌트로 만들지 않는다
|
|
58
|
+
- 사이트 유형: 공공서비스·공공기관·일반사이트·커머스에서 쓴다. CMS·관리자는 시스템 공지를 `alert`로 화면 안에 둔다
|
|
59
|
+
|
|
60
|
+
### 다른 알림 컴포넌트와의 구분
|
|
61
|
+
|
|
62
|
+
| | 공지 띠 | Alert | Toast |
|
|
63
|
+
|---|---------|-------|-------|
|
|
64
|
+
| 위치 | 페이지 최상단 | 해당 콘텐츠 영역 안 | 화면 모서리 |
|
|
65
|
+
| 성격 | 사이트 전체 안내 (정적) | 이 화면의 상태 메시지 | 방금 한 동작의 결과 |
|
|
66
|
+
| 사라짐 | 사용자가 닫음 | 상태가 바뀔 때 | 몇 초 뒤 자동 |
|
|
67
|
+
| 라이브 영역 | 쓰지 않음 | `role="alert"`/`status` | `role="status"`/`alert` |
|
|
68
|
+
|
|
69
|
+
## 접근성
|
|
70
|
+
|
|
71
|
+
- 영역 이름 `aria-label="사이트 공지"` — 페이지에 비슷한 영역이 더 있으면 서로 다른 이름으로 구분한다
|
|
72
|
+
- 링크는 밑줄로 구분한다. 색 차이만으로 링크임을 전하지 않는다
|
|
73
|
+
- 닫기 버튼은 아이콘만 있으므로 `aria-label` 필수. 아이콘은 `aria-hidden="true"`
|
|
74
|
+
- 터치 영역: 닫기 버튼 44×44px, 링크 `min-h-[4.4rem]` (R-13)
|
|
75
|
+
- 대비: 본문 텍스트 `--color-text`, 라벨은 `--color-text-inverse` on `--color-information-60`/`--color-warning-60`/`--color-danger-60` (4.5:1 이상)
|
|
76
|
+
- 닫은 뒤 초점이 문서 처음으로 날아가지 않도록 헤더로 옮긴다 (WCAG 2.4.3)
|
|
77
|
+
- 동적으로 삽입하는 긴급 안내(장애 발생 직후 등)는 이 컴포넌트가 아니라 [alert](alert.md)의 `role="alert"`를 쓴다
|
|
78
|
+
|
|
79
|
+
## 출처
|
|
80
|
+
|
|
81
|
+
- 색상은 `--color-info-surface` · `--color-information-20` · `--color-information-60` (톤별 warning/danger 동일 구조)
|
|
82
|
+
- 간격·타이포는 프로젝트 밀도에 맞는 CSS/Tailwind 직접값 사용
|
|
83
|
+
- CSS: `src/styles/6-components/notice-bar.css`
|
|
84
|
+
- JS: `src/js/notice-bar.js`
|
|
85
|
+
- 아이콘: `close` 스프라이트 — `/assets/icons/sprite.svg` (아이콘 카탈로그, R-27)
|