---
url: https://docs.nemo12.com/design-system/focus-and-load.md
description: >-
  Luật đo được cho Focus Order và Information Load: learner nhìn vào đâu trước,
  và mỗi màn chứa bao nhiêu thông tin là vừa (mã F-*).
---

# Focus Order và Information Load (SRC-1303)

Chủ dự án 09.10.2026: hai lỗi hay gặp nhất khi rà màn theo 25 yếu tố của
[ui.nemo12.com](https://ui.nemo12.com/) là **"learner không biết nhìn vào đâu trước, rồi đâu sau"** và
**"quá nhiều thông tin"**. Trang này biến hai câu ấy thành luật đo được (`F-*` thứ tự tập trung, `L-*`
tải thông tin) và đặt thang chấm 25 yếu tố mà skill `/ui-audit-25` (`.claude/skills/ui-audit-25/SKILL.md`)
dùng. Nó là một phần của [DS-001](./index.md) và đứng trên [hierarchy.md](./hierarchy.md): hierarchy.md
nói thứ bậc (bốn bậc, thang chữ), trang này nói **ngân sách** (bao nhiêu thứ, theo thứ tự nào).

"Tầm nhìn đầu" (above the fold) = khung 375 x 812 và 1440 x 900, tính từ dưới header dính.

## 1. Focus Order: mắt bắt đầu ở đâu, đi tiếp ở đâu

| Mã | Luật | Đo bằng |
| --- | --- | --- |
| F1 | **Một việc chính mỗi màn.** Đúng một nút tô đầy (`variant="accent"` hay `default` cỡ lg) trong tầm nhìn đầu. Việc thứ hai là nút viền hoặc link. | e2e: đếm nút tô đầy có `top < innerHeight` |
| F2 | **h1 nói màn này để làm gì** (tên bài, tên việc), không nói tên app. Đúng một h1. | e2e: 1 `h1` trong `[data-part=journey-content]` |
| F3 | **Thứ tự đọc 1-2-3 cố định**: (1) em đang ở đâu: h1 + một dòng phụ; (2) làm gì bây giờ: nút chính, đứng ngay dưới phần (1), không có khối nào chen giữa ngoài một dòng công thức hay một câu dặn; (3) hỗ trợ và tra cứu: phía dưới nút chính, gập lại. | e2e: `y(h1) < y(nút chính) < y(khối gập đầu tiên)` |
| F4 | **Nút chính đổi theo trạng thái**, không đứng yên một nhãn. Xong hết thì việc chính là bước kế (bài sau, chủ đề sau); "Làm lại" lùi xuống thành nút viền. | e2e ở trạng thái xong |
| F5 | **Vị trí hiện tại khớp với màn.** Menu và thanh bước sáng đúng mục của màn đang mở; không sáng một bước learner đã đi qua (vd. "Choose" khi đã ở trong bài). | e2e: `aria-current=step` đúng `data-step` |
| F6 | **Nhóm hỗ trợ có một câu dẫn** nói vì sao nên mở (tiếng Việt ở trang hành trình theo SRC-953; tiếng Anh ở trang bốn kỹ năng, Full tests và Grammar theo SRC-1325), để mắt biết đó là bậc 3, không phải việc phải làm. | review |
| F7 | **Cột phụ không tranh tầm nhìn.** Cột phải hay thẻ trạng thái chỉ đứng ở màn mà nó là câu trả lời (hub, trang journey); ở màn làm bài nó không hiện, nội dung lấy đủ bề ngang. Ở 375px không có gì đứng giữa header và h1 ngoài vệt đường dẫn. | e2e: không `[data-part=status-card]` ở màn luyện |

## 2. Information Load: bao nhiêu là đủ

| Mã | Ngân sách | Đo bằng |
| --- | --- | --- |
| L1 | **Tối đa 5 khối nhìn thấy trong tầm nhìn đầu** ở 375px, tính sau header: vệt đường dẫn, khối tiêu đề (kicker + h1 + dòng phụ = 1), công thức, nút chính, mỗi card hay khối gập = 1. | e2e đếm con trực tiếp có `top < innerHeight` |
| L2 | **Header nội dung tối đa ba lớp**: kicker (tuỳ chọn), h1, một dòng phụ (= hierarchy.md H-I3). | e2e |
| L3 | **Tối đa 7 mục cùng cấp** trong một nhóm điều hướng, **tối đa 5 mục hỗ trợ** mở cùng lúc; hơn nữa thì gập phần dư (= H-I6). | test thuần |
| L4 | **Hiện dần**: bậc 3-4 (video, giải thích, ví dụ, lỗi hay gặp, tra cứu) gập mặc định; mở một mục không tự mở mục khác. Đang làm bài thì chỉ còn bài trên màn (SRC-1068). | e2e `aria-expanded=false` |
| L5 | **Không nói một điều hai lần** trên cùng màn (= H-I5): thẻ trạng thái không lặp số mà trang đã nói, vệt đường dẫn không lặp thêm một kicker cùng chữ, tiến độ chỉ một chỗ. | e2e đếm chuỗi |
| L6 | **Mỗi khối một câu hỏi.** Một khối trả lời đúng một câu learner đang hỏi; khối trả lời hai câu thì tách hoặc bỏ một nửa. | review |
| L7 | **Dữ liệu trống thì nói thật một dòng** ("Not set yet"), không vẽ cả khung rỗng chiếm tầm nhìn. | review |

## 3. Thang chấm 25 yếu tố

Nguồn 25 yếu tố: `apps/ui/src/content.ts` (năm lớp Structure, Interaction, Components, Experience,
Visual, mỗi lớp năm yếu tố; chi tiết ở `apps/ui/src/deep/*.ts`). Mỗi yếu tố chấm một trong ba mức,
luôn kèm **bằng chứng** (số đo, selector, ảnh chụp):

| Mức | Nghĩa | Điểm |
| --- | --- | --- |
| pass | đạt mọi luật liên quan | 2 |
| partial | đạt phần lớn, còn một vi phạm nhỏ | 1 |
| fail | vi phạm một luật có mã, hoặc learner kẹt | 0 |

Điểm màn = tổng / 50. Thứ tự sửa: **fail của F-* và L-* trước\*\* (hai lỗi chủ dự án nêu), rồi fail còn
lại theo lớp Structure → Interaction → Experience → Components → Visual, rồi partial. Mỗi PR sửa một
lô (tối đa 3-5 yếu tố), chấm lại, ghi vào bảng điểm.

| # | Yếu tố | Luật chấm chính |
| --- | --- | --- |
| 1 | Information Architecture | hierarchy.md §1 bốn bậc; L6 |
| 2 | Navigation | F5; menu cấp 1 luôn mở, Learn luôn nổi, mục khác là tag (SRC-1321, đảo menu gập SRC-1300) |
| 3 | Layout | layout-standard.md; F7 |
| 4 | Visual Hierarchy | F1-F3; hierarchy.md §2 |
| 5 | Responsive Design | audit-ui lớp 2 ở 375/768/1440; L1 ở 375px |
| 6 | Interaction Pattern | dùng component có sẵn (Fold, Accordion), không tự chế |
| 7 | User Flow | F4; có đường đi tiếp sau khi xong |
| 8 | Affordance | nút trông như nút, khối gập có dấu +/− và `aria-expanded` |
| 9 | Feedback | kết quả ngay sau hành động (Correct / Not yet + lời giải) |
| 10 | State | đủ trạng thái: chưa làm, đang làm, xong, đang tải, lỗi |
| 11 | Design System | DS-001 §0 bộ ba; token, không màu cứng |
| 12 | Components | shadcn `Button`, `Card`; không nút tự vẽ |
| 13 | UI Patterns | card-patterns.md |
| 14 | Forms | nhãn, `aria-label`, phím Enter, lỗi tại chỗ |
| 15 | Data Display | `tabular-nums`, số đi kèm đơn vị, không lặp (L5) |
| 16 | Onboarding | màn đầu có một câu dẫn và một việc (F1, F6) |
| 17 | Empty State | L7 |
| 18 | Error Handling | không tìm thấy, mất mạng: nói thật, có đường về |
| 19 | Accessibility | tương phản, vùng bấm 44px, focus nhìn thấy, đúng vai |
| 20 | Personalization | dữ liệu thật của learner, không số mẫu |
| 21 | Typography | thang năm cấp hierarchy.md §2a |
| 22 | Color | một màu nhấn cho việc chính; trạng thái có chữ đi kèm |
| 23 | Spacing | thang 4-8-12-16-24-32; khe nhóm > khe trong nhóm |
| 24 | Iconography | icon đi kèm chữ hoặc có tên cho trình đọc màn hình |
| 25 | Motion | preset `Motion.tsx`; tôn trọng reduced motion |

## 4. Bảng điểm theo màn

Mỗi màn đã rà có một file trong [`docs/design-system/scorecards/`](./scorecards/learn-ielts-grammar-topic.md):
ngày, điểm, 25 dòng mức + bằng chứng, các lô đã sửa (PR), việc còn lại. Lượt sau mở file ấy, chấm lại,
sửa lô kế tiếp: đó là cách đi **dần dần** qua 25 yếu tố mà không phải rà lại từ đầu.

Lượt 4 (09.10.2026) mở thêm 16 màn chính của learn `/ielts`: [hub](./scorecards/learn-ielts-hub.md), [goal](./scorecards/learn-ielts-goal.md), [level](./scorecards/learn-ielts-level.md), [diagnostic](./scorecards/learn-ielts-diagnostic.md), [diagnostic report](./scorecards/learn-ielts-diagnostic-report.md), [learning plan](./scorecards/learn-ielts-learning-plan.md), [progress](./scorecards/learn-ielts-progress.md), [unstuck](./scorecards/learn-ielts-unstuck.md), [listening](./scorecards/learn-ielts-listening.md), [writing](./scorecards/learn-ielts-writing.md), [speaking](./scorecards/learn-ielts-speaking.md), [tests](./scorecards/learn-ielts-tests.md), [grammar](./scorecards/learn-ielts-grammar.md), [leaderboard](./scorecards/learn-ielts-leaderboard.md), [live](./scorecards/learn-ielts-live.md), [speak together](./scorecards/learn-ielts-speaking-pair.md).
