---
url: https://docs.nemo12.com/architecture/sdd-029-public-site-ia/zones-ielts-sat.md
description: >-
  Các vòng 2026-09-16: các bước, khu IELTS dày lên, màn quyết định hai bước, khu
  SAT, hai bản giới thiệu theo vai.
---

# SDD-029 · Các bước, khu IELTS, khu SAT và hai bản giới thiệu theo vai

Một phần của [SDD-029](./index.md). Các vòng 2026-09-16: các bước, khu IELTS dày lên, màn quyết định hai bước, khu SAT, hai bản giới thiệu theo vai.

## Lịch sử quyết định

#### 10.12 Các bước: hai tên, và một thẻ một lúc (chỉ đạo 2026-09-16, vòng năm)

Khối giải thích giữa trang môn đổi hai thứ:

**Mỗi bước có tên tiếng Việt VÀ tên tiếng Anh.** `en` không phải bản dịch của `title` mà là **tên
gọi của bước đó trong hệ khái niệm Nemo12**: Goal Setting · Diagnosis · Competency Gap · Learning
Plan · Readiness. Người học sẽ gặp lại đúng những chữ ấy trong app và trong tài liệu, nên gọi đúng
tên ngay từ trang giới thiệu là dạy trước một từ vựng họ sắp cần.

**Một thẻ một lúc**, thay cho lưới năm thẻ. Lưới khiến người đọc lướt qua cả năm trong ba giây và
không đọc thẻ nào, trong khi đây là phần nói rõ Nemo12 làm việc theo thứ tự nào. Dải tab mang tên
tiếng Anh, thẻ mang cả hai tên, có nút lùi/tiến và mũi tên trái phải trên bàn phím.

Hai thứ phải giữ khi sửa khối này:

* **Chữ của MỌI bước vẫn nằm trong HTML tĩnh.** `routes.ts` đưa cả năm bước (kèm `gets` và câu dẫn)
  vào `paras` của trang môn. Trên trang thật, DOM chỉ chứa một bước tại một thời điểm; nếu bản tĩnh
  cũng chỉ có một bước thì bốn bước còn lại không tồn tại với máy tìm kiếm, mà đó lại là phần chữ
  dày nhất và khác biệt nhất giữa hai vai.
* **Chiều cao tối thiểu của thẻ.** Các bước dài ngắn khác nhau; không ghim thì mỗi lần bấm cả trang
  nhảy, và nút vừa bấm chạy khỏi đầu ngón tay.

##### `FadeIn` không dùng được cho nội dung đổi tại chỗ

Bản đầu bọc thẻ bằng `FadeIn`, và thẻ **biến mất**: nội dung có trong DOM nhưng người dùng thấy một
khoảng trống. `FadeIn` dùng `whileInView`, tức chờ phần tử **đi vào** khung nhìn. Thẻ bước được dựng
lại khi đã nằm sẵn trong khung nhìn, nên không có cú đi vào nào xảy ra và nó đứng nguyên ở
`opacity: 0`.

Thêm preset `Appear` vào `Motion.tsx` (đúng luật DS-001 §0: cần hiệu ứng chưa có thì thêm preset,
không kéo gói mới). Luật chọn giữa hai cái:

| Dùng | Khi |
| --- | --- |
| `FadeIn` | nội dung xuất hiện lần đầu lúc người dùng cuộn tới |
| `Appear` | nội dung đổi vì người dùng bấm (tab, bước, bộ lọc) |

#### 10.13 Khu IELTS dày lên: đồ hoạ, các trang con, và chân trang theo môn (2026-09-16, vòng sáu)

Sáu chỉ đạo liên tiếp trong một ngày, gom lại vì chúng cùng một mạch: **trang môn IELTS phải nhìn
ra là IELTS, và người đọc nó không nên đi lang thang.**

**Đồ hoạ sinh từ mã, không phải ảnh (SRC-755).** Trang môn trước đó toàn chữ. Ba đồ hoạ tương tác
được thêm: phiếu điểm bấm được (số ngẫu nhiên, chỉ trang trí), thang band kèm quy đổi CEFR, và bộ
chọn đích đến làm sáng vùng band thường được yêu cầu. Cả ba là **đồ hoạ dữ liệu vẽ bằng SVG/CSS**,
nên luật cấm ảnh stock và ảnh AI ở §6 không bị đụng tới: ở đây không có tấm ảnh nào. Phiếu điểm cố
ý không mang tên người, ngày thi hay số báo danh - ba thứ đó biến một mẫu giao diện thành một tài
liệu giả.

Hàm làm tròn Overall có test riêng (`ieltsGraphics.test.ts`): phiếu dạy đúng một điều - Overall
không phải trung bình cộng - và hàm sai thì phiếu vẫn đẹp mà dạy sai cho mọi người vào trang.

**`/ielts/diagnosis` (SRC-755).** Một khung báo cáo đổi theo ba mốc: ngay sau bài đo (5 mục), sau 3
tháng (10 mục), sau 6 tháng (14 mục). Mục mới mang nhãn "Mới ở mốc này" và nói rõ **vì sao nó không
thể có sớm hơn** - thiếu câu đó thì trang đọc ra như Nemo12 giữ lại thông tin để bán dần.

**Trích đoạn báo cáo trên `/ielts/methodology` (SRC-1267, 06.10.2026).** Thẻ "Chẩn đoán trước, học
sau" ở tab Cách học có thêm một bản báo cáo thu nhỏ (`IeltsReportExcerpt.tsx`), theo đúng thứ tự
báo cáo thật ở learn: Overall ước lượng, bốn kỹ năng, ba kỹ năng con luyện trước, câu trả lời chia
theo độ chắc chắn, việc tiếp theo. Nhãn "Báo cáo mẫu" và dòng "Số liệu minh hoạ, không phải của một
learner thật" là bắt buộc. Band lấy từ learner mẫu lần đo 1 của trang này qua `sampleSkillBand`
(`ieltsSubskills.ts`), nên hai trang nói cùng một con số. Test: `IeltsReportExcerpt.test.tsx`.

**`/{vai}/university/ielts/journey` (SRC-756).** Nút "Xem lộ trình năm bước" rời khỏi hero (ở đó nó
mời người đọc rời trang trước khi họ biết mình rời đi để xem gì) và xuống ngay dưới khối năm bước.
Trang đích tách vai rõ với `/ielts/journey`: **bên kia là LÝ LẼ** (vì sao thứ tự là thứ tự đó),
**bên này là QUY TRÌNH** (mỗi bước ai làm gì, mất bao lâu, xong thì cầm gì, chỗ hay hỏng). Hai trang
cùng chủ đề mà không tách vai thì Google chọn hộ một bản và dìm bản kia.

**Khối Mentors trên trang môn (SRC-756).** Lấy từ `mentor_profiles` qua `/v1/public/mentors`, lọc
theo thẻ môn. Chưa hồ sơ nào mang thẻ của môn đó thì khối **biến mất hẳn** - cùng luật với ảnh ở §6.
Khối này KHÔNG mang nhãn "Đã xác minh trường lớp" dù trang đội ngũ đầy đủ có: đây là lát giới thiệu
chứ không phải chỗ kiểm chứng, và nó chỉ hiện tối đa sáu người nên nhãn tạo ra đúng câu hỏi nó không
trả lời nổi.

**Chân trang của TRANG MÔN thu hẹp về đúng môn đó (SRC-756).** Trước đó chân trang trang IELTS bày
SAT, Toán, Vào cấp 3 và AI & Future Skills - bốn lời mời đi chỗ khác, đặt đúng lúc người đọc vừa đọc
xong. Nay cột đầu chỉ còn lối đi trong môn cộng **một** lối lùi về trang mục tiêu, và cột giữa rút
về ba mục không phải lối rẽ nội dung (Về Nemo12 · Bắt đầu · Quyền riêng tư).

**Ba trang con về việc học thật (SRC-757).**

| Trang | Trả lời câu gì | Nguồn dữ liệu |
| --- | --- | --- |
| `.../schedule` | Một tuần học trông như thế nào | `mentor_slots` qua `GET /v1/public/slots` |
| `.../tasks` | Các buổi tự học thì làm gì | 10 dạng bài, mỗi dạng khai thứ chạy nó trong nền tảng |
| `.../questions-to-ask` | Nên hỏi gì trước khi chọn chỗ học | 12 câu, dùng được ở bất kỳ đâu |

`GET /v1/public/slots` không cần phiên, cùng lẽ với `/v1/public/mentors`: phụ huynh phải thấy giờ
học trước khi tạo tài khoản. Nó đã lược `meeting_url`, tên người dạy và số người đã ghi tên, và có
test giữ đúng ba thứ ấy ở ngoài. Chọn giờ trên trang **không phải là ghi tên**: trang công khai
không có phiên, nên lựa chọn chỉ đi kèm sang luồng demo qua `trackEvent` và `?demo_slot=`.

Trang `tasks` chia theo **bốn nguyên nhân sai**, không theo bốn kỹ năng: chia theo kỹ năng không trả
lời được câu "vì sao làm cái này thì lên điểm". Trang `questions-to-ask` cố ý **không** có cột
"Nemo12 trả lời thế nào" - một danh sách câu hỏi mà chỉ một nơi trả lời được thì không còn là danh
sách câu hỏi.

**Trang môn SAT theo khuôn IELTS, và năm trang con (SRC-1015).** Chỉ đạo chủ dự án 2026-09-23: trang
`/{vai}/university/sat` phải có giao diện và nội dung kiểu trang IELTS. Trang SAT vốn đã dùng chung
`SubjectPage` nhưng thiếu mọi thứ làm trang IELTS nhận ra được ngay: đồ hoạ, trang chi tiết năm bước,
lối sang chẩn đoán. Nay:

* **Ba đồ hoạ riêng** (`SatGraphics.tsx`), không bật đồ hoạ IELTS: phiếu điểm bấm được trong hero
  (hai phần 200-800, tổng 400-1600, kèm percentile xấp xỉ), thang điểm 1000-1550 kèm nghĩa khi nộp
  hồ sơ, và "Bạn cần bao nhiêu" theo ba nhóm đích (Đại học Việt Nam · Đại học Mỹ, học bổng merit ·
  Top 30 Mỹ). Percentile và dải điểm là mức của NHÓM, kèm câu nhắc kiểm tra trang tuyển sinh.
  Phiếu điểm mở sẵn ở 780 + 780 = 1560, không còn lấy ngẫu nhiên (SRC-1037, chỉ đạo chủ dự án 25.09.2026).
* **Năm bước khớp khuôn IELTS**: Target Score · Starting Point · Diagnosis · Learning Plan ·
  Readiness, dẫn sang trang chi tiết. Dải tối "Chẩn đoán" (+ "Học phí" với bố mẹ) như IELTS. Học phí
  vẫn là một trang duy nhất ở `/sat/tuition`.
* **Năm trang con** dưới `/{vai}/university/sat/`, bảng `SAT_SUBPAGE` trong `App.tsx` khớp bản tĩnh
  trong `routes.ts`:

| Trang | Trả lời câu gì |
| --- | --- |
| `.../test-format` | Bài Digital SAT gồm những gì: 2 phần, 4 module, 98 câu, 2 giờ 14 phút, tám miền kiến thức |
| `.../journey` | Năm bước chi tiết: ai làm gì, bao lâu, cầm cái gì, chỗ hay hỏng (`satJourneySteps.ts`) |
| `.../diagnosis` | Bản chẩn đoán: tám miền, bốn nguyên nhân sai, ba việc làm trước (bản mẫu số minh hoạ) |
| `.../schedule` | Một tuần ôn SAT, kể cả phần tự học |
| `.../questions-to-ask` | Tám câu nên hỏi bất kỳ chỗ ôn SAT nào, không có cột "Nemo12 trả lời thế nào" |

Khu bấm chọn `/sat/learner` giữ nguyên, nay là mục "Đọc tiếp" chứ không còn là nút phụ ở hero.
Thêm `.../mentors` và `.../events`: dùng lại `IeltsMentorsPage` / `IeltsEvents` với `exam="sat"`
(lọc hồ sơ theo thẻ `sat`, đọc chuỗi `NEMO SAT` trong `community_events`). Khi chưa có hồ sơ hay buổi
nào, hai trang hiện trạng thái rỗng có lối đi tiếp, không trắng trang.

**Nút phải trông ra nút (SRC-758).** Dưới theme biển mọi bề mặt đều là kính mờ trắng loãng, và nút
`outline` có viền nhạt hơn cả viền thẻ bên cạnh. Tầng override trong `apps/web/src/index.css` tách
nút khỏi họ bề mặt bằng ba dấu hiệu cùng lúc: viền 2px gần trắng đặc, một bóng đổ (các thẻ đều
phẳng), và chữ 700; rê chuột thì đảo màu thành nền trắng chữ xanh sâu.

#### 10.14 Màn quyết định tách thành hai bước (SRC-758, 2026-09-16, vòng bảy)

§10.10 chốt trang chủ là màn quyết định hỏi hai câu. Vòng này tách **mỗi câu một bước**: bước 1 chọn
vai, chọn xong sang ngay bước 2 chọn mục tiêu. Bày cả hai cùng lúc thì màn hình đọc ra là một biểu
mẫu năm ô cần điền; tách ra thì mỗi lúc chỉ có một câu hỏi, và câu hai hỏi đúng giọng của vai đã
chọn thay vì một bản chung đoán trước.

Bước 1 không có nút xác nhận riêng (chọn vai là bấm, thêm nút "Tiếp tục" là bắt bấm hai lần cho một
quyết định); bước 2 thì có, vì ở đó người dùng rời trang. Bước 2 mang nút đổi vai: không có nó thì
người bấm nhầm chỉ còn cách tải lại trang, mà tải lại cũng vô ích vì vai đã lưu vào `localStorage`.

Việc tách bước **không** làm mất đường của bot: bản tĩnh do `apps/web/scripts/prerender.mjs` sinh ra vẫn mang
đủ sáu link của route `/`, và bot không chạy JavaScript nên luôn đọc bản đầy đủ.

#### 10.15 Khu SAT: người đọc đã quyết thi rồi (SRC-759 · 760 · 761, 2026-09-16, vòng tám)

**SRC-759 — trang môn SAT bỏ hẳn câu "SAT có dành cho bạn không".** Bản trước mở đầu bằng hai câu
phải trả lời trước khi luyện, trong đó câu thứ nhất là có nên thi hay không. Chủ dự án chốt: người
vào `/students/sat` mặc định đã biết SAT quan trọng và đã chắc chắn muốn ôn. Hỏi lại câu
đó là bắt họ trả tiền bằng một màn hình cho một quyết định họ đã ra rồi, và trang mất luôn cơ hội
nói thứ họ thật sự cần.

Trang vì thế mở bằng đúng chỗ họ đang đứng: điểm xuất phát hôm nay, khoảng cách tới điểm cần, thứ tự
việc phải làm. Năm bước thay sáu, bước đầu là **Starting Point** chứ không phải *Is SAT for Me*, và
CTA đổi từ "Trả lời sáu câu hỏi" sang "Đo điểm xuất phát".

`/sat/learner/is-sat-for-me` **vẫn còn URL của nó** — trang đó phục vụ người tới từ tìm kiếm với
đúng câu hỏi ấy, và một URL công khai đã có thì không xoá. Thứ bị gỡ là chỗ nó đứng trong mạch của
trang môn.

**SRC-760 — học phí SAT ra trang riêng `/sat/tuition`.** Trang môn chỉ còn một link. Lý do là hai
câu hỏi khác nhau: trang môn trả lời "tôi đi thế nào tới điểm mình cần", còn "tôi trả tiền cho cái
gì" cần cả một trang mới nói hết. Nhét bảng giá vào cuối trang môn thì người hỏi câu thứ hai chỉ
nhận được một cột số, còn người đang đọc lộ trình thì bị cắt ngang bằng chuyện tiền.

Cơ chế: `Deep` trong `subjectCopy.ts` có thêm trường tuỳ chọn `tuitionHref`; môn nào khai nó thì
`SubjectPage` thay `PricingBlock` bằng một khối dẫn sang. Đây là cách duy nhất giữ đúng một chỗ nói
chuyện tiền cho mỗi môn — hai chỗ là hai chỗ phải sửa khi giá đổi, và chỗ bị quên sẽ nói sai lâu hơn
bất kỳ ai kịp nhận ra.

`SatTuition.tsx` đi theo đúng thứ tự của `IeltsTuition` (§10 phần học phí IELTS, SRC-735): bạn trả
tiền cho cái gì → ba mức đồng hành → mentor vào lúc nào → câu hỏi thường gặp. Và cùng ràng buộc:
**không con số nào** trên trang, vì chủ dự án chưa chốt học phí SAT và một con số bịa ra sẽ nằm lại
trong kết quả tìm kiếm rất lâu sau khi trang đã sửa. Chỗ duy nhất sửa khi có giá là hằng số
`PRICE_NOTE`.

**SRC-762 — vai bố mẹ cũng bỏ ý "con có cần SAT không".** Bản đầu của vòng này chỉ đổi vai học
sinh, và giữ vai bố mẹ với lập luận "bố mẹ là người trả tiền nên vẫn đang hỏi con có cần không".
Chủ dự án đọc xong và bác: gia đình tìm tới trang SAT thì đã quyết rồi, **cả hai người**. Trang bố
mẹ vì thế mở bằng "Con đang ở đâu trên đường tới điểm SAT con cần?", bốn bước bỏ bước *Is SAT
Required*, và câu "nếu không cần thì chúng tôi nói thẳng" đi theo. Câu dẫn của môn SAT trong
`goals.ts` (hiện ở thanh điều hướng và chân trang) cũng bỏ ý ấy ở cả hai vai.

Vai bố mẹ nhận luôn `tuitionHref` như vai học sinh, nên cả hai vai chỉ còn một chỗ nói chuyện tiền
là `/sat/tuition`. Vị trí vẫn khác nhau theo §10.3: bố mẹ gặp khối học phí ở GIỮA trang, học sinh ở
CUỐI — `tuitionHref` chỉ thay cái khối, không đụng chỗ đặt.

**SRC-761 — trang riêng cho "bài SAT thật ra đo cái gì", có trải nghiệm ngay trong trang.** Trang
này đã tồn tại từ SRC-714 với đầy đủ phần bấm thử (một câu mô phỏng, chọn xong còn bị hỏi tiếp *vì
sao bạn chọn đáp án đó*), nhưng đứng tên "SAT không phải IELTS" — một cái tên nói về sự so sánh, nên
không ai đoán ra nó trả lời đúng câu hỏi kia. Vòng này đổi tên trang, `h1`, breadcrumb, mục trên
thanh điều hướng và mọi link dẫn tới thành **"Bài thi SAT thật ra đo cái gì?"**.

Không dựng trang thứ hai. Hai trang cùng trả lời một câu hỏi thì Google chọn hộ một bản và dìm bản
kia (luật đã ghi ở đầu `subjectCopy.ts`), và người đọc gặp hai cửa cho cùng một việc.

### 10.11 Hai bản giới thiệu theo vai (SRC-766, chỉ đạo 2026-09-16)

`/about` nói sứ mệnh · tầm nhìn · triết lý cho mọi người, và vì phải nói với mọi người nên nó không
nói riêng với ai. Hai trang mới trả lời đúng câu hỏi từng vai mang theo:

| URL | Người đọc | Câu họ hỏi |
| --- | --- | --- |
| `/parents/about` | bố mẹ | "Chỗ này giúp con tôi cái gì, tôi nhìn thấy gì, và các anh KHÔNG làm gì?" |
| `/students/about` | học sinh | "Học ở đây khác chỗ khác ra sao, và tôi sẽ phải làm gì?" |

Ba quyết định:

* **Không chép lại ba đoạn của `/about`.** Hai trang mới không nhắc lại sứ mệnh/tầm nhìn theo lời
  khác; chúng nói thứ `/about` không nói. Ba trang cùng nói một nội dung là ba trang cạnh tranh
  nhau trên cùng một truy vấn, và Google chọn hộ một bản.
* **Trang bố mẹ có hẳn mục "Điều Nemo12 không làm".** Bố mẹ đọc trang giới thiệu là để dò xem chỗ
  này có hứa hão không; nói trước giới hạn đáng tin hơn mọi lời cam kết.
* **Chữ cho bot nằm hai chỗ.** `routes.ts` không import React được (§5), nên `paras` của hai trang
  là bản rút gọn chép tay từ `CorePages.tsx` — đổi nội dung trang thì đổi cả hai, đúng như mọi
  route khác trong file đó.

Cả hai vào `SECONDARY` của chân trang chứ không lên thanh nav: trang giới thiệu là thứ người ta tìm
khi đã muốn tìm, không phải lối rẽ mời người đang đọc bỏ dở.
