Marlins IA · Khoá học, thư viện sách, trang chỗ học và quiz
Một phần của Marlins IA. card khoá học, khoá cho bố mẹ, Parent Learning System, thư viện sách, câu bố mẹ hay nói, trang chỗ học, Unit, quiz, câu định danh.
Khoá học: card nhỏ, chi tiết ở trang riêng (SRC-652)
/courses danh sách — MỖI KHOÁ MỘT CARD NHỎ (môn · số buổi học thử · giờ · buổi tới)
/courses/{id} chi tiết một khoá — dùng lại đúng thân đầy đủ của CoursesPanelTrước đó mọi khoá trải hết trên một trang: bố mẹ phải cuộn qua toàn bộ mô tả khoá đầu mới thấy khoá thứ hai tồn tại, và không có URL nào để gửi riêng một khoá cho nhau. Trang chi tiết không có bản dựng thứ hai — nó lọc CoursesPanel còn một khoá, nên nội dung và nút đăng ký không thể lệch nhau.
Bố mẹ học thử Unit 1 (7 ngày) — CHƯA DỰNG, đã gỡ khỏi UI (SRC-656). Bản SRC-652 có một nút trỏ tạm vào learn.nemo12.com; trên production nó dẫn bố mẹ tới màn "nhập mã mời" của học sinh. Hai thứ còn thiếu, đều là dữ liệu/kiến trúc chứ không phải giao diện:
learnchặn toàn app khi tài khoản không có learner đang hoạt động (App.tsx:1348) — bố mẹ theo định nghĩa thì không có. Cần một đường xem thử cho vai phụ huynh.- Bảng
courses(lớp có lịch) không có cột nào trỏ sangcurriculum_courses, nên không có dữ liệu nào nói "Toán 1 dạy Unit nào". Deep link đúng cũng không dựng được.
Luật rút ra: không hứa trên UI một tính năng chưa có đường chạy. Một nút dẫn tới ngõ cụt tệ hơn là không có nút — bố mẹ bấm, gặp màn sai, rồi mất tin vào phần còn lại của trang.
Khoá học cho bố mẹ: danh sách gọn → trang chi tiết có Unit/Lesson (SRC-664)
/parent-courses 3 thẻ gọn: bậc · tên · "n unit · m bài". KHÔNG giá, KHÔNG mô tả.
/parent-courses/{code} chi tiết: giới thiệu · giá · Unit 1 miễn phí · danh sách Unit → LessonThẻ danh sách bỏ giá và mô tả vì ở màn chọn, hai thứ đó không giúp chọn — chúng chỉ làm mỗi thẻ cao gấp ba và đẩy khoá thứ ba xuống dưới màn hình. Cả hai còn nguyên ở trang chi tiết, nơi bố mẹ đã chọn xong và đang cân nhắc thật.
Unit 1 miễn phí nói ngay trên đầu danh sách unit: đây là thứ quyết định bố mẹ có bắt đầu hay không. Các unit sau gắn nhãn "Mở khi đăng ký".
Ranh giới nội dung (QG-014, đã gỡ ở SRC-672). packages.ts khi đó chỉ chứa cấu trúc rỗng — tên unit và tên bài. CLAUDE.md cho phép đúng phần này ("cấu trúc rỗng mà xưởng cần để bám vào… khi chưa có workflow sinh chúng") và cấm gõ tay phần còn lại: Big Idea, Essential Question, guiding question, formative task, kho câu hỏi. Tầng Unit chưa có workflow nào — đo trên D1 ngày 2026-08-26, content_runs có lesson=253, items=395, unit=0.
Bài chỉ có tên, không có nút "Vào học": dựng nút dẫn tới trang rỗng đúng là lỗi đã mắc ở SRC-656. Nhãn "Đang soạn" từng hiện trên mỗi bài nay bỏ hết (SRC-670) — lặp lại một trạng thái nội bộ trên 16 dòng liền nhau là nhiễu, và nó nói về việc của Nemo12 chứ không phải việc của bố mẹ.
Bố cục trang chi tiết (SRC-670)
THÂN (trái) PANEL PHẢI (sticky)
giới thiệu Học phí
"Có phải bạn đang gặp?" [ Bắt đầu học ]
"Học xong, bạn sẽ" Miễn phí 1 lesson
Accordion: Unit → EQ → LessonBản 2026-09-03 (SRC-672) đổi ba chỗ. Nỗi đau đứng đầu thân trang, viết bằng giọng thứ nhất của chính bố mẹ: người đọc phải nhận ra mình trong một câu thì mới đọc tiếp. Mọi unit đóng sẵn — mở sẵn Unit 1 thì bố mẹ đọc luôn nó và không còn thấy khung cả khoá, mà khung mới là thứ giúp quyết; Essential Question vẫn hiện ngay dưới tên unit kể cả khi đóng, nên đọc lướt vẫn biết mỗi unit đi trả lời câu gì. Nhãn "Học thử"/"Khoá" trên từng dòng bài bị bỏ: 162 dòng mà dòng nào cũng đeo nhãn thì nhãn không còn nói gì, và thông tin "miễn phí một bài" đã nằm ngay trong nút.
Nút "Bắt đầu học" / "Miễn phí 1 lesson" làm được thật: nó mở Unit 1 rồi cuộn tới đúng chỗ học miễn phí. Không trỏ sang màn hình chưa tồn tại — luật rút ra ở SRC-656.
Mỗi unit một card, mỗi lesson một card (2026-09-03). Gộp cả chương trình vào một tấm thì 4-5 unit đọc như một danh sách dài không có ranh giới; tách card là mắt thấy ngay unit bắt đầu và kết thúc ở đâu. Lesson cũng vậy: một chỗ học là một việc bố mẹ ngồi xuống làm, nên nó phải đọc như một đơn vị trọn vẹn chứ không như một dòng trong danh sách. Cả chương trình vẫn nằm trong một card lớn bọc ngoài, nên ba tầng thẻ đọc ra ba tầng nội dung: khoá → unit → chỗ học.
Cạm bẫy đã sập hai lần ở đây: card của unit phải là component Card bọc ngoàiAccordionItem, không phải asChild và cũng không phải utility bg-card viết tay. Lớp theme .theme-marlins.od-root bám vào [data-slot="card"]; asChild để props của AccordionItem thắng nên data-slot thành accordion-item, còn utility thì không có data-slot nào — cả hai cách đều cho ra thẻ TRẮNG ĐẶC, chữ trắng trên nền trắng, trên nền biển sâu.
Bên trong một Unit (2026-09-03)
Một unit có đúng MỘT Essential Question, hiện ngay dưới tên unit kể cả khi đang đóng. Bản trước để ba câu ngang hàng nối bằng dấu chấm giữa: ba câu cùng cấp thì không câu nào dẫn đường nữa, người đọc lướt qua như lướt một danh sách. Ba câu cũ nay là ba lesson bên dưới, mỗi lesson một card, gồm việc bố mẹ làm và một guiding question.
Key Concepts đứng giữa Big Idea và các lesson, mỗi khái niệm một chip bấm được, mở popover chứa nghĩa và một ví dụ có thật. Thuật ngữ luôn giữ tiếng Anh (SRC-604): thuật ngữ là định danh, mỗi nơi dịch một kiểu thì bố mẹ tra tiếp ở tài liệu khác không ra. Nghĩa và ví dụ thì song ngữ, vì đó mới là phần để hiểu. Không trải nghĩa ra thẳng trang: 3 khái niệm × nửa màn hình mỗi unit thì khung khoá lại chìm, mà khung mới là thứ giúp quyết.
Số liệu hiện tại: 15 khoá · 54 unit · 54 Essential Question · 162 Key Concept · 162 lesson, tổng 897 mẩu chữ song ngữ.
Học phí và lịch là thứ bố mẹ tra đi tra lại trong lúc đọc chương trình; nằm trong dòng chảy nội dung thì mỗi lần muốn xem lại giá phải cuộn ngược lên đầu.
Chương trình gom vào accordion vì 4 unit × 3 bài trải hết là 16 dòng, mà ở màn quyết-định-có-học-không thì bố mẹ cần thấy khung khoá trước. type="multiple" chứ không "single": bố mẹ hay mở hai unit cạnh nhau để so xem khoá đi từ đâu tới đâu — đóng cái này để mở cái kia là cản đúng việc đó.
Chuyển động dùng FadeIn của Motion.tsx (DS-001: motion, qua LazyMotion + m), biên độ 10px, so le 60ms.
Parent Learning System: 15 khoá cho bố mẹ (SRC-671)
Ba gói cũ (Marlin Start · Compass · Mind) gắn retired, không xoá: người đã mua vẫn còn dấu vết và link cũ không 404. Thay bằng 15 khoá nhóm theo giai đoạn của một vòng học, không xếp phẳng theo số — xếp phẳng thì 15 thẻ đọc như một danh mục rời rạc.
| Nhóm | Khoá |
|---|---|
| Hiểu con | 1 Understanding Your Child as a Learner · 2 The Student Portrait · 3 The Competency Framework for Parents |
| Chọn điều đáng học | 4 What Should My Child Learn? · 5 Goals That Matter · 6 Building 21 for Parents |
| Làm việc học hiệu quả | 7 How Children Actually Learn · 8 Assessment · 9 Learning Math Well · 10 Learning English for Life |
| Dựng tự chủ và quan hệ | 11 Raising an Independent Learner · 12 Talking So Your Child Can Hear You · 13 From Pressure to Ownership |
| Sẵn sàng cho tương lai | 14 Future Skills · 15 Designing Your Child's Learning Journey |
Tổng 54 unit · 162 chỗ học. Mỗi khoá mang jobs trỏ về bảng 10 Job-To-Be-Done, nên tra ngược được "job này khoá nào phục vụ".
Giá: 2.900.000đ một khoá; mua từ 3 khoá bất kỳ thì còn 1.900.000đ mỗi khoá. Giá nói ngay đầu danh sách chứ không giấu trong từng khoá — combo là lý do bố mẹ đọc tiếp cả 15 khoá thay vì dừng ở khoá đầu thấy hợp.
Luật học thử: mở đúng chỗ học đầu tiên của Unit 1, phần còn lại khoá. Cài trong đúng một hàm isFreePreview(unitIndex, questionIndex) chứ không rải cờ trên dữ liệu: luật mở khoá chỉ nên có một chỗ để sửa, và chỗ đó phải là nơi cả UI lẫn API sau này cùng gọi. Test khoá bất biến "mỗi khoá đúng MỘT chỗ miễn phí".
Provenance: nội dung do chủ dự án soạn
Toàn bộ course outcome, tên unit, Big Idea và Essential Question do chủ dự án soạn và gửi trong hội thoại 2026-09-03. Khi đó việc này còn vướng QG-014; cổng ấy đã gỡ hẳn ở SRC-672, nên nội dung soạn tay nay hợp lệ, không cần miễn trừ gì.
Điều vẫn giữ là ghi rõ nguồn gốc: mỗi khoá mang provenance: "owner" thay cho một content_runs.id. Đọc dữ liệu là biết ngay nó không ra từ xưởng nội dung — không ai phải đoán. Đây là phần đáng giữ của QG-014 kể cả sau khi cổng chặn biến mất.
Còn nợ: mỗi chỗ học mới có câu hỏi, chưa có bài để học — kể cả chỗ đã mở miễn phí. Cần workflow sinh nội dung tầng Unit (content_runs.unit = 0).
Thư viện sách cho bố mẹ (SRC-673)
Hai mươi quyển, tên do chủ dự án gửi 2026-09-03, giữ cả hai tên: tên tiếng Anh kiểu book title là tên riêng nên không dịch theo công tắc VI/EN, tên tiếng Việt đứng dưới như phụ đề. Phần còn lại (lời hứa, nỗi đau, mục lục, đoạn đọc thử) song ngữ.
Ba trang, không gộp:
| URL | Việc của bố mẹ ở đây |
|---|---|
/ebooks | nhìn cả kệ, lọc theo nhóm |
/ebooks/{slug} | quyết có đọc quyển này không |
/ebooks/{slug}/read | đọc |
Gộp trang đọc vào trang giới thiệu thì mất đường gửi riêng cho nhau, và một màn vừa bán vừa cho đọc thì không làm tốt việc nào. Trang đọc cố ý là cột chữ hẹp giữa màn — ngược với luật full-width của phần còn lại — vì dòng dài quá 75 ký tự thì mắt lạc dòng; cỡ chữ đổi được và nhớ trong localStorage của chính máy người đọc.
Bìa sinh bằng thuật toán (EbookCover.tsx): bìa thật chưa có, nhưng 20 ô xám giống nhau thì không nhận ra quyển nào. Bìa dựng từ băm FNV-1a của seq:title rồi bơm vào mulberry32, nên cùng một tên luôn ra cùng một bìa — dùng Math.random thì mỗi lần tải một bìa khác, tức là mất luôn tác dụng nhận diện. Bảng màu bó trong họ biển sâu chứ không lấy cả dải màu: 20 bìa cạnh nhau mỗi tấm một tông thì trang đọc như hộp kẹo. Là SVG nên phóng to vẫn nét và không thêm request nào cho một trang có 20 tấm bìa.
Đọc thử = chương 1, và đó là sự thật của dữ liệu: excerpt là toàn bộ chữ hiện có của quyển sách trong repo. Trang đọc nói thẳng "các chương còn lại vẫn đang được viết" thay vì hứa một thứ chưa có đường chạy (luật rút ra ở SRC-656).
Những câu bố mẹ hay nói: Pain → Need → Competency (SRC-704)
Chỉ đạo chủ dự án 2026-09-12: dựng một trang giới thiệu event cho Marlins không mở bằng "Student Portrait", mà mở bằng những câu phụ huynh thực sự nói hàng ngày, rồi bóc dần Pain → Need → Job → Event.
| URL | Trả lời câu gì |
|---|---|
/marlin-pains | "Có ai giống nhà tôi không?" — 8 câu bố mẹ hay nói, mỗi câu một thẻ |
/marlin-pains/{slug} | "Vậy thật ra con đang thiếu gì?" — quote → JTBD → điểm quan trọng → need → competency |
Bốn quyết định của trang này, và lý do:
- Đọc KHÔNG cần đăng nhập. Người đọc chính là phụ huynh chưa có tài khoản; đặt trang sau cửa Google thì chính người cần nó nhất là người không mở được. Nhánh route vì thế nằm trước cửa đăng nhập trong
apps/marlins/src/App.tsx, và hai endpointGET /v1/marlin-pains[/{slug}]là public có khai báo trongauthCoverage.test.ts— cùng lẽ với/v1/b21/*. - Nội dung nằm trong D1, không nằm trong bundle.
marlin_pains+marlin_pain_quotes+marlin_pain_needs+marlin_pain_need_competencies(migration 0214, seedscripts/seed-marlin-pains.sql). Sửa một câu là một lần seed, không phải một lần deploy app. - Tên competency lấy bằng JOIN sang
b21_competencies, không chép lại. Bảng nối chỉ giữ mã và câuwhygiải thích vì sao competency ấy trả lời cho need ấy. Chép tên vào bảng nối thì lần cập nhật khung B21 đầu tiên là lần trang này bắt đầu nói khác vớib21.nemo12.com. Mã đã bị khung gỡ vẫn hiện (rơi về chính mã đó) chứ không im lặng biến mất — mất một dòng mà không ai biết là đúng thứ lỗi khó tìm nhất. - Bấm một need thì mở ra tại chỗ, không sang trang khác. Phụ huynh đang đọc một mạch từ câu than phiền xuống; một lần đổi trang ở giữa mạch đó là một lần mất chỗ. Link từng competency mở tab mới sang
b21.nemo12.com/f/{khung}/c/{mã}— cùng lý do, chỉ ngược chiều: rời cổng Marlins giữa mạch đọc thì phải quay lại được bằng cách đóng tab.
Ánh xạ 8 pain → 16 need → 42 competency của khung nemo (Building 21 Student Competencies) là ánh xạ do người chọn, không phải suy ra từ từ khoá: một cổng keyword sẽ nối "motivation" với mọi competency có chữ "effort" và không nối được need relevance với SS.3 Make an Impact, tức là sai ở đúng chỗ ánh xạ này có giá trị.
Chữ trên trang là tiếng Việt, thuật ngữ giữ nguyên tiếng Anh (Autonomy, JTBD, Transferable Skills) đúng như bản chủ dự án viết, và trang không có nút EN/VI: chỉ có một bản, nên một cái nút hai lựa chọn mà một lựa chọn không tồn tại là một cái nút nói dối.
Trang khoá bố mẹ: học phí đóng sẵn, badge trên nền biển, khối năng lực chỉ cho người soạn (SRC-705)
Ba chỉnh từ ảnh chụp màn hình của chủ dự án ngày 2026-09-13, đều trên /parent-courses/{code}.
Học phí vào accordion đóng sẵn. SRC-664 đã bỏ giá khỏi thẻ danh sách vì ở màn chọn giá không giúp chọn; ở trang chi tiết thì giá ở lại, nhưng nó đang phơi ra trong một thẻ riêng ở cột phải, tức là thứ đầu tiên mắt bắt được khi trang mở. Bố mẹ quyết bằng con số trước khi kịp đọc khoá dạy gì. Nay nó đóng sẵn dưới tiêu đề "Học phí", một cú bấm là mở — không giấu, chỉ đổi thứ tự đọc: nội dung trước, giá sau.
Badge viền phải tự khai màu chữ trong theme biển sâu. variant="outline" của shadcn là border-border text-foreground, mà --foreground là màu mực sinh ra cho nền sáng; trên nền biển nó ra chữ gần đen trên xanh đậm và chip Key Concept đọc như đang bị vô hiệu hoá. Đây là lần thứ ba cùng một khuôn hỏng trong .theme-marlins (trước đó: .text-muted-foreground, và .n12-tab ở SRC-580) — bất cứ lớp nào lấy màu mực làm mặc định đều chìm ở cổng này, và không có gì đỏ ở đâu cả. Luật mới nhắm đúng [data-slot="badge"].border-border để badge đặc ("Bậc 1", "Miễn phí") giữ nguyên màu nền của chúng.
Khối năng lực trong Unit chỉ hiện cho người soạn. Mã PC.1.2, chữ "bậc", "ảnh hưởng ké" là ngôn ngữ của người thiết kế chương trình; bố mẹ vào đây để hiểu con mình. apps/marlins/src/authorView.ts gác UnitCompetencyBlock theo email tài khoản.
Đây là cổng hiển thị, không phải gác bảo mật: GET /v1/marlin-framework vẫn trả khung năng lực cho mọi người và devtools vẫn đọc được. Đúng mức cần cho một thứ để soát nội dung — ngày nào khung trở thành thứ phải giấu thật thì phải gác ở API, không phải ở màn hình. Kiểm ở cả hai chỗ (Courses.tsx và trong chính component): để component tự trả null thì div bọc ngoài vẫn còn và để lại một khoảng trống không ai giải thích được.
CourseCompetencySummary ở đầu trang vẫn hiện cho mọi người — nó cũng dùng mã PC.x, và có thể sẽ theo sau, nhưng nó không nằm trong ảnh chủ dự án gửi nên chưa đổi.
Trang chỗ học: khoảng cách là thứ chia bài, không phải trang trí (SRC-706)
Ảnh chủ dự án gửi 2026-09-13: body của /parent-courses/{code}/u/{ui}/l/{li} đọc như một mảng chữ liền. Hai nguyên nhân, và chúng cộng hưởng với nhau.
Mọi khối cách nhau đúng một khoảng. Wrapper để space-y-6, tức khoảng cách giữa hai cụm lớn bằng khoảng cách giữa hai đoạn văn bên trong một cụm. Mắt không có chỗ nào để biết một cụm đã kết thúc, nên toàn trang phải đọc tuần tự từ trên xuống mới hiểu cấu trúc — trong khi cấu trúc ấy đã được vẽ sẵn ở panel trái. Nay space-y-16 ở cấp cụm, space-y-5/p-8 bên trong: chênh lệch giữa hai mức mới là thứ nói "đây là một cụm khác".
Ba dòng đầu trang lặp lại thứ đã có ở chỗ khác. "Unit n · tên unit" nằm ngay bên trái trong panel mục lục; "chỗ học miễn phí" đã nói ở trang khoá lúc bố mẹ bấm vào. Cả hai bị bỏ — bố mẹ mở một chỗ học ra là để đọc nội dung, không phải để được nhắc mình đang ở đâu ba lần. Còn lại tên bài và Guiding Question.
Khối quiz rút từ ba dòng xuống một: bỏ "n câu, mỗi câu 4 phương án" (bấm vào là thấy, biết trước cũng không đổi quyết định) và bỏ dòng ba con số lần-gần-nhất/tốt-nhất/số-lần. Ba con số đứng cạnh nhau thì không con số nào đọng lại; giữ đúng "tốt nhất" là cái bố mẹ thật sự muốn biết.
Giới hạn đã biết: apps/marlins chưa có bộ e2e nên thay đổi này chỉ được kiểm tới typecheck + build, không có cổng nào bắt lỗi runtime hay nhìn được bố cục thật.
Tổng quan Unit: bậc thứ ba có đường đi tới (SRC-707)
Chỉ đạo chủ dự án 2026-09-13: panel trái của chế độ học phải có một link mở Unit Overview.
Chẩn đoán: cây khoá có bốn bậc (Course → Unit → Lesson → cụm), nhưng panel trái chỉ có đường tới hai bậc — khoá (logo, nút ✕) và chỗ học. Bậc Unit giữ đúng ba thứ quyết định nghĩa của cả unit (Big Idea · Essential Question · Key Concepts) mà không có cửa nào: bố mẹ đang đọc dở phải thoát ra trang bán rồi mở đúng accordion mới xem lại được "unit này trả lời câu gì".
| URL | Trả lời câu gì |
|---|---|
/parent-courses/{code}/u/{n} | "Unit này rốt cuộc đi trả lời câu gì, và bắt đầu từ đâu" |
/parent-courses/{code}/u/{n}/l/{m} | "Tôi làm gì trong chỗ học này" |
Bốn quyết định:
- Hai cửa vào, không phải một. Một dòng
Tổng quan Unit nđứng ngay trên mục lục (một cú bấm, không phải mở dropdown trước), và tên unit trong dropdown nay là nút chứ không phải nhãn — một tiêu đề đứng trước danh sách mà bấm không được là đúng chỗ người ta sẽ bấm đầu tiên. - Cùng khung học, không phải trang khác. Tổng quan unit là một bậc của chính cây ấy, nên nó giữ panel trái; đưa ra ngoài khung học thì bố mẹ mất mục lục ngay lúc cần nó nhất.
- Mục lục đổi theo màn đang mở. Ở tổng quan, "Trong bài này" thành "Trong unit này" và liệt kê các chỗ học. Liệt kê các cụm của chỗ học số 1 trong lúc xem tổng quan là mời bố mẹ vào một chỗ chưa ai chọn.
- Không khoá theo học thử. Trang này là KHUNG của unit — thứ đã hiện công khai ở trang khoá để bố mẹ quyết có mua không. Khoá nó ở đây là giấu đúng thứ mình đang dùng để mời. Nội dung thân bài vẫn khoá như cũ (
isFreePreview).
Khác trang khoá ở một chỗ có chủ đích: Key Concept ở đây trải nghĩa và ví dụ ra thẳng trang, không giấu sau popover. Ở trang bán mỗi chữ thêm là một chữ đẩy khung khoá xuống dưới; ở đây bố mẹ đã vào học và đang cần đúng phần sâu ấy.
Quiz là một cụm, nên nó chỉ hiện ở màn của nó (SRC-708)
Thân bài vốn đã hiện một cụm một lúc từ 2026-09-04 — nhưng khối quiz thì được render ở mọi cụm. Nên màn "Vào bài" mang theo cả thẻ quiz của cụm thứ tư, màn "Ba ví dụ" cũng vậy: mục lục bên trái nói có bốn cụm, còn màn hình thì mỗi cụm rưỡi một lần. Đó là phần lớn cảm giác chật còn lại sau khi đã giãn khoảng cách ở SRC-706.
Nay here.slug === "quiz" mới render khối đó, đúng như ba cụm kia. Kèm theo: viên nút "Đọc xong cụm này" không hiện ở màn quiz — ở đó việc phải làm là bấm "Làm quiz", nên hai lời mời cạnh nhau cho cùng một bước là một lời mời thừa.
Đường đi vẫn liền: đánh dấu xong cụm cuối trước quiz thì toggle() đưa thẳng sang trang quiz (logic có sẵn), nên bố mẹ đọc tuần tự không bao giờ phải ghé màn quiz để bấm thêm một nút nữa. Màn quiz là chỗ dành cho người bấm thẳng vào mục 4 trong mục lục, hoặc quay lại sau một tuần để làm lại.
Câu định danh của cổng: một câu, hai đầu trang (SRC-721)
Chỉ đạo chủ dự án 2026-09-15: chỗ cạnh logo đổi từ "cổng phụ huynh" sang
Cộng đồng cha mẹ thay đổi bản thân, để giúp con đi được xa hơn
và câu ấy là giá trị dùng chung cho cả header lẫn chân trang, giữ ở apps/marlins/src/brand.ts.
Vì sao đổi: "cổng phụ huynh" mô tả cái cửa (đây là khu vực dành cho phụ huynh), còn câu mới nói bố mẹ vào đây để làm gì. Trước chỉ đạo này header và chân trang còn nói hai câu khác hẳn nhau, tức là hai đầu của cùng một trang tự giới thiệu bằng hai giọng.
Hai độ dài, không phải một câu rồi cắt bằng CSS: từ xl trở lên hiện câu đầy đủ, hẹp hơn thì bản ngắn "Cộng đồng cha mẹ thay đổi bản thân". Cắt bằng truncate sẽ ra "Cộng đồng cha mẹ thay đổi bản…", một câu dở dang đọc như lỗi hiển thị; bản ngắn dừng ở một mệnh đề trọn nghĩa.
Câu này nằm ở dòng thứ hai, dưới tên Marlins, không nối tiếp cùng dòng với logo: nó dài hơn hẳn nhãn cũ, để cùng dòng thì trên laptop nó đẩy công tắc ngôn ngữ và menu avatar sát mép. Thứ tự đọc cũng đúng vai — tên trước, lời hứa sau.