Card patterns (SRC-1298)
Chủ dự án 08.10.2026: nội dung lesson phải tách thành các card riêng, khoảng cách rộng cả trong card lẫn giữa các card để đọc thoáng; cách trình bày trong card phải đa dạng; và mọi loại thông tin được vẽ bằng đúng một pattern trong một thư viện cố định, không vẽ tuỳ hứng. Cùng ngày chủ dự án nhấn thêm: nội dung kiểu "em gõ X, AI trả lời Y" (Lượt 1 / Lượt 2) phải có pattern hội thoại riêng.
Trang này là một phần của DS-001, đứng cạnh Information Hierarchy (thứ bậc chữ, một h1, một nút tô đầy) và Guided Journey (cấu trúc journey). Áp cho mọi màn AI Teen (lesson, unit) và mọi màn mới dựng nội dung học.
1. Luật
- CP-1. Một loại thông tin, đúng một pattern. Bảng §3 là bảng tra bắt buộc. Loại thông tin chưa có trong bảng thì thêm một dòng ở đây và một id trong
patterns.tstrước, rồi mới vẽ. - CP-2. Một mapping duy nhất cho khối bài học.
apps/learn/src/aiTeen/blockPatterns.tsquyết định khối nào thành pattern nào (BLOCK_PATTERNSlà kiểu ánh xạ trênLessonBlock["kind"], nên thêm mộtkindmà không khai pattern là lỗi kiểu;classifyBlocklàswitchvét cạn). Component vẽ (LessonBlockCard.tsx) không tự quyết. - CP-3. File nội dung giữ chữ trơn. Cấu trúc (lượt hội thoại, bước, cột so sánh, khung) được phân tích lúc vẽ từ quy ước chữ có sẵn (§4), có unit test chạy trên mọi khối thật. Tác giả không phải viết JSON.
- CP-4. Nhịp khoảng cách. Giữa các card
gap-6, từsmlàgap-8(STACK); trong cardp-5 gap-4, từsmlàp-6 gap-5(CARD_PAD). Một phần đọc là một CHUỖI card, không phải một cột chữ dài. - CP-5. Mọi card mang
data-pattern="<id>"để test và audit thấy pattern nào vẽ thông tin nào. - CP-6. Chữ theo hierarchy.md: nhãn trên đầu card là
T.meta(không phải kicker), tiêu đề card là h3T.card; chỉintro,nextvà kết quả Kiểm tra mang h2 của bước. Card lồng tối đa một cấp (ô bên trong card là nền nhạt, không phải card thứ hai có bóng). - CP-7. Màu chỉ từ token. Viền trái
accentcho thứ cần chú ý, nềnmuted/40cho thứ phụ trợ,destructive/5cho cảnh báo,success/10cho "Thật ra". Không màu thô, không giá trị tuỳ ý.
2. Thư viện (18 pattern)
Mã nguồn: apps/learn/src/components/cards/patterns.ts (danh sách, mục đích, khoảng cách) và Cards.tsx (một component mỗi pattern, cùng một vỏ PatternCard).
| Pattern | Mục đích | Cấu tạo | Màu, nhấn | Đáp ứng (375px → desktop) |
|---|---|---|---|---|
intro | Câu hỏi dẫn dắt của lesson và một câu tóm tắt | h2 câu hỏi + đoạn tóm tắt | viền trái accent, nền accent/5 | một cột |
outcomes | Lesson / unit outcomes | h3 + danh sách có dấu tick | trơn, tick accent | một cột |
output | Thứ em cầm ra khỏi lesson | nhãn "Em sẽ cầm ra" + một câu chữ lớn + dòng meta | nền muted/40 | một cột |
concepts | Key concept của lesson | h3 + chip (bấm mở giải thích) | trơn | chip xuống dòng |
prose | Chữ đọc | h3 tuỳ chọn + đoạn ngắn; dòng - thành gạch đầu dòng | trơn | một cột, max đo theo cột chính |
example | Ví dụ kể bằng lời | nhãn "Ví dụ" + h3 + đoạn | nền muted/40 | một cột |
chat | Hội thoại em gõ / AI trả lời, một hay nhiều lượt | nhãn "Ví dụ hỏi đáp" + h3; mỗi lượt một ô có nhãn "Lượt n"; bong bóng em (phải, nền accent/10, "Em gõ") và AI (trái, viền, "AI" + nhãn "Minh hoạ do Nemo viết"); danh sách đánh số trong câu AI thành <ol> | accent cho nhãn lượt | lượt xếp chồng; từ md hai lượt đứng cạnh nhau (data-variant="compare") |
compare | Hai bản đặt cạnh nhau | h3 + 2 ô có nhãn | ô nền background có viền | xếp chồng; từ md hai cột |
steps | Quy trình, chuỗi vòng | h3 + dòng thời gian đánh số tròn | số trên nền accent/10 | một cột |
framework | Khung có 2-4 phần có tên (vd 4 phần của một prompt) | h3 + ô gạch, mỗi ô nhãn + một câu | ô nền accent/5 | một cột; từ sm lưới 2 cột |
prompt | Prompt mẫu để chép | nhãn "Prompt mẫu" + h3 + khối chữ đơn cách + nút Chép | khối nền muted/40 | khối xuống dòng, không cuộn ngang |
callout | Mẹo / cảnh báo / giới hạn | biểu tượng + nhãn ("Mẹo", "Cẩn thận", "Giới hạn") + đoạn | tip: viền accent · warning: viền + nền destructive · limit: nền muted | một cột |
misconception | Hiểu lầm và sự thật | hai ô "Hiểu lầm" (X) → "Thật ra" (tick) | destructive/5 và success/10 | xếp chồng; từ md hai cột |
reflection | Câu hỏi để em tự nghĩ | biểu tượng + "Câu hỏi cho em" + câu hỏi + ô ghi chú | nền muted/40 | một cột |
checklist | Bài làm tay có danh sách tự kiểm | nhãn "Câu n · Thực hành" + đề + gợi ý + ô tick | trơn | một cột |
quiz | Câu hỏi có phương án (cổng đọc, Kiểm tra, tự chấm rubric) | nhãn + câu hỏi + các nút chọn | chọn: viền primary | một cột; rubric 5 mức thành lưới từ lg |
result | Điểm, kết quả kiểm tra, giải thích, bằng chứng | h2/nhãn + điểm + việc tiếp | đạt: viền accent | một cột |
next | Đường đi tiếp (lesson sau, Practice) | h2 + meta + nút | trơn | nút xuống dòng ở 320px |
3. Bảng tra: loại thông tin → pattern bắt buộc
| Loại thông tin (AI Teen lesson và unit) | Pattern |
|---|---|
| Câu hỏi dẫn dắt + tóm tắt lesson (Bắt đầu · Câu hỏi) | intro |
| Lesson Outcomes, Unit Outcomes dạng danh sách | outcomes |
| "Em sẽ cầm ra", bước Đúc kết · Sản phẩm, "Em sẽ làm ra sản phẩm nào?" của unit | output |
| Concept chip của lesson, "Em sẽ học được gì?" của unit | concepts |
Khối text thường | prose |
Khối example kể bằng lời | example |
Khối example theo quy ước "Em gõ / AI có thể trả lời" (Lượt 1/2 …) | chat |
Khối example có hai đầu mục VIẾT HOA (TRƯỚC / SAU …) | compare |
Khối text / example có ≥3 dòng "1." / "Bước n" / "Vòng n" liên tiếp; danh sách activity khi lesson chưa có bài | steps |
Khối text có 2-4 dòng liên tiếp "Nhãn ngắn: nội dung" (khung 4 phần của prompt …) | framework |
Khối prompt | prompt |
Khối tip (mẹo / cảnh báo / giới hạn tự nhận theo từ khoá) | callout |
| Khối có "Hiểu lầm: … / Thật ra: …" | misconception |
"Câu hỏi cho em: …" sau một hội thoại, khối text tiêu đề "Em tự rút ra …", câu Reflect của unit, ô "Sản phẩm của em" ở Assess | reflection |
| Bài thực hành có checklist (Practice) | checklist |
| Câu kiểm tra nhanh của cổng đọc, câu Kiểm tra, tự chấm rubric ở Assess | quiz |
| Tổng điểm cổng đọc, giải thích sau khi qua, "Em đúng k/N câu", thẻ "Cần ôn", bằng chứng tự chấm, "Unit đã xong" | result |
| Lesson tiếp theo / trước, sang Practice, thông báo "không có câu kiểm tra" | next |
Nút "Xong bước này" và thanh "Sang …" cuối mỗi bước là điều hướng của Guided Journey, không phải nội dung, nên đứng ngoài card (guided-journey.md).
4. Quy ước chữ mà bộ phân tích đọc
Quy ước trong body | Thành |
|---|---|
Dòng LƯỢT n / Lượt n đứng riêng | nhãn một lượt mới |
Dòng bắt đầu Em gõ: hoặc Prompt: | bong bóng của em (bỏ ngoặc kép bọc ngoài) |
Dòng bắt đầu AI có thể trả lời (có thể kèm kiểu như, (…)) | bong bóng AI; các dòng ngay sau nối vào đến dòng trống |
Dòng (… minh hoạ …) đứng riêng | bỏ, thay bằng nhãn "Minh hoạ do Nemo viết" trên mỗi câu AI |
Dòng bắt đầu Câu hỏi cho em: | card reflection riêng ngay sau hội thoại |
Test giữ: apps/learn/src/aiTeen/blockPatterns.test.ts (mọi kind có pattern, mọi khối thật rơi vào pattern kind ấy cho phép, mọi khối dùng quy ước hội thoại thành chat không sót dấu). E2E aiTeen.spec.ts kiểm data-pattern, khoảng cách giữa card và 375px không tràn ngang.