# 알림 · 토스트 · 인라인 오류

| 항목 | 경로 |
|------|------|
| 데모 | `alert.html` |
| CSS | `css/alert.css` (+ 폼 연동 시 `form.css`) |
| JS | `js/common.js` — toast 섹션 |
| 관련 | 모달 알림 → [popup.md](./popup.md) (`alertdialog`) |

---

## 언제 무엇을

| 유형 | 용도 | 접근성 |
|------|------|--------|
| `.alert` 배너 | 페이지에 고정되는 안내·결과 | `role="status"`(일반) / `role="alert"`(오류·긴급) |
| `.toast` | 잠깐 뜨는 저장 완료 등 | `#toastRegion` `aria-live` |
| `.field-msg` | 입력 필드 바로 아래 오류/도움말 | `aria-describedby` + `aria-invalid` |
| 모달 | 확인이 꼭 필요한 알림 | `alertdialog` (popup) |

---

## 페이지 배너

```html
<div class="alert alert--success" role="status">
  <div class="alert__body">
    <p class="alert__tit">저장 완료</p>
    <p class="alert__msg">입력하신 내용이 저장되었습니다.</p>
  </div>
</div>

<div class="alert alert--error" role="alert">
  <div class="alert__body">
    <p class="alert__tit">오류</p>
    <p class="alert__msg">필수 항목을 확인해 주세요.</p>
  </div>
  <button type="button" class="alert__close" data-alert-close>닫기</button>
</div>
```

변형: `alert--info` · `alert--success` · `alert--warning` · `alert--error`

---

## 토스트

```html
<!-- body 하단 1회 -->
<div id="toastRegion" class="toast-region" aria-live="polite" aria-relevant="additions" aria-atomic="false"></div>
```

```js
toastShow('저장되었습니다.', { type: 'success' });
toastShow('처리 중 오류가 발생했습니다.', { type: 'error', duration: 6000 });
```

| 옵션 | 기본 | 설명 |
|------|------|------|
| `type` | `'info'` | info / success / warning / error |
| `duration` | `4000` | ms · `0`이면 자동 닫기 없음 |
| `closable` | `true` | 닫기 버튼 |

- 포커스·호버 중에는 자동 닫기 일시 정지 (`prefers-reduced-motion` 시 애니메이션 없음)
- 오류는 토스트에 `role="alert"` 부여

---

## 인라인 필드 오류

```html
<label for="userEmail" class="form-label">이메일</label>
<div class="form-field">
  <input type="email" id="userEmail" class="form-input"
    aria-invalid="true" aria-describedby="userEmailHelp userEmailErr">
</div>
<p id="userEmailHelp" class="field-msg is-help">예: name@example.com</p>
<p id="userEmailErr" class="field-msg is-error" role="alert">이메일 형식이 올바르지 않습니다.</p>
```

- 오류 문구는 입력과 **`aria-describedby`로 연결** (오류만 넣어도 됨)
- 오류 상태: **`aria-invalid="true"`**
- 성공 후 오류를 지우면 `aria-invalid` 제거 · 오류 `p` 삭제 또는 `hidden`

---

## 접근성 체크

- [ ] 배너/토스트에 상태 역할(`status`/`alert`/`aria-live`) 있음
- [ ] 색만으로 구별하지 않음 (제목·문구로 의미 전달)
- [ ] 닫기 버튼에 이름(“닫기”)
- [ ] 필드 오류 ↔ `aria-describedby` / `aria-invalid`
- [ ] 중요한 확인은 토스트 대신 모달(`alertdialog`)

---

## 복사 패키지

```
css/alert.css
js/common.js          ← toast 섹션
마크업: alert.html
(#toastRegion 은 body에 1개)
```
