---
url: https://docs.nemo12.com/product/prd-002-learner-ux.md
description: >-
  PRD-002 Learner-first UX: audit hiện trạng 14.08.2026, nhu cầu learner thành
  yêu cầu có trọng số, nguyên tắc thiết kế nạp vào DS-001.
---

# PRD-002 — Learner-first UX: Phân tích yêu cầu & trọng số

> Nguồn: SRC-042 (chỉ đạo 2026-08-14): rà soát features + User Stories, tái tạo Design System (màu sắc, visual direction), phân tích yêu cầu **từ góc độ Learner**, đánh trọng số, rồi sửa toàn bộ UI theo thứ tự **learn → marlins → dolphin**.

Danh sách REQ-UX chính thức nằm trong [PRD-001 §5](prd-001/req/learner.md) (nguồn sự thật duy nhất về requirement catalog). File này là **phân tích**: hiện trạng, lập luận, trọng số.

## 1. Phương pháp

1. Rà soát US-01..57 (danh mục tại thời điểm 2026-08-14; nay đã tới US-79) và toàn bộ REQ ✔ liên quan UI (nhóm LRN, VIS, PAR, MEN, SCH, POR, ADAPT).
2. Audit UI hiện tại của 3 portal (learn / marlins / dolphin) trên code thật.
3. Đứng vai **Nemo (11–15 tuổi, dùng điện thoại là chính, mở app sau giờ học, năng lượng thấp)** để suy ra nhu cầu giao diện; đối chiếu persona + JTBD trong PRD-001 §2.
4. Đánh trọng số 1–10 theo tác động lên core job ("biết chính xác nên làm gì tiếp theo") × tần suất gặp trên hành trình.

## 2. Audit hiện trạng (2026-08-14)

Điểm mạnh: flow đúng (Root → School Home → Cockpit), nội dung tiếng Việt tốt, tone thân thiện sẵn ("Lần đo này chưa đủ tin cậy" — REQ-INT-22), token hóa một phần (ocean/coral/sand).

Vấn đề tìm thấy (mã A-xx để trace vào REQ-UX):

| # | Vấn đề | Ảnh hưởng Learner |
| --- | --- | --- |
| A-01 | Màn "Hôm nay" không có **một** hành động nổi bật duy nhất — ReadinessBar, ModeBanner, danh sách next actions cùng cấp thị giác | Mở app vẫn phải tự quyết "bắt đầu từ đâu" — đúng pain #1 của persona |
| A-02 | Trạng thái tải chỉ là chữ "Đang tải…" — không skeleton; nút bấm không có busy/press state nhất quán | Cảm giác app "đơ", bấm lại nhiều lần |
| A-03 | Hero school là **một mảng màu phẳng** (`background: var(--accent)`); school chỉ khác nhau đúng màu nút | Không có cảm giác "thế giới riêng" từng school |
| A-04 | Thanh tiến độ mỏng 8–12px, không nhãn ngữ cảnh; con số % đứng trơ | Tiến bộ — động lực chính — không "nhìn thấy được" |
| A-05 | Typography phẳng: heading không có scale rõ, card title = font-bold đơn thuần | Khó quét màn hình nhanh, mọi thứ đều "bằng nhau" |
| A-06 | Touch target nhỏ (nút py-1 px-3, tab py-2), tab underline mảnh | Khó bấm trên điện thoại — thiết bị chính của Nemo |
| A-07 | Ba app **lặp code UI** (AvatarMenu/GoogleButton/ProgressViews copy 3 bản) và tự quyết style ad-hoc (style inline `var(--accent)`) | Lệch nhau dần — đúng RISK-012 legacy từng dính |
| A-08 | Màu đỏ `text-destructive` dùng cho lỗi tải dữ liệu học tập; trạng thái node "yếu" cũng đỏ | Trẻ đọc là "mình sai/mình kém" — phán xét không cần thiết |
| A-09 | Empty state nghèo (chỉ 1 câu), thiếu bước tiếp theo | Learner đứng ở ngõ cụt |
| A-10 | Focus/hover có nhưng không đồng bộ; radius/đổ bóng mỗi chỗ một kiểu (rounded-card lẫn rounded-full lẫn shadow tùy hứng) | Cảm giác thiếu trau chuốt, giảm niềm tin (Marlin nhìn cùng màn hình) |

## 3. Nhu cầu Learner → yêu cầu có trọng số

Trọng số (W, /10) = tác động lên core job × tần suất. Cột REQ trỏ về catalog PRD-001 §5 nhóm REQ-UX.

| REQ | Yêu cầu (phát biểu từ vai Nemo) | W | Vì sao trọng số này | Sửa vấn đề | US |
| --- | --- | --- | --- | --- | --- |
| REQ-UX-01 | "Mở app là em biết ngay **một việc** nên làm hôm nay, và vì sao" — mỗi màn đúng 1 primary action (màu coral), phần còn lại lùi cấp | 10 | Đây chính là core job; gặp mọi lần mở app | A-01 | US-03, US-58 |
| REQ-UX-02 | "Em **nhìn thấy** mình tiến bộ" — mastery/readiness là thanh/vòng đậm, có nhãn ngữ cảnh, animation tăng tiến | 9 | Động lực quay lại hằng ngày; gặp ở mọi tab | A-04 | US-06, US-34/35, US-59 |
| REQ-UX-03 | "App không làm em thấy mình kém" — đỏ chỉ dành cho lỗi hệ thống; trạng thái học tập thấp dùng amber/neutral + lời khích lệ; empty state luôn có bước tiếp theo | 9 | An toàn tâm lý quyết định trẻ có quay lại; sai một lần là mất niềm tin | A-08, A-09 | US-54, US-56 |
| REQ-UX-04 | "Chữ dễ đọc, không mỏi" — sàn 14px, body 16px, line-height ≥1.5, contrast AA, độ dài dòng đọc được | 8 | Nền tảng của mọi màn; kế thừa ràng buộc legacy có chủ đích | A-05 | US-20 |
| REQ-UX-05 | "Đâu cũng thấy quen" — 3 portal chỉ dùng component + token của `@nemo12/design-system` (lớp `n12-*`); cấm style ad-hoc, cấm copy component giữa app | 8 | Chống RISK-012; chi phí duy trì; niềm tin gia đình | A-07, A-10 | US-60 |
| REQ-UX-06 | "App luôn nói nó đang làm gì" — skeleton khi tải, busy trên nút, error có nút thử lại; transition 150–200ms, tôn trọng reduced-motion | 7 | Gặp mọi request; mạng học sinh không ổn định | A-02 | US-20 |
| REQ-UX-07 | "Bấm trúng bằng ngón cái" — touch target ≥44px, layout 1 cột co giãn, hành động chính trong tầm ngón cái | 7 | Mobile là thiết bị chính (Q-029) | A-06 | US-22 |
| REQ-UX-08 | "Mỗi school là một thế giới" — hero gradient 2 stop từ accent, icon lớn, accent xuyên suốt tab/nút/chip; nhưng vẫn một hệ component | 6 | Bản sắc tạo hứng thú; xếp sau vì gặp ít màn hơn | A-03 | US-41, US-59 |
| REQ-UX-09 | "Một màn một việc" — mỗi màn ≤3 khối thông tin, chi tiết thì bấm mở dần (progressive disclosure) | 6 | Giảm tải nhận thức cho trẻ; hỗ trợ UX-01 | A-01 | US-58 |
| REQ-UX-10 | (Vai phụ huynh/mentor) "Cổng người lớn cùng ngôn ngữ hình ảnh, mật độ thông tin cao hơn, số liệu luôn kèm giải thích" | 5 | Quan trọng nhưng tần suất thấp hơn learner; đi sau learn theo đúng thứ tự chỉ đạo | A-07 | US-36, US-60 |

## 4. Nguyên tắc thiết kế rút ra (nạp vào DS-001 v0.2)

1. **One coral action** — mỗi màn đúng một nút coral; mọi nút khác là ocean/outline/ghost.
2. **Progress is the hero** — thanh tiến độ dày, có nhãn, có chuyển động; con số luôn kèm ngữ cảnh.
3. **Đỏ = hệ thống hỏng, không phải học sinh kém** — semantic màu học tập: seafoam (vững) / ocean (đang học) / amber (cần ôn) / neutral (chưa đo).
4. **Thế giới nước sâu → nông**: hero đậm (deep), nội dung trên nền sand sáng; school accent là "sinh vật" nổi bật trên nền đó.
5. **Thin theme**: school chỉ đổi `--accent/--accent-deep/--accent-soft`; không fork component.
6. **Trạng thái là một phần giao diện**: loading/empty/error đều được thiết kế, không phải để trống.

## 5. Phạm vi & thứ tự áp dụng

1. `packages/design-system` v0.2 (tokens + lớp component `n12-*`) — nguồn duy nhất.
2. **learn.nemo12.com** (trọng số learner cao nhất, mọi màn: Join, Root, SchoolHome, Onboarding, Cockpit, Diagnostic, Learning/Lab, ExamPractice, Toàn cảnh, Tiến độ, Whale, Portrait, Profile).
3. **marlins.nemo12.com** (ChildReport, Portrait planner, Explore, Whale).
4. **dolphin.nemo12.com** (danh sách learner + drill-down).
5. **coral.nemo12.com** (bổ sung chỉ đạo cùng ngày: content plane staff cũng về chung một hệ — REQ-UX-05/10).

## 6. Luật trình bày đã chốt trên app learn (đợt 2026-08-18 → 2026-08-24)

Các luật dưới đây là **kết quả áp dụng** REQ-UX-01..10 vào từng màn thật, chốt qua nhiều vòng feedback trên ảnh chụp màn hình. Chúng có tính ràng buộc như requirement: mọi màn mới phải tuân theo, và mọi con số nêu ra là con số bắt buộc, không phải gợi ý.

### 6.1 Gọi đúng tên và gọi đủ tên

1. **Hai loại trải nghiệm gọi đủ tên**: "Learning Experience" và "Assessment Experience". Không rút gọn thành "bài học" / "bài đo" ở nhãn giao diện. Cả hai **trình bày giống hệt nhau** — mỗi lần đúng một câu, chạy bằng cùng một bộ máy, chỉ khác `focusKind`; Assessment không được bày cả 10 câu thành danh sách dài. Assessment có đường dẫn riêng `/<trường>/danh-gia/<môn>/<unit>`.
2. **Ba tầng Package · Module · Unit luôn hiện tên đầy đủ**, cả ba, ở mọi nơi. Cấm tên rút gọn kèm tooltip: tên bị cắt mất đúng phần cần đọc ("Tính thà…", "Hình không…"), mà trên điện thoại — thiết bị chính của Nemo (REQ-UX-07) — không có chuột để rê xem tooltip. Thẻ cao thêm một dòng rẻ hơn một cái tên không đọc được.
3. **Tên môn nói đúng một lần, ở chỗ mắt đang nhìn.** Card mastery đặt tên môn vào chính câu hỏi của nó ("Em học chắc **môn Toán** tới đâu?"); panel phải không có card "Môn học" riêng lặp lại điều đó. Tên môn lấy từ payload overview, client không giữ bảng tên thứ hai.
4. **Cấm viết tắt mã nội bộ trên mặt giao diện learner và phụ huynh** (LT, DS, SH…). Tên đầy đủ phải lấy từ gốc dữ liệu (`strands.name_vi`) chứ không dịch ở client: mã strand là chuyện nội bộ, người đọc không có cách nào tra ra nó nghĩa là gì.
5. **Khu bản đồ toàn môn gọi là "Toàn cảnh".** Tên "Đường học" mô tả hình dạng chứ không mô tả việc, nên từng đổi sang "La bàn" (SRC-372); sau đó Compass bị gỡ khỏi menu vì nó chỉ là mục lục Phần 1..N, còn Toàn cảnh trả lời đúng câu "con đang ở đâu" bằng con số và màu. **Trạng thái hiện tại: menu không có mục La bàn; "Đường học" chỉ còn là tên chuỗi Experience bên trong một Unit.**

### 6.2 Chế độ ngôn ngữ

6. **Bật EN thì không còn một chữ tiếng Việt nào trên màn hình**, kể cả tên môn ("Toán" → "Maths"), nhãn panel phải và tooltip. Panel phải hiện trên **mọi** trang, nên sót một nhãn ở đó là sót ở khắp nơi — mọi nhãn phải đi qua `t()` và bảng dịch dùng chung, không hardcode.

### 6.3 Panel phải — ghi nhận việc đã làm

7. **"Con đã làm gần đây" xếp dọc, mỗi mục là một khối hai dòng full-width**: tên bài đậm ở trên, mốc thời gian ở dòng dưới cỡ 11px, mờ 70%, các khối cách nhau `gap-2`. Tên và mốc chen chung một dòng làm chip dài ngắn lổn nhổn, mắt không quét dọc được.
8. **Card "Xong hôm nay"** cho cảm giác hoàn thành (REQ-UX-02): mỗi Experience hoàn thành trong ngày là một dấu ✓ tròn seafoam, **tối đa 12 dấu**, tên bài ở tooltip cộng 3 tên gần nhất mờ bên dưới. Chỉ đếm bài `completed` — bài trượt không nằm trong khu ăn mừng. **Card chỉ dựng khi có ít nhất một việc để mừng**: một khu ăn mừng rỗng là lời chê.
9. **Số 0 không bao giờ đứng trơ.** 0 điểm hôm nay hiển thị thành một lời mời; ô "đã vững" kèm dòng "còn N unit nữa là tròn X" để mốc kế tiếp luôn nhìn thấy được.

### 6.4 Popover trên Toàn cảnh

10. **Popover neo `fixed` phủ toàn màn hình**, không neo bên trong thẻ. Panel phải có khung riêng và có cuộn, nên popover neo trong đó bị cắt. Khi popover mở, **chính thẻ chứa nó phải được nâng lên `z-50`**: theme cho `.n12-card` một `backdrop-filter`, thứ này mở một stacking context riêng và nhốt mọi `z-index` bên trong.
11. **Mọi popover đều có lối vào bài.** Popover Package và Module dẫn vào Unit đầu tiên của mình; popover Unit dẫn vào cả Learning Experience lẫn Assessment Experience của Unit đó. Mức xem mặc định chỉ bày Package, nên thiếu lối này là không có đường nào vào học.
12. **Popover thẻ "đã làm gần đây" gồm đúng ba thứ**: một câu khen đúng mức việc đã làm (thang: đi hết Unit > quay lại nhiều lượt > mới bắt đầu), một nút đi tiếp, một nút đóng.
13. **Popover Unit bày hai đại lượng bằng hai hình khác nhau** (luật SRC-175 cấm trộn mastery với coverage): **mười ô vuông** là mức vững thang 10, cùng một thước với mọi thẻ trên bản đồ; **các hình tròn** là độ phủ, mỗi chặng một hình, đặc là đã đo. Dùng cùng một hình cho cả hai thì learner đọc "8" mà không biết 8 đó là vững hay đã đi qua.
14. **Độ phủ đếm CHẶNG của đường học** (Khám phá, Lab, Luyện tập, Đo giữa, Đo cuối) — không đếm node và không gọi là "lesson". Đếm node cho ra "đã phủ 1/1" ở gần như mọi Unit (phần lớn Unit chỉ có một node), đặt cạnh dải mười ô thì hai con số đá nhau. **Mẫu số lấy từ đường học gốc với `done` luôn false**, vì đường học thật sinh thêm ô "Luyện thêm" sau mỗi lượt xong — mẫu số tự phình thì learner càng làm càng thấy xa đích.
15. Bản đồ toàn môn **chỉ tải khi popover mở lần đầu**: phần lớn lượt vào app không mở popover nào.

### 6.5 Điều hướng trong Unit

16. **Bấm một chấm Experience trong Unit phải mở đúng bài đó**, ngay cả khi khung Cockpit không gắn lại: màn đang mở phải đồng bộ theo node trên URL chứ không chỉ đọc URL một lần lúc gắn component. Kèm luật kiểm thử: **fixture e2e phải dùng đúng id node như production** (`skill_nodes` dùng chung) — fixture đặt hai id khác nhau cho cùng một node từng làm test xanh trong lúc tính năng hỏng, nên test điều hướng phải bám vào **đích đến thật**.

### 6.6 Trang Kế hoạch — ẩn 80%, mở khi bấm

17. **Mặc định chỉ hiện card đích** (số tuần + chip chặng + phút/ngày). Ba khu "Tuần này con làm gì" · "Chặng đường" · "Kế hoạch đã đổi gì" gấp lại thành ba dòng tiêu đề kèm số đếm; bấm mới mở, **mỗi lúc chỉ một khu** (accordion — cùng luật SRC-126, phục vụ REQ-UX-09).
18. **Đếm bằng TUẦN làm tròn, không đếm bằng ngày lẻ.** "76 ngày" là con số đúng mà vô dụng: không ai lập kế hoạch theo ngày lẻ, và số lớn đọc ra cảm giác xa vời; "11 tuần" khớp luôn đơn vị các chặng bên dưới.
19. **Có một dải đường đi trực quan**: mỗi chặng một khúc dài theo số tuần, khúc đang đi tô đậm — nhìn một cái biết đang ở đâu, thay vì đọc hai dòng rồi tự cộng trong đầu. Màn hình toàn chữ là màn hình không đọc được với trẻ 11–15 tuổi.

### 6.7 Card learner ở panel phải và trang Hồ sơ

20. **Mặt card learner chỉ có tên và lớp** — hai thứ trả lời câu "hệ có nhớ mình là ai không". Bấm mới mở ra năm sinh, tuổi và tối đa 3 nguyện vọng.
21. **Tuổi luôn suy ra từ năm sinh, không lưu thành cột**: lưu tuổi là lưu một con số sẽ sai sau đúng một năm mà không ai nhớ đi sửa.
22. **Nguyện vọng chỉ tải khi learner mở card**: panel phải hiện ở mọi trang, còn đây là dữ liệu gần như không đổi.
23. **Link "Khai ngay" chỉ hiện khi hồ sơ thật sự còn thiếu**, và chỉ sau khi card đã mở (trước đó danh sách nguyện vọng rỗng không có nghĩa là chưa đặt). Card chỉ đọc mà nói "Chưa khai năm sinh" thì thành lời trách; hồ sơ đủ rồi mà vẫn để lời mời đứng đó thì thành nhiễu, trái luật tối giản (SRC-048).
24. **Trang Hồ sơ tách thành ba card riêng, mỗi card có công tắc sửa riêng**: (1) thông tin chung, ngày sinh format `DD.MM.YYYY`; (2) trường và lớp hiện tại cùng tỉnh thành; (3) nguyện vọng. Lý do tách thật chứ không kẻ đường ngang: ba cụm đổi theo **ba nhịp** khác nhau — tên và ngày sinh gần như không đổi, trường lớp đổi mỗi năm một lần, nguyện vọng đổi vài lần một tháng trong năm cuối cấp. Gộp một form thì mỗi lần sửa nguyện vọng lại có nguy cơ chạm nhầm ngày sinh. Tách ở giao diện, **không tách ở hợp đồng dữ liệu**: hai cụm đầu vẫn gửi trọn năm trường qua cùng `PATCH /profile`.
25. **Trần ba nguyện vọng.** Từ nguyện vọng thứ tư trở đi thứ tự ưu tiên hết nghĩa và kế hoạch học cũng không đuổi theo nổi bốn đích.
26. **Bỏ một nguyện vọng là đánh dấu `dropped`, không xoá dòng**: kế hoạch đã từng chạy theo đích đó, xoá sạch là mất luôn lý do vì sao mấy tuần trước hệ xếp bài như vậy.
27. **Hồ sơ là trang để ĐỌC.** Nút "Sửa" cỡ nhỏ, nép về phải (nút Huỷ/Lưu trong form cũng vậy) — nút kéo hết chiều ngang mang sức nặng của hành động chính, mời bấm vào việc mà đa số lần vào trang không ai cần làm. Tiêu đề mỗi card nằm trong **băng riêng có đường kẻ ngăn**, vì ba card xếp dọc cần một mốc rõ để biết card mới bắt đầu ở đâu. Ô nhập nguyện vọng **giấu sau nút**, mặc định chỉ hiện các nguyện vọng hiện có.
28. **Mỗi hành động thêm/bỏ nguyện vọng phải có câu xác nhận `role="status"` trên màn hình.** Im lặng sau một hành động là bắt người dùng tự đoán (nối tiếp REQ-UX-06). Kèm luật kiểm thử: **mock e2e phải trả đúng hình dạng payload của API thật**, và việc chuẩn hoá payload đặt ở một chỗ duy nhất trong `api.ts` — mock viết theo hình dạng sai từng hợp thức hoá một bug khiến nguyện vọng vào được D1 mà danh sách vẫn rỗng.
29. **Chi tiết nguyện vọng mở trong ô riêng**, và **link "Bỏ" chỉ nằm trong ô sửa** — bỏ nguyện vọng là việc hiếm và không thu lại được, đặt cạnh tên trường ở lớp ngoài cùng thì chạm nhầm một cái là mất. Phải đi qua hai bước cố ý.
30. **Độ ưu tiên gọi bằng chữ** — "cao nhất", "cao nhì", "cao thứ ba" — không dùng số 1-2-3, vì số thứ tự bắt người đọc tự dịch xem 1 là cao nhất hay thấp nhất.
31. **Mỗi nguyện vọng mang môn thi, ngày thi và hệ số.** Kỳ thi vào 10 chuyên chấm theo hệ số và mỗi trường xếp khác nhau; thiếu hệ số thì kế hoạch học không biết một điểm Toán đáng giá gấp mấy một điểm Văn ở đích này — mà đó đúng là thứ quyết định nên dồn thời gian vào đâu.

### 6.8 Màn làm bài — vùng nháp

32. **Có icon bút chì trong hàng điều khiển** (cùng hàng với "Nhắc lại" và "Bỏ qua"), bấm thì xổ ra một ô viết nháp.
33. **Nháp KHÔNG được lưu ở bất kỳ đâu** — không state cha, không `localStorage`, không server. Đây là thiết kế chứ không phải thiếu tính năng: nháp là chỗ được phép sai và được phép bẩn, trẻ biết bị lưu thì sẽ viết dè. Xoá bảo đảm bằng hai cơ chế chồng nhau: chuyển câu thì xoá state, và ô nháp mang `key` theo `item.id` nên đổi câu là dựng ô mới tinh (phòng cả đường vào lại câu cũ từ hàng đợi sai).
34. **Lời hứa nằm ngay trên mặt ô**: "Không lưu lại — sang câu khác là biến mất".

### 6.9 Vào môn ở Squid, và mục tiêu IELTS (SRC-696, chỉ đạo 2026-09-09)

35. **Cửa đo mở đầu chỉ chặn ở Turtle và Shark.** Ở Squid (IELTS · SAT · AP), learner bấm vào một môn là để xem chương trình và **đặt mục tiêu** trước đã; dựng một bài đo 10 câu chắn ngang lối vào là bắt người vừa mới tới phải thi trước khi được nhìn. Bài đo vẫn còn nguyên, nhưng ở đây nó là **một lời mời bỏ qua được** đặt trên nội dung, không phải một bức tường. Luật cũ (SDD-021 §3.1) giữ nguyên ở hai school phổ thông, nơi mọi bài học đều xếp theo bằng chứng năng lực.
36. **Mục tiêu IELTS: learner chỉ đặt BỐN kỹ năng, Overall là của hệ.** Màn hình không có ô nhập Overall và API bỏ qua nếu client gửi lên. Overall tính theo đúng cách chấm của IELTS — trung bình bốn kỹ năng, làm tròn nửa bậc, phần dư .25 lên nửa bậc và .75 lên cả bậc. Cho sửa tay con số ấy là mở đường cho một mục tiêu tự mâu thuẫn với chính bốn kỹ năng của nó.
37. **Tối đa 5 mốc trung gian**, mỗi mốc cũng là một ngày cộng bốn kỹ năng cộng Overall tự tính. Trần 5 canh ở server (409), và khi đủ thì nút nói rõ "Đã đủ 5 mốc" chứ không lặng lẽ biến mất (REQ-UX-03). Mốc chỉ thêm được sau khi đã có đích: một chặng giữa đường mà không có đích thì không nói lên điều gì.
38. **Card IELTS mặc định để ĐỌC, bấm "Sửa" mới mở ô chọn** — cùng khuôn hai card còn lại của trang Hồ sơ. Bản đầu bày form mở sẵn nên một mục tiêu được nói tới ba lần trên cùng một màn (ô chọn, khối Overall, dòng "Đang nhắm…") và ngày hiện hai định dạng khác nhau. Chế độ đọc là một dòng nói hết: Overall, ngày (theo lối người Việt: 05.11.2026), rồi bốn band ở dòng dưới. Mốc trung gian cũng vậy: mỗi mốc một dòng bấm được, ô sửa mở ra tại chỗ, và **nút xoá nằm trong ô sửa** chứ không ở mặt danh sách (cùng lý do với SRC-526).
39. **Mục tiêu IELTS là một CARD trong trang Hồ sơ**, tên card là "IELTS", đứng **song song** với card "Mục tiêu vào trường" — hai cái đích cùng cấp của một learner (một vào trường, một là điểm chuẩn hoá) thì ở cạnh nhau. Nó không phải một mục riêng ở cột trái: mục tiêu là thứ khai một lần rồi thỉnh thoảng sửa, đúng nhịp của trang Hồ sơ.
40. **Card "Nguyện vọng" đổi tên thành "Mục tiêu vào trường".** "Nguyện vọng" là tiếng của phiếu đăng ký thi vào 10; thứ đang nói ở đây là cái đích mà kế hoạch học hướng tới, và đặt cạnh card IELTS thì hai cái tên phải cùng một hệ.
41. **Mục tiêu IELTS đi vào Student Portrait**, hiển thị CHỈ ĐỌC ở cả learn và Marlins. Sửa thì về đúng card IELTS trong Hồ sơ: một con số sửa được ở hai nơi là một con số sớm muộn cũng lệch.
42. **Môn IELTS không có mục "Lịch thi học kỳ"** ở cột trái. IELTS thi theo ngày tự đăng ký, không theo lịch học kỳ của trường; ở môn này mục ấy rỗng nghĩa.

### 6.10 Lộ trình IELTS (SRC-697, chỉ đạo 2026-09-09)

43. **Lộ trình có TRANG RIÊNG** (`/<trường>/ielts-roadmap/<môn>`), mở từ link "Xem lộ trình" trên card IELTS và từ mục "Lộ trình IELTS" ở cột trái (đứng đúng chỗ mà môn phổ thông để "Lịch thi học kỳ"). Card trong Hồ sơ trả lời "con nhắm bao nhiêu"; trang này trả lời "đường đi có đi nổi không". Trang chỉ ĐỌC — sửa vẫn về đúng một chỗ là card.

44. **Mỗi chặng nói ba con số**: cách nhau bao nhiêu tuần (và bao nhiêu ngày), Overall tăng bao nhiêu, và từng kỹ năng tăng bao nhiêu. Có dấu cộng/trừ tường minh (`+0.5`, `±0.0`) để đọc lướt ra ngay hướng đi.

45. **Nhận xét rủi ro theo ba mức** — Vừa sức · Hơi gấp · Rất gấp — tính bằng `weeks_needed / weeks`, trong đó `weeks_needed` là số tuần mà kinh nghiệm luyện thi cho là cần để leo từng nửa bậc (càng lên cao càng chậm: 6 tuần dưới 5.5, 8 tuần tới 6.5, 10 tuần tới 7.5, 12 tuần trên đó), lấy theo **kỹ năng cần lâu nhất** vì bốn kỹ năng học song song chứ không nối đuôi. Chặng có `strain` cao nhất được gắn nhãn **"Chặng gấp nhất"**.

46. **Mức chắc chắn phải nói đúng như nó có.** Đây là ước lượng thô, không phải dự báo; chữ trên màn hình dùng "khoảng", và mức nặng nhất dùng màu coral chứ không phải `destructive` — một lộ trình gấp không phải là lỗi của đứa trẻ (REQ-UX-03).

47. \~~**Không có chặng nào TRƯỚC mốc đầu tiên**: hệ chưa biết điểm hiện tại của learner. Mốc đầu đứng một mình kèm đúng một câu nói vì sao. Đoán một điểm gốc rồi phán "gấp" là bịa ra một con số rồi lo lắng vì chính nó.~~ **Đổi ở SRC-717** (§6.11): learner tự khai được điểm hiện tại, nên chặng đầu có thật. Lý do cũ vẫn đứng nguyên cho trường hợp chưa khai — hệ vẫn KHÔNG đoán hộ.

48. **Ba cạnh phải nói thẳng chứ không im lặng**: mốc đặt điểm thấp hơn mốc trước, hai mốc trùng ngày hay đảo thứ tự, và chặng giữ nguyên điểm (chặng ôn). Cả ba đều có câu riêng thay vì rơi vào một nhãn chung.

49. **Bảng lộ trình: MỖI DÒNG MỘT MỐC** (SRC-702, chỉ đạo 2026-09-10), xếp theo ngày tăng dần, ngày gần nhất trên cùng và ngày thi dưới cùng. Đúng sáu cột: **Ngày · Nghe · Nói · Đọc · Viết · Overall** — thứ tự kỹ năng do chủ dự án chốt, không phải thứ tự L-R-W-S của phiếu điểm IELTS, và nhãn tiếng Việt vì đây là chữ learner đọc. Khoảng cách (số tuần) và nhãn rủi ro nằm gọn dưới ô ngày của chính mốc ấy thay vì chiếm thêm hai cột. Dưới bảng chỉ còn **một câu**, cho đúng chặng gấp nhất: bản trước liệt kê mọi chặng đáng lo, mà mỗi dòng lặp lại ngày và mức độ đã có trong bảng, nên không câu nào được đọc.

50. \~~**Lộ trình trình bày dạng BẢNG** (SRC-698, chỉ đạo 2026-09-10): mỗi **cột** một mốc, **cột cuối là ngày thi**; bốn **dòng** đầu là bốn kỹ năng, rồi Overall, rồi hai dòng nói về CHẶNG chứ không về mốc — "Cách mốc trước" (số tuần) và "Nhận xét" (Vừa sức · Hơi gấp · Rất gấp). Đọc theo hàng thì thấy một kỹ năng đi lên thế nào suốt cả lộ trình, điều mà lối xếp dọc trước đó không cho thấy vì bốn kỹ năng bị trộn vào từng khối. Mức tăng so với cột trước đứng ngay cạnh điểm (`6.5 +0.5`), cột đầu để dấu gạch vì chưa có chặng nào phía trước.~~ **Đổi trục ở SRC-702** (mục 49).

51. **Câu nhận xét đầy đủ để DƯỚI bảng**, chỉ các chặng đáng lo, mỗi chặng một dòng gọi tên bằng ngày. Nhét cả câu vào một ô thì cột co lại còn một chữ mỗi dòng, mà cắt ngắn thì mất đúng phần nói phải làm gì. Bảng rộng thì **cuộn ngang trong chính nó**, không đẩy cả trang trôi sang phải.

52. **Dữ liệu mục tiêu của một người đi bằng SEED, không bằng migration** (SRC-703). Ba mốc trung gian đặt hộ chủ dự án ngày 2026-09-10 nằm ở `scripts/seed-ielts-milestones-owner.sql`, chạy qua `seed-data.yml`. Migration sẽ chép mục tiêu cá nhân ấy vào mọi bản D1 mới, kể cả bản của người khác. Câu SQL **khoá vào đúng email người yêu cầu** chứ không phải "mục tiêu đang active" nói chung: lúc chạy có thật một tài khoản khác cũng đang có mục tiêu IELTS, và câu rộng sẽ thêm mốc vào lộ trình của người đó mà không ai phát hiện ra.

### 6.11 Điểm hiện tại và mốc do hệ chia (SRC-717, chỉ đạo 2026-09-14)

51. **Learner tự khai điểm hiện tại của bốn kỹ năng**, và đó là một con số **có nguồn**: con tự đoán · theo bài thi thử · điểm thi thật. Ba mức tin cậy rất khác nhau, nên nhãn nguồn đi kèm ở mọi chỗ hiện con số. Một lộ trình dựng trên phỏng đoán mà trông như dựng trên điểm thi thật là một lời hứa hão.
52. **Điểm hiện tại thuộc về LEARNER, không thuộc về mục tiêu** (bảng riêng, migration 0217). Khai được trước khi đặt đích, và đổi đích thì không mất điểm xuất phát. Nó cũng mang ngày (`assessed_on`): "hôm nay con nghĩ mình khoảng 6.0" chỉ đúng vào hôm đó.
53. **Một bản đang hiệu lực cho mỗi learner**: tự đánh giá lại thì ghi đè. Đây là điểm xuất phát để vẽ lộ trình, không phải sổ theo dõi tiến bộ — thứ đó là bằng chứng từ bài làm thật và do Learner Model lo.
54. **Hệ chia mốc giúp, nhưng KHÔNG tự lưu.** Learner bấm "Nhờ hệ chia mốc giúp" → xem bảng đề xuất kèm một câu nói giai đoạn đó nhắm vào đâu → bấm "Dùng lộ trình này" thì mới ghi, và ghi là **thay toàn bộ** các mốc đang có (họ vừa nhìn thấy danh sách sắp thay thế). Một lượt gọi AI mà tự tay ghi đè mốc learner đã đặt thì lần sau không ai dám bấm.
55. **Phân vai AI và code là bất di bất dịch.** AI làm phần có nhận định: nhịp nào nhanh nhịp nào chậm, kỹ năng nào đẩy trước, và câu ghi chú. Code làm phần phải đúng: không mốc nào thấp hơn điểm hiện tại, không mốc nào cao hơn mục tiêu, không đi lùi giữa hai mốc, band là nửa bậc, ngày nằm trong khoảng và tăng dần. `repairPlan` chạy trên **mọi** đề xuất, không phải chỉ khi thấy nghi ngờ — model sẽ lỡ, và lỡ ở đây là bày một lộ trình vô nghĩa mà nhìn vẫn như thật.
56. **AI hỏng thì vẫn có lộ trình, và màn hình NÓI RA điều đó.** Bản dự phòng tính bằng công thức: mốc chia đều theo ngày, band chia theo **chi phí thời gian** chứ không theo số band (nửa bậc ở dải 7.5 tốn gấp đôi nửa bậc ở dải 5.0). Bày lộ trình công thức như thể AI vừa nghĩ ra nó là nói sai về chính thứ learner đang nhìn (QG-015).
57. **Mốc mang lai lịch** (`origin`): `ai_suggested` khi hệ đề xuất và learner chưa đụng vào, `learner` khi họ tự đặt hoặc đã sửa. Sửa tay một mốc là nó chuyển sang `learner` ngay — giữ nhãn cũ sẽ khiến màn hình nói "hệ đề xuất" cho một con số do chính họ gõ.
58. **Ô điểm hiện tại không tự mở.** Lượt đầu vào card đã có ô chọn mục tiêu mở sẵn; thêm một biểu mẫu nữa là hai thứ cùng đòi điền trên một màn hình. Chưa khai thì card nói thẳng "hệ chưa biết con đang ở đâu, nên chưa chia được các mốc ở giữa" kèm đúng một nút.

## 7. Trang chủ learn là màn chọn chương trình (SRC-1255, 06.10.2026)

* `learn.nemo12.com/` không còn tự chuyển sang `/ielts`. Nó là màn **"Bạn muốn học gì?"**: bước 2 của trang chủ www (`apps/web/src/site/RoleGate.tsx`) với vai học sinh cố định, vì learn chỉ dành cho người học nên không có bước "Bạn là ai?".
* Nhóm và thứ tự chép từ `PROGRAM_GROUPS` của www, chỉ giữ chương trình đã có trang trên learn: College (IELTS, SAT, AP) · English (SPEAK, GRAMMAR, ESSAY) · Math (MATH) · Future (AI TEEN). Đích lấy từ `PROGRAM_NAV`.
* Màn công khai. Bấm một thẻ là sang thẳng chương trình; cổng đăng nhập của từng chương trình lo phần còn lại.
* Hub school cũ (Turtle, Shark, Lighthouse, Lịch, Khoá học) chuyển sang `/schools`; learner đã đăng nhập có link "Các school của em" ngay dưới lưới. Người lớn vào nhầm có một dòng nhỏ ở đáy: "Bạn là phụ huynh? Vào trang phụ huynh" (marlins.nemo12.com).

## Trace

* §7 → SRC-1255 (trang chủ learn chọn chương trình, bỏ bước chọn vai, hub school sang /schools).
* §6.10 → SRC-697, SRC-698, SRC-702, SRC-703 (bảng lộ trình: cột là mốc, dòng là kỹ năng) (trang lộ trình riêng: khoảng cách giữa các mốc, điểm tăng, nhận xét chặng gấp nhất).
* §6.11 → SRC-717 (learner tự khai điểm hiện tại bốn kỹ năng có nguồn; hệ chia mốc trung gian bằng AI qua AI Gateway, learner xem và sửa được; bản dự phòng bằng công thức khi AI hỏng).
* §6.9 → SRC-696 (vào môn ở Squid không bị bài đo chặn; mục tiêu IELTS bốn kỹ năng + Overall do hệ tính + tối đa 5 mốc; đưa vào Student Portrait).
* §6 → SRC-250, SRC-251, SRC-252, SRC-372, SRC-461, SRC-462, SRC-468, SRC-470, SRC-474, SRC-512, SRC-513, SRC-517, SRC-518, SRC-519, SRC-521, SRC-522, SRC-525, SRC-526, SRC-527, SRC-534 (canonical hoá 2026-08-26).
* SRC-042 → file này + PRD-001 §5 (REQ-UX-01..10, US-58..60) + [DS-001 v0.2](../design-system/index.md).
* REQ-UX-\* → SDD: DS-001; QG: QG-007. Câu hỏi mở: Q-107..Q-110 (Đợt 7).
