# Toast
Thông báo nổi ngắn ở dưới màn hình ("Đã nhập 10 trân châu đen", "Khách phát hiện tờ tiền giả!"), tự tắt sau khoảng 2,5 giây; có thể kèm icon, số tiền thưởng lớn và nút hành động như "Hoàn tác".
## Khi nào dùng
- Báo kết quả một hành động vừa xong, không cần người chơi trả lời: nhập hàng, bán ly, đổi giá.
- Báo chuyện xấu cần chú ý ngay (phạt, tiền giả, lỗi): dùng `tone: 'alert'`.
- Báo thưởng ("+50k" lì xì Thần Tài, tiền vía): `tone: 'reward'`.
- Cho phép sửa sai nhanh ("Đã bỏ 1 ly" + "Hoàn tác"): thêm `action`.
- Cần người chơi chọn "Có/Không" thì dùng Dialog, đừng dùng toast.
## Biến thể
| Biến thể | Lớp | Dùng khi |
|---|---|---|
| Thường | `tt-toast` | Nền `ink`, chữ `bg`, bo 24, viền 1.5px `on-fill` 25% |
| Cảnh báo | `tt-toast tt-toast--alert` | Nền `toast-alert`, chữ `on-fill` (`.pri` của game) |
| Thành công | `tt-toast tt-toast--rich tt-toast--success` | Nền `toast-success`, icon ✓ |
| Lưu ý | `tt-toast tt-toast--rich tt-toast--warn` | Nền `toast-warn`, icon ! |
| Thông tin | `tt-toast tt-toast--rich tt-toast--info` | Nền `toast-info`, icon i |
| Phần thưởng | `tt-toast tt-toast--rich tt-toast--reward` | Nền `toast-reward`, icon + số tiền lớn 1.45rem |
| Trưng bày | `tt-toast tt-toast--inline` | Chỉ để vẽ mẫu tĩnh trong tài liệu, không dùng trong game |
`tt-toast--rich` (xếp ngang icon + chữ + nút) do JS tự thêm khi toast có icon, tone mới hoặc nút. Mỗi tone luôn có icon hoặc chữ đi kèm, không chỉ khác màu.
## Cấu trúc
```html
Đã nhập 10 trân châu đen
iĐã bỏ 1 ly trà sữa
```
Phần tử con: `tt-toast__icon` (`--img` khi là PNG, ảnh bên trong dùng lớp `tt-toast__img`), `tt-toast__text`, `tt-toast__label`, `tt-toast__amount`, `tt-toast__action`.
## Trạng thái
| Trạng thái | Hiệu ứng |
|---|---|
| Ẩn (mặc định) | `opacity: 0`, `pointer-events: none` |
| `is-shown` | `opacity: 1`, chuyển .25s; nằm cách đáy 85px + `env(safe-area-inset-bottom)` |
| `tt-toast--action.is-shown` | Như trên nhưng `pointer-events: auto` để bấm được nút (JS chỉ thêm `--action` khi có `action`) |
## Hành vi JS
```js
TTMU.toast(message, { tone?, icon?, amount?, action?: { label, onClick }, duration?: ms }) // trả về hàm ẩn toast sớm
TTMU.toast('Đã nhập 10 trân châu đen');
TTMU.toast('Khách phát hiện tờ tiền giả! −5k', { tone: 'alert', duration: 3500 });
TTMU.toast('Lì xì Thần Tài', { tone: 'reward', amount: '+50k', icon: '../../assets/Icons/ic_money.png' });
TTMU.toast('Đã bỏ 1 ly trà sữa', { tone: 'info', action: { label: 'Hoàn tác', onClick: undo } });
```
- `amount` chỉ có tác dụng với `tone: 'reward'` (tone khác bỏ qua).
- `tone`: `alert | success | warn | info | reward`. `icon`: ký tự ngắn hoặc đường dẫn ảnh; mặc định ✓ ! i ★ theo tone.
- Có `action` thì toast hiện tối thiểu 6 giây, tạm dừng đếm khi hover hoặc focus vào toast, tiếp tục (còn ít nhất 1,5 giây) khi rời đi. Bấm nút: toast ẩn rồi gọi `onClick`.
- Chỉ có một phần tử toast, được tạo ở lần gọi đầu và dùng lại; gọi liên tiếp thì thay nội dung và tính lại giờ.
- Toast `alert` đang hiện thì toast thường không đè được (giống `pri` của game).
- Vùng `role="status"` được tạo rỗng ở lần gọi đầu, nội dung điền ở tick kế tiếp (để screen reader đọc được toast đầu tiên) và xoá sau khi mờ hẳn.
- Toast (z-index 100000) nằm dưới nền mờ của Dialog (100050) và dưới UrgentAlert (100060), giống game: toast, kể cả toast có nút hành động, bị che khi chúng đang mở, nên gọi toast sau khi dialog / cảnh báo khẩn đã resolve. Tooltip (100070) nằm trên cùng.
- Chữ được gán bằng `textContent`. Hàm `toast()` gốc dùng `innerHTML` nên chuỗi có thẻ HTML từng gây XSS. Không bao giờ truyền HTML vào đây; ký tự `<` sẽ hiện nguyên văn.
## Token sử dụng
`ink`, `bg`, `on-fill`, `toast-alert`, `toast-success`, `toast-warn`, `toast-info`, `toast-reward`, `shadow-toast`, `radius-24`, `radius-pill`, `radius-round`, `space-4`, `space-10`, `space-12`, `space-22`.
## Khả năng tiếp cận
- Phần tử có `role="status"` và `aria-live="polite"`: screen reader đọc khi rảnh, không ngắt lời đang đọc. Icon trang trí có `aria-hidden`.
- Toast thường không nhận focus và không bấm được. Toast có nút thì nút là `